[libgda: 1/3] sqlcipher.patch was updated against sqlcipehr



commit 512d2b6cebb16d677fe37f92cc3071a22fb3958e
Author: Pavlo Solntsev <p sun fun gmail com>
Date:   Sat Mar 31 22:54:02 2018 -0500

    sqlcipher.patch was updated against sqlcipehr
    
    ./providers/sqlcipher/sqlcipher.patch was regenerated against upstream
    source of sqlcipher. It was necessary, since the following error was
    observed:
    
    sqlite3.c: In function ‘sqlcipher_openssl_hmac’:
    sqlite3.c:17150:12: error: storage size of ‘hctx’ isn’t known
       HMAC_CTX hctx;
    
    The methodology to generate sqlcipher.patch was taken from the following
    file: ./providers/sqlcipehr/NOTE_for_new_SQLCipher_version.
    
    This problem was also mentioned as the bug: 781832

 providers/sqlcipher/sqlcipher.patch | 167754 ++++++++++++++++++++++++---------
 1 file changed, 125716 insertions(+), 42038 deletions(-)
---
diff --git a/providers/sqlcipher/sqlcipher.patch b/providers/sqlcipher/sqlcipher.patch
index d47cdf488..87fa5f1e5 100644
--- a/providers/sqlcipher/sqlcipher.patch
+++ b/providers/sqlcipher/sqlcipher.patch
@@ -1,43861 +1,127402 @@
---- sqlite3.c.sqlite   2016-03-09 15:41:25.053136000 +0100
-+++ sqlite3.c  2016-03-09 15:41:16.424942202 +0100
-@@ -13786,9 +13786,45 @@
- #endif /* _SQLITEINT_H_ */
- 
- /************** End of sqliteInt.h *******************************************/
--/************** Begin file global.c ******************************************/
-+/************** Begin file crypto.c ******************************************/
-+/* 
-+** SQLCipher
-+** http://sqlcipher.net
-+** 
-+** Copyright (c) 2008 - 2013, ZETETIC LLC
-+** All rights reserved.
-+** 
-+** Redistribution and use in source and binary forms, with or without
-+** modification, are permitted provided that the following conditions are met:
-+**     * Redistributions of source code must retain the above copyright
-+**       notice, this list of conditions and the following disclaimer.
-+**     * Redistributions in binary form must reproduce the above copyright
-+**       notice, this list of conditions and the following disclaimer in the
-+**       documentation and/or other materials provided with the distribution.
-+**     * Neither the name of the ZETETIC LLC nor the
-+**       names of its contributors may be used to endorse or promote products
-+**       derived from this software without specific prior written permission.
-+** 
-+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
-+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
-+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+**  
-+*/
-+/* BEGIN SQLCIPHER */
-+#ifdef SQLITE_HAS_CODEC
-+
-+/* #include <assert.h> */
-+/************** Include btreeInt.h in the middle of crypto.c *****************/
-+/************** Begin file btreeInt.h ****************************************/
+--- sqlite3.h.sqlite   2018-03-07 17:32:12.658688849 -0600
++++ sqlite3.h  2018-03-06 14:53:41.275051055 -0600
+@@ -1,5 +1,5 @@
  /*
--** 2008 June 13
-+** 2004 April 6
+-** 2001 September 15
++** 2001-09-15
  **
  ** The author disclaims copyright to this source code.  In place of
  ** a legal notice, here is a blessing:
-@@ -13798,2674 +13834,3856 @@
- **    May you share freely, never taking more than you give.
+@@ -23,15 +23,15 @@
  **
- *************************************************************************
-+** This file implements an external (disk-based) database using BTrees.
-+** For a detailed discussion of BTrees, refer to
+ ** The official C-language API documentation for SQLite is derived
+ ** from comments in this file.  This file is the authoritative source
+-** on how SQLite interfaces are suppose to operate.
++** on how SQLite interfaces are supposed to operate.
  **
--** This file contains definitions of global variables and constants.
--*/
--
--/* An array to map all upper-case characters into their corresponding
--** lower-case character. 
-+**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
-+**     "Sorting And Searching", pages 473-480. Addison-Wesley
-+**     Publishing Company, Reading, Massachusetts.
+ ** The name of this file under configuration management is "sqlite.h.in".
+ ** The makefile makes some minor changes to this file (such as inserting
+ ** the version number) and changes its name to "sqlite3.h" as
+ ** part of the build process.
+ */
+-#ifndef _SQLITE3_H_
+-#define _SQLITE3_H_
++#ifndef SQLITE3_H
++#define SQLITE3_H
+ #include <stdarg.h>     /* Needed for the definition of va_list */
+ 
+ /*
+@@ -54,8 +54,17 @@
+ #ifndef SQLITE_CDECL
+ # define SQLITE_CDECL
+ #endif
++#ifndef SQLITE_APICALL
++# define SQLITE_APICALL
++#endif
+ #ifndef SQLITE_STDCALL
+-# define SQLITE_STDCALL
++# define SQLITE_STDCALL SQLITE_APICALL
++#endif
++#ifndef SQLITE_CALLBACK
++# define SQLITE_CALLBACK
++#endif
++#ifndef SQLITE_SYSAPI
++# define SQLITE_SYSAPI
+ #endif
+ 
+ /*
+@@ -99,32 +108,33 @@
+ ** be held constant and Z will be incremented or else Y will be incremented
+ ** and Z will be reset to zero.
  **
--** SQLite only considers US-ASCII (or EBCDIC) characters.  We do not
--** handle case conversions for the UTF character set since the tables
--** involved are nearly as big or bigger than SQLite itself.
--*/
--SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
--#ifdef SQLITE_ASCII
--      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
--     18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
--     36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
--     54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
--    104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
--    122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
--    108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
--    126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
--    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
--    162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
--    180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
--    198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
--    216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
--    234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
--    252,253,254,255
--#endif
--#ifdef SQLITE_EBCDIC
--      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 0x */
--     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */
--     32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 2x */
--     48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
--     64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
--     80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
--     96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */
--    112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 7x */
--    128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
--    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, /* 9x */
--    160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
--    176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
--    192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
--    208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
--    224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */
--    240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */
--#endif
--};
--
--/*
--** The following 256 byte lookup table is used to support SQLites built-in
--** equivalents to the following standard library functions:
-+** The basic idea is that each page of the file contains N database
-+** entries and N+1 pointers to subpages.
+-** Since version 3.6.18, SQLite source code has been stored in the
++** Since [version 3.6.18] ([dateof:3.6.18]), 
++** SQLite source code has been stored in the
+ ** <a href="http://www.fossil-scm.org/";>Fossil configuration management
+ ** system</a>.  ^The SQLITE_SOURCE_ID macro evaluates to
+ ** a string which identifies a particular check-in of SQLite
+ ** within its configuration management system.  ^The SQLITE_SOURCE_ID
+-** string contains the date and time of the check-in (UTC) and an SHA1
+-** hash of the entire source tree.
++** string contains the date and time of the check-in (UTC) and a SHA1
++** or SHA3-256 hash of the entire source tree.
  **
--**   isspace()                        0x01
--**   isalpha()                        0x02
--**   isdigit()                        0x04
--**   isalnum()                        0x06
--**   isxdigit()                       0x08
--**   toupper()                        0x20
--**   SQLite identifier character      0x40
-+**   ----------------------------------------------------------------
-+**   |  Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) |
-+**   ----------------------------------------------------------------
+ ** See also: [sqlite3_libversion()],
+ ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
+ ** [sqlite_version()] and [sqlite_source_id()].
+ */
+-#define SQLITE_VERSION        "3.8.10.2"
+-#define SQLITE_VERSION_NUMBER 3008010
+-#define SQLITE_SOURCE_ID      "2015-05-20 18:17:19 2ef4f3a5b1d1d0c4338f8243d40a2452cc1f7fe4"
++#define SQLITE_VERSION        "3.20.1"
++#define SQLITE_VERSION_NUMBER 3020001
++#define SQLITE_SOURCE_ID      "2017-08-24 16:21:36 
8d3a7ea6c5690d6b7c3767558f4f01b511c55463e3f9e64506801fe9b74dce34"
+ 
+ /*
+ ** CAPI3REF: Run-Time Library Version Numbers
+-** KEYWORDS: sqlite3_version, sqlite3_sourceid
++** KEYWORDS: sqlite3_version sqlite3_sourceid
  **
--** Bit 0x20 is set if the mapped character requires translation to upper
--** case. i.e. if the character is a lower-case ASCII character.
--** If x is a lower-case ASCII character, then its upper-case equivalent
--** is (x - 0x20). Therefore toupper() can be implemented as:
-+** All of the keys on the page that Ptr(0) points to have values less
-+** than Key(0).  All of the keys on page Ptr(1) and its subpages have
-+** values greater than Key(0) and less than Key(1).  All of the keys
-+** on Ptr(N) and its subpages have values greater than Key(N-1).  And
-+** so forth.
+ ** These interfaces provide the same information as the [SQLITE_VERSION],
+ ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
+ ** but are associated with the library instead of the header file.  ^(Cautious
+ ** programmers might include assert() statements in their application to
+ ** verify that values returned by these interfaces match the macros in
+-** the header, and thus insure that the application is
++** the header, and thus ensure that the application is
+ ** compiled with matching library and header files.
  **
--**   (x & ~(map[x]&0x20))
-+** Finding a particular key requires reading O(log(M)) pages from the 
-+** disk where M is the number of entries in the tree.
+ ** <blockquote><pre>
+@@ -146,9 +156,9 @@
+ ** See also: [sqlite_version()] and [sqlite_source_id()].
+ */
+ SQLITE_API SQLITE_EXTERN const char sqlite3_version[];
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void);
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void);
+-SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void);
++SQLITE_API const char *sqlite3_libversion(void);
++SQLITE_API const char *sqlite3_sourceid(void);
++SQLITE_API int sqlite3_libversion_number(void);
+ 
+ /*
+ ** CAPI3REF: Run-Time Library Compilation Options Diagnostics
+@@ -173,8 +183,8 @@
+ ** [sqlite_compileoption_get()] and the [compile_options pragma].
+ */
+ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+-SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName);
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N);
++SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
++SQLITE_API const char *sqlite3_compileoption_get(int N);
+ #endif
+ 
+ /*
+@@ -213,7 +223,7 @@
  **
--** Standard function tolower() is implemented using the sqlite3UpperToLower[]
--** array. tolower() is used more often than toupper() by SQLite.
-+** In this implementation, a single file can hold one or more separate 
-+** BTrees.  Each BTree is identified by the index of its root page.  The
-+** key and data for any entry are combined to form the "payload".  A
-+** fixed amount of payload can be carried directly on the database
-+** page.  If the payload is larger than the preset amount then surplus
-+** bytes are stored on overflow pages.  The payload for an entry
-+** and the preceding pointer are combined to form a "Cell".  Each 
-+** page has a small header which contains the Ptr(N) pointer and other
-+** information such as the size of key and data.
+ ** See the [threading mode] documentation for additional information.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void);
++SQLITE_API int sqlite3_threadsafe(void);
+ 
+ /*
+ ** CAPI3REF: Database Connection Handle
+@@ -249,7 +259,11 @@
+ */
+ #ifdef SQLITE_INT64_TYPE
+   typedef SQLITE_INT64_TYPE sqlite_int64;
+-  typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
++# ifdef SQLITE_UINT64_TYPE
++    typedef SQLITE_UINT64_TYPE sqlite_uint64;
++# else  
++    typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
++# endif
+ #elif defined(_MSC_VER) || defined(__BORLANDC__)
+   typedef __int64 sqlite_int64;
+   typedef unsigned __int64 sqlite_uint64;
+@@ -310,8 +324,8 @@
+ ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
+ ** argument is a harmless no-op.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*);
++SQLITE_API int sqlite3_close(sqlite3*);
++SQLITE_API int sqlite3_close_v2(sqlite3*);
+ 
+ /*
+ ** The type for a callback function.
+@@ -347,7 +361,7 @@
+ ** from [sqlite3_malloc()] and passed back through the 5th parameter.
+ ** To avoid memory leaks, the application should invoke [sqlite3_free()]
+ ** on error message strings returned through the 5th parameter of
+-** of sqlite3_exec() after the error message string is no longer needed.
++** sqlite3_exec() after the error message string is no longer needed.
+ ** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors
+ ** occur, then sqlite3_exec() sets the pointer in its 5th parameter to
+ ** NULL before returning.
+@@ -374,7 +388,7 @@
+ ** Restrictions:
  **
--** Bit 0x40 is set if the character non-alphanumeric and can be used in an 
--** SQLite identifier.  Identifiers are alphanumerics, "_", "$", and any
--** non-ASCII UTF character. Hence the test for whether or not a character is
--** part of an identifier is 0x46.
-+** FORMAT DETAILS
+ ** <ul>
+-** <li> The application must insure that the 1st parameter to sqlite3_exec()
++** <li> The application must ensure that the 1st parameter to sqlite3_exec()
+ **      is a valid and open [database connection].
+ ** <li> The application must not close the [database connection] specified by
+ **      the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
+@@ -382,7 +396,7 @@
+ **      the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
+ ** </ul>
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_exec(
++SQLITE_API int sqlite3_exec(
+   sqlite3*,                                  /* An open database */
+   const char *sql,                           /* SQL to be evaluated */
+   int (*callback)(void*,int,char**,char**),  /* Callback function */
+@@ -403,7 +417,7 @@
+ */
+ #define SQLITE_OK           0   /* Successful result */
+ /* beginning-of-error-codes */
+-#define SQLITE_ERROR        1   /* SQL error or missing database */
++#define SQLITE_ERROR        1   /* Generic error */
+ #define SQLITE_INTERNAL     2   /* Internal logic error in SQLite */
+ #define SQLITE_PERM         3   /* Access permission denied */
+ #define SQLITE_ABORT        4   /* Callback routine requested an abort */
+@@ -418,7 +432,7 @@
+ #define SQLITE_FULL        13   /* Insertion failed because database is full */
+ #define SQLITE_CANTOPEN    14   /* Unable to open the database file */
+ #define SQLITE_PROTOCOL    15   /* Database lock protocol error */
+-#define SQLITE_EMPTY       16   /* Database is empty */
++#define SQLITE_EMPTY       16   /* Not used */
+ #define SQLITE_SCHEMA      17   /* The database schema changed */
+ #define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */
+ #define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */
+@@ -426,7 +440,7 @@
+ #define SQLITE_MISUSE      21   /* Library used incorrectly */
+ #define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
+ #define SQLITE_AUTH        23   /* Authorization denied */
+-#define SQLITE_FORMAT      24   /* Auxiliary database format error */
++#define SQLITE_FORMAT      24   /* Not used */
+ #define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */
+ #define SQLITE_NOTADB      26   /* File opened that is not a database file */
+ #define SQLITE_NOTICE      27   /* Notifications from sqlite3_log() */
+@@ -443,7 +457,8 @@
+ ** [result codes].  However, experience has shown that many of
+ ** these result codes are too coarse-grained.  They do not provide as
+ ** much information about problems as programmers might like.  In an effort to
+-** address this, newer versions of SQLite (version 3.3.8 and later) include
++** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8]
++** and later) include
+ ** support for additional result codes that provide more detailed information
+ ** about errors. These [extended result codes] are enabled or disabled
+ ** on a per database connection basis using the
+@@ -477,6 +492,8 @@
+ #define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
+ #define SQLITE_IOERR_GETTEMPPATH       (SQLITE_IOERR | (25<<8))
+ #define SQLITE_IOERR_CONVPATH          (SQLITE_IOERR | (26<<8))
++#define SQLITE_IOERR_VNODE             (SQLITE_IOERR | (27<<8))
++#define SQLITE_IOERR_AUTH              (SQLITE_IOERR | (28<<8))
+ #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
+ #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
+ #define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
+@@ -504,6 +521,7 @@
+ #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
+ #define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
+ #define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
++#define SQLITE_OK_LOAD_PERMANENTLY     (SQLITE_OK | (1<<8))
+ 
+ /*
+ ** CAPI3REF: Flags For File Open Operations
+@@ -558,7 +576,7 @@
+ ** file that were written at the application level might have changed
+ ** and that adjacent bytes, even bytes within the same sector are
+ ** guaranteed to be unchanged.  The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
+-** flag indicate that a file cannot be deleted when open.  The
++** flag indicates that a file cannot be deleted when open.  The
+ ** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
+ ** read-only media and cannot be changed even by processes with
+ ** elevated privileges.
+@@ -708,6 +726,9 @@
+ ** <li> [SQLITE_IOCAP_ATOMIC64K]
+ ** <li> [SQLITE_IOCAP_SAFE_APPEND]
+ ** <li> [SQLITE_IOCAP_SEQUENTIAL]
++** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
++** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
++** <li> [SQLITE_IOCAP_IMMUTABLE]
+ ** </ul>
  **
--** SQLite's versions are identical to the standard versions assuming a
--** locale of "C". They are implemented as macros in sqliteInt.h.
--*/
--#ifdef SQLITE_ASCII
--SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
--  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 00..07    ........ */
--  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,  /* 08..0f    ........ */
--  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 10..17    ........ */
--  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 18..1f    ........ */
--  0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,  /* 20..27     !"#$%&' */
--  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 28..2f    ()*+,-./ */
--  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,  /* 30..37    01234567 */
--  0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 38..3f    89:;<=>? */
--
--  0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02,  /* 40..47    @ABCDEFG */
--  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 48..4f    HIJKLMNO */
--  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 50..57    PQRSTUVW */
--  0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40,  /* 58..5f    XYZ[\]^_ */
--  0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22,  /* 60..67    `abcdefg */
--  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 68..6f    hijklmno */
--  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 70..77    pqrstuvw */
--  0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 78..7f    xyz{|}~. */
--
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 80..87    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 88..8f    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 90..97    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 98..9f    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* a0..a7    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* a8..af    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* b0..b7    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* b8..bf    ........ */
--
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* c0..c7    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* c8..cf    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* d0..d7    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* d8..df    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e0..e7    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e8..ef    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* f0..f7    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40   /* f8..ff    ........ */
--};
--#endif
--
--/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
--** compatibility for legacy applications, the URI filename capability is
--** disabled by default.
-+** The file is divided into pages.  The first page is called page 1,
-+** the second is page 2, and so forth.  A page number of zero indicates
-+** "no such page".  The page size can be any power of 2 between 512 and 65536.
-+** Each page can be either a btree page, a freelist page, an overflow
-+** page, or a pointer-map page.
+ ** The SQLITE_IOCAP_ATOMIC property means that all writes of
+@@ -792,8 +813,13 @@
+ ** <li>[[SQLITE_FCNTL_FILE_POINTER]]
+ ** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer
+ ** to the [sqlite3_file] object associated with a particular database
+-** connection.  See the [sqlite3_file_control()] documentation for
+-** additional information.
++** connection.  See also [SQLITE_FCNTL_JOURNAL_POINTER].
++**
++** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]]
++** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer
++** to the [sqlite3_file] object associated with the journal file (either
++** the [rollback journal] or the [write-ahead log]) for a particular database
++** connection.  See also [SQLITE_FCNTL_FILE_POINTER].
  **
--** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
--** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
-+** The first page is always a btree page.  The first 100 bytes of the first
-+** page contain a special header (the "file header") that describes the file.
-+** The format of the file header is as follows:
+ ** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
+ ** No longer in use.
+@@ -831,7 +857,7 @@
+ ** opcode allows these two values (10 retries and 25 milliseconds of delay)
+ ** to be adjusted.  The values are changed for all database connections
+ ** within the same process.  The argument is a pointer to an array of two
+-** integers where the first integer i the new retry count and the second
++** integers where the first integer is the new retry count and the second
+ ** integer is the delay.  If either integer is negative, then the setting
+ ** is not changed but instead the prior value of that setting is written
+ ** into the array entry, allowing the current retry settings to be
+@@ -880,6 +906,15 @@
+ ** pointer in case this file-control is not implemented.  This file-control
+ ** is intended for diagnostic use only.
  **
--** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
--** disabled. The default value may be changed by compiling with the
--** SQLITE_USE_URI symbol defined.
-+**   OFFSET   SIZE    DESCRIPTION
-+**      0      16     Header string: "SQLite format 3\000"
-+**     16       2     Page size in bytes.  (1 means 65536)
-+**     18       1     File format write version
-+**     19       1     File format read version
-+**     20       1     Bytes of unused space at the end of each page
-+**     21       1     Max embedded payload fraction (must be 64)
-+**     22       1     Min embedded payload fraction (must be 32)
-+**     23       1     Min leaf payload fraction (must be 32)
-+**     24       4     File change counter
-+**     28       4     Reserved for future use
-+**     32       4     First freelist page
-+**     36       4     Number of freelist pages in the file
-+**     40      60     15 4-byte meta values passed to higher layers
++** <li>[[SQLITE_FCNTL_VFS_POINTER]]
++** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level
++** [VFSes] currently in use.  ^(The argument X in
++** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be
++** of type "[sqlite3_vfs] **".  This opcodes will set *X
++** to a pointer to the top-level VFS.)^
++** ^When there are multiple VFS shims in the stack, this opcode finds the
++** upper-most shim only.
 +**
-+**     40       4     Schema cookie
-+**     44       4     File format of schema layer
-+**     48       4     Size of page cache
-+**     52       4     Largest root-page (auto/incr_vacuum)
-+**     56       4     1=UTF-8 2=UTF16le 3=UTF16be
-+**     60       4     User version
-+**     64       4     Incremental vacuum mode
-+**     68       4     Application-ID
-+**     72      20     unused
-+**     92       4     The version-valid-for number
-+**     96       4     SQLITE_VERSION_NUMBER
+ ** <li>[[SQLITE_FCNTL_PRAGMA]]
+ ** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] 
+ ** file control is sent to the open [sqlite3_file] object corresponding
+@@ -950,6 +985,12 @@
+ ** on whether or not the file has been renamed, moved, or deleted since it
+ ** was first opened.
+ **
++** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
++** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
++** underlying native file handle associated with a file handle.  This file
++** control interprets its argument as a pointer to a native file handle and
++** writes the resulting value there.
 +**
-+** All of the integer values are big-endian (most significant byte first).
+ ** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
+ ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging.  This
+ ** opcode causes the xFileControl method to swap the file handle with the one
+@@ -963,6 +1004,14 @@
+ ** circumstances in order to fix a problem with priority inversion.
+ ** Applications should <em>not</em> use this file-control.
+ **
++** <li>[[SQLITE_FCNTL_ZIPVFS]]
++** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other
++** VFS should return SQLITE_NOTFOUND for this opcode.
 +**
-+** The file change counter is incremented when the database is changed
-+** This counter allows other processes to know when the file has changed
-+** and thus when they need to flush their cache.
++** <li>[[SQLITE_FCNTL_RBU]]
++** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by
++** the RBU extension only.  All other VFS should return SQLITE_NOTFOUND for
++** this opcode.  
+ ** </ul>
+ */
+ #define SQLITE_FCNTL_LOCKSTATE               1
+@@ -988,6 +1037,12 @@
+ #define SQLITE_FCNTL_COMMIT_PHASETWO        22
+ #define SQLITE_FCNTL_WIN32_SET_HANDLE       23
+ #define SQLITE_FCNTL_WAL_BLOCK              24
++#define SQLITE_FCNTL_ZIPVFS                 25
++#define SQLITE_FCNTL_RBU                    26
++#define SQLITE_FCNTL_VFS_POINTER            27
++#define SQLITE_FCNTL_JOURNAL_POINTER        28
++#define SQLITE_FCNTL_WIN32_GET_HANDLE       29
++#define SQLITE_FCNTL_PDB                    30
+ 
+ /* deprecated names */
+ #define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
+@@ -1008,6 +1063,16 @@
+ typedef struct sqlite3_mutex sqlite3_mutex;
+ 
+ /*
++** CAPI3REF: Loadable Extension Thunk
 +**
-+** The max embedded payload fraction is the amount of the total usable
-+** space in a page that can be consumed by a single cell for standard
-+** B-tree (non-LEAFDATA) tables.  A value of 255 means 100%.  The default
-+** is to limit the maximum cell size so that at least 4 cells will fit
-+** on one page.  Thus the default max embedded payload fraction is 64.
++** A pointer to the opaque sqlite3_api_routines structure is passed as
++** the third parameter to entry points of [loadable extensions].  This
++** structure must be typedefed in order to work around compiler warnings
++** on some platforms.
++*/
++typedef struct sqlite3_api_routines sqlite3_api_routines;
++
++/*
+ ** CAPI3REF: OS Interface Object
+ **
+ ** An instance of the sqlite3_vfs object defines the interface between
+@@ -1200,7 +1265,7 @@
+   const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
+   /*
+   ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
+-  ** New fields may be appended in figure versions.  The iVersion
++  ** New fields may be appended in future versions.  The iVersion
+   ** value will increment whenever this happens. 
+   */
+ };
+@@ -1342,10 +1407,10 @@
+ ** must return [SQLITE_OK] on success and some other [error code] upon
+ ** failure.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void);
+-SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void);
+-SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void);
+-SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
++SQLITE_API int sqlite3_initialize(void);
++SQLITE_API int sqlite3_shutdown(void);
++SQLITE_API int sqlite3_os_init(void);
++SQLITE_API int sqlite3_os_end(void);
+ 
+ /*
+ ** CAPI3REF: Configuring The SQLite Library
+@@ -1356,9 +1421,11 @@
+ ** applications and so this routine is usually not necessary.  It is
+ ** provided to support rare applications with unusual needs.
+ **
+-** The sqlite3_config() interface is not threadsafe.  The application
+-** must insure that no other SQLite interfaces are invoked by other
+-** threads while sqlite3_config() is running.  Furthermore, sqlite3_config()
++** <b>The sqlite3_config() interface is not threadsafe. The application
++** must ensure that no other SQLite interfaces are invoked by other
++** threads while sqlite3_config() is running.</b>
 +**
-+** If the payload for a cell is larger than the max payload, then extra
-+** payload is spilled to overflow pages.  Once an overflow page is allocated,
-+** as many bytes as possible are moved into the overflow pages without letting
-+** the cell size drop below the min embedded payload fraction.
++** The sqlite3_config() interface
+ ** may only be invoked prior to library initialization using
+ ** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
+ ** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
+@@ -1376,7 +1443,7 @@
+ ** ^If the option is unknown or SQLite is unable to set the option
+ ** then this routine returns a non-zero [error code].
+ */
+-SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...);
++SQLITE_API int sqlite3_config(int, ...);
+ 
+ /*
+ ** CAPI3REF: Configure database connections
+@@ -1395,7 +1462,7 @@
+ ** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
+ ** the call is considered successful.
+ */
+-SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...);
++SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
+ 
+ /*
+ ** CAPI3REF: Memory Allocation Routines
+@@ -1585,29 +1652,34 @@
+ ** </dd>
+ **
+ ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
+-** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a static memory buffer
++** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool
+ ** that SQLite can use for the database page cache with the default page
+ ** cache implementation.  
+-** This configuration should not be used if an application-define page
+-** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]
+-** configuration option.
++** This configuration option is a no-op if an application-define page
++** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2].
+ ** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
+-** 8-byte aligned
+-** memory, the size of each page buffer (sz), and the number of pages (N).
++** 8-byte aligned memory (pMem), the size of each page cache line (sz),
++** and the number of cache lines (N).
+ ** The sz argument should be the size of the largest database page
+ ** (a power of two between 512 and 65536) plus some extra bytes for each
+ ** page header.  ^The number of extra bytes needed by the page header
+-** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option 
+-** to [sqlite3_config()].
++** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ].
+ ** ^It is harmless, apart from the wasted memory,
+-** for the sz parameter to be larger than necessary.  The first
+-** argument should pointer to an 8-byte aligned block of memory that
+-** is at least sz*N bytes of memory, otherwise subsequent behavior is
+-** undefined.
+-** ^SQLite will use the memory provided by the first argument to satisfy its
+-** memory needs for the first N pages that it adds to cache.  ^If additional
+-** page cache memory is needed beyond what is provided by this option, then
+-** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>
++** for the sz parameter to be larger than necessary.  The pMem
++** argument must be either a NULL pointer or a pointer to an 8-byte
++** aligned block of memory of at least sz*N bytes, otherwise
++** subsequent behavior is undefined.
++** ^When pMem is not NULL, SQLite will strive to use the memory provided
++** to satisfy page cache needs, falling back to [sqlite3_malloc()] if
++** a page cache line is larger than sz bytes or if all of the pMem buffer
++** is exhausted.
++** ^If pMem is NULL and N is non-zero, then each database connection
++** does an initial bulk allocation for page cache memory
++** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or
++** of -1024*N bytes if N is negative, . ^If additional
++** page cache memory is needed beyond what is provided by the initial
++** allocation, then SQLite goes to [sqlite3_malloc()] separately for each
++** additional cache line. </dd>
+ **
+ ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
+ ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer 
+@@ -1785,6 +1857,20 @@
+ ** is enabled (using the [PRAGMA threads] command) and the amount of content
+ ** to be sorted exceeds the page size times the minimum of the
+ ** [PRAGMA cache_size] setting and this value.
 +**
-+** The min leaf payload fraction is like the min embedded payload fraction
-+** except that it applies to leaf nodes in a LEAFDATA tree.  The maximum
-+** payload fraction for a LEAFDATA tree is always 100% (or 255) and it
-+** not specified in the header.
++** [[SQLITE_CONFIG_STMTJRNL_SPILL]]
++** <dt>SQLITE_CONFIG_STMTJRNL_SPILL
++** <dd>^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which
++** becomes the [statement journal] spill-to-disk threshold.  
++** [Statement journals] are held in memory until their size (in bytes)
++** exceeds this threshold, at which point they are written to disk.
++** Or if the threshold is -1, statement journals are always held
++** exclusively in memory.
++** Since many statement journals never become large, setting the spill
++** threshold to a value such as 64KiB can greatly reduce the amount of
++** I/O required to support statement rollback.
++** The default value for this setting is controlled by the
++** [SQLITE_STMTJRNL_SPILL] compile-time option.
+ ** </dl>
+ */
+ #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
+@@ -1812,6 +1898,7 @@
+ #define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
+ #define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
+ #define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
++#define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
+ 
+ /*
+ ** CAPI3REF: Database Connection Configuration Options
+@@ -1869,11 +1956,78 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the trigger setting is not reported back. </dd>
+ **
++** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
++** <dd> ^This option is used to enable or disable the two-argument
++** version of the [fts3_tokenizer()] function which is part of the
++** [FTS3] full-text search engine extension.
++** There should be two additional arguments.
++** The first argument is an integer which is 0 to disable fts3_tokenizer() or
++** positive to enable fts3_tokenizer() or negative to leave the setting
++** unchanged.
++** The second parameter is a pointer to an integer into which
++** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
++** following this call.  The second parameter may be a NULL pointer, in
++** which case the new setting is not reported back. </dd>
 +**
-+** Each btree pages is divided into three sections:  The header, the
-+** cell pointer array, and the cell content area.  Page 1 also has a 100-byte
-+** file header that occurs before the page header.
++** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
++** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
++** interface independently of the [load_extension()] SQL function.
++** The [sqlite3_enable_load_extension()] API enables or disables both the
++** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
++** There should be two additional arguments.
++** When the first argument to this interface is 1, then only the C-API is
++** enabled and the SQL function remains disabled.  If the first argument to
++** this interface is 0, then both the C-API and the SQL function are disabled.
++** If the first argument is -1, then no changes are made to state of either the
++** C-API or the SQL function.
++** The second parameter is a pointer to an integer into which
++** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
++** is disabled or enabled following this call.  The second parameter may
++** be a NULL pointer, in which case the new setting is not reported back.
++** </dd>
 +**
-+**      |----------------|
-+**      | file header    |   100 bytes.  Page 1 only.
-+**      |----------------|
-+**      | page header    |   8 bytes for leaves.  12 bytes for interior nodes
-+**      |----------------|
-+**      | cell pointer   |   |  2 bytes per cell.  Sorted order.
-+**      | array          |   |  Grows downward
-+**      |                |   v
-+**      |----------------|
-+**      | unallocated    |
-+**      | space          |
-+**      |----------------|   ^  Grows upwards
-+**      | cell content   |   |  Arbitrary order interspersed with freeblocks.
-+**      | area           |   |  and free space fragments.
-+**      |----------------|
++** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
++** <dd> ^This option is used to change the name of the "main" database
++** schema.  ^The sole argument is a pointer to a constant UTF8 string
++** which will become the new schema name in place of "main".  ^SQLite
++** does not make a copy of the new main schema name string, so the application
++** must ensure that the argument passed into this DBCONFIG option is unchanged
++** until after the database connection closes.
++** </dd>
 +**
-+** The page headers looks like this:
++** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
++** <dd> Usually, when a database in wal mode is closed or detached from a 
++** database handle, SQLite checks if this will mean that there are now no 
++** connections at all to the database. If so, it performs a checkpoint 
++** operation before closing the connection. This option may be used to
++** override this behaviour. The first parameter passed to this operation
++** is an integer - non-zero to disable checkpoints-on-close, or zero (the
++** default) to enable them. The second parameter is a pointer to an integer
++** into which is written 0 or 1 to indicate whether checkpoints-on-close
++** have been disabled - 0 if they are not disabled, 1 if they are.
++** </dd>
 +**
-+**   OFFSET   SIZE     DESCRIPTION
-+**      0       1      Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf
-+**      1       2      byte offset to the first freeblock
-+**      3       2      number of cells on this page
-+**      5       2      first byte of the cell content area
-+**      7       1      number of fragmented free bytes
-+**      8       4      Right child (the Ptr(N) value).  Omitted on leaves.
++** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
++** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
++** the [query planner stability guarantee] (QPSG).  When the QPSG is active,
++** a single SQL query statement will always use the same algorithm regardless
++** of values of [bound parameters].)^ The QPSG disables some query optimizations
++** that look at the values of bound parameters, which can make some queries
++** slower.  But the QPSG has the advantage of more predictable behavior.  With
++** the QPSG active, SQLite will always use the same query plan in the field as
++** was used during testing in the lab.
++** </dd>
 +**
-+** The flags define the format of this btree page.  The leaf flag means that
-+** this page has no children.  The zerodata flag means that this page carries
-+** only keys and no data.  The intkey flag means that the key is an integer
-+** which is stored in the key size entry of the cell header rather than in
-+** the payload area.
+ ** </dl>
+ */
+-#define SQLITE_DBCONFIG_LOOKASIDE       1001  /* void* int int */
+-#define SQLITE_DBCONFIG_ENABLE_FKEY     1002  /* int int* */
+-#define SQLITE_DBCONFIG_ENABLE_TRIGGER  1003  /* int int* */
++#define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
++#define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
++#define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
++#define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
++#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
++#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
++#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */
++#define SQLITE_DBCONFIG_ENABLE_QPSG           1007 /* int int* */
+ 
+ 
+ /*
+@@ -1884,7 +2038,7 @@
+ ** [extended result codes] feature of SQLite. ^The extended result
+ ** codes are disabled by default for historical compatibility.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff);
++SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
+ 
+ /*
+ ** CAPI3REF: Last Insert Rowid
+@@ -1898,20 +2052,30 @@
+ ** the table has a column of type [INTEGER PRIMARY KEY] then that column
+ ** is another alias for the rowid.
+ **
+-** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the 
+-** most recent successful [INSERT] into a rowid table or [virtual table]
+-** on database connection D.
+-** ^Inserts into [WITHOUT ROWID] tables are not recorded.
+-** ^If no successful [INSERT]s into rowid tables
+-** have ever occurred on the database connection D, 
+-** then sqlite3_last_insert_rowid(D) returns zero.
+-**
+-** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
+-** method, then this routine will return the [rowid] of the inserted
+-** row as long as the trigger or virtual table method is running.
+-** But once the trigger or virtual table method ends, the value returned 
+-** by this routine reverts to what it was before the trigger or virtual
+-** table method began.)^
++** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
++** the most recent successful [INSERT] into a rowid table or [virtual table]
++** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
++** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred 
++** on the database connection D, then sqlite3_last_insert_rowid(D) returns 
++** zero.
 +**
-+** The cell pointer array begins on the first byte after the page header.
-+** The cell pointer array contains zero or more 2-byte numbers which are
-+** offsets from the beginning of the page to the cell content in the cell
-+** content area.  The cell pointers occur in sorted order.  The system strives
-+** to keep free space after the last cell pointer so that new cells can
-+** be easily added without having to defragment the page.
++** As well as being set automatically as rows are inserted into database
++** tables, the value returned by this function may be set explicitly by
++** [sqlite3_set_last_insert_rowid()]
 +**
-+** Cell content is stored at the very end of the page and grows toward the
-+** beginning of the page.
++** Some virtual table implementations may INSERT rows into rowid tables as
++** part of committing a transaction (e.g. to flush data accumulated in memory
++** to disk). In this case subsequent calls to this function return the rowid
++** associated with these internal INSERT operations, which leads to 
++** unintuitive results. Virtual table implementations that do write to rowid
++** tables in this way can avoid this problem by restoring the original 
++** rowid value using [sqlite3_set_last_insert_rowid()] before returning 
++** control to the user.
 +**
-+** Unused space within the cell content area is collected into a linked list of
-+** freeblocks.  Each freeblock is at least 4 bytes in size.  The byte offset
-+** to the first freeblock is given in the header.  Freeblocks occur in
-+** increasing order.  Because a freeblock must be at least 4 bytes in size,
-+** any group of 3 or fewer unused bytes in the cell content area cannot
-+** exist on the freeblock chain.  A group of 3 or fewer free bytes is called
-+** a fragment.  The total number of bytes in all fragments is recorded.
-+** in the page header at offset 7.
++** ^(If an [INSERT] occurs within a trigger then this routine will 
++** return the [rowid] of the inserted row as long as the trigger is 
++** running. Once the trigger program ends, the value returned 
++** by this routine reverts to what it was before the trigger was fired.)^
+ **
+ ** ^An [INSERT] that fails due to a constraint violation is not a
+ ** successful [INSERT] and does not change the value returned by this
+@@ -1936,7 +2100,17 @@
+ ** unpredictable and might not equal either the old or the new
+ ** last insert [rowid].
+ */
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*);
++SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
++
++/*
++** CAPI3REF: Set the Last Insert Rowid value.
++** METHOD: sqlite3
 +**
-+**    SIZE    DESCRIPTION
-+**      2     Byte offset of the next freeblock
-+**      2     Bytes in this freeblock
++** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
++** set the value returned by calling sqlite3_last_insert_rowid(D) to R 
++** without inserting a row into the database.
++*/
++SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
+ 
+ /*
+ ** CAPI3REF: Count The Number Of Rows Modified
+@@ -1989,7 +2163,7 @@
+ ** while [sqlite3_changes()] is running then the value returned
+ ** is unpredictable and not meaningful.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*);
++SQLITE_API int sqlite3_changes(sqlite3*);
+ 
+ /*
+ ** CAPI3REF: Total Number Of Rows Modified
+@@ -2013,7 +2187,7 @@
+ ** while [sqlite3_total_changes()] is running then the value
+ ** returned is unpredictable and not meaningful.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*);
++SQLITE_API int sqlite3_total_changes(sqlite3*);
+ 
+ /*
+ ** CAPI3REF: Interrupt A Long-Running Query
+@@ -2049,11 +2223,8 @@
+ ** ^A call to sqlite3_interrupt(D) that occurs when there are no running
+ ** SQL statements is a no-op and has no effect on SQL statements
+ ** that are started after the sqlite3_interrupt() call returns.
+-**
+-** If the database connection closes while [sqlite3_interrupt()]
+-** is running then bad things will likely happen.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*);
++SQLITE_API void sqlite3_interrupt(sqlite3*);
+ 
+ /*
+ ** CAPI3REF: Determine If An SQL Statement Is Complete
+@@ -2088,8 +2259,8 @@
+ ** The input to [sqlite3_complete16()] must be a zero-terminated
+ ** UTF-16 string in native byte order.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql);
+-SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql);
++SQLITE_API int sqlite3_complete(const char *sql);
++SQLITE_API int sqlite3_complete16(const void *sql);
+ 
+ /*
+ ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
+@@ -2150,7 +2321,7 @@
+ ** A busy handler must not close the database connection
+ ** or [prepared statement] that invoked the busy handler.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
++SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
+ 
+ /*
+ ** CAPI3REF: Set A Busy Timeout
+@@ -2173,7 +2344,7 @@
+ **
+ ** See also:  [PRAGMA busy_timeout]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms);
++SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
+ 
+ /*
+ ** CAPI3REF: Convenience Routines For Running Queries
+@@ -2248,7 +2419,7 @@
+ ** reflected in subsequent calls to [sqlite3_errcode()] or
+ ** [sqlite3_errmsg()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
++SQLITE_API int sqlite3_get_table(
+   sqlite3 *db,          /* An open database */
+   const char *zSql,     /* SQL to be evaluated */
+   char ***pazResult,    /* Results of the query */
+@@ -2256,7 +2427,7 @@
+   int *pnColumn,        /* Number of result columns written here */
+   char **pzErrmsg       /* Error msg written here */
+ );
+-SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result);
++SQLITE_API void sqlite3_free_table(char **result);
+ 
+ /*
+ ** CAPI3REF: Formatted String Printing Functions
+@@ -2362,10 +2533,10 @@
+ ** addition that after the string has been read and copied into
+ ** the result, [sqlite3_free()] is called on the input string.)^
+ */
+-SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...);
+-SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list);
+-SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...);
+-SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list);
++SQLITE_API char *sqlite3_mprintf(const char*,...);
++SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
++SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
++SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
+ 
+ /*
+ ** CAPI3REF: Memory Allocation Subsystem
+@@ -2455,12 +2626,12 @@
+ ** a block of memory after it has been released using
+ ** [sqlite3_free()] or [sqlite3_realloc()].
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int);
+-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64);
+-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int);
+-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64);
+-SQLITE_API void SQLITE_STDCALL sqlite3_free(void*);
+-SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*);
++SQLITE_API void *sqlite3_malloc(int);
++SQLITE_API void *sqlite3_malloc64(sqlite3_uint64);
++SQLITE_API void *sqlite3_realloc(void*, int);
++SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64);
++SQLITE_API void sqlite3_free(void*);
++SQLITE_API sqlite3_uint64 sqlite3_msize(void*);
+ 
+ /*
+ ** CAPI3REF: Memory Allocator Statistics
+@@ -2485,8 +2656,8 @@
+ ** by [sqlite3_memory_highwater(1)] is the high-water mark
+ ** prior to the reset.
+ */
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void);
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag);
++SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
++SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
+ 
+ /*
+ ** CAPI3REF: Pseudo-Random Number Generator
+@@ -2509,17 +2680,19 @@
+ ** internally and without recourse to the [sqlite3_vfs] xRandomness
+ ** method.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P);
++SQLITE_API void sqlite3_randomness(int N, void *P);
+ 
+ /*
+ ** CAPI3REF: Compile-Time Authorization Callbacks
+ ** METHOD: sqlite3
++** KEYWORDS: {authorizer callback}
+ **
+ ** ^This routine registers an authorizer callback with a particular
+ ** [database connection], supplied in the first argument.
+ ** ^The authorizer callback is invoked as SQL statements are being compiled
+ ** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
+-** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()].  ^At various
++** [sqlite3_prepare_v3()], [sqlite3_prepare16()], [sqlite3_prepare16_v2()],
++** and [sqlite3_prepare16_v3()].  ^At various
+ ** points during the compilation process, as logic is being created
+ ** to perform various actions, the authorizer callback is invoked to
+ ** see if those actions are allowed.  ^The authorizer callback should
+@@ -2541,8 +2714,10 @@
+ ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
+ ** to the callback is an integer [SQLITE_COPY | action code] that specifies
+ ** the particular action to be authorized. ^The third through sixth parameters
+-** to the callback are zero-terminated strings that contain additional
+-** details about the action to be authorized.
++** to the callback are either NULL pointers or zero-terminated strings
++** that contain additional details about the action to be authorized.
++** Applications must always be prepared to encounter a NULL pointer in any
++** of the third through the sixth parameters of the authorization callback.
+ **
+ ** ^If the action code is [SQLITE_READ]
+ ** and the callback returns [SQLITE_IGNORE] then the
+@@ -2551,6 +2726,10 @@
+ ** been read if [SQLITE_OK] had been returned.  The [SQLITE_IGNORE]
+ ** return can be used to deny an untrusted user access to individual
+ ** columns of a table.
++** ^When a table is referenced by a [SELECT] but no column values are
++** extracted from that table (for example in a query like
++** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
++** is invoked once for that table with a column name that is an empty string.
+ ** ^If the action code is [SQLITE_DELETE] and the callback returns
+ ** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
+ ** [truncate optimization] is disabled and all rows are deleted individually.
+@@ -2592,7 +2771,7 @@
+ ** as stated in the previous paragraph, sqlite3_step() invokes
+ ** sqlite3_prepare_v2() to reprepare a statement after a schema change.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
++SQLITE_API int sqlite3_set_authorizer(
+   sqlite3*,
+   int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
+   void *pUserData
+@@ -2672,6 +2851,9 @@
+ ** CAPI3REF: Tracing And Profiling Functions
+ ** METHOD: sqlite3
+ **
++** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
++** instead of the routines described here.
 +**
-+** Cells are of variable length.  Cells are stored in the cell content area at
-+** the end of the page.  Pointers to the cells are in the cell pointer array
-+** that immediately follows the page header.  Cells is not necessarily
-+** contiguous or in order, but cell pointers are contiguous and in order.
+ ** These routines register callback functions that can be used for
+ ** tracing and profiling the execution of SQL statements.
+ **
+@@ -2697,11 +2879,105 @@
+ ** sqlite3_profile() function is considered experimental and is
+ ** subject to change in future versions of SQLite.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
+-SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*,
++SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
++   void(*xTrace)(void*,const char*), void*);
++SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
+    void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
+ 
+ /*
++** CAPI3REF: SQL Trace Event Codes
++** KEYWORDS: SQLITE_TRACE
 +**
-+** Cell content makes use of variable length integers.  A variable
-+** length integer is 1 to 9 bytes where the lower 7 bits of each 
-+** byte are used.  The integer consists of all bytes that have bit 8 set and
-+** the first byte with bit 8 clear.  The most significant byte of the integer
-+** appears first.  A variable-length integer may not be more than 9 bytes long.
-+** As a special case, all 8 bytes of the 9th byte are used as data.  This
-+** allows a 64-bit integer to be encoded in 9 bytes.
++** These constants identify classes of events that can be monitored
++** using the [sqlite3_trace_v2()] tracing logic.  The third argument
++** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
++** the following constants.  ^The first argument to the trace callback
++** is one of the following constants.
 +**
-+**    0x00                      becomes  0x00000000
-+**    0x7f                      becomes  0x0000007f
-+**    0x81 0x00                 becomes  0x00000080
-+**    0x82 0x00                 becomes  0x00000100
-+**    0x80 0x7f                 becomes  0x0000007f
-+**    0x8a 0x91 0xd1 0xac 0x78  becomes  0x12345678
-+**    0x81 0x81 0x81 0x81 0x01  becomes  0x10204081
++** New tracing constants may be added in future releases.
 +**
-+** Variable length integers are used for rowids and to hold the number of
-+** bytes of key and data in a btree cell.
++** ^A trace callback has four arguments: xCallback(T,C,P,X).
++** ^The T argument is one of the integer type codes above.
++** ^The C argument is a copy of the context pointer passed in as the
++** fourth argument to [sqlite3_trace_v2()].
++** The P and X arguments are pointers whose meanings depend on T.
 +**
-+** The content of a cell looks like this:
++** <dl>
++** [[SQLITE_TRACE_STMT]] <dt>SQLITE_TRACE_STMT</dt>
++** <dd>^An SQLITE_TRACE_STMT callback is invoked when a prepared statement
++** first begins running and possibly at other times during the
++** execution of the prepared statement, such as at the start of each
++** trigger subprogram. ^The P argument is a pointer to the
++** [prepared statement]. ^The X argument is a pointer to a string which
++** is the unexpanded SQL text of the prepared statement or an SQL comment 
++** that indicates the invocation of a trigger.  ^The callback can compute
++** the same text that would have been returned by the legacy [sqlite3_trace()]
++** interface by using the X argument when X begins with "--" and invoking
++** [sqlite3_expanded_sql(P)] otherwise.
 +**
-+**    SIZE    DESCRIPTION
-+**      4     Page number of the left child. Omitted if leaf flag is set.
-+**     var    Number of bytes of data. Omitted if the zerodata flag is set.
-+**     var    Number of bytes of key. Or the key itself if intkey flag is set.
-+**      *     Payload
-+**      4     First page of the overflow chain.  Omitted if no overflow
++** [[SQLITE_TRACE_PROFILE]] <dt>SQLITE_TRACE_PROFILE</dt>
++** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same
++** information as is provided by the [sqlite3_profile()] callback.
++** ^The P argument is a pointer to the [prepared statement] and the
++** X argument points to a 64-bit integer which is the estimated of
++** the number of nanosecond that the prepared statement took to run.
++** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
 +**
-+** Overflow pages form a linked list.  Each page except the last is completely
-+** filled with data (pagesize - 4 bytes).  The last page can have as little
-+** as 1 byte of data.
++** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
++** <dd>^An SQLITE_TRACE_ROW callback is invoked whenever a prepared
++** statement generates a single row of result.  
++** ^The P argument is a pointer to the [prepared statement] and the
++** X argument is unused.
 +**
-+**    SIZE    DESCRIPTION
-+**      4     Page number of next overflow page
-+**      *     Data
++** [[SQLITE_TRACE_CLOSE]] <dt>SQLITE_TRACE_CLOSE</dt>
++** <dd>^An SQLITE_TRACE_CLOSE callback is invoked when a database
++** connection closes.
++** ^The P argument is a pointer to the [database connection] object
++** and the X argument is unused.
++** </dl>
++*/
++#define SQLITE_TRACE_STMT       0x01
++#define SQLITE_TRACE_PROFILE    0x02
++#define SQLITE_TRACE_ROW        0x04
++#define SQLITE_TRACE_CLOSE      0x08
++
++/*
++** CAPI3REF: SQL Trace Hook
++** METHOD: sqlite3
 +**
-+** Freelist pages come in two subtypes: trunk pages and leaf pages.  The
-+** file header points to the first in a linked list of trunk page.  Each trunk
-+** page points to multiple leaf pages.  The content of a leaf page is
-+** unspecified.  A trunk page looks like this:
++** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback
++** function X against [database connection] D, using property mask M
++** and context pointer P.  ^If the X callback is
++** NULL or if the M mask is zero, then tracing is disabled.  The
++** M argument should be the bitwise OR-ed combination of
++** zero or more [SQLITE_TRACE] constants.
 +**
-+**    SIZE    DESCRIPTION
-+**      4     Page number of next trunk page
-+**      4     Number of leaf pointers on this page
-+**      *     zero or more pages numbers of leaves
- */
--#ifndef SQLITE_USE_URI
--# define  SQLITE_USE_URI 0
--#endif
- 
--/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
--** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
--** that compile-time option is omitted.
++** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides 
++** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2().
++**
++** ^The X callback is invoked whenever any of the events identified by 
++** mask M occur.  ^The integer return value from the callback is currently
++** ignored, though this may change in future releases.  Callback
++** implementations should return zero to ensure future compatibility.
++**
++** ^A trace callback is invoked with four arguments: callback(T,C,P,X).
++** ^The T argument is one of the [SQLITE_TRACE]
++** constants to indicate why the callback was invoked.
++** ^The C argument is a copy of the context pointer.
++** The P and X arguments are pointers whose meanings depend on T.
++**
++** The sqlite3_trace_v2() interface is intended to replace the legacy
++** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
++** are deprecated.
++*/
++SQLITE_API int sqlite3_trace_v2(
++  sqlite3*,
++  unsigned uMask,
++  int(*xCallback)(unsigned,void*,void*,void*),
++  void *pCtx
++);
 +
-+/* The following value is the maximum cell size assuming a maximum page
-+** size give above.
++/*
+ ** CAPI3REF: Query Progress Callbacks
+ ** METHOD: sqlite3
+ **
+@@ -2733,7 +3009,7 @@
+ ** database connections for the meaning of "modify" in this paragraph.
+ **
  */
--#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
--# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
--#endif
-+#define MX_CELL_SIZE(pBt)  ((int)(pBt->pageSize-8))
+-SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
++SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
  
--/* The minimum PMA size is set to this value multiplied by the database
--** page size in bytes.
-+/* The maximum number of cells on a single page of the database.  This
-+** assumes a minimum cell size of 6 bytes  (4 bytes for the cell itself
-+** plus 2 bytes for the index to the cell in the page header).  Such
-+** small cells will be rare, but they are possible.
+ /*
+ ** CAPI3REF: Opening A New Database Connection
+@@ -2962,15 +3238,15 @@
+ **
+ ** See also: [sqlite3_temp_directory]
  */
--#ifndef SQLITE_SORTER_PMASZ
--# define SQLITE_SORTER_PMASZ 250
--#endif
-+#define MX_CELL(pBt) ((pBt->pageSize-8)/6)
-+
-+/* Forward declarations */
-+typedef struct MemPage MemPage;
-+typedef struct BtLock BtLock;
+-SQLITE_API int SQLITE_STDCALL sqlite3_open(
++SQLITE_API int sqlite3_open(
+   const char *filename,   /* Database filename (UTF-8) */
+   sqlite3 **ppDb          /* OUT: SQLite db handle */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_open16(
++SQLITE_API int sqlite3_open16(
+   const void *filename,   /* Database filename (UTF-16) */
+   sqlite3 **ppDb          /* OUT: SQLite db handle */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
++SQLITE_API int sqlite3_open_v2(
+   const char *filename,   /* Database filename (UTF-8) */
+   sqlite3 **ppDb,         /* OUT: SQLite db handle */
+   int flags,              /* Flags */
+@@ -3016,9 +3292,9 @@
+ ** VFS method, then the behavior of this routine is undefined and probably
+ ** undesirable.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam);
+-SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
++SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
++SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
++SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
+ 
  
  /*
--** The following singleton contains the global configuration for
--** the SQLite library.
-+** This is a magic string that appears at the beginning of every
-+** SQLite database in order to identify the file as a real database.
-+**
-+** You can change this value at compile-time by specifying a
-+** -DSQLITE_FILE_HEADER="..." on the compiler command-line.  The
-+** header must be exactly 16 bytes including the zero-terminator so
-+** the string itself should be 15 characters long.  If you change
-+** the header, then your custom library will not be able to read 
-+** databases generated by the standard tools and the standard tools
-+** will not be able to read databases created by your custom library.
+@@ -3062,11 +3338,11 @@
+ ** was invoked incorrectly by the application.  In that case, the
+ ** error code and message may or may not be set.
  */
--SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
--   SQLITE_DEFAULT_MEMSTATUS,  /* bMemstat */
--   1,                         /* bCoreMutex */
--   SQLITE_THREADSAFE==1,      /* bFullMutex */
--   SQLITE_USE_URI,            /* bOpenUri */
--   SQLITE_ALLOW_COVERING_INDEX_SCAN,   /* bUseCis */
--   0x7ffffffe,                /* mxStrlen */
--   0,                         /* neverCorrupt */
--   128,                       /* szLookaside */
--   500,                       /* nLookaside */
--   {0,0,0,0,0,0,0,0},         /* m */
--   {0,0,0,0,0,0,0,0,0},       /* mutex */
--   {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
--   (void*)0,                  /* pHeap */
--   0,                         /* nHeap */
--   0, 0,                      /* mnHeap, mxHeap */
--   SQLITE_DEFAULT_MMAP_SIZE,  /* szMmap */
--   SQLITE_MAX_MMAP_SIZE,      /* mxMmap */
--   (void*)0,                  /* pScratch */
--   0,                         /* szScratch */
--   0,                         /* nScratch */
--   (void*)0,                  /* pPage */
--   0,                         /* szPage */
--   0,                         /* nPage */
--   0,                         /* mxParserStack */
--   0,                         /* sharedCacheEnabled */
--   SQLITE_SORTER_PMASZ,       /* szPma */
--   /* All the rest should always be initialized to zero */
--   0,                         /* isInit */
--   0,                         /* inProgress */
--   0,                         /* isMutexInit */
--   0,                         /* isMallocInit */
--   0,                         /* isPCacheInit */
--   0,                         /* nRefInitMutex */
--   0,                         /* pInitMutex */
--   0,                         /* xLog */
--   0,                         /* pLogArg */
--#ifdef SQLITE_ENABLE_SQLLOG
--   0,                         /* xSqllog */
--   0,                         /* pSqllogArg */
--#endif
--#ifdef SQLITE_VDBE_COVERAGE
--   0,                         /* xVdbeBranch */
--   0,                         /* pVbeBranchArg */
--#endif
--#ifndef SQLITE_OMIT_BUILTIN_TEST
--   0,                         /* xTestCallback */
-+#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */
-+#  define SQLITE_FILE_HEADER "SQLite format 3"
- #endif
--   0                          /* bLocaltimeFault */
--};
+-SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db);
+-SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db);
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*);
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int);
++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);
  
  /*
--** Hash table for global functions - functions common to all
--** database connections.  After initialization, this table is
--** read-only.
-+** Page type flags.  An ORed combination of these flags appear as the
-+** first byte of on-disk image of every BTree page.
+ ** CAPI3REF: Prepared Statement Object
+@@ -3134,7 +3410,7 @@
+ **
+ ** New run-time limit categories may be added in future releases.
  */
--SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
-+#define PTF_INTKEY    0x01
-+#define PTF_ZERODATA  0x02
-+#define PTF_LEAFDATA  0x04
-+#define PTF_LEAF      0x08
+-SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
++SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
+ 
+ /*
+ ** CAPI3REF: Run-Time Limit Categories
+@@ -3165,9 +3441,9 @@
+ **
+ ** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
+ ** <dd>The maximum number of instructions in a virtual machine program
+-** used to implement an SQL statement.  This limit is not currently
+-** enforced, though that might be added in some future release of
+-** SQLite.</dd>)^
++** used to implement an SQL statement.  If [sqlite3_prepare_v2()] or
++** the equivalent tries to allocate space for more than this many opcodes
++** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^
+ **
+ ** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
+ ** <dd>The maximum number of arguments on a function.</dd>)^
+@@ -3206,22 +3482,58 @@
+ #define SQLITE_LIMIT_WORKER_THREADS           11
  
  /*
--** Constant tokens for values 0 and 1.
-+** As each page of the file is loaded into memory, an instance of the following
-+** structure is appended and initialized to zero.  This structure stores
-+** information about the page that is decoded from the raw file page.
++** CAPI3REF: Prepare Flags
 +**
-+** The pParent field points back to the parent page.  This allows us to
-+** walk up the BTree from any leaf to the root.  Care must be taken to
-+** unref() the parent page pointer when this page is no longer referenced.
-+** The pageDestructor() routine handles that chore.
++** These constants define various flags that can be passed into
++** "prepFlags" parameter of the [sqlite3_prepare_v3()] and
++** [sqlite3_prepare16_v3()] interfaces.
 +**
-+** Access to all fields of this structure is controlled by the mutex
-+** stored in MemPage.pBt->mutex.
++** New flags may be added in future releases of SQLite.
++**
++** <dl>
++** [[SQLITE_PREPARE_PERSISTENT]] ^(<dt>SQLITE_PREPARE_PERSISTENT</dt>
++** <dd>The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner
++** that the prepared statement will be retained for a long time and
++** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()]
++** and [sqlite3_prepare16_v3()] assume that the prepared statement will 
++** be used just once or at most a few times and then destroyed using
++** [sqlite3_finalize()] relatively soon. The current implementation acts
++** on this hint by avoiding the use of [lookaside memory] so as not to
++** deplete the limited store of lookaside memory. Future versions of
++** SQLite may act on this hint differently.
++** </dl>
++*/
++#define SQLITE_PREPARE_PERSISTENT              0x01
++
++/*
+ ** CAPI3REF: Compiling An SQL Statement
+ ** KEYWORDS: {SQL statement compiler}
+ ** METHOD: sqlite3
+ ** CONSTRUCTOR: sqlite3_stmt
+ **
+-** To execute an SQL query, it must first be compiled into a byte-code
+-** program using one of these routines.
++** To execute an SQL statement, it must first be compiled into a byte-code
++** program using one of these routines.  Or, in other words, these routines
++** are constructors for the [prepared statement] object.
++**
++** The preferred routine to use is [sqlite3_prepare_v2()].  The
++** [sqlite3_prepare()] interface is legacy and should be avoided.
++** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used
++** for special purposes.
++**
++** The use of the UTF-8 interfaces is preferred, as SQLite currently
++** does all parsing using UTF-8.  The UTF-16 interfaces are provided
++** as a convenience.  The UTF-16 interfaces work by converting the
++** input text into UTF-8, then invoking the corresponding UTF-8 interface.
+ **
+ ** The first argument, "db", is a [database connection] obtained from a
+ ** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
+ ** [sqlite3_open16()].  The database connection must not have been closed.
+ **
+ ** The second argument, "zSql", is the statement to be compiled, encoded
+-** as either UTF-8 or UTF-16.  The sqlite3_prepare() and sqlite3_prepare_v2()
+-** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
+-** use UTF-16.
++** as either UTF-8 or UTF-16.  The sqlite3_prepare(), sqlite3_prepare_v2(),
++** and sqlite3_prepare_v3()
++** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(),
++** and sqlite3_prepare16_v3() use UTF-16.
+ **
+ ** ^If the nByte argument is negative, then zSql is read up to the
+ ** first zero terminator. ^If nByte is positive, then it is the
+@@ -3248,10 +3560,11 @@
+ ** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK];
+ ** otherwise an [error code] is returned.
+ **
+-** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
+-** recommended for all new programs. The two older interfaces are retained
+-** for backwards compatibility, but their use is discouraged.
+-** ^In the "v2" interfaces, the prepared statement
++** The sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(),
++** and sqlite3_prepare16_v3() interfaces are recommended for all new programs.
++** The older interfaces (sqlite3_prepare() and sqlite3_prepare16())
++** are retained for backwards compatibility, but their use is discouraged.
++** ^In the "vX" interfaces, the prepared statement
+ ** that is returned (the [sqlite3_stmt] object) contains a copy of the
+ ** original SQL text. This causes the [sqlite3_step()] interface to
+ ** behave differently in three ways:
+@@ -3284,46 +3597,93 @@
+ ** or [GLOB] operator or if the parameter is compared to an indexed column
+ ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
+ ** </li>
++**
++** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
++** the extra prepFlags parameter, which is a bit array consisting of zero or
++** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags.  ^The
++** sqlite3_prepare_v2() interface works exactly the same as
++** sqlite3_prepare_v3() with a zero prepFlags parameter.
+ ** </ol>
  */
--SQLITE_PRIVATE const Token sqlite3IntTokens[] = {
--   { "0", 1 },
--   { "1", 1 }
-+struct MemPage {
-+  u8 isInit;           /* True if previously initialized. MUST BE FIRST! */
-+  u8 nOverflow;        /* Number of overflow cell bodies in aCell[] */
-+  u8 intKey;           /* True if table b-trees.  False for index b-trees */
-+  u8 intKeyLeaf;       /* True if the leaf of an intKey table */
-+  u8 noPayload;        /* True if internal intKey page (thus w/o data) */
-+  u8 leaf;             /* True if a leaf page */
-+  u8 hdrOffset;        /* 100 for page 1.  0 otherwise */
-+  u8 childPtrSize;     /* 0 if leaf==1.  4 if leaf==0 */
-+  u8 max1bytePayload;  /* min(maxLocal,127) */
-+  u8 bBusy;            /* Prevent endless loops on corrupt database files */
-+  u16 maxLocal;        /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
-+  u16 minLocal;        /* Copy of BtShared.minLocal or BtShared.minLeaf */
-+  u16 cellOffset;      /* Index in aData of first cell pointer */
-+  u16 nFree;           /* Number of free bytes on the page */
-+  u16 nCell;           /* Number of cells on this page, local and ovfl */
-+  u16 maskPage;        /* Mask for page offset */
-+  u16 aiOvfl[5];       /* Insert the i-th overflow cell before the aiOvfl-th
-+                       ** non-overflow cell */
-+  u8 *apOvfl[5];       /* Pointers to the body of overflow cells */
-+  BtShared *pBt;       /* Pointer to BtShared that this page is part of */
-+  u8 *aData;           /* Pointer to disk image of the page data */
-+  u8 *aDataEnd;        /* One byte past the end of usable data */
-+  u8 *aCellIdx;        /* The cell index area */
-+  DbPage *pDbPage;     /* Pager page handle */
-+  Pgno pgno;           /* Page number for this page */
- };
+-SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
++SQLITE_API int sqlite3_prepare(
++  sqlite3 *db,            /* Database handle */
++  const char *zSql,       /* SQL statement, UTF-8 encoded */
++  int nByte,              /* Maximum length of zSql in bytes. */
++  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
++  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
++);
++SQLITE_API int sqlite3_prepare_v2(
+   sqlite3 *db,            /* Database handle */
+   const char *zSql,       /* SQL statement, UTF-8 encoded */
+   int nByte,              /* Maximum length of zSql in bytes. */
+   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+   const char **pzTail     /* OUT: Pointer to unused portion of zSql */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
++SQLITE_API int sqlite3_prepare_v3(
+   sqlite3 *db,            /* Database handle */
+   const char *zSql,       /* SQL statement, UTF-8 encoded */
+   int nByte,              /* Maximum length of zSql in bytes. */
++  unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
+   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+   const char **pzTail     /* OUT: Pointer to unused portion of zSql */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
++SQLITE_API int sqlite3_prepare16(
+   sqlite3 *db,            /* Database handle */
+   const void *zSql,       /* SQL statement, UTF-16 encoded */
+   int nByte,              /* Maximum length of zSql in bytes. */
+   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+   const void **pzTail     /* OUT: Pointer to unused portion of zSql */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
++SQLITE_API int sqlite3_prepare16_v2(
+   sqlite3 *db,            /* Database handle */
+   const void *zSql,       /* SQL statement, UTF-16 encoded */
+   int nByte,              /* Maximum length of zSql in bytes. */
+   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+   const void **pzTail     /* OUT: Pointer to unused portion of zSql */
+ );
++SQLITE_API int sqlite3_prepare16_v3(
++  sqlite3 *db,            /* Database handle */
++  const void *zSql,       /* SQL statement, UTF-16 encoded */
++  int nByte,              /* Maximum length of zSql in bytes. */
++  unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
++  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
++  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
++);
  
--
  /*
--** The value of the "pending" byte must be 0x40000000 (1 byte past the
--** 1-gibabyte boundary) in a compatible database.  SQLite never uses
--** the database page that contains the pending byte.  It never attempts
--** to read or write that page.  The pending byte page is set assign
--** for use by the VFS layers as space for managing file locks.
--**
--** During testing, it is often desirable to move the pending byte to
--** a different position in the file.  This allows code that has to
--** deal with the pending byte to run on files that are much smaller
--** than 1 GiB.  The sqlite3_test_control() interface can be used to
--** move the pending byte.
--**
--** IMPORTANT:  Changing the pending byte to any value other than
--** 0x40000000 results in an incompatible database file format!
--** Changing the pending byte during operation will result in undefined
--** and incorrect behavior.
-+** The in-memory image of a disk page has the auxiliary information appended
-+** to the end.  EXTRA_SIZE is the number of bytes of space needed to hold
-+** that extra information.
- */
--#ifndef SQLITE_OMIT_WSD
--SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
--#endif
-+#define EXTRA_SIZE sizeof(MemPage)
+ ** CAPI3REF: Retrieving Statement SQL
+ ** METHOD: sqlite3_stmt
+ **
+-** ^This interface can be used to retrieve a saved copy of the original
+-** SQL text used to create a [prepared statement] if that statement was
+-** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
++** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8
++** SQL text used to create [prepared statement] P if P was
++** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
++** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
++** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
++** string containing the SQL text of prepared statement P with
++** [bound parameters] expanded.
++**
++** ^(For example, if a prepared statement is created using the SQL
++** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
++** and parameter :xyz is unbound, then sqlite3_sql() will return
++** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
++** will return "SELECT 2345,NULL".)^
++**
++** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory
++** is available to hold the result, or if the result would exceed the
++** the maximum string length determined by the [SQLITE_LIMIT_LENGTH].
++**
++** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
++** bound parameter expansions.  ^The [SQLITE_OMIT_TRACE] compile-time
++** option causes sqlite3_expanded_sql() to always return NULL.
++**
++** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
++** automatically freed when the prepared statement is finalized.
++** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
++** is obtained from [sqlite3_malloc()] and must be free by the application
++** by passing it to [sqlite3_free()].
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt);
++SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
++SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
  
  /*
--** Properties of opcodes.  The OPFLG_INITIALIZER macro is
--** created by mkopcodeh.awk during compilation.  Data is obtained
--** from the comments following the "case OP_xxxx:" statements in
--** the vdbe.c file.  
-+** A linked list of the following structures is stored at BtShared.pLock.
-+** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor 
-+** is opened on the table with root page BtShared.iTable. Locks are removed
-+** from this list when a transaction is committed or rolled back, or when
-+** a btree handle is closed.
+ ** CAPI3REF: Determine If An SQL Statement Writes The Database
+@@ -3354,8 +3714,12 @@
+ ** sqlite3_stmt_readonly() to return true since, while those statements
+ ** change the configuration of a database connection, they do not make 
+ ** changes to the content of the database files on disk.
++** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since
++** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
++** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
++** sqlite3_stmt_readonly() returns false for those commands.
  */
--SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
-+struct BtLock {
-+  Btree *pBtree;        /* Btree handle holding this lock */
-+  Pgno iTable;          /* Root page of table */
-+  u8 eLock;             /* READ_LOCK or WRITE_LOCK */
-+  BtLock *pNext;        /* Next in BtShared.pLock list */
-+};
+-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
++SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
  
--/************** End of global.c **********************************************/
--/************** Begin file ctime.c *******************************************/
--/*
--** 2010 February 23
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
-+/* Candidate values for BtLock.eLock */
-+#define READ_LOCK     1
-+#define WRITE_LOCK    2
-+
-+/* A Btree handle
+ /*
+ ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
+@@ -3363,7 +3727,8 @@
  **
--**    May you do good and not evil.
--**    May you find forgiveness for yourself and forgive others.
--**    May you share freely, never taking more than you give.
-+** A database connection contains a pointer to an instance of
-+** this object for every database file that it has open.  This structure
-+** is opaque to the database connection.  The database connection cannot
-+** see the internals of this structure and only deals with pointers to
-+** this structure.
+ ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
+ ** [prepared statement] S has been stepped at least once using 
+-** [sqlite3_step(S)] but has not run to completion and/or has not 
++** [sqlite3_step(S)] but has neither run to completion (returned
++** [SQLITE_DONE] from [sqlite3_step(S)]) nor
+ ** been reset using [sqlite3_reset(S)].  ^The sqlite3_stmt_busy(S)
+ ** interface returns false if S is a NULL pointer.  If S is not a 
+ ** NULL pointer and is not a pointer to a valid [prepared statement]
+@@ -3375,7 +3740,7 @@
+ ** for example, in diagnostic routines to search for prepared 
+ ** statements that are holding a transaction open.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*);
++SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
+ 
+ /*
+ ** CAPI3REF: Dynamically Typed Value Object
+@@ -3390,7 +3755,9 @@
+ ** Some interfaces require a protected sqlite3_value.  Other interfaces
+ ** will accept either a protected or an unprotected sqlite3_value.
+ ** Every interface that accepts sqlite3_value arguments specifies
+-** whether or not it requires a protected sqlite3_value.
++** whether or not it requires a protected sqlite3_value.  The
++** [sqlite3_value_dup()] interface can be used to construct a new 
++** protected sqlite3_value from an unprotected sqlite3_value.
  **
--*************************************************************************
-+** For some database files, the same underlying database cache might be 
-+** shared between multiple connections.  In that case, each connection
-+** has it own instance of this object.  But each instance of this object
-+** points to the same BtShared object.  The database cache and the
-+** schema associated with the database file are all contained within
-+** the BtShared object.
+ ** The terms "protected" and "unprotected" refer to whether or not
+ ** a mutex is held.  An internal mutex is held for a protected
+@@ -3414,7 +3781,7 @@
+ ** The [sqlite3_value_blob | sqlite3_value_type()] family of
+ ** interfaces require protected sqlite3_value objects.
+ */
+-typedef struct Mem sqlite3_value;
++typedef struct sqlite3_value sqlite3_value;
+ 
+ /*
+ ** CAPI3REF: SQL Function Context Object
+@@ -3516,6 +3883,15 @@
+ ** [sqlite3_blob_open | incremental BLOB I/O] routines.
+ ** ^A negative value for the zeroblob results in a zero-length BLOB.
  **
--** This file implements routines used to report what compile-time options
--** SQLite was built with.
-+** All fields in this structure are accessed under sqlite3.mutex.
-+** The pBt pointer itself may not be changed while there exists cursors 
-+** in the referenced BtShared that point back to this Btree since those
-+** cursors have to go through this Btree to find their BtShared and
-+** they often do so without holding sqlite3.mutex.
++** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
++** [prepared statement] S to have an SQL value of NULL, but to also be
++** associated with the pointer P of type T.  ^D is either a NULL pointer or
++** a pointer to a destructor function for P. ^SQLite will invoke the
++** destructor D with a single argument of P when it is finished using
++** P.  The T parameter should be a static string, preferably a string
++** literal. The sqlite3_bind_pointer() routine is part of the
++** [pointer passing interface] added for SQLite 3.20.0.
++**
+ ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
+ ** for the [prepared statement] or with a prepared statement for which
+ ** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
+@@ -3537,19 +3913,21 @@
+ ** See also: [sqlite3_bind_parameter_count()],
+ ** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
  */
--
--#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
--
-+struct Btree {
-+  sqlite3 *db;       /* The database connection holding this btree */
-+  BtShared *pBt;     /* Sharable content of this btree */
-+  u8 inTrans;        /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
-+  u8 sharable;       /* True if we can share pBt with another db */
-+  u8 locked;         /* True if db currently has pBt locked */
-+  int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
-+  int nBackup;       /* Number of backup operations reading this btree */
-+  u32 iDataVersion;  /* Combines with pBt->pPager->iDataVersion */
-+  Btree *pNext;      /* List of other sharable Btrees from the same db */
-+  Btree *pPrev;      /* Back pointer of the same list */
-+#ifndef SQLITE_OMIT_SHARED_CACHE
-+  BtLock lock;       /* Object used to lock page 1 */
-+#endif
-+};
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
++SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
++SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
+                         void(*)(void*));
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double);
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int);
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int);
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
++SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
++SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
++SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
++SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
++SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
++SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
++SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
+                          void(*)(void*), unsigned char encoding);
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
++SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
++SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
++SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
++SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
  
  /*
--** An array of names of all compile-time options.  This array should 
--** be sorted A-Z.
-+** Btree.inTrans may take one of the following values.
+ ** CAPI3REF: Number Of SQL Parameters
+@@ -3570,7 +3948,7 @@
+ ** [sqlite3_bind_parameter_name()], and
+ ** [sqlite3_bind_parameter_index()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
++SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
+ 
+ /*
+ ** CAPI3REF: Name Of A Host Parameter
+@@ -3591,14 +3969,14 @@
+ ** ^If the value N is out of range or if the N-th parameter is
+ ** nameless, then NULL is returned.  ^The returned string is
+ ** always in UTF-8 encoding even if the named parameter was
+-** originally specified as UTF-16 in [sqlite3_prepare16()] or
+-** [sqlite3_prepare16_v2()].
++** originally specified as UTF-16 in [sqlite3_prepare16()],
++** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
  **
--** This array looks large, but in a typical installation actually uses
--** only a handful of compile-time options, so most times this array is usually
--** rather short and uses little memory space.
-+** If the shared-data extension is enabled, there may be multiple users
-+** of the Btree structure. At most one of these may open a write transaction,
-+** but any number may have active read transactions.
+ ** See also: [sqlite3_bind_blob|sqlite3_bind()],
+ ** [sqlite3_bind_parameter_count()], and
+ ** [sqlite3_bind_parameter_index()].
  */
--static const char * const azCompileOpt[] = {
--
--/* These macros are provided to "stringify" the value of the define
--** for those options in which the value is meaningful. */
--#define CTIMEOPT_VAL_(opt) #opt
--#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
-+#define TRANS_NONE  0
-+#define TRANS_READ  1
-+#define TRANS_WRITE 2
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int);
++SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
  
--#if SQLITE_32BIT_ROWID
--  "32BIT_ROWID",
--#endif
--#if SQLITE_4_BYTE_ALIGNED_MALLOC
--  "4_BYTE_ALIGNED_MALLOC",
--#endif
--#if SQLITE_CASE_SENSITIVE_LIKE
--  "CASE_SENSITIVE_LIKE",
--#endif
--#if SQLITE_CHECK_PAGES
--  "CHECK_PAGES",
--#endif
--#if SQLITE_COVERAGE_TEST
--  "COVERAGE_TEST",
--#endif
--#if SQLITE_DEBUG
--  "DEBUG",
--#endif
--#if SQLITE_DEFAULT_LOCKING_MODE
--  "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
--#endif
--#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
--  "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
--#endif
--#if SQLITE_DISABLE_DIRSYNC
--  "DISABLE_DIRSYNC",
--#endif
--#if SQLITE_DISABLE_LFS
--  "DISABLE_LFS",
--#endif
--#if SQLITE_ENABLE_API_ARMOR
--  "ENABLE_API_ARMOR",
--#endif
--#if SQLITE_ENABLE_ATOMIC_WRITE
--  "ENABLE_ATOMIC_WRITE",
--#endif
--#if SQLITE_ENABLE_CEROD
--  "ENABLE_CEROD",
-+/*
-+** An instance of this object represents a single database file.
-+** 
-+** A single database file can be in use at the same time by two
-+** or more database connections.  When two or more connections are
-+** sharing the same database file, each connection has it own
-+** private Btree object for the file and each of those Btrees points
-+** to this one BtShared object.  BtShared.nRef is the number of
-+** connections currently sharing this database file.
+ /*
+ ** CAPI3REF: Index Of A Parameter With A Given Name
+@@ -3609,13 +3987,14 @@
+ ** parameter to [sqlite3_bind_blob|sqlite3_bind()].  ^A zero
+ ** is returned if no matching parameter is found.  ^The parameter
+ ** name must be given in UTF-8 even if the original statement
+-** was prepared from UTF-16 text using [sqlite3_prepare16_v2()].
++** was prepared from UTF-16 text using [sqlite3_prepare16_v2()] or
++** [sqlite3_prepare16_v3()].
+ **
+ ** See also: [sqlite3_bind_blob|sqlite3_bind()],
+ ** [sqlite3_bind_parameter_count()], and
+-** [sqlite3_bind_parameter_index()].
++** [sqlite3_bind_parameter_name()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
++SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+ 
+ /*
+ ** CAPI3REF: Reset All Bindings On A Prepared Statement
+@@ -3625,19 +4004,23 @@
+ ** the [sqlite3_bind_blob | bindings] on a [prepared statement].
+ ** ^Use this routine to reset all host parameters to NULL.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*);
++SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
+ 
+ /*
+ ** CAPI3REF: Number Of Columns In A Result Set
+ ** METHOD: sqlite3_stmt
+ **
+ ** ^Return the number of columns in the result set returned by the
+-** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
+-** statement that does not return data (for example an [UPDATE]).
++** [prepared statement]. ^If this routine returns 0, that means the 
++** [prepared statement] returns no data (for example an [UPDATE]).
++** ^However, just because this routine returns a positive number does not
++** mean that one or more rows of data will be returned.  ^A SELECT statement
++** will always have a positive sqlite3_column_count() but depending on the
++** WHERE clause constraints and the table content, it might return no rows.
+ **
+ ** See also: [sqlite3_data_count()]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt);
++SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Column Names In A Result Set
+@@ -3666,8 +4049,8 @@
+ ** then the name of the column is unspecified and may change from
+ ** one release of SQLite to the next.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N);
++SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
++SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
+ 
+ /*
+ ** CAPI3REF: Source Of Data In A Query Result
+@@ -3715,12 +4098,12 @@
+ ** for the same [prepared statement] and result column
+ ** at the same time then the results are undefined.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int);
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int);
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int);
++SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
++SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
++SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
++SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
++SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
++SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
+ 
+ /*
+ ** CAPI3REF: Declared Datatype Of A Query Result
+@@ -3752,23 +4135,25 @@
+ ** is associated with individual values, not with the containers
+ ** used to hold those values.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int);
++SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
++SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
+ 
+ /*
+ ** CAPI3REF: Evaluate An SQL Statement
+ ** METHOD: sqlite3_stmt
+ **
+-** After a [prepared statement] has been prepared using either
+-** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
++** After a [prepared statement] has been prepared using any of
++** [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()],
++** or [sqlite3_prepare16_v3()] or one of the legacy
+ ** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
+ ** must be called one or more times to evaluate the statement.
+ **
+ ** The details of the behavior of the sqlite3_step() interface depend
+-** on whether the statement was prepared using the newer "v2" interface
+-** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy
+-** interface [sqlite3_prepare()] and [sqlite3_prepare16()].  The use of the
+-** new "v2" interface is recommended for new applications but the legacy
++** on whether the statement was prepared using the newer "vX" interfaces
++** [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()],
++** [sqlite3_prepare16_v2()] or the older legacy
++** interfaces [sqlite3_prepare()] and [sqlite3_prepare16()].  The use of the
++** new "vX" interface is recommended for new applications but the legacy
+ ** interface will continue to be supported.
+ **
+ ** ^In the legacy interface, the return value will be either [SQLITE_BUSY],
+@@ -3814,7 +4199,8 @@
+ ** other than [SQLITE_ROW] before any subsequent invocation of
+ ** sqlite3_step().  Failure to reset the prepared statement using 
+ ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
+-** sqlite3_step().  But after version 3.6.23.1, sqlite3_step() began
++** sqlite3_step().  But after [version 3.6.23.1] ([dateof:3.6.23.1]),
++** sqlite3_step() began
+ ** calling [sqlite3_reset()] automatically in this circumstance rather
+ ** than returning [SQLITE_MISUSE].  This is not considered a compatibility
+ ** break because any application that ever receives an SQLITE_MISUSE error
+@@ -3828,12 +4214,13 @@
+ ** specific [error codes] that better describes the error.
+ ** We admit that this is a goofy design.  The problem has been fixed
+ ** with the "v2" interface.  If you prepare all of your SQL statements
+-** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
++** using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()]
++** or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead
+ ** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
+ ** then the more specific [error codes] are returned directly
+-** by sqlite3_step().  The use of the "v2" interface is recommended.
++** by sqlite3_step().  The use of the "vX" interfaces is recommended.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*);
++SQLITE_API int sqlite3_step(sqlite3_stmt*);
+ 
+ /*
+ ** CAPI3REF: Number of columns in a result set
+@@ -3854,7 +4241,7 @@
+ **
+ ** See also: [sqlite3_column_count()]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
++SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Fundamental Datatypes
+@@ -3893,7 +4280,27 @@
+ ** KEYWORDS: {column access functions}
+ ** METHOD: sqlite3_stmt
+ **
+-** These routines form the "result set" interface.
++** <b>Summary:</b>
++** <blockquote><table border=0 cellpadding=0 cellspacing=0>
++** <tr><td><b>sqlite3_column_blob</b><td>&rarr;<td>BLOB result
++** <tr><td><b>sqlite3_column_double</b><td>&rarr;<td>REAL result
++** <tr><td><b>sqlite3_column_int</b><td>&rarr;<td>32-bit INTEGER result
++** <tr><td><b>sqlite3_column_int64</b><td>&rarr;<td>64-bit INTEGER result
++** <tr><td><b>sqlite3_column_text</b><td>&rarr;<td>UTF-8 TEXT result
++** <tr><td><b>sqlite3_column_text16</b><td>&rarr;<td>UTF-16 TEXT result
++** <tr><td><b>sqlite3_column_value</b><td>&rarr;<td>The result as an 
++** [sqlite3_value|unprotected sqlite3_value] object.
++** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
++** <tr><td><b>sqlite3_column_bytes</b><td>&rarr;<td>Size of a BLOB
++** or a UTF-8 TEXT result in bytes
++** <tr><td><b>sqlite3_column_bytes16&nbsp;&nbsp;</b>
++** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
++** TEXT in bytes
++** <tr><td><b>sqlite3_column_type</b><td>&rarr;<td>Default
++** datatype of the result
++** </table></blockquote>
 +**
-+** Fields in this structure are accessed under the BtShared.mutex
-+** mutex, except for nRef and pNext which are accessed under the
-+** global SQLITE_MUTEX_STATIC_MASTER mutex.  The pPager field
-+** may not be modified once it is initially set as long as nRef>0.
-+** The pSchema field may be set once under BtShared.mutex and
-+** thereafter is unchanged as long as nRef>0.
++** <b>Details:</b>
+ **
+ ** ^These routines return information about a single column of the current
+ ** result row of a query.  ^In every case the first argument is a pointer
+@@ -3916,16 +4323,29 @@
+ ** are called from a different thread while any of these routines
+ ** are pending, then the results are undefined.
+ **
++** The first six interfaces (_blob, _double, _int, _int64, _text, and _text16)
++** each return the value of a result column in a specific data format.  If
++** the result column is not initially in the requested format (for example,
++** if the query returns an integer but the sqlite3_column_text() interface
++** is used to extract the value) then an automatic type conversion is performed.
 +**
-+** isPending:
+ ** ^The sqlite3_column_type() routine returns the
+ ** [SQLITE_INTEGER | datatype code] for the initial data type
+ ** of the result column.  ^The returned value is one of [SQLITE_INTEGER],
+-** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].  The value
+-** returned by sqlite3_column_type() is only meaningful if no type
+-** conversions have occurred as described below.  After a type conversion,
+-** the value returned by sqlite3_column_type() is undefined.  Future
++** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].
++** The return value of sqlite3_column_type() can be used to decide which
++** of the first six interface should be used to extract the column value.
++** The value returned by sqlite3_column_type() is only meaningful if no
++** automatic type conversions have occurred for the value in question.  
++** After a type conversion, the result of calling sqlite3_column_type()
++** is undefined, though harmless.  Future
+ ** versions of SQLite may change the behavior of sqlite3_column_type()
+ ** following a type conversion.
+ **
++** If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes()
++** or sqlite3_column_bytes16() interfaces can be used to determine the size
++** of that BLOB or string.
 +**
-+**   If a BtShared client fails to obtain a write-lock on a database
-+**   table (because there exists one or more read-locks on the table),
-+**   the shared-cache enters 'pending-lock' state and isPending is
-+**   set to true.
+ ** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
+ ** routine returns the number of bytes in that BLOB or string.
+ ** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts
+@@ -3954,16 +4374,21 @@
+ ** even empty strings, are always zero-terminated.  ^The return
+ ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
+ **
+-** ^The object returned by [sqlite3_column_value()] is an
+-** [unprotected sqlite3_value] object.  An unprotected sqlite3_value object
+-** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
++** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
++** [unprotected sqlite3_value] object.  In a multithreaded environment,
++** an unprotected sqlite3_value object may only be used safely with
++** [sqlite3_bind_value()] and [sqlite3_result_value()].
+ ** If the [unprotected sqlite3_value] object returned by
+ ** [sqlite3_column_value()] is used in any other way, including calls
+ ** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
+-** or [sqlite3_value_bytes()], then the behavior is undefined.
++** or [sqlite3_value_bytes()], the behavior is not threadsafe.
++** Hence, the sqlite3_column_value() interface
++** is normally only useful within the implementation of 
++** [application-defined SQL functions] or [virtual tables], not within
++** top-level application code.
+ **
+-** These routines attempt to convert the value where appropriate.  ^For
+-** example, if the internal representation is FLOAT and a text result
++** The these routines may attempt to convert the datatype of the result.
++** ^For example, if the internal representation is FLOAT and a text result
+ ** is requested, [sqlite3_snprintf()] is used internally to perform the
+ ** conversion automatically.  ^(The following table details the conversions
+ ** that are applied:
+@@ -3991,12 +4416,6 @@
+ ** </table>
+ ** </blockquote>)^
+ **
+-** The table above makes reference to standard C library functions atoi()
+-** and atof().  SQLite does not really use these functions.  It has its
+-** own equivalent internal routines.  The atoi() and atof() names are
+-** used in the table for brevity and because they are familiar to most
+-** C programmers.
+-**
+ ** Note that when type conversions occur, pointers returned by prior
+ ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
+ ** sqlite3_column_text16() may be invalidated.
+@@ -4021,7 +4440,7 @@
+ ** of conversion are done in place when it is possible, but sometimes they
+ ** are not possible and in those cases prior pointers are invalidated.
+ **
+-** The safest and easiest to remember policy is to invoke these routines
++** The safest policy is to invoke these routines
+ ** in one of the following ways:
+ **
+ ** <ul>
+@@ -4041,7 +4460,7 @@
+ ** ^The pointers returned are valid until a type conversion occurs as
+ ** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
+ ** [sqlite3_finalize()] is called.  ^The memory space used to hold strings
+-** and BLOBs is freed automatically.  Do <b>not</b> pass the pointers returned
++** and BLOBs is freed automatically.  Do not pass the pointers returned
+ ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
+ ** [sqlite3_free()].
+ **
+@@ -4051,16 +4470,16 @@
+ ** pointer.  Subsequent calls to [sqlite3_errcode()] will return
+ ** [SQLITE_NOMEM].)^
+ */
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol);
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+-SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol);
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol);
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol);
+-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol);
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol);
+-SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol);
++SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
++SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
++SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
++SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
++SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
++SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
++SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
++SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
++SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
++SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
+ 
+ /*
+ ** CAPI3REF: Destroy A Prepared Statement Object
+@@ -4088,7 +4507,7 @@
+ ** statement after it has been finalized can result in undefined and
+ ** undesirable behavior such as segfaults and heap corruption.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt);
++SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Reset A Prepared Statement Object
+@@ -4115,7 +4534,7 @@
+ ** ^The [sqlite3_reset(S)] interface does not change the values
+ ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt);
++SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Create Or Redefine SQL Functions
+@@ -4215,7 +4634,7 @@
+ ** close the database connection nor finalize or reset the prepared
+ ** statement in which the function is running.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
++SQLITE_API int sqlite3_create_function(
+   sqlite3 *db,
+   const char *zFunctionName,
+   int nArg,
+@@ -4225,7 +4644,7 @@
+   void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+   void (*xFinal)(sqlite3_context*)
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
++SQLITE_API int sqlite3_create_function16(
+   sqlite3 *db,
+   const void *zFunctionName,
+   int nArg,
+@@ -4235,7 +4654,7 @@
+   void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+   void (*xFinal)(sqlite3_context*)
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
++SQLITE_API int sqlite3_create_function_v2(
+   sqlite3 *db,
+   const char *zFunctionName,
+   int nArg,
+@@ -4281,34 +4700,53 @@
+ ** these functions, we will not explain what they do.
+ */
+ #ifndef SQLITE_OMIT_DEPRECATED
+-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*);
+-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*);
+-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void);
+-SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void);
+-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
++SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
++SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
++SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
++SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
++SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
++SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+                       void*,sqlite3_int64);
+ #endif
+ 
+ /*
+-** CAPI3REF: Obtaining SQL Function Parameter Values
++** CAPI3REF: Obtaining SQL Values
+ ** METHOD: sqlite3_value
+ **
+-** The C-language implementation of SQL functions and aggregates uses
+-** this set of interface routines to access the parameter values on
+-** the function or aggregate.
+-**
+-** The xFunc (for scalar functions) or xStep (for aggregates) parameters
+-** to [sqlite3_create_function()] and [sqlite3_create_function16()]
+-** define callbacks that implement the SQL functions and aggregates.
+-** The 3rd parameter to these callbacks is an array of pointers to
+-** [protected sqlite3_value] objects.  There is one [sqlite3_value] object for
+-** each parameter to the SQL function.  These routines are used to
+-** extract values from the [sqlite3_value] objects.
++** <b>Summary:</b>
++** <blockquote><table border=0 cellpadding=0 cellspacing=0>
++** <tr><td><b>sqlite3_value_blob</b><td>&rarr;<td>BLOB value
++** <tr><td><b>sqlite3_value_double</b><td>&rarr;<td>REAL value
++** <tr><td><b>sqlite3_value_int</b><td>&rarr;<td>32-bit INTEGER value
++** <tr><td><b>sqlite3_value_int64</b><td>&rarr;<td>64-bit INTEGER value
++** <tr><td><b>sqlite3_value_pointer</b><td>&rarr;<td>Pointer value
++** <tr><td><b>sqlite3_value_text</b><td>&rarr;<td>UTF-8 TEXT value
++** <tr><td><b>sqlite3_value_text16</b><td>&rarr;<td>UTF-16 TEXT value in
++** the native byteorder
++** <tr><td><b>sqlite3_value_text16be</b><td>&rarr;<td>UTF-16be TEXT value
++** <tr><td><b>sqlite3_value_text16le</b><td>&rarr;<td>UTF-16le TEXT value
++** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
++** <tr><td><b>sqlite3_value_bytes</b><td>&rarr;<td>Size of a BLOB
++** or a UTF-8 TEXT in bytes
++** <tr><td><b>sqlite3_value_bytes16&nbsp;&nbsp;</b>
++** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
++** TEXT in bytes
++** <tr><td><b>sqlite3_value_type</b><td>&rarr;<td>Default
++** datatype of the value
++** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
++** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
++** </table></blockquote>
 +**
-+**   The shared-cache leaves the 'pending lock' state when either of
-+**   the following occur:
++** <b>Details:</b>
 +**
-+**     1) The current writer (BtShared.pWriter) concludes its transaction, OR
-+**     2) The number of locks held by other connections drops to zero.
++** These routines extract type, size, and content information from
++** [protected sqlite3_value] objects.  Protected sqlite3_value objects
++** are used to pass parameter information into implementation of
++** [application-defined SQL functions] and [virtual tables].
+ **
+ ** These routines work only with [protected sqlite3_value] objects.
+ ** Any attempt to use these routines on an [unprotected sqlite3_value]
+-** object results in undefined behavior.
++** is not threadsafe.
+ **
+ ** ^These routines work just like the corresponding [column access functions]
+ ** except that these routines take a single [protected sqlite3_value] object
+@@ -4319,6 +4757,24 @@
+ ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces
+ ** extract UTF-16 strings as big-endian and little-endian respectively.
+ **
++** ^If [sqlite3_value] object V was initialized 
++** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)]
++** and if X and Y are strings that compare equal according to strcmp(X,Y),
++** then sqlite3_value_pointer(V,Y) will return the pointer P.  ^Otherwise,
++** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer() 
++** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
 +**
-+**   while in the 'pending-lock' state, no connection may start a new
-+**   transaction.
++** ^(The sqlite3_value_type(V) interface returns the
++** [SQLITE_INTEGER | datatype code] for the initial datatype of the
++** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER],
++** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^
++** Other interfaces might change the datatype for an sqlite3_value object.
++** For example, if the datatype is initially SQLITE_INTEGER and
++** sqlite3_value_text(V) is called to extract a text value for that
++** integer, then subsequent calls to sqlite3_value_type(V) might return
++** SQLITE_TEXT.  Whether or not a persistent internal datatype conversion
++** occurs is undefined and may change from one release of SQLite to the next.
 +**
-+**   This feature is included to help prevent writer-starvation.
-+*/
-+struct BtShared {
-+  Pager *pPager;        /* The page cache */
-+  sqlite3 *db;          /* Database connection currently using this Btree */
-+  BtCursor *pCursor;    /* A list of all open cursors */
-+  MemPage *pPage1;      /* First page of the database */
-+  u8 openFlags;         /* Flags to sqlite3BtreeOpen() */
-+#ifndef SQLITE_OMIT_AUTOVACUUM
-+  u8 autoVacuum;        /* True if auto-vacuum is enabled */
-+  u8 incrVacuum;        /* True if incr-vacuum is enabled */
-+  u8 bDoTruncate;       /* True to truncate db on commit */
- #endif
--#if SQLITE_ENABLE_COLUMN_METADATA
--  "ENABLE_COLUMN_METADATA",
-+  u8 inTransaction;     /* Transaction state */
-+  u8 max1bytePayload;   /* Maximum first byte of cell for a 1-byte payload */
-+#ifdef SQLITE_HAS_CODEC
-+  u8 optimalReserve;    /* Desired amount of reserved space per page */
- #endif
--#if SQLITE_ENABLE_DBSTAT_VTAB
--  "ENABLE_DBSTAT_VTAB",
-+  u16 btsFlags;         /* Boolean parameters.  See BTS_* macros below */
-+  u16 maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
-+  u16 minLocal;         /* Minimum local payload in non-LEAFDATA tables */
-+  u16 maxLeaf;          /* Maximum local payload in a LEAFDATA table */
-+  u16 minLeaf;          /* Minimum local payload in a LEAFDATA table */
-+  u32 pageSize;         /* Total number of bytes on a page */
-+  u32 usableSize;       /* Number of usable bytes on each page */
-+  int nTransaction;     /* Number of open transactions (read + write) */
-+  u32 nPage;            /* Number of pages in the database */
-+  void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
-+  void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
-+  sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */
-+  Bitvec *pHasContent;  /* Set of pages moved to free-list this transaction */
-+#ifndef SQLITE_OMIT_SHARED_CACHE
-+  int nRef;             /* Number of references to this structure */
-+  BtShared *pNext;      /* Next on a list of sharable BtShared structs */
-+  BtLock *pLock;        /* List of locks held on this shared-btree struct */
-+  Btree *pWriter;       /* Btree with currently open write transaction */
- #endif
--#if SQLITE_ENABLE_EXPENSIVE_ASSERT
--  "ENABLE_EXPENSIVE_ASSERT",
-+  u8 *pTmpSpace;        /* Temp space sufficient to hold a single cell */
-+};
-+
-+/*
-+** Allowed values for BtShared.btsFlags
-+*/
-+#define BTS_READ_ONLY        0x0001   /* Underlying file is readonly */
-+#define BTS_PAGESIZE_FIXED   0x0002   /* Page size can no longer be changed */
-+#define BTS_SECURE_DELETE    0x0004   /* PRAGMA secure_delete is enabled */
-+#define BTS_INITIALLY_EMPTY  0x0008   /* Database was empty at trans start */
-+#define BTS_NO_WAL           0x0010   /* Do not open write-ahead-log files */
-+#define BTS_EXCLUSIVE        0x0020   /* pWriter has an exclusive lock */
-+#define BTS_PENDING          0x0040   /* Waiting for read-locks to clear */
-+
-+/*
-+** An instance of the following structure is used to hold information
-+** about a cell.  The parseCellPtr() function fills in this structure
-+** based on information extract from the raw disk page.
-+*/
-+typedef struct CellInfo CellInfo;
-+struct CellInfo {
-+  i64 nKey;      /* The key for INTKEY tables, or nPayload otherwise */
-+  u8 *pPayload;  /* Pointer to the start of payload */
-+  u32 nPayload;  /* Bytes of payload */
-+  u16 nLocal;    /* Amount of payload held locally, not on overflow */
-+  u16 iOverflow; /* Offset to overflow page number.  Zero if no overflow */
-+  u16 nSize;     /* Size of the cell content on the main b-tree page */
-+};
+ ** ^(The sqlite3_value_numeric_type() interface attempts to apply
+ ** numeric affinity to the value.  This means that an attempt is
+ ** made to convert the value to an integer or floating point.  If
+@@ -4336,18 +4792,48 @@
+ ** These routines must be called from the same thread as
+ ** the SQL function that supplied the [sqlite3_value*] parameters.
+ */
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*);
+-SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*);
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*);
+-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
++SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
++SQLITE_API double sqlite3_value_double(sqlite3_value*);
++SQLITE_API int sqlite3_value_int(sqlite3_value*);
++SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
++SQLITE_API void *sqlite3_value_pointer(sqlite3_value*, const char*);
++SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
++SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
++SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
++SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
++SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
++SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
++SQLITE_API int sqlite3_value_type(sqlite3_value*);
++SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
 +
 +/*
-+** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than
-+** this will be declared corrupt. This value is calculated based on a
-+** maximum database size of 2^31 pages a minimum fanout of 2 for a
-+** root-node and 3 for all other internal nodes.
++** CAPI3REF: Finding The Subtype Of SQL Values
++** METHOD: sqlite3_value
 +**
-+** If a tree that appears to be taller than this is encountered, it is
-+** assumed that the database is corrupt.
++** The sqlite3_value_subtype(V) function returns the subtype for
++** an [application-defined SQL function] argument V.  The subtype
++** information can be used to pass a limited amount of context from
++** one SQL function to another.  Use the [sqlite3_result_subtype()]
++** routine to set the subtype for the return value of an SQL function.
 +*/
-+#define BTCURSOR_MAX_DEPTH 20
++SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
 +
 +/*
-+** A cursor is a pointer to a particular entry within a particular
-+** b-tree within a database file.
-+**
-+** The entry is identified by its MemPage and the index in
-+** MemPage.aCell[] of the entry.
++** CAPI3REF: Copy And Free SQL Values
++** METHOD: sqlite3_value
 +**
-+** A single database file can be shared by two more database connections,
-+** but cursors cannot be shared.  Each cursor is associated with a
-+** particular database connection identified BtCursor.pBtree.db.
++** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
++** object D and returns a pointer to that copy.  ^The [sqlite3_value] returned
++** is a [protected sqlite3_value] object even if the input is not.
++** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
++** memory allocation fails.
 +**
-+** Fields in this structure are accessed under the BtShared.mutex
-+** found at self->pBt->mutex. 
-+**
-+** skipNext meaning:
-+**    eState==SKIPNEXT && skipNext>0:  Next sqlite3BtreeNext() is no-op.
-+**    eState==SKIPNEXT && skipNext<0:  Next sqlite3BtreePrevious() is no-op.
-+**    eState==FAULT:                   Cursor fault with skipNext as error code.
-+*/
-+struct BtCursor {
-+  Btree *pBtree;            /* The Btree to which this cursor belongs */
-+  BtShared *pBt;            /* The BtShared this cursor points to */
-+  BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
-+  struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
-+  Pgno *aOverflow;          /* Cache of overflow page locations */
-+  CellInfo info;            /* A parse of the cell we are pointing at */
-+  i64 nKey;                 /* Size of pKey, or last integer key */
-+  void *pKey;               /* Saved key that was cursor last known position */
-+  Pgno pgnoRoot;            /* The root page of this tree */
-+  int nOvflAlloc;           /* Allocated size of aOverflow[] array */
-+  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive.
-+                   ** Error code if eState==CURSOR_FAULT */
-+  u8 curFlags;              /* zero or more BTCF_* flags defined below */
-+  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
-+  u8 hints;                             /* As configured by CursorSetHints() */
-+  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 */
-+};
-+
-+/*
-+** Legal values for BtCursor.curFlags
++** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
++** previously obtained from [sqlite3_value_dup()].  ^If V is a NULL pointer
++** then sqlite3_value_free(V) is a harmless no-op.
 +*/
-+#define BTCF_WriteFlag    0x01   /* True if a write cursor */
-+#define BTCF_ValidNKey    0x02   /* True if info.nKey is valid */
-+#define BTCF_ValidOvfl    0x04   /* True if aOverflow is valid */
-+#define BTCF_AtLast       0x08   /* Cursor is pointing ot the last entry */
-+#define BTCF_Incrblob     0x10   /* True if an incremental I/O handle */
-+
-+/*
-+** Potential values for BtCursor.eState.
-+**
-+** CURSOR_INVALID:
-+**   Cursor does not point to a valid entry. This can happen (for example) 
-+**   because the table is empty or because BtreeCursorFirst() has not been
-+**   called.
-+**
-+** CURSOR_VALID:
-+**   Cursor points to a valid entry. getPayload() etc. may be called.
-+**
-+** CURSOR_SKIPNEXT:
-+**   Cursor is valid except that the Cursor.skipNext field is non-zero
-+**   indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
-+**   operation should be a no-op.
++SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
++SQLITE_API void sqlite3_value_free(sqlite3_value*);
+ 
+ /*
+ ** CAPI3REF: Obtain Aggregate Function Context
+@@ -4392,7 +4878,7 @@
+ ** This routine must be called from the same thread in which
+ ** the aggregate SQL function is running.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes);
++SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
+ 
+ /*
+ ** CAPI3REF: User Data For Functions
+@@ -4407,7 +4893,7 @@
+ ** This routine must be called from the same thread in which
+ ** the application-defined function is running.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*);
++SQLITE_API void *sqlite3_user_data(sqlite3_context*);
+ 
+ /*
+ ** CAPI3REF: Database Connection For Functions
+@@ -4419,7 +4905,7 @@
+ ** and [sqlite3_create_function16()] routines that originally
+ ** registered the application defined function.
+ */
+-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*);
++SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
+ 
+ /*
+ ** CAPI3REF: Function Auxiliary Data
+@@ -4436,10 +4922,11 @@
+ ** the compiled regular expression can be reused on multiple
+ ** invocations of the same function.
+ **
+-** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
+-** associated by the sqlite3_set_auxdata() function with the Nth argument
+-** value to the application-defined function. ^If there is no metadata
+-** associated with the function argument, this sqlite3_get_auxdata() interface
++** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
++** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
++** value to the application-defined function.  ^N is zero for the left-most
++** function argument.  ^If there is no metadata
++** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
+ ** returns a NULL pointer.
+ **
+ ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
+@@ -4451,12 +4938,13 @@
+ ** SQLite will invoke the destructor function X with parameter P exactly
+ ** once, when the metadata is discarded.
+ ** SQLite is free to discard the metadata at any time, including: <ul>
+-** <li> when the corresponding function parameter changes, or
+-** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+-**      SQL statement, or
+-** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
+-** <li> during the original sqlite3_set_auxdata() call when a memory 
+-**      allocation error occurs. </ul>)^
++** <li> ^(when the corresponding function parameter changes)^, or
++** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
++**      SQL statement)^, or
++** <li> ^(when sqlite3_set_auxdata() is invoked again on the same
++**       parameter)^, or
++** <li> ^(during the original sqlite3_set_auxdata() call when a memory 
++**      allocation error occurs.)^ </ul>
+ **
+ ** Note the last bullet in particular.  The destructor X in 
+ ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
+@@ -4469,11 +4957,15 @@
+ ** function parameters that are compile-time constants, including literal
+ ** values and [parameters] and expressions composed from the same.)^
+ **
++** The value of the N parameter to these interfaces should be non-negative.
++** Future enhancements may make use of negative N values to define new
++** kinds of function caching behavior.
 +**
-+** CURSOR_REQUIRESEEK:
-+**   The table that this cursor was opened on still exists, but has been 
-+**   modified since the cursor was last used. The cursor position is saved
-+**   in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in 
-+**   this state, restoreCursorPosition() can be called to attempt to
-+**   seek the cursor to the saved position.
+ ** These routines must be called from the same thread in which
+ ** the SQL function is running.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N);
+-SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
++SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
++SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
+ 
+ 
+ /*
+@@ -4512,9 +5004,9 @@
+ ** to by the second parameter and which is N bytes long where N is the
+ ** third parameter.
+ **
+-** ^The sqlite3_result_zeroblob() interfaces set the result of
+-** the application-defined function to be a BLOB containing all zero
+-** bytes and N bytes in size, where N is the value of the 2nd parameter.
++** ^The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N)
++** interfaces set the result of the application-defined function to be
++** a BLOB containing all zero bytes and N bytes in size.
+ **
+ ** ^The sqlite3_result_double() interface sets the result from
+ ** an application-defined function to be a floating point value specified
+@@ -4592,11 +5084,11 @@
+ ** when it has finished using that result.
+ ** ^If the 4th parameter to the sqlite3_result_text* interfaces
+ ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
+-** then SQLite makes a copy of the result into space obtained from
++** then SQLite makes a copy of the result into space obtained
+ ** from [sqlite3_malloc()] before it returns.
+ **
+ ** ^The sqlite3_result_value() interface sets the result of
+-** the application-defined function to be a copy the
++** the application-defined function to be a copy of the
+ ** [unprotected sqlite3_value] object specified by the 2nd parameter.  ^The
+ ** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
+ ** so that the [sqlite3_value] specified in the parameter may change or
+@@ -4605,30 +5097,58 @@
+ ** [unprotected sqlite3_value] object is required, so either
+ ** kind of [sqlite3_value] object can be used with this interface.
+ **
++** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an
++** SQL NULL value, just like [sqlite3_result_null(C)], except that it
++** also associates the host-language pointer P or type T with that 
++** NULL value such that the pointer can be retrieved within an
++** [application-defined SQL function] using [sqlite3_value_pointer()].
++** ^If the D parameter is not NULL, then it is a pointer to a destructor
++** for the P parameter.  ^SQLite invokes D with P as its only argument
++** when SQLite is finished with P.  The T parameter should be a static
++** string and preferably a string literal. The sqlite3_result_pointer()
++** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
 +**
-+** CURSOR_FAULT:
-+**   An unrecoverable error (an I/O error or a malloc failure) has occurred
-+**   on a different connection that shares the BtShared cache with this
-+**   cursor.  The error has left the cache in an inconsistent state.
-+**   Do nothing else with this cursor.  Any attempt to use the cursor
-+**   should return the error code stored in BtCursor.skipNext
-+*/
-+#define CURSOR_INVALID           0
-+#define CURSOR_VALID             1
-+#define CURSOR_SKIPNEXT          2
-+#define CURSOR_REQUIRESEEK       3
-+#define CURSOR_FAULT             4
+ ** If these routines are called from within the different thread
+ ** than the one containing the application-defined function that received
+ ** the [sqlite3_context] pointer, the results are undefined.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*,
++SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
++SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
+                            sqlite3_uint64,void(*)(void*));
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
++SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
++SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
++SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
++SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
++SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
++SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
++SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
++SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
++SQLITE_API void sqlite3_result_null(sqlite3_context*);
++SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
++SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
+                            void(*)(void*), unsigned char encoding);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
++SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
++SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
++SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
++SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
++SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*));
++SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
++SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
 +
-+/* 
-+** The database page the PENDING_BYTE occupies. This page is never used.
-+*/
-+# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
 +
 +/*
-+** These macros define the location of the pointer-map entry for a 
-+** database page. The first argument to each is the number of usable
-+** bytes on each page of the database (often 1024). The second is the
-+** page number to look up in the pointer map.
++** CAPI3REF: Setting The Subtype Of An SQL Function
++** METHOD: sqlite3_context
 +**
-+** PTRMAP_PAGENO returns the database page number of the pointer-map
-+** page that stores the required pointer. PTRMAP_PTROFFSET returns
-+** the offset of the requested map entry.
-+**
-+** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page,
-+** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be
-+** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
-+** this test.
++** The sqlite3_result_subtype(C,T) function causes the subtype of
++** the result from the [application-defined SQL function] with 
++** [sqlite3_context] C to be the value T.  Only the lower 8 bits 
++** of the subtype T are preserved in current versions of SQLite;
++** higher order bits are discarded.
++** The number of subtype bytes preserved by SQLite might increase
++** in future releases of SQLite.
 +*/
-+#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)
-+#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1))
-+#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
-+
-+/*
-+** The pointer map is a lookup table that identifies the parent page for
-+** each child page in the database file.  The parent page is the page that
-+** contains a pointer to the child.  Every page in the database contains
-+** 0 or 1 parent pages.  (In this context 'database page' refers
-+** to any page that is not part of the pointer map itself.)  Each pointer map
-+** entry consists of a single byte 'type' and a 4 byte parent page number.
-+** The PTRMAP_XXX identifiers below are the valid types.
++SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
+ 
+ /*
+ ** CAPI3REF: Define New Collating Sequences
+@@ -4710,14 +5230,14 @@
+ **
+ ** See also:  [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
++SQLITE_API int sqlite3_create_collation(
+   sqlite3*, 
+   const char *zName, 
+   int eTextRep, 
+   void *pArg,
+   int(*xCompare)(void*,int,const void*,int,const void*)
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
++SQLITE_API int sqlite3_create_collation_v2(
+   sqlite3*, 
+   const char *zName, 
+   int eTextRep, 
+@@ -4725,7 +5245,7 @@
+   int(*xCompare)(void*,int,const void*,int,const void*),
+   void(*xDestroy)(void*)
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
++SQLITE_API int sqlite3_create_collation16(
+   sqlite3*, 
+   const void *zName,
+   int eTextRep, 
+@@ -4760,12 +5280,12 @@
+ ** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
+ ** [sqlite3_create_collation_v2()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
++SQLITE_API int sqlite3_collation_needed(
+   sqlite3*, 
+   void*, 
+   void(*)(void*,sqlite3*,int eTextRep,const char*)
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
++SQLITE_API int sqlite3_collation_needed16(
+   sqlite3*, 
+   void*,
+   void(*)(void*,sqlite3*,int eTextRep,const void*)
+@@ -4779,11 +5299,11 @@
+ ** The code to implement this API is not available in the public release
+ ** of SQLite.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_key(
++SQLITE_API int sqlite3_key(
+   sqlite3 *db,                   /* Database to be rekeyed */
+   const void *pKey, int nKey     /* The key */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(
++SQLITE_API int sqlite3_key_v2(
+   sqlite3 *db,                   /* Database to be rekeyed */
+   const char *zDbName,           /* Name of the database */
+   const void *pKey, int nKey     /* The key */
+@@ -4797,11 +5317,11 @@
+ ** The code to implement this API is not available in the public release
+ ** of SQLite.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_rekey(
++SQLITE_API int sqlite3_rekey(
+   sqlite3 *db,                   /* Database to be rekeyed */
+   const void *pKey, int nKey     /* The new key */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(
++SQLITE_API int sqlite3_rekey_v2(
+   sqlite3 *db,                   /* Database to be rekeyed */
+   const char *zDbName,           /* Name of the database */
+   const void *pKey, int nKey     /* The new key */
+@@ -4811,7 +5331,7 @@
+ ** Specify the activation key for a SEE database.  Unless 
+ ** activated, none of the SEE routines will work.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(
++SQLITE_API void sqlite3_activate_see(
+   const char *zPassPhrase        /* Activation phrase */
+ );
+ #endif
+@@ -4821,7 +5341,7 @@
+ ** Specify the activation key for a CEROD database.  Unless 
+ ** activated, none of the CEROD routines will work.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod(
++SQLITE_API void sqlite3_activate_cerod(
+   const char *zPassPhrase        /* Activation phrase */
+ );
+ #endif
+@@ -4843,7 +5363,7 @@
+ ** all, then the behavior of sqlite3_sleep() may deviate from the description
+ ** in the previous paragraphs.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int);
++SQLITE_API int sqlite3_sleep(int);
+ 
+ /*
+ ** CAPI3REF: Name Of The Folder Holding Temporary Files
+@@ -4962,7 +5482,7 @@
+ ** connection while this routine is running, then the return value
+ ** is undefined.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
++SQLITE_API int sqlite3_get_autocommit(sqlite3*);
+ 
+ /*
+ ** CAPI3REF: Find The Database Handle Of A Prepared Statement
+@@ -4975,7 +5495,7 @@
+ ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
+ ** create the statement in the first place.
+ */
+-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
++SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
+ 
+ /*
+ ** CAPI3REF: Return The Filename For A Database Connection
+@@ -4992,7 +5512,7 @@
+ ** will be an absolute pathname, even if the filename used
+ ** to open the database originally was a URI or relative pathname.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName);
++SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
+ 
+ /*
+ ** CAPI3REF: Determine if a database is read-only
+@@ -5002,7 +5522,7 @@
+ ** of connection D is read-only, 0 if it is read/write, or -1 if N is not
+ ** the name of a database on connection D.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
++SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
+ 
+ /*
+ ** CAPI3REF: Find the next prepared statement
+@@ -5018,7 +5538,7 @@
+ ** [sqlite3_next_stmt(D,S)] must refer to an open database
+ ** connection and in particular must not be a NULL pointer.
+ */
+-SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
++SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Commit And Rollback Notification Callbacks
+@@ -5067,8 +5587,8 @@
+ **
+ ** See also the [sqlite3_update_hook()] interface.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+-SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
++SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
++SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
+ 
+ /*
+ ** CAPI3REF: Data Change Notification Callbacks
+@@ -5077,7 +5597,7 @@
+ ** ^The sqlite3_update_hook() interface registers a callback function
+ ** with the [database connection] identified by the first argument
+ ** to be invoked whenever a row is updated, inserted or deleted in
+-** a rowid table.
++** a [rowid table].
+ ** ^Any callback set by a previous call to this function
+ ** for the same database connection is overridden.
+ **
+@@ -5098,7 +5618,7 @@
+ ** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
+ **
+ ** ^In the current implementation, the update hook
+-** is not invoked when duplication rows are deleted because of an
++** is not invoked when conflicting rows are deleted because of an
+ ** [ON CONFLICT | ON CONFLICT REPLACE] clause.  ^Nor is the update hook
+ ** invoked when rows are deleted using the [truncate optimization].
+ ** The exceptions defined in this paragraph might change in a future
+@@ -5116,10 +5636,10 @@
+ ** on the same [database connection] D, or NULL for
+ ** the first call on D.
+ **
+-** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
+-** interfaces.
++** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()],
++** and [sqlite3_preupdate_hook()] interfaces.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
++SQLITE_API void *sqlite3_update_hook(
+   sqlite3*, 
+   void(*)(void *,int ,char const *,char const *,sqlite3_int64),
+   void*
+@@ -5134,7 +5654,8 @@
+ ** and disabled if the argument is false.)^
+ **
+ ** ^Cache sharing is enabled and disabled for an entire process.
+-** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
++** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). 
++** In prior versions of SQLite,
+ ** sharing was enabled or disabled for each thread separately.
+ **
+ ** ^(The cache sharing mode set by this interface effects all subsequent
+@@ -5159,7 +5680,7 @@
+ **
+ ** See Also:  [SQLite Shared-Cache Mode]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int);
++SQLITE_API int sqlite3_enable_shared_cache(int);
+ 
+ /*
+ ** CAPI3REF: Attempt To Free Heap Memory
+@@ -5175,7 +5696,7 @@
+ **
+ ** See also: [sqlite3_db_release_memory()]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int);
++SQLITE_API int sqlite3_release_memory(int);
+ 
+ /*
+ ** CAPI3REF: Free Memory Used By A Database Connection
+@@ -5189,7 +5710,7 @@
+ **
+ ** See also: [sqlite3_release_memory()]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
++SQLITE_API int sqlite3_db_release_memory(sqlite3*);
+ 
+ /*
+ ** CAPI3REF: Impose A Limit On Heap Size
+@@ -5228,7 +5749,8 @@
+ **      from the heap.
+ ** </ul>)^
+ **
+-** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
++** Beginning with SQLite [version 3.7.3] ([dateof:3.7.3]), 
++** the soft heap limit is enforced
+ ** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT]
+ ** compile-time option is invoked.  With [SQLITE_ENABLE_MEMORY_MANAGEMENT],
+ ** the soft heap limit is enforced on every memory allocation.  Without
+@@ -5241,7 +5763,7 @@
+ ** The circumstances under which SQLite will enforce the soft heap limit may
+ ** changes in future releases of SQLite.
+ */
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N);
++SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
+ 
+ /*
+ ** CAPI3REF: Deprecated Soft Heap Limit Interface
+@@ -5252,7 +5774,7 @@
+ ** only.  All new applications should use the
+ ** [sqlite3_soft_heap_limit64()] interface rather than this one.
+ */
+-SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N);
++SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
+ 
+ 
+ /*
+@@ -5267,9 +5789,11 @@
+ ** column exists.  ^The sqlite3_table_column_metadata() interface returns
+ ** SQLITE_ERROR and if the specified column does not exist.
+ ** ^If the column-name parameter to sqlite3_table_column_metadata() is a
+-** NULL pointer, then this routine simply checks for the existance of the
++** NULL pointer, then this routine simply checks for the existence of the
+ ** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
+-** does not.
++** does not.  If the table name parameter T in a call to
++** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is
++** undefined behavior.
+ **
+ ** ^The column is identified by the second, third and fourth parameters to
+ ** this function. ^(The second parameter is either the name of the database
+@@ -5322,7 +5846,7 @@
+ ** parsed, if that has not already been done, and returns an error if
+ ** any errors are encountered while loading the schema.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
++SQLITE_API int sqlite3_table_column_metadata(
+   sqlite3 *db,                /* Connection handle */
+   const char *zDbName,        /* Database name or NULL */
+   const char *zTableName,     /* Table name */
+@@ -5364,12 +5888,21 @@
+ ** should free this memory by calling [sqlite3_free()].
+ **
+ ** ^Extension loading must be enabled using
+-** [sqlite3_enable_load_extension()] prior to calling this API,
++** [sqlite3_enable_load_extension()] or
++** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
++** prior to calling this API,
+ ** otherwise an error will be returned.
+ **
++** <b>Security warning:</b> It is recommended that the 
++** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
++** interface.  The use of the [sqlite3_enable_load_extension()] interface
++** should be avoided.  This will keep the SQL function [load_extension()]
++** disabled and prevent SQL injections from giving attackers
++** access to extension loading capabilities.
 +**
-+** The purpose of the pointer map is to facility moving pages from one
-+** position in the file to another as part of autovacuum.  When a page
-+** is moved, the pointer in its parent must be updated to point to the
-+** new location.  The pointer map is used to locate the parent page quickly.
+ ** See also the [load_extension() SQL function].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
++SQLITE_API int sqlite3_load_extension(
+   sqlite3 *db,          /* Load the extension into this database connection */
+   const char *zFile,    /* Name of the shared library containing extension */
+   const char *zProc,    /* Entry point.  Derived from zFile if 0 */
+@@ -5389,8 +5922,19 @@
+ ** ^Call the sqlite3_enable_load_extension() routine with onoff==1
+ ** to turn extension loading on and call it with onoff==0 to turn
+ ** it back off again.
 +**
-+** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not
-+**                  used in this case.
++** ^This interface enables or disables both the C-API
++** [sqlite3_load_extension()] and the SQL function [load_extension()].
++** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
++** to enable or disable only the C-API.)^
 +**
-+** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number 
-+**                  is not used in this case.
++** <b>Security warning:</b> It is recommended that extension loading
++** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
++** rather than this interface, so the [load_extension()] SQL function
++** remains disabled. This will prevent SQL injections from giving attackers
++** access to extension loading capabilities.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff);
++SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
+ 
+ /*
+ ** CAPI3REF: Automatically Load Statically Linked Extensions
+@@ -5402,7 +5946,7 @@
+ **
+ ** ^(Even though the function prototype shows that xEntryPoint() takes
+ ** no arguments and returns void, SQLite invokes xEntryPoint() with three
+-** arguments and expects and integer result as if the signature of the
++** arguments and expects an integer result as if the signature of the
+ ** entry point where as follows:
+ **
+ ** <blockquote><pre>
+@@ -5428,7 +5972,7 @@
+ ** See also: [sqlite3_reset_auto_extension()]
+ ** and [sqlite3_cancel_auto_extension()]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void));
++SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void));
+ 
+ /*
+ ** CAPI3REF: Cancel Automatic Extension Loading
+@@ -5440,7 +5984,7 @@
+ ** unregistered and it returns 0 if X was not on the list of initialization
+ ** routines.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
++SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
+ 
+ /*
+ ** CAPI3REF: Reset Automatic Extension Loading
+@@ -5448,7 +5992,7 @@
+ ** ^This interface disables all automatic extensions previously
+ ** registered using [sqlite3_auto_extension()].
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void);
++SQLITE_API void sqlite3_reset_auto_extension(void);
+ 
+ /*
+ ** The interface to the virtual-table mechanism is currently considered
+@@ -5550,6 +6094,17 @@
+ ** ^Information about the ORDER BY clause is stored in aOrderBy[].
+ ** ^Each term of aOrderBy records a column of the ORDER BY clause.
+ **
++** The colUsed field indicates which columns of the virtual table may be
++** required by the current scan. Virtual table columns are numbered from
++** zero in the order in which they appear within the CREATE TABLE statement
++** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
++** the corresponding bit is set within the colUsed mask if the column may be
++** required by SQLite. If the table has at least 64 columns and any column
++** to the right of the first 63 is required, then bit 63 of colUsed is also
++** set. In other words, column iCol may be required if the expression
++** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to 
++** non-zero.
 +**
-+** PTRMAP_OVERFLOW1: The database page is the first page in a list of 
-+**                   overflow pages. The page number identifies the page that
-+**                   contains the cell with a pointer to this overflow page.
+ ** The [xBestIndex] method must fill aConstraintUsage[] with information
+ ** about what parameters to pass to xFilter.  ^If argvIndex>0 then
+ ** the right-hand side of the corresponding aConstraint[] is evaluated
+@@ -5575,19 +6130,39 @@
+ ** ^The estimatedRows value is an estimate of the number of rows that
+ ** will be returned by the strategy.
+ **
++** The xBestIndex method may optionally populate the idxFlags field with a 
++** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
++** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
++** assumes that the strategy may visit at most one row. 
 +**
-+** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of
-+**                   overflow pages. The page-number identifies the previous
-+**                   page in the overflow page list.
++** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
++** SQLite also assumes that if a call to the xUpdate() method is made as
++** part of the same statement to delete or update a virtual table row and the
++** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
++** any database changes. In other words, if the xUpdate() returns
++** SQLITE_CONSTRAINT, the database contents must be exactly as they were
++** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
++** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
++** the xUpdate method are automatically rolled back by SQLite.
 +**
-+** PTRMAP_BTREE: The database page is a non-root btree page. The page number
-+**               identifies the parent page in the btree.
-+*/
-+#define PTRMAP_ROOTPAGE 1
-+#define PTRMAP_FREEPAGE 2
-+#define PTRMAP_OVERFLOW1 3
-+#define PTRMAP_OVERFLOW2 4
-+#define PTRMAP_BTREE 5
-+
-+/* A bunch of assert() statements to check the transaction state variables
-+** of handle p (type Btree*) are internally consistent.
-+*/
-+#define btreeIntegrity(p) \
-+  assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \
-+  assert( p->pBt->inTransaction>=p->inTrans ); 
-+
-+
-+/*
-+** The ISAUTOVACUUM macro is used within balance_nonroot() to determine
-+** if the database supports auto-vacuum or not. Because it is used
-+** within an expression that is an argument to another macro 
-+** (sqliteMallocRaw), it is not possible to use conditional compilation.
-+** So, this macro is defined instead.
+ ** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
+-** structure for SQLite version 3.8.2. If a virtual table extension is
++** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). 
++** If a virtual table extension is
+ ** used with an SQLite version earlier than 3.8.2, the results of attempting 
+ ** to read or write the estimatedRows field are undefined (but are likely 
+ ** to included crashing the application). The estimatedRows field should
+ ** therefore only be used if [sqlite3_libversion_number()] returns a
+-** value greater than or equal to 3008002.
++** value greater than or equal to 3008002. Similarly, the idxFlags field
++** was added for [version 3.9.0] ([dateof:3.9.0]). 
++** It may therefore only be used if
++** sqlite3_libversion_number() returns a value greater than or equal to
++** 3009000.
+ */
+ struct sqlite3_index_info {
+   /* Inputs */
+   int nConstraint;           /* Number of entries in aConstraint */
+   struct sqlite3_index_constraint {
+-     int iColumn;              /* Column on left-hand side of constraint */
++     int iColumn;              /* Column constrained.  -1 for ROWID */
+      unsigned char op;         /* Constraint operator */
+      unsigned char usable;     /* True if this constraint is usable */
+      int iTermOffset;          /* Used internally - xBestIndex should ignore */
+@@ -5609,9 +6184,18 @@
+   double estimatedCost;           /* Estimated cost of using this index */
+   /* Fields below are only available in SQLite 3.8.2 and later */
+   sqlite3_int64 estimatedRows;    /* Estimated number of rows returned */
++  /* Fields below are only available in SQLite 3.9.0 and later */
++  int idxFlags;              /* Mask of SQLITE_INDEX_SCAN_* flags */
++  /* Fields below are only available in SQLite 3.10.0 and later */
++  sqlite3_uint64 colUsed;    /* Input: Mask of columns used by statement */
+ };
+ 
+ /*
++** CAPI3REF: Virtual Table Scan Flags
 +*/
-+#ifndef SQLITE_OMIT_AUTOVACUUM
-+#define ISAUTOVACUUM (pBt->autoVacuum)
-+#else
-+#define ISAUTOVACUUM 0
- #endif
--#if SQLITE_ENABLE_FTS1
--  "ENABLE_FTS1",
-+
++#define SQLITE_INDEX_SCAN_UNIQUE      1     /* Scan visits at most 1 row */
 +
 +/*
-+** This structure is passed around through all the sanity checking routines
-+** in order to keep track of some global state information.
-+**
-+** The aRef[] array is allocated so that there is 1 bit for each page in
-+** the database. As the integrity-check proceeds, for each page used in
-+** the database the corresponding bit is set. This allows integrity-check to 
-+** detect pages that are used twice and orphaned pages (both of which 
-+** indicate corruption).
-+*/
-+typedef struct IntegrityCk IntegrityCk;
-+struct IntegrityCk {
-+  BtShared *pBt;    /* The tree being checked out */
-+  Pager *pPager;    /* The associated pager.  Also accessible by pBt->pPager */
-+  u8 *aPgRef;       /* 1 bit per page in the db (see above) */
-+  Pgno nPage;       /* Number of pages in the database */
-+  int mxErr;        /* Stop accumulating errors when this reaches zero */
-+  int nErr;         /* Number of messages written to zErrMsg so far */
-+  int mallocFailed; /* A memory allocation error has occurred */
-+  const char *zPfx; /* Error message prefix */
-+  int v1, v2;       /* Values for up to two %d fields in zPfx */
-+  StrAccum errMsg;  /* Accumulate the error message text here */
-+};
+ ** CAPI3REF: Virtual Table Constraint Operator Codes
+ **
+ ** These macros defined the allowed values for the
+@@ -5619,12 +6203,15 @@
+ ** an operator that is part of a constraint term in the wHERE clause of
+ ** a query that uses a [virtual table].
+ */
+-#define SQLITE_INDEX_CONSTRAINT_EQ    2
+-#define SQLITE_INDEX_CONSTRAINT_GT    4
+-#define SQLITE_INDEX_CONSTRAINT_LE    8
+-#define SQLITE_INDEX_CONSTRAINT_LT    16
+-#define SQLITE_INDEX_CONSTRAINT_GE    32
+-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
++#define SQLITE_INDEX_CONSTRAINT_EQ      2
++#define SQLITE_INDEX_CONSTRAINT_GT      4
++#define SQLITE_INDEX_CONSTRAINT_LE      8
++#define SQLITE_INDEX_CONSTRAINT_LT     16
++#define SQLITE_INDEX_CONSTRAINT_GE     32
++#define SQLITE_INDEX_CONSTRAINT_MATCH  64
++#define SQLITE_INDEX_CONSTRAINT_LIKE   65
++#define SQLITE_INDEX_CONSTRAINT_GLOB   66
++#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
+ 
+ /*
+ ** CAPI3REF: Register A Virtual Table Implementation
+@@ -5652,13 +6239,13 @@
+ ** interface is equivalent to sqlite3_create_module_v2() with a NULL
+ ** destructor.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
++SQLITE_API int sqlite3_create_module(
+   sqlite3 *db,               /* SQLite connection to register module with */
+   const char *zName,         /* Name of the module */
+   const sqlite3_module *p,   /* Methods for the module */
+   void *pClientData          /* Client data for xCreate/xConnect */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
++SQLITE_API int sqlite3_create_module_v2(
+   sqlite3 *db,               /* SQLite connection to register module with */
+   const char *zName,         /* Name of the module */
+   const sqlite3_module *p,   /* Methods for the module */
+@@ -5721,7 +6308,7 @@
+ ** to declare the format (the names and datatypes of the columns) of
+ ** the virtual tables they implement.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL);
++SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
+ 
+ /*
+ ** CAPI3REF: Overload A Function For A Virtual Table
+@@ -5740,7 +6327,7 @@
+ ** purpose is to be a placeholder function that can be overloaded
+ ** by a [virtual table].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
++SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+ 
+ /*
+ ** The interface to the virtual-table mechanism defined above (back up
+@@ -5815,6 +6402,12 @@
+ ** [database connection] error code and message accessible via 
+ ** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 
+ **
++** A BLOB referenced by sqlite3_blob_open() may be read using the
++** [sqlite3_blob_read()] interface and modified by using
++** [sqlite3_blob_write()].  The [BLOB handle] can be moved to a
++** different row of the same table using the [sqlite3_blob_reopen()]
++** interface.  However, the column, table, or database of a [BLOB handle]
++** cannot be changed after the [BLOB handle] is opened.
+ **
+ ** ^(If the row that a BLOB handle points to is modified by an
+ ** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
+@@ -5838,8 +6431,12 @@
+ **
+ ** To avoid a resource leak, every open [BLOB handle] should eventually
+ ** be released by a call to [sqlite3_blob_close()].
++**
++** See also: [sqlite3_blob_close()],
++** [sqlite3_blob_reopen()], [sqlite3_blob_read()],
++** [sqlite3_blob_bytes()], [sqlite3_blob_write()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
++SQLITE_API int sqlite3_blob_open(
+   sqlite3*,
+   const char *zDb,
+   const char *zTable,
+@@ -5853,11 +6450,11 @@
+ ** CAPI3REF: Move a BLOB Handle to a New Row
+ ** METHOD: sqlite3_blob
+ **
+-** ^This function is used to move an existing blob handle so that it points
++** ^This function is used to move an existing [BLOB handle] so that it points
+ ** to a different row of the same database table. ^The new row is identified
+ ** by the rowid value passed as the second argument. Only the row can be
+ ** changed. ^The database, table and column on which the blob handle is open
+-** remain the same. Moving an existing blob handle to a new row can be
++** remain the same. Moving an existing [BLOB handle] to a new row is
+ ** faster than closing the existing handle and opening a new one.
+ **
+ ** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
+@@ -5872,7 +6469,7 @@
+ **
+ ** ^This function sets the database handle error code and message.
+ */
+-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
++SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
+ 
+ /*
+ ** CAPI3REF: Close A BLOB Handle
+@@ -5895,7 +6492,7 @@
+ ** is passed a valid open blob handle, the values returned by the 
+ ** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *);
++SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
+ 
+ /*
+ ** CAPI3REF: Return The Size Of An Open BLOB
+@@ -5911,7 +6508,7 @@
+ ** been closed by [sqlite3_blob_close()].  Passing any other pointer in
+ ** to this routine results in undefined and probably undesirable behavior.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *);
++SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
+ 
+ /*
+ ** CAPI3REF: Read Data From A BLOB Incrementally
+@@ -5940,7 +6537,7 @@
+ **
+ ** See also: [sqlite3_blob_write()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
++SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
+ 
+ /*
+ ** CAPI3REF: Write Data Into A BLOB Incrementally
+@@ -5982,7 +6579,7 @@
+ **
+ ** See also: [sqlite3_blob_read()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
++SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
+ 
+ /*
+ ** CAPI3REF: Virtual File System Objects
+@@ -6013,9 +6610,9 @@
+ ** ^(If the default VFS is unregistered, another VFS is chosen as
+ ** the default.  The choice for the new VFS is arbitrary.)^
+ */
+-SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName);
+-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
++SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
++SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
++SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
+ 
+ /*
+ ** CAPI3REF: Mutexes
+@@ -6068,6 +6665,9 @@
+ ** <li>  SQLITE_MUTEX_STATIC_APP1
+ ** <li>  SQLITE_MUTEX_STATIC_APP2
+ ** <li>  SQLITE_MUTEX_STATIC_APP3
++** <li>  SQLITE_MUTEX_STATIC_VFS1
++** <li>  SQLITE_MUTEX_STATIC_VFS2
++** <li>  SQLITE_MUTEX_STATIC_VFS3
+ ** </ul>
+ **
+ ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
+@@ -6128,11 +6728,11 @@
+ **
+ ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
+ */
+-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int);
+-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*);
+-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*);
+-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*);
++SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
++SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
++SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
++SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
++SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
+ 
+ /*
+ ** CAPI3REF: Mutex Methods Object
+@@ -6242,8 +6842,8 @@
+ ** interface should also return 1 when given a NULL pointer.
+ */
+ #ifndef NDEBUG
+-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
++SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
++SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
+ #endif
+ 
+ /*
+@@ -6262,13 +6862,16 @@
+ #define SQLITE_MUTEX_STATIC_MEM       3  /* sqlite3_malloc() */
+ #define SQLITE_MUTEX_STATIC_MEM2      4  /* NOT USED */
+ #define SQLITE_MUTEX_STATIC_OPEN      4  /* sqlite3BtreeOpen() */
+-#define SQLITE_MUTEX_STATIC_PRNG      5  /* sqlite3_random() */
++#define SQLITE_MUTEX_STATIC_PRNG      5  /* sqlite3_randomness() */
+ #define SQLITE_MUTEX_STATIC_LRU       6  /* lru page list */
+ #define SQLITE_MUTEX_STATIC_LRU2      7  /* NOT USED */
+ #define SQLITE_MUTEX_STATIC_PMEM      7  /* sqlite3PageMalloc() */
+ #define SQLITE_MUTEX_STATIC_APP1      8  /* For use by application */
+ #define SQLITE_MUTEX_STATIC_APP2      9  /* For use by application */
+ #define SQLITE_MUTEX_STATIC_APP3     10  /* For use by application */
++#define SQLITE_MUTEX_STATIC_VFS1     11  /* For use by built-in VFS */
++#define SQLITE_MUTEX_STATIC_VFS2     12  /* For use by extension VFS */
++#define SQLITE_MUTEX_STATIC_VFS3     13  /* For use by application VFS */
+ 
+ /*
+ ** CAPI3REF: Retrieve the mutex for a database connection
+@@ -6280,7 +6883,7 @@
+ ** ^If the [threading mode] is Single-thread or Multi-thread then this
+ ** routine returns a NULL pointer.
+ */
+-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*);
++SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
+ 
+ /*
+ ** CAPI3REF: Low-Level Control Of Database Files
+@@ -6315,7 +6918,7 @@
+ **
+ ** See also: [SQLITE_FCNTL_LOCKSTATE]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
++SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+ 
+ /*
+ ** CAPI3REF: Testing Interface
+@@ -6334,7 +6937,7 @@
+ ** Unlike most of the SQLite API, this function is not guaranteed to
+ ** operate consistently from one release to the next.
+ */
+-SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
++SQLITE_API int sqlite3_test_control(int op, ...);
+ 
+ /*
+ ** CAPI3REF: Testing Interface Operation Codes
+@@ -6363,6 +6966,7 @@
+ #define SQLITE_TESTCTRL_SCRATCHMALLOC           17
+ #define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
+ #define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
++#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD    19
+ #define SQLITE_TESTCTRL_NEVER_CORRUPT           20
+ #define SQLITE_TESTCTRL_VDBE_COVERAGE           21
+ #define SQLITE_TESTCTRL_BYTEORDER               22
+@@ -6397,8 +7001,8 @@
+ **
+ ** See also: [sqlite3_db_status()]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+-SQLITE_API int SQLITE_STDCALL sqlite3_status64(
++SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
++SQLITE_API int sqlite3_status64(
+   int op,
+   sqlite3_int64 *pCurrent,
+   sqlite3_int64 *pHighwater,
+@@ -6482,7 +7086,8 @@
+ ** The value written into the *pCurrent parameter is undefined.</dd>)^
+ **
+ ** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
+-** <dd>This parameter records the deepest parser stack.  It is only
++** <dd>The *pHighwater parameter records the deepest parser stack. 
++** The *pCurrent value is undefined.  The *pHighwater value is only
+ ** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
+ ** </dl>
+ **
+@@ -6522,7 +7127,7 @@
+ **
+ ** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
++SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+ 
+ /*
+ ** CAPI3REF: Status Parameters for database connections
+@@ -6568,6 +7173,18 @@
+ ** memory used by all pager caches associated with the database connection.)^
+ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
+ **
++** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] 
++** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt>
++** <dd>This parameter is similar to DBSTATUS_CACHE_USED, except that if a
++** pager cache is shared between two or more connections the bytes of heap
++** memory used by that pager cache is divided evenly between the attached
++** connections.)^  In other words, if none of the pager caches associated
++** with the database connection are shared, this request returns the same
++** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are
++** shared, the value returned by this call will be smaller than that returned
++** by DBSTATUS_CACHE_USED. ^The highwater mark associated with
++** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.
++**
+ ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
+ ** <dd>This parameter returns the approximate number of bytes of heap
+ ** memory used to store the schema for all databases associated
+@@ -6625,7 +7242,8 @@
+ #define SQLITE_DBSTATUS_CACHE_MISS           8
+ #define SQLITE_DBSTATUS_CACHE_WRITE          9
+ #define SQLITE_DBSTATUS_DEFERRED_FKS        10
+-#define SQLITE_DBSTATUS_MAX                 10   /* Largest defined DBSTATUS */
++#define SQLITE_DBSTATUS_CACHE_USED_SHARED   11
++#define SQLITE_DBSTATUS_MAX                 11   /* Largest defined DBSTATUS */
+ 
+ 
+ /*
+@@ -6652,7 +7270,7 @@
+ **
+ ** See also: [sqlite3_status()] and [sqlite3_db_status()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
++SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+ 
+ /*
+ ** CAPI3REF: Status Parameters for prepared statements
+@@ -6688,6 +7306,24 @@
+ ** used as a proxy for the total work done by the prepared statement.
+ ** If the number of virtual machine operations exceeds 2147483647
+ ** then the value returned by this statement status code is undefined.
++**
++** [[SQLITE_STMTSTATUS_REPREPARE]] <dt>SQLITE_STMTSTATUS_REPREPARE</dt>
++** <dd>^This is the number of times that the prepare statement has been
++** automatically regenerated due to schema changes or change to 
++** [bound parameters] that might affect the query plan.
++**
++** [[SQLITE_STMTSTATUS_RUN]] <dt>SQLITE_STMTSTATUS_RUN</dt>
++** <dd>^This is the number of times that the prepared statement has
++** been run.  A single "run" for the purposes of this counter is one
++** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
++** The counter is incremented on the first [sqlite3_step()] call of each
++** cycle.
++**
++** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
++** <dd>^This is the approximate number of bytes of heap memory
++** used to store the prepared statement.  ^This value is not actually
++** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
++** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
+ ** </dd>
+ ** </dl>
+ */
+@@ -6695,6 +7331,9 @@
+ #define SQLITE_STMTSTATUS_SORT              2
+ #define SQLITE_STMTSTATUS_AUTOINDEX         3
+ #define SQLITE_STMTSTATUS_VM_STEP           4
++#define SQLITE_STMTSTATUS_REPREPARE         5
++#define SQLITE_STMTSTATUS_RUN               6
++#define SQLITE_STMTSTATUS_MEMUSED           99
+ 
+ /*
+ ** CAPI3REF: Custom Page Cache Object
+@@ -6979,7 +7618,7 @@
+ ** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
+ ** an error.
+ **
+-** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if 
++** ^A call to sqlite3_backup_init() will fail, returning NULL, if 
+ ** there is already a read or read-write transaction open on the 
+ ** destination database.
+ **
+@@ -7121,16 +7760,16 @@
+ ** same time as another thread is invoking sqlite3_backup_step() it is
+ ** possible that they return invalid values.
+ */
+-SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
++SQLITE_API sqlite3_backup *sqlite3_backup_init(
+   sqlite3 *pDest,                        /* Destination database handle */
+   const char *zDestName,                 /* Destination database name */
+   sqlite3 *pSource,                      /* Source database handle */
+   const char *zSourceName                /* Source database name */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage);
+-SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p);
+-SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p);
+-SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p);
++SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
++SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
++SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
++SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
+ 
+ /*
+ ** CAPI3REF: Unlock Notification
+@@ -7247,7 +7886,7 @@
+ ** the special "DROP TABLE/INDEX" case, the extended error code is just 
+ ** SQLITE_LOCKED.)^
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
++SQLITE_API int sqlite3_unlock_notify(
+   sqlite3 *pBlocked,                          /* Waiting connection */
+   void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
+   void *pNotifyArg                            /* Argument to pass to xNotify */
+@@ -7262,23 +7901,48 @@
+ ** strings in a case-independent fashion, using the same definition of "case
+ ** independence" that SQLite uses internally when comparing identifiers.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *);
+-SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
++SQLITE_API int sqlite3_stricmp(const char *, const char *);
++SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
+ 
+ /*
+ ** CAPI3REF: String Globbing
+ *
+-** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches
+-** the glob pattern P, and it returns non-zero if string X does not match
+-** the glob pattern P.  ^The definition of glob pattern matching used in
++** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if
++** string X matches the [GLOB] pattern P.
++** ^The definition of [GLOB] pattern matching used in
+ ** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the
+-** SQL dialect used by SQLite.  ^The sqlite3_strglob(P,X) function is case
+-** sensitive.
++** SQL dialect understood by SQLite.  ^The [sqlite3_strglob(P,X)] function
++** is case sensitive.
++**
++** Note that this routine returns zero on a match and non-zero if the strings
++** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
++**
++** See also: [sqlite3_strlike()].
++*/
++SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
 +
 +/*
-+** Routines to read or write a two- and four-byte big-endian integer values.
++** CAPI3REF: String LIKE Matching
++*
++** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if
++** string X matches the [LIKE] pattern P with escape character E.
++** ^The definition of [LIKE] pattern matching used in
++** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
++** operator in the SQL dialect understood by SQLite.  ^For "X LIKE P" without
++** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
++** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case
++** insensitive - equivalent upper and lower case ASCII characters match
++** one another.
++**
++** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
++** only ASCII characters are case folded.
+ **
+ ** Note that this routine returns zero on a match and non-zero if the strings
+ ** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
++**
++** See also: [sqlite3_strglob()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr);
++SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
+ 
+ /*
+ ** CAPI3REF: Error Logging Interface
+@@ -7301,7 +7965,7 @@
+ ** a few hundred characters, it will be truncated to the length of the
+ ** buffer.
+ */
+-SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...);
++SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
+ 
+ /*
+ ** CAPI3REF: Write-Ahead Log Commit Hook
+@@ -7335,9 +7999,9 @@
+ ** previously registered write-ahead log callback. ^Note that the
+ ** [sqlite3_wal_autocheckpoint()] interface and the
+ ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
+-** those overwrite any prior [sqlite3_wal_hook()] settings.
++** overwrite any prior [sqlite3_wal_hook()] settings.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
++SQLITE_API void *sqlite3_wal_hook(
+   sqlite3*, 
+   int(*)(void *,sqlite3*,const char*,int),
+   void*
+@@ -7372,7 +8036,7 @@
+ ** is only necessary if the default setting is found to be suboptimal
+ ** for a particular application.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
++SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
+ 
+ /*
+ ** CAPI3REF: Checkpoint a database
+@@ -7394,7 +8058,7 @@
+ ** start a callback but which do not need the full power (and corresponding
+ ** complication) of [sqlite3_wal_checkpoint_v2()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
++SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+ 
+ /*
+ ** CAPI3REF: Checkpoint a database
+@@ -7488,7 +8152,7 @@
+ ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
+ ** from SQL.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
++SQLITE_API int sqlite3_wal_checkpoint_v2(
+   sqlite3 *db,                    /* Database handle */
+   const char *zDb,                /* Name of attached database (or NULL) */
+   int eMode,                      /* SQLITE_CHECKPOINT_* value */
+@@ -7524,7 +8188,7 @@
+ ** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].)  Further options
+ ** may be added in the future.
+ */
+-SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...);
++SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
+ 
+ /*
+ ** CAPI3REF: Virtual Table Configuration Options
+@@ -7577,7 +8241,7 @@
+ ** of the SQL statement that triggered the call to the [xUpdate] method of the
+ ** [virtual table].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
++SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
+ 
+ /*
+ ** CAPI3REF: Conflict resolution modes
+@@ -7682,7 +8346,7 @@
+ **
+ ** See also: [sqlite3_stmt_scanstatus_reset()]
+ */
+-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus(
++SQLITE_API int sqlite3_stmt_scanstatus(
+   sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
+   int idx,                  /* Index of loop to report on */
+   int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
+@@ -7698,8 +8362,332 @@
+ ** This API is only available if the library is built with pre-processor
+ ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
+ */
+-SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
++SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
+ 
++/*
++** CAPI3REF: Flush caches to disk mid-transaction
++**
++** ^If a write-transaction is open on [database connection] D when the
++** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
++** pages in the pager-cache that are not currently in use are written out 
++** to disk. A dirty page may be in use if a database cursor created by an
++** active SQL statement is reading from it, or if it is page 1 of a database
++** file (page 1 is always "in use").  ^The [sqlite3_db_cacheflush(D)]
++** interface flushes caches for all schemas - "main", "temp", and
++** any [attached] databases.
++**
++** ^If this function needs to obtain extra database locks before dirty pages 
++** can be flushed to disk, it does so. ^If those locks cannot be obtained 
++** immediately and there is a busy-handler callback configured, it is invoked
++** in the usual manner. ^If the required lock still cannot be obtained, then
++** the database is skipped and an attempt made to flush any dirty pages
++** belonging to the next (if any) database. ^If any databases are skipped
++** because locks cannot be obtained, but no other error occurs, this
++** function returns SQLITE_BUSY.
++**
++** ^If any other error occurs while flushing dirty pages to disk (for
++** example an IO error or out-of-memory condition), then processing is
++** abandoned and an SQLite [error code] is returned to the caller immediately.
++**
++** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK.
++**
++** ^This function does not set the database handle error code or message
++** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
 +*/
-+#define get2byte(x)   ((x)[0]<<8 | (x)[1])
-+#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v))
-+#define get4byte sqlite3Get4byte
-+#define put4byte sqlite3Put4byte
++SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
 +
-+/************** End of btreeInt.h ********************************************/
-+/************** Continuing where we left off in crypto.c *********************/
-+/************** Include crypto.h in the middle of crypto.c *******************/
-+/************** Begin file crypto.h ******************************************/
-+/* 
-+** SQLCipher
-+** crypto.h developed by Stephen Lombardo (Zetetic LLC) 
-+** sjlombardo at zetetic dot net
-+** http://zetetic.net
-+** 
-+** Copyright (c) 2008, ZETETIC LLC
-+** All rights reserved.
-+** 
-+** Redistribution and use in source and binary forms, with or without
-+** modification, are permitted provided that the following conditions are met:
-+**     * Redistributions of source code must retain the above copyright
-+**       notice, this list of conditions and the following disclaimer.
-+**     * Redistributions in binary form must reproduce the above copyright
-+**       notice, this list of conditions and the following disclaimer in the
-+**       documentation and/or other materials provided with the distribution.
-+**     * Neither the name of the ZETETIC LLC nor the
-+**       names of its contributors may be used to endorse or promote products
-+**       derived from this software without specific prior written permission.
-+** 
-+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
-+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
-+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+**  
++/*
++** CAPI3REF: The pre-update hook.
++**
++** ^These interfaces are only available if SQLite is compiled using the
++** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
++**
++** ^The [sqlite3_preupdate_hook()] interface registers a callback function
++** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
++** on a database table.
++** ^At most one preupdate hook may be registered at a time on a single
++** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
++** the previous setting.
++** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()]
++** with a NULL pointer as the second parameter.
++** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
++** the first parameter to callbacks.
++**
++** ^The preupdate hook only fires for changes to real database tables; the
++** preupdate hook is not invoked for changes to [virtual tables] or to
++** system tables like sqlite_master or sqlite_stat1.
++**
++** ^The second parameter to the preupdate callback is a pointer to
++** the [database connection] that registered the preupdate hook.
++** ^The third parameter to the preupdate callback is one of the constants
++** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to identify the
++** kind of update operation that is about to occur.
++** ^(The fourth parameter to the preupdate callback is the name of the
++** database within the database connection that is being modified.  This
++** will be "main" for the main database or "temp" for TEMP tables or 
++** the name given after the AS keyword in the [ATTACH] statement for attached
++** databases.)^
++** ^The fifth parameter to the preupdate callback is the name of the
++** table that is being modified.
++**
++** For an UPDATE or DELETE operation on a [rowid table], the sixth
++** parameter passed to the preupdate callback is the initial [rowid] of the 
++** row being modified or deleted. For an INSERT operation on a rowid table,
++** or any operation on a WITHOUT ROWID table, the value of the sixth 
++** parameter is undefined. For an INSERT or UPDATE on a rowid table the
++** seventh parameter is the final rowid value of the row being inserted
++** or updated. The value of the seventh parameter passed to the callback
++** function is not defined for operations on WITHOUT ROWID tables, or for
++** INSERT operations on rowid tables.
++**
++** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
++** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
++** provide additional information about a preupdate event. These routines
++** may only be called from within a preupdate callback.  Invoking any of
++** these routines from outside of a preupdate callback or with a
++** [database connection] pointer that is different from the one supplied
++** to the preupdate callback results in undefined and probably undesirable
++** behavior.
++**
++** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns
++** in the row that is being inserted, updated, or deleted.
++**
++** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to
++** a [protected sqlite3_value] that contains the value of the Nth column of
++** the table row before it is updated.  The N parameter must be between 0
++** and one less than the number of columns or the behavior will be
++** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE
++** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the
++** behavior is undefined.  The [sqlite3_value] that P points to
++** will be destroyed when the preupdate callback returns.
++**
++** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to
++** a [protected sqlite3_value] that contains the value of the Nth column of
++** the table row after it is updated.  The N parameter must be between 0
++** and one less than the number of columns or the behavior will be
++** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE
++** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the
++** behavior is undefined.  The [sqlite3_value] that P points to
++** will be destroyed when the preupdate callback returns.
++**
++** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate
++** callback was invoked as a result of a direct insert, update, or delete
++** operation; or 1 for inserts, updates, or deletes invoked by top-level 
++** triggers; or 2 for changes resulting from triggers called by top-level
++** triggers; and so forth.
++**
++** See also:  [sqlite3_update_hook()]
 +*/
-+/* BEGIN SQLCIPHER */
-+#ifdef SQLITE_HAS_CODEC
-+#ifndef CRYPTO_H
-+#define CRYPTO_H
++#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
++SQLITE_API void *sqlite3_preupdate_hook(
++  sqlite3 *db,
++  void(*xPreUpdate)(
++    void *pCtx,                   /* Copy of third arg to preupdate_hook() */
++    sqlite3 *db,                  /* Database handle */
++    int op,                       /* SQLITE_UPDATE, DELETE or INSERT */
++    char const *zDb,              /* Database name */
++    char const *zName,            /* Table name */
++    sqlite3_int64 iKey1,          /* Rowid of row about to be deleted/updated */
++    sqlite3_int64 iKey2           /* New rowid value (for a rowid UPDATE) */
++  ),
++  void*
++);
++SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
++SQLITE_API int sqlite3_preupdate_count(sqlite3 *);
++SQLITE_API int sqlite3_preupdate_depth(sqlite3 *);
++SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
++#endif
 +
-+#if !defined (SQLCIPHER_CRYPTO_CC) \
-+   && !defined (SQLCIPHER_CRYPTO_LIBTOMCRYPT) \
-+   && !defined (SQLCIPHER_CRYPTO_OPENSSL)
-+#define SQLCIPHER_CRYPTO_OPENSSL
- #endif
--#if SQLITE_ENABLE_FTS2
--  "ENABLE_FTS2",
++/*
++** CAPI3REF: Low-level system error code
++**
++** ^Attempt to return the underlying operating system error code or error
++** number that caused the most recent I/O error or failure to open a file.
++** The return value is OS-dependent.  For example, on unix systems, after
++** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be
++** called to get back the underlying "errno" that caused the problem, such
++** as ENOSPC, EAUTH, EISDIR, and so forth.  
++*/
++SQLITE_API int sqlite3_system_errno(sqlite3*);
 +
-+#define FILE_HEADER_SZ 16
++/*
++** CAPI3REF: Database Snapshot
++** KEYWORDS: {snapshot} {sqlite3_snapshot}
++** EXPERIMENTAL
++**
++** An instance of the snapshot object records the state of a [WAL mode]
++** database for some specific point in history.
++**
++** In [WAL mode], multiple [database connections] that are open on the
++** same database file can each be reading a different historical version
++** of the database file.  When a [database connection] begins a read
++** transaction, that connection sees an unchanging copy of the database
++** as it existed for the point in time when the transaction first started.
++** Subsequent changes to the database from other connections are not seen
++** by the reader until a new read transaction is started.
++**
++** The sqlite3_snapshot object records state information about an historical
++** version of the database file so that it is possible to later open a new read
++** transaction that sees that historical version of the database rather than
++** the most recent version.
++**
++** The constructor for this object is [sqlite3_snapshot_get()].  The
++** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
++** to an historical snapshot (if possible).  The destructor for 
++** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
++*/
++typedef struct sqlite3_snapshot {
++  unsigned char hidden[48];
++} sqlite3_snapshot;
 +
-+#ifndef CIPHER_VERSION
-+#ifdef SQLCIPHER_FIPS
-+#define CIPHER_VERSION "3.3.1 FIPS"
-+#else
-+#define CIPHER_VERSION "3.3.1"
- #endif
--#if SQLITE_ENABLE_FTS3
--  "ENABLE_FTS3",
- #endif
--#if SQLITE_ENABLE_FTS3_PARENTHESIS
--  "ENABLE_FTS3_PARENTHESIS",
++/*
++** CAPI3REF: Record A Database Snapshot
++** EXPERIMENTAL
++**
++** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
++** new [sqlite3_snapshot] object that records the current state of
++** schema S in database connection D.  ^On success, the
++** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
++** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
++** If there is not already a read-transaction open on schema S when
++** this function is called, one is opened automatically. 
++**
++** The following must be true for this function to succeed. If any of
++** the following statements are false when sqlite3_snapshot_get() is
++** called, SQLITE_ERROR is returned. The final value of *P is undefined
++** in this case. 
++**
++** <ul>
++**   <li> The database handle must be in [autocommit mode].
++**
++**   <li> Schema S of [database connection] D must be a [WAL mode] database.
++**
++**   <li> There must not be a write transaction open on schema S of database
++**        connection D.
++**
++**   <li> One or more transactions must have been written to the current wal
++**        file since it was created on disk (by any connection). This means
++**        that a snapshot cannot be taken on a wal mode database with no wal 
++**        file immediately after it is first opened. At least one transaction
++**        must be written to it first.
++** </ul>
++**
++** This function may also return SQLITE_NOMEM.  If it is called with the
++** database handle in autocommit mode but fails for some other reason, 
++** whether or not a read transaction is opened on schema S is undefined.
++**
++** The [sqlite3_snapshot] object returned from a successful call to
++** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
++** to avoid a memory leak.
++**
++** The [sqlite3_snapshot_get()] interface is only available when the
++** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++*/
++SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
++  sqlite3 *db,
++  const char *zSchema,
++  sqlite3_snapshot **ppSnapshot
++);
 +
-+#ifndef CIPHER
-+#define CIPHER "aes-256-cbc"
- #endif
--#if SQLITE_ENABLE_FTS4
--  "ENABLE_FTS4",
++/*
++** CAPI3REF: Start a read transaction on an historical snapshot
++** EXPERIMENTAL
++**
++** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
++** read transaction for schema S of
++** [database connection] D such that the read transaction
++** refers to historical [snapshot] P, rather than the most
++** recent change to the database.
++** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
++** or an appropriate [error code] if it fails.
++**
++** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
++** the first operation following the [BEGIN] that takes the schema S
++** out of [autocommit mode].
++** ^In other words, schema S must not currently be in
++** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
++** database connection D must be out of [autocommit mode].
++** ^A [snapshot] will fail to open if it has been overwritten by a
++** [checkpoint].
++** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
++** database connection D does not know that the database file for
++** schema S is in [WAL mode].  A database connection might not know
++** that the database file is in [WAL mode] if there has been no prior
++** I/O on that database connection, or if the database entered [WAL mode] 
++** after the most recent I/O on the database connection.)^
++** (Hint: Run "[PRAGMA application_id]" against a newly opened
++** database connection in order to make it ready to use snapshots.)
++**
++** The [sqlite3_snapshot_open()] interface is only available when the
++** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++*/
++SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
++  sqlite3 *db,
++  const char *zSchema,
++  sqlite3_snapshot *pSnapshot
++);
 +
-+#define CIPHER_DECRYPT 0
-+#define CIPHER_ENCRYPT 1
++/*
++** CAPI3REF: Destroy a snapshot
++** EXPERIMENTAL
++**
++** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
++** The application must eventually free every [sqlite3_snapshot] object
++** using this routine to avoid a memory leak.
++**
++** The [sqlite3_snapshot_free()] interface is only available when the
++** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++*/
++SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
 +
-+#define CIPHER_READ_CTX 0
-+#define CIPHER_WRITE_CTX 1
-+#define CIPHER_READWRITE_CTX 2
++/*
++** CAPI3REF: Compare the ages of two snapshot handles.
++** EXPERIMENTAL
++**
++** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
++** of two valid snapshot handles. 
++**
++** If the two snapshot handles are not associated with the same database 
++** file, the result of the comparison is undefined. 
++**
++** Additionally, the result of the comparison is only valid if both of the
++** snapshot handles were obtained by calling sqlite3_snapshot_get() since the
++** last time the wal file was deleted. The wal file is deleted when the
++** database is changed back to rollback mode or when the number of database
++** clients drops to zero. If either snapshot handle was obtained before the 
++** wal file was last deleted, the value returned by this function 
++** is undefined.
++**
++** Otherwise, this API returns a negative value if P1 refers to an older
++** snapshot than P2, zero if the two handles refer to the same database
++** snapshot, and a positive value if P1 is a newer snapshot than P2.
++*/
++SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
++  sqlite3_snapshot *p1,
++  sqlite3_snapshot *p2
++);
 +
-+#ifndef PBKDF2_ITER
-+#define PBKDF2_ITER 64000
++/*
++** CAPI3REF: Recover snapshots from a wal file
++** EXPERIMENTAL
++**
++** If all connections disconnect from a database file but do not perform
++** a checkpoint, the existing wal file is opened along with the database
++** file the next time the database is opened. At this point it is only
++** possible to successfully call sqlite3_snapshot_open() to open the most
++** recent snapshot of the database (the one at the head of the wal file),
++** even though the wal file may contain other valid snapshots for which
++** clients have sqlite3_snapshot handles.
++**
++** This function attempts to scan the wal file associated with database zDb
++** of database handle db and make all valid snapshots available to
++** sqlite3_snapshot_open(). It is an error if there is already a read
++** transaction open on the database, or if the database is not a wal mode
++** database.
++**
++** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
++*/
++SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
+ 
+ /*
+ ** Undo the hack that converts floating point types to integer for
+@@ -7712,8 +8700,9 @@
+ #ifdef __cplusplus
+ }  /* End of the 'extern "C"' block */
  #endif
--#if SQLITE_ENABLE_ICU
--  "ENABLE_ICU",
+-#endif /* _SQLITE3_H_ */
++#endif /* SQLITE3_H */
+ 
++/******** Begin file sqlite3rtree.h *********/
+ /*
+ ** 2010 August 30
+ **
+@@ -7753,7 +8742,7 @@
+ **
+ **   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
++SQLITE_API int sqlite3_rtree_geometry_callback(
+   sqlite3 *db,
+   const char *zGeom,
+   int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
+@@ -7779,7 +8768,7 @@
+ **
+ **   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
++SQLITE_API int sqlite3_rtree_query_callback(
+   sqlite3 *db,
+   const char *zQueryFunc,
+   int (*xQueryFunc)(sqlite3_rtree_query_info*),
+@@ -7813,6 +8802,8 @@
+   int eParentWithin;                /* Visibility of parent node */
+   int eWithin;                      /* OUT: Visiblity */
+   sqlite3_rtree_dbl rScore;         /* OUT: Write the score here */
++  /* The following fields are only available in 3.8.11 and later */
++  sqlite3_value **apSqlParam;       /* Original SQL values of parameters */
+ };
+ 
+ /*
+@@ -7829,3 +8820,1875 @@
+ 
+ #endif  /* ifndef _SQLITE3RTREE_H_ */
+ 
++/******** End of sqlite3rtree.h *********/
++/******** Begin file sqlite3session.h *********/
 +
-+/* possible flags for cipher_ctx->flags */
-+#define CIPHER_FLAG_HMAC          0x01
-+#define CIPHER_FLAG_LE_PGNO       0x02
-+#define CIPHER_FLAG_BE_PGNO       0x04
++#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION)
++#define __SQLITESESSION_H_ 1
 +
-+#ifndef DEFAULT_CIPHER_FLAGS
-+#define DEFAULT_CIPHER_FLAGS CIPHER_FLAG_HMAC | CIPHER_FLAG_LE_PGNO
- #endif
--#if SQLITE_ENABLE_IOTRACE
--  "ENABLE_IOTRACE",
++/*
++** Make sure we can call this stuff from C++.
++*/
++#ifdef __cplusplus
++extern "C" {
++#endif
 +
 +
-+/* by default, sqlcipher will use a reduced number of iterations to generate
-+   the HMAC key / or transform a raw cipher key 
-+   */
-+#ifndef FAST_PBKDF2_ITER
-+#define FAST_PBKDF2_ITER 2
- #endif
--#if SQLITE_ENABLE_LOAD_EXTENSION
--  "ENABLE_LOAD_EXTENSION",
++/*
++** CAPI3REF: Session Object Handle
++*/
++typedef struct sqlite3_session sqlite3_session;
 +
-+/* this if a fixed random array that will be xor'd with the database salt to ensure that the
-+   salt passed to the HMAC key derivation function is not the same as that used to derive
-+   the encryption key. This can be overridden at compile time but it will make the resulting
-+   binary incompatible with the default builds when using HMAC. A future version of SQLcipher
-+   will likely allow this to be defined at runtime via pragma */ 
-+#ifndef HMAC_SALT_MASK
-+#define HMAC_SALT_MASK 0x3a
- #endif
--#if SQLITE_ENABLE_LOCKING_STYLE
--  "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
++/*
++** CAPI3REF: Changeset Iterator Handle
++*/
++typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
 +
-+#ifndef CIPHER_MAX_IV_SZ
-+#define CIPHER_MAX_IV_SZ 16
- #endif
--#if SQLITE_ENABLE_MEMORY_MANAGEMENT
--  "ENABLE_MEMORY_MANAGEMENT",
++/*
++** CAPI3REF: Create A New Session Object
++**
++** Create a new session object attached to database handle db. If successful,
++** a pointer to the new object is written to *ppSession and SQLITE_OK is
++** returned. If an error occurs, *ppSession is set to NULL and an SQLite
++** error code (e.g. SQLITE_NOMEM) is returned.
++**
++** It is possible to create multiple session objects attached to a single
++** database handle.
++**
++** Session objects created using this function should be deleted using the
++** [sqlite3session_delete()] function before the database handle that they
++** are attached to is itself closed. If the database handle is closed before
++** the session object is deleted, then the results of calling any session
++** module function, including [sqlite3session_delete()] on the session object
++** are undefined.
++**
++** Because the session module uses the [sqlite3_preupdate_hook()] API, it
++** is not possible for an application to register a pre-update hook on a
++** database handle that has one or more session objects attached. Nor is
++** it possible to create a session object attached to a database handle for
++** which a pre-update hook is already defined. The results of attempting 
++** either of these things are undefined.
++**
++** The session object will be used to create changesets for tables in
++** database zDb, where zDb is either "main", or "temp", or the name of an
++** attached database. It is not an error if database zDb is not attached
++** to the database when the session object is created.
++*/
++SQLITE_API int sqlite3session_create(
++  sqlite3 *db,                    /* Database handle */
++  const char *zDb,                /* Name of db (e.g. "main") */
++  sqlite3_session **ppSession     /* OUT: New session object */
++);
 +
-+#ifndef CIPHER_MAX_KEY_SZ
-+#define CIPHER_MAX_KEY_SZ 64
- #endif
--#if SQLITE_ENABLE_MEMSYS3
--  "ENABLE_MEMSYS3",
++/*
++** CAPI3REF: Delete A Session Object
++**
++** Delete a session object previously allocated using 
++** [sqlite3session_create()]. Once a session object has been deleted, the
++** results of attempting to use pSession with any other session module
++** function are undefined.
++**
++** Session objects must be deleted before the database handle to which they
++** are attached is closed. Refer to the documentation for 
++** [sqlite3session_create()] for details.
++*/
++SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
 +
 +
-+#ifdef CODEC_DEBUG
-+#define CODEC_TRACE(X)  {printf X;fflush(stdout);}
-+#else
-+#define CODEC_TRACE(X)
- #endif
--#if SQLITE_ENABLE_MEMSYS5
--  "ENABLE_MEMSYS5",
++/*
++** CAPI3REF: Enable Or Disable A Session Object
++**
++** Enable or disable the recording of changes by a session object. When
++** enabled, a session object records changes made to the database. When
++** disabled - it does not. A newly created session object is enabled.
++** Refer to the documentation for [sqlite3session_changeset()] for further
++** details regarding how enabling and disabling a session object affects
++** the eventual changesets.
++**
++** Passing zero to this function disables the session. Passing a value
++** greater than zero enables it. Passing a value less than zero is a 
++** no-op, and may be used to query the current state of the session.
++**
++** The return value indicates the final state of the session object: 0 if 
++** the session is disabled, or 1 if it is enabled.
++*/
++SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
 +
-+#ifdef CODEC_DEBUG_PAGEDATA
-+#define CODEC_HEXDUMP(DESC,BUFFER,LEN)  \
-+  { \
-+    int __pctr; \
-+    printf(DESC); \
-+    for(__pctr=0; __pctr < LEN; __pctr++) { \
-+      if(__pctr % 16 == 0) printf("\n%05x: ",__pctr); \
-+      printf("%02x ",((unsigned char*) BUFFER)[__pctr]); \
-+    } \
-+    printf("\n"); \
-+    fflush(stdout); \
-+  }
-+#else
-+#define CODEC_HEXDUMP(DESC,BUFFER,LEN)
- #endif
--#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
--  "ENABLE_OVERSIZE_CELL_CHECK",
++/*
++** CAPI3REF: Set Or Clear the Indirect Change Flag
++**
++** Each change recorded by a session object is marked as either direct or
++** indirect. A change is marked as indirect if either:
++**
++** <ul>
++**   <li> The session object "indirect" flag is set when the change is
++**        made, or
++**   <li> The change is made by an SQL trigger or foreign key action 
++**        instead of directly as a result of a users SQL statement.
++** </ul>
++**
++** If a single row is affected by more than one operation within a session,
++** then the change is considered indirect if all operations meet the criteria
++** for an indirect change above, or direct otherwise.
++**
++** This function is used to set, clear or query the session object indirect
++** flag.  If the second argument passed to this function is zero, then the
++** indirect flag is cleared. If it is greater than zero, the indirect flag
++** is set. Passing a value less than zero does not modify the current value
++** of the indirect flag, and may be used to query the current state of the 
++** indirect flag for the specified session object.
++**
++** The return value indicates the final state of the indirect flag: 0 if 
++** it is clear, or 1 if it is set.
++*/
++SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
 +
-+/* extensions defined in pager.c */ 
-+SQLITE_PRIVATE void sqlite3pager_get_codec(Pager *pPager, void **ctx);
-+SQLITE_PRIVATE int sqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno);
-+SQLITE_PRIVATE sqlite3_file *sqlite3Pager_get_fd(Pager *pPager);
-+SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetCodec(
-+  Pager *pPager,
-+  void *(*xCodec)(void*,void*,Pgno,int),
-+  void (*xCodecSizeChng)(void*,int,int),
-+  void (*xCodecFree)(void*),
-+  void *pCodec
++/*
++** CAPI3REF: Attach A Table To A Session Object
++**
++** If argument zTab is not NULL, then it is the name of a table to attach
++** to the session object passed as the first argument. All subsequent changes 
++** made to the table while the session object is enabled will be recorded. See 
++** documentation for [sqlite3session_changeset()] for further details.
++**
++** Or, if argument zTab is NULL, then changes are recorded for all tables
++** in the database. If additional tables are added to the database (by 
++** executing "CREATE TABLE" statements) after this call is made, changes for 
++** the new tables are also recorded.
++**
++** Changes can only be recorded for tables that have a PRIMARY KEY explicitly
++** defined as part of their CREATE TABLE statement. It does not matter if the 
++** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY
++** KEY may consist of a single column, or may be a composite key.
++** 
++** It is not an error if the named table does not exist in the database. Nor
++** is it an error if the named table does not have a PRIMARY KEY. However,
++** no changes will be recorded in either of these scenarios.
++**
++** Changes are not recorded for individual rows that have NULL values stored
++** in one or more of their PRIMARY KEY columns.
++**
++** SQLITE_OK is returned if the call completes without error. Or, if an error 
++** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
++*/
++SQLITE_API int sqlite3session_attach(
++  sqlite3_session *pSession,      /* Session object */
++  const char *zTab                /* Table name */
 +);
-+SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetError(Pager *pPager, int error);
-+/* end extensions defined in pager.c */
-+ 
++
 +/*
-+**  Simple shared routines for converting hex char strings to binary data
-+ */
-+static int cipher_hex2int(char c) {
-+  return (c>='0' && c<='9') ? (c)-'0' :
-+         (c>='A' && c<='F') ? (c)-'A'+10 :
-+         (c>='a' && c<='f') ? (c)-'a'+10 : 0;
-+}
++** CAPI3REF: Set a table filter on a Session Object.
++**
++** The second argument (xFilter) is the "filter callback". For changes to rows 
++** in tables that are not attached to the Session object, the filter is called
++** to determine whether changes to the table's rows should be tracked or not. 
++** If xFilter returns 0, changes is not tracked. Note that once a table is 
++** attached, xFilter will not be called again.
++*/
++SQLITE_API void sqlite3session_table_filter(
++  sqlite3_session *pSession,      /* Session object */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of third arg to _filter_table() */
++    const char *zTab              /* Table name */
++  ),
++  void *pCtx                      /* First argument passed to xFilter */
++);
 +
-+static void cipher_hex2bin(const unsigned char *hex, int sz, unsigned char *out){
-+  int i;
-+  for(i = 0; i < sz; i += 2){
-+    out[i/2] = (cipher_hex2int(hex[i])<<4) | cipher_hex2int(hex[i+1]);
-+  }
-+}
++/*
++** CAPI3REF: Generate A Changeset From A Session Object
++**
++** Obtain a changeset containing changes to the tables attached to the 
++** session object passed as the first argument. If successful, 
++** set *ppChangeset to point to a buffer containing the changeset 
++** and *pnChangeset to the size of the changeset in bytes before returning
++** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to
++** zero and return an SQLite error code.
++**
++** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes,
++** each representing a change to a single row of an attached table. An INSERT
++** change contains the values of each field of a new database row. A DELETE
++** contains the original values of each field of a deleted database row. An
++** UPDATE change contains the original values of each field of an updated
++** database row along with the updated values for each updated non-primary-key
++** column. It is not possible for an UPDATE change to represent a change that
++** modifies the values of primary key columns. If such a change is made, it
++** is represented in a changeset as a DELETE followed by an INSERT.
++**
++** Changes are not recorded for rows that have NULL values stored in one or 
++** more of their PRIMARY KEY columns. If such a row is inserted or deleted,
++** no corresponding change is present in the changesets returned by this
++** function. If an existing row with one or more NULL values stored in
++** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL,
++** only an INSERT is appears in the changeset. Similarly, if an existing row
++** with non-NULL PRIMARY KEY values is updated so that one or more of its
++** PRIMARY KEY columns are set to NULL, the resulting changeset contains a
++** DELETE change only.
++**
++** The contents of a changeset may be traversed using an iterator created
++** using the [sqlite3changeset_start()] API. A changeset may be applied to
++** a database with a compatible schema using the [sqlite3changeset_apply()]
++** API.
++**
++** Within a changeset generated by this function, all changes related to a
++** single table are grouped together. In other words, when iterating through
++** a changeset or when applying a changeset to a database, all changes related
++** to a single table are processed before moving on to the next table. Tables
++** are sorted in the same order in which they were attached (or auto-attached)
++** to the sqlite3_session object. The order in which the changes related to
++** a single table are stored is undefined.
++**
++** Following a successful call to this function, it is the responsibility of
++** the caller to eventually free the buffer that *ppChangeset points to using
++** [sqlite3_free()].
++**
++** <h3>Changeset Generation</h3>
++**
++** Once a table has been attached to a session object, the session object
++** records the primary key values of all new rows inserted into the table.
++** It also records the original primary key and other column values of any
++** deleted or updated rows. For each unique primary key value, data is only
++** recorded once - the first time a row with said primary key is inserted,
++** updated or deleted in the lifetime of the session.
++**
++** There is one exception to the previous paragraph: when a row is inserted,
++** updated or deleted, if one or more of its primary key columns contain a
++** NULL value, no record of the change is made.
++**
++** The session object therefore accumulates two types of records - those
++** that consist of primary key values only (created when the user inserts
++** a new record) and those that consist of the primary key values and the
++** original values of other table columns (created when the users deletes
++** or updates a record).
++**
++** When this function is called, the requested changeset is created using
++** both the accumulated records and the current contents of the database
++** file. Specifically:
++**
++** <ul>
++**   <li> For each record generated by an insert, the database is queried
++**        for a row with a matching primary key. If one is found, an INSERT
++**        change is added to the changeset. If no such row is found, no change 
++**        is added to the changeset.
++**
++**   <li> For each record generated by an update or delete, the database is 
++**        queried for a row with a matching primary key. If such a row is
++**        found and one or more of the non-primary key fields have been
++**        modified from their original values, an UPDATE change is added to 
++**        the changeset. Or, if no such row is found in the table, a DELETE 
++**        change is added to the changeset. If there is a row with a matching
++**        primary key in the database, but all fields contain their original
++**        values, no change is added to the changeset.
++** </ul>
++**
++** This means, amongst other things, that if a row is inserted and then later
++** deleted while a session object is active, neither the insert nor the delete
++** will be present in the changeset. Or if a row is deleted and then later a 
++** row with the same primary key values inserted while a session object is
++** active, the resulting changeset will contain an UPDATE change instead of
++** a DELETE and an INSERT.
++**
++** When a session object is disabled (see the [sqlite3session_enable()] API),
++** it does not accumulate records when rows are inserted, updated or deleted.
++** This may appear to have some counter-intuitive effects if a single row
++** is written to more than once during a session. For example, if a row
++** is inserted while a session object is enabled, then later deleted while 
++** the same session object is disabled, no INSERT record will appear in the
++** changeset, even though the delete took place while the session was disabled.
++** Or, if one field of a row is updated while a session is disabled, and 
++** another field of the same row is updated while the session is enabled, the
++** resulting changeset will contain an UPDATE change that updates both fields.
++*/
++SQLITE_API int sqlite3session_changeset(
++  sqlite3_session *pSession,      /* Session object */
++  int *pnChangeset,               /* OUT: Size of buffer at *ppChangeset */
++  void **ppChangeset              /* OUT: Buffer containing changeset */
++);
 +
-+static void cipher_bin2hex(const unsigned char* in, int sz, char *out) {
-+    int i;
-+    for(i=0; i < sz; i++) {
-+      sqlite3_snprintf(3, out + (i*2), "%02x ", in[i]);
-+    } 
-+}
++/*
++** CAPI3REF: Load The Difference Between Tables Into A Session 
++**
++** If it is not already attached to the session object passed as the first
++** argument, this function attaches table zTbl in the same manner as the
++** [sqlite3session_attach()] function. If zTbl does not exist, or if it
++** does not have a primary key, this function is a no-op (but does not return
++** an error).
++**
++** Argument zFromDb must be the name of a database ("main", "temp" etc.)
++** attached to the same database handle as the session object that contains 
++** a table compatible with the table attached to the session by this function.
++** A table is considered compatible if it:
++**
++** <ul>
++**   <li> Has the same name,
++**   <li> Has the same set of columns declared in the same order, and
++**   <li> Has the same PRIMARY KEY definition.
++** </ul>
++**
++** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables
++** are compatible but do not have any PRIMARY KEY columns, it is not an error
++** but no changes are added to the session object. As with other session
++** APIs, tables without PRIMARY KEYs are simply ignored.
++**
++** This function adds a set of changes to the session object that could be
++** used to update the table in database zFrom (call this the "from-table") 
++** so that its content is the same as the table attached to the session 
++** object (call this the "to-table"). Specifically:
++**
++** <ul>
++**   <li> For each row (primary key) that exists in the to-table but not in 
++**     the from-table, an INSERT record is added to the session object.
++**
++**   <li> For each row (primary key) that exists in the to-table but not in 
++**     the from-table, a DELETE record is added to the session object.
++**
++**   <li> For each row (primary key) that exists in both tables, but features 
++**     different non-PK values in each, an UPDATE record is added to the
++**     session.  
++** </ul>
++**
++** To clarify, if this function is called and then a changeset constructed
++** using [sqlite3session_changeset()], then after applying that changeset to 
++** database zFrom the contents of the two compatible tables would be 
++** identical.
++**
++** It an error if database zFrom does not exist or does not contain the
++** required compatible table.
++**
++** If the operation successful, SQLITE_OK is returned. Otherwise, an SQLite
++** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
++** may be set to point to a buffer containing an English language error 
++** message. It is the responsibility of the caller to free this buffer using
++** sqlite3_free().
++*/
++SQLITE_API int sqlite3session_diff(
++  sqlite3_session *pSession,
++  const char *zFromDb,
++  const char *zTbl,
++  char **pzErrMsg
++);
 +
-+/* extensions defined in crypto_impl.c */
-+typedef struct codec_ctx codec_ctx;
 +
-+/* activation and initialization */
-+void sqlcipher_activate();
-+void sqlcipher_deactivate();
-+int sqlcipher_codec_ctx_init(codec_ctx **, Db *, Pager *, sqlite3_file *, const void *, int);
-+void sqlcipher_codec_ctx_free(codec_ctx **);
-+int sqlcipher_codec_key_derive(codec_ctx *);
-+int sqlcipher_codec_key_copy(codec_ctx *, int);
++/*
++** CAPI3REF: Generate A Patchset From A Session Object
++**
++** The differences between a patchset and a changeset are that:
++**
++** <ul>
++**   <li> DELETE records consist of the primary key fields only. The 
++**        original values of other fields are omitted.
++**   <li> The original values of any modified fields are omitted from 
++**        UPDATE records.
++** </ul>
++**
++** A patchset blob may be used with up to date versions of all 
++** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(), 
++** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly,
++** attempting to use a patchset blob with old versions of the
++** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error. 
++**
++** Because the non-primary key "old.*" fields are omitted, no 
++** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset
++** is passed to the sqlite3changeset_apply() API. Other conflict types work
++** in the same way as for changesets.
++**
++** Changes within a patchset are ordered in the same way as for changesets
++** generated by the sqlite3session_changeset() function (i.e. all changes for
++** a single table are grouped together, tables appear in the order in which
++** they were attached to the session object).
++*/
++SQLITE_API int sqlite3session_patchset(
++  sqlite3_session *pSession,      /* Session object */
++  int *pnPatchset,                /* OUT: Size of buffer at *ppChangeset */
++  void **ppPatchset               /* OUT: Buffer containing changeset */
++);
 +
-+/* page cipher implementation */
-+int sqlcipher_page_cipher(codec_ctx *, int, Pgno, int, int, unsigned char *, unsigned char *);
++/*
++** CAPI3REF: Test if a changeset has recorded any changes.
++**
++** Return non-zero if no changes to attached tables have been recorded by 
++** the session object passed as the first argument. Otherwise, if one or 
++** more changes have been recorded, return zero.
++**
++** Even if this function returns zero, it is possible that calling
++** [sqlite3session_changeset()] on the session handle may still return a
++** changeset that contains no changes. This can happen when a row in 
++** an attached table is modified and then later on the original values 
++** are restored. However, if this function returns non-zero, then it is
++** guaranteed that a call to sqlite3session_changeset() will return a 
++** changeset containing zero changes.
++*/
++SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
 +
-+/* context setters & getters */
-+void sqlcipher_codec_ctx_set_error(codec_ctx *, int);
++/*
++** CAPI3REF: Create An Iterator To Traverse A Changeset 
++**
++** Create an iterator used to iterate through the contents of a changeset.
++** If successful, *pp is set to point to the iterator handle and SQLITE_OK
++** is returned. Otherwise, if an error occurs, *pp is set to zero and an
++** SQLite error code is returned.
++**
++** The following functions can be used to advance and query a changeset 
++** iterator created by this function:
++**
++** <ul>
++**   <li> [sqlite3changeset_next()]
++**   <li> [sqlite3changeset_op()]
++**   <li> [sqlite3changeset_new()]
++**   <li> [sqlite3changeset_old()]
++** </ul>
++**
++** It is the responsibility of the caller to eventually destroy the iterator
++** by passing it to [sqlite3changeset_finalize()]. The buffer containing the
++** changeset (pChangeset) must remain valid until after the iterator is
++** destroyed.
++**
++** Assuming the changeset blob was created by one of the
++** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
++** [sqlite3changeset_invert()] functions, all changes within the changeset 
++** that apply to a single table are grouped together. This means that when 
++** an application iterates through a changeset using an iterator created by 
++** this function, all changes that relate to a single table are visited 
++** consecutively. There is no chance that the iterator will visit a change 
++** the applies to table X, then one for table Y, and then later on visit 
++** another change for table X.
++*/
++SQLITE_API int sqlite3changeset_start(
++  sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
++  int nChangeset,                 /* Size of changeset blob in bytes */
++  void *pChangeset                /* Pointer to blob containing changeset */
++);
 +
-+int sqlcipher_codec_ctx_set_pass(codec_ctx *, const void *, int, int);
-+void sqlcipher_codec_get_keyspec(codec_ctx *, void **zKey, int *nKey);
 +
-+int sqlcipher_codec_ctx_set_pagesize(codec_ctx *, int);
-+int sqlcipher_codec_ctx_get_pagesize(codec_ctx *);
-+int sqlcipher_codec_ctx_get_reservesize(codec_ctx *);
++/*
++** CAPI3REF: Advance A Changeset Iterator
++**
++** This function may only be used with iterators created by function
++** [sqlite3changeset_start()]. If it is called on an iterator passed to
++** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
++** is returned and the call has no effect.
++**
++** Immediately after an iterator is created by sqlite3changeset_start(), it
++** does not point to any change in the changeset. Assuming the changeset
++** is not empty, the first call to this function advances the iterator to
++** point to the first change in the changeset. Each subsequent call advances
++** the iterator to point to the next change in the changeset (if any). If
++** no error occurs and the iterator points to a valid change after a call
++** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned. 
++** Otherwise, if all changes in the changeset have already been visited,
++** SQLITE_DONE is returned.
++**
++** If an error occurs, an SQLite error code is returned. Possible error 
++** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or 
++** SQLITE_NOMEM.
++*/
++SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
 +
-+void sqlcipher_set_default_pagesize(int page_size);
-+int sqlcipher_get_default_pagesize();
++/*
++** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
++**
++** The pIter argument passed to this function may either be an iterator
++** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
++** created by [sqlite3changeset_start()]. In the latter case, the most recent
++** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this
++** is not the case, this function returns [SQLITE_MISUSE].
++**
++** If argument pzTab is not NULL, then *pzTab is set to point to a
++** nul-terminated utf-8 encoded string containing the name of the table
++** affected by the current change. The buffer remains valid until either
++** sqlite3changeset_next() is called on the iterator or until the 
++** conflict-handler function returns. If pnCol is not NULL, then *pnCol is 
++** set to the number of columns in the table affected by the change. If
++** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change
++** is an indirect change, or false (0) otherwise. See the documentation for
++** [sqlite3session_indirect()] for a description of direct and indirect
++** changes. Finally, if pOp is not NULL, then *pOp is set to one of 
++** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the 
++** type of change that the iterator currently points to.
++**
++** If no error occurs, SQLITE_OK is returned. If an error does occur, an
++** SQLite error code is returned. The values of the output variables may not
++** be trusted in this case.
++*/
++SQLITE_API int sqlite3changeset_op(
++  sqlite3_changeset_iter *pIter,  /* Iterator object */
++  const char **pzTab,             /* OUT: Pointer to table name */
++  int *pnCol,                     /* OUT: Number of columns in table */
++  int *pOp,                       /* OUT: SQLITE_INSERT, DELETE or UPDATE */
++  int *pbIndirect                 /* OUT: True for an 'indirect' change */
++);
 +
-+void sqlcipher_set_default_kdf_iter(int iter);
-+int sqlcipher_get_default_kdf_iter();
++/*
++** CAPI3REF: Obtain The Primary Key Definition Of A Table
++**
++** For each modified table, a changeset includes the following:
++**
++** <ul>
++**   <li> The number of columns in the table, and
++**   <li> Which of those columns make up the tables PRIMARY KEY.
++** </ul>
++**
++** This function is used to find which columns comprise the PRIMARY KEY of
++** the table modified by the change that iterator pIter currently points to.
++** If successful, *pabPK is set to point to an array of nCol entries, where
++** nCol is the number of columns in the table. Elements of *pabPK are set to
++** 0x01 if the corresponding column is part of the tables primary key, or
++** 0x00 if it is not.
++**
++** If argument pnCol is not NULL, then *pnCol is set to the number of columns
++** in the table.
++**
++** If this function is called when the iterator does not point to a valid
++** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
++** SQLITE_OK is returned and the output variables populated as described
++** above.
++*/
++SQLITE_API int sqlite3changeset_pk(
++  sqlite3_changeset_iter *pIter,  /* Iterator object */
++  unsigned char **pabPK,          /* OUT: Array of boolean - true for PK cols */
++  int *pnCol                      /* OUT: Number of entries in output array */
++);
 +
-+int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *, int, int);
-+int sqlcipher_codec_ctx_get_kdf_iter(codec_ctx *ctx, int);
++/*
++** CAPI3REF: Obtain old.* Values From A Changeset Iterator
++**
++** The pIter argument passed to this function may either be an iterator
++** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
++** created by [sqlite3changeset_start()]. In the latter case, the most recent
++** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. 
++** Furthermore, it may only be called if the type of change that the iterator
++** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise,
++** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
++**
++** Argument iVal must be greater than or equal to 0, and less than the number
++** of columns in the table affected by the current change. Otherwise,
++** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
++**
++** If successful, this function sets *ppValue to point to a protected
++** sqlite3_value object containing the iVal'th value from the vector of 
++** original row values stored as part of the UPDATE or DELETE change and
++** returns SQLITE_OK. The name of the function comes from the fact that this 
++** is similar to the "old.*" columns available to update or delete triggers.
++**
++** If some other error occurs (e.g. an OOM condition), an SQLite error code
++** is returned and *ppValue is set to NULL.
++*/
++SQLITE_API int sqlite3changeset_old(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int iVal,                       /* Column number */
++  sqlite3_value **ppValue         /* OUT: Old value (or NULL pointer) */
++);
 +
-+void* sqlcipher_codec_ctx_get_kdf_salt(codec_ctx *ctx);
++/*
++** CAPI3REF: Obtain new.* Values From A Changeset Iterator
++**
++** The pIter argument passed to this function may either be an iterator
++** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
++** created by [sqlite3changeset_start()]. In the latter case, the most recent
++** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. 
++** Furthermore, it may only be called if the type of change that the iterator
++** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise,
++** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
++**
++** Argument iVal must be greater than or equal to 0, and less than the number
++** of columns in the table affected by the current change. Otherwise,
++** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
++**
++** If successful, this function sets *ppValue to point to a protected
++** sqlite3_value object containing the iVal'th value from the vector of 
++** new row values stored as part of the UPDATE or INSERT change and
++** returns SQLITE_OK. If the change is an UPDATE and does not include
++** a new value for the requested column, *ppValue is set to NULL and 
++** SQLITE_OK returned. The name of the function comes from the fact that 
++** this is similar to the "new.*" columns available to update or delete 
++** triggers.
++**
++** If some other error occurs (e.g. an OOM condition), an SQLite error code
++** is returned and *ppValue is set to NULL.
++*/
++SQLITE_API int sqlite3changeset_new(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int iVal,                       /* Column number */
++  sqlite3_value **ppValue         /* OUT: New value (or NULL pointer) */
++);
 +
-+int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *, int, int);
-+int sqlcipher_codec_ctx_get_fast_kdf_iter(codec_ctx *, int);
++/*
++** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
++**
++** This function should only be used with iterator objects passed to a
++** conflict-handler callback by [sqlite3changeset_apply()] with either
++** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function
++** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue
++** is set to NULL.
++**
++** Argument iVal must be greater than or equal to 0, and less than the number
++** of columns in the table affected by the current change. Otherwise,
++** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
++**
++** If successful, this function sets *ppValue to point to a protected
++** sqlite3_value object containing the iVal'th value from the 
++** "conflicting row" associated with the current conflict-handler callback
++** and returns SQLITE_OK.
++**
++** If some other error occurs (e.g. an OOM condition), an SQLite error code
++** is returned and *ppValue is set to NULL.
++*/
++SQLITE_API int sqlite3changeset_conflict(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int iVal,                       /* Column number */
++  sqlite3_value **ppValue         /* OUT: Value from conflicting row */
++);
 +
-+int sqlcipher_codec_ctx_set_cipher(codec_ctx *, const char *, int);
-+const char* sqlcipher_codec_ctx_get_cipher(codec_ctx *ctx, int for_ctx);
++/*
++** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
++**
++** This function may only be called with an iterator passed to an
++** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
++** it sets the output variable to the total number of known foreign key
++** violations in the destination database and returns SQLITE_OK.
++**
++** In all other cases this function returns SQLITE_MISUSE.
++*/
++SQLITE_API int sqlite3changeset_fk_conflicts(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int *pnOut                      /* OUT: Number of FK violations */
++);
 +
-+void* sqlcipher_codec_ctx_get_data(codec_ctx *);
 +
-+void sqlcipher_exportFunc(sqlite3_context *, int, sqlite3_value **);
++/*
++** CAPI3REF: Finalize A Changeset Iterator
++**
++** This function is used to finalize an iterator allocated with
++** [sqlite3changeset_start()].
++**
++** This function should only be called on iterators created using the
++** [sqlite3changeset_start()] function. If an application calls this
++** function with an iterator passed to a conflict-handler by
++** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the
++** call has no effect.
++**
++** If an error was encountered within a call to an sqlite3changeset_xxx()
++** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an 
++** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding
++** to that error is returned by this function. Otherwise, SQLITE_OK is
++** returned. This is to allow the following pattern (pseudo-code):
++**
++**   sqlite3changeset_start();
++**   while( SQLITE_ROW==sqlite3changeset_next() ){
++**     // Do something with change.
++**   }
++**   rc = sqlite3changeset_finalize();
++**   if( rc!=SQLITE_OK ){
++**     // An error has occurred 
++**   }
++*/
++SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
 +
-+void sqlcipher_set_default_use_hmac(int use);
-+int sqlcipher_get_default_use_hmac();
++/*
++** CAPI3REF: Invert A Changeset
++**
++** This function is used to "invert" a changeset object. Applying an inverted
++** changeset to a database reverses the effects of applying the uninverted
++** changeset. Specifically:
++**
++** <ul>
++**   <li> Each DELETE change is changed to an INSERT, and
++**   <li> Each INSERT change is changed to a DELETE, and
++**   <li> For each UPDATE change, the old.* and new.* values are exchanged.
++** </ul>
++**
++** This function does not change the order in which changes appear within
++** the changeset. It merely reverses the sense of each individual change.
++**
++** If successful, a pointer to a buffer containing the inverted changeset
++** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and
++** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are
++** zeroed and an SQLite error code returned.
++**
++** It is the responsibility of the caller to eventually call sqlite3_free()
++** on the *ppOut pointer to free the buffer allocation following a successful 
++** call to this function.
++**
++** WARNING/TODO: This function currently assumes that the input is a valid
++** changeset. If it is not, the results are undefined.
++*/
++SQLITE_API int sqlite3changeset_invert(
++  int nIn, const void *pIn,       /* Input changeset */
++  int *pnOut, void **ppOut        /* OUT: Inverse of input */
++);
 +
-+void sqlcipher_set_hmac_salt_mask(unsigned char mask);
-+unsigned char sqlcipher_get_hmac_salt_mask();
++/*
++** CAPI3REF: Concatenate Two Changeset Objects
++**
++** This function is used to concatenate two changesets, A and B, into a 
++** single changeset. The result is a changeset equivalent to applying
++** changeset A followed by changeset B. 
++**
++** This function combines the two input changesets using an 
++** sqlite3_changegroup object. Calling it produces similar results as the
++** following code fragment:
++**
++**   sqlite3_changegroup *pGrp;
++**   rc = sqlite3_changegroup_new(&pGrp);
++**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
++**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB);
++**   if( rc==SQLITE_OK ){
++**     rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
++**   }else{
++**     *ppOut = 0;
++**     *pnOut = 0;
++**   }
++**
++** Refer to the sqlite3_changegroup documentation below for details.
++*/
++SQLITE_API int sqlite3changeset_concat(
++  int nA,                         /* Number of bytes in buffer pA */
++  void *pA,                       /* Pointer to buffer containing changeset A */
++  int nB,                         /* Number of bytes in buffer pB */
++  void *pB,                       /* Pointer to buffer containing changeset B */
++  int *pnOut,                     /* OUT: Number of bytes in output changeset */
++  void **ppOut                    /* OUT: Buffer containing output changeset */
++);
 +
-+int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use);
-+int sqlcipher_codec_ctx_get_use_hmac(codec_ctx *ctx, int for_ctx);
 +
-+int sqlcipher_codec_ctx_set_flag(codec_ctx *ctx, unsigned int flag);
-+int sqlcipher_codec_ctx_unset_flag(codec_ctx *ctx, unsigned int flag);
-+int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag, int for_ctx);
++/*
++** CAPI3REF: Changegroup Handle
++*/
++typedef struct sqlite3_changegroup sqlite3_changegroup;
 +
-+const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx);
-+int sqlcipher_codec_ctx_migrate(codec_ctx *ctx);
-+int sqlcipher_codec_add_random(codec_ctx *ctx, const char *data, int random_sz);
-+int sqlcipher_cipher_profile(sqlite3 *db, const char *destination);
-+static void sqlcipher_profile_callback(void *file, const char *sql, sqlite3_uint64 run_time);
-+static int sqlcipher_codec_get_store_pass(codec_ctx *ctx);
-+static void sqlcipher_codec_get_pass(codec_ctx *ctx, void **zKey, int *nKey);
-+static void sqlcipher_codec_set_store_pass(codec_ctx *ctx, int value);
-+int sqlcipher_codec_fips_status(codec_ctx *ctx);
++/*
++** CAPI3REF: Create A New Changegroup Object
++**
++** An sqlite3_changegroup object is used to combine two or more changesets
++** (or patchsets) into a single changeset (or patchset). A single changegroup
++** object may combine changesets or patchsets, but not both. The output is
++** always in the same format as the input.
++**
++** If successful, this function returns SQLITE_OK and populates (*pp) with
++** a pointer to a new sqlite3_changegroup object before returning. The caller
++** should eventually free the returned object using a call to 
++** sqlite3changegroup_delete(). If an error occurs, an SQLite error code
++** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL.
++**
++** The usual usage pattern for an sqlite3_changegroup object is as follows:
++**
++** <ul>
++**   <li> It is created using a call to sqlite3changegroup_new().
++**
++**   <li> Zero or more changesets (or patchsets) are added to the object
++**        by calling sqlite3changegroup_add().
++**
++**   <li> The result of combining all input changesets together is obtained 
++**        by the application via a call to sqlite3changegroup_output().
++**
++**   <li> The object is deleted using a call to sqlite3changegroup_delete().
++** </ul>
++**
++** Any number of calls to add() and output() may be made between the calls to
++** new() and delete(), and in any order.
++**
++** As well as the regular sqlite3changegroup_add() and 
++** sqlite3changegroup_output() functions, also available are the streaming
++** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
++*/
++SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
 +
- #endif
--#if SQLITE_ENABLE_RTREE
--  "ENABLE_RTREE",
- #endif
--#if defined(SQLITE_ENABLE_STAT4)
--  "ENABLE_STAT4",
--#elif defined(SQLITE_ENABLE_STAT3)
--  "ENABLE_STAT3",
--#endif
--#if SQLITE_ENABLE_UNLOCK_NOTIFY
--  "ENABLE_UNLOCK_NOTIFY",
--#endif
--#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
--  "ENABLE_UPDATE_DELETE_LIMIT",
--#endif
--#if SQLITE_HAS_CODEC
--  "HAS_CODEC",
--#endif
--#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
--  "HAVE_ISNAN",
--#endif
--#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
--  "HOMEGROWN_RECURSIVE_MUTEX",
--#endif
--#if SQLITE_IGNORE_AFP_LOCK_ERRORS
--  "IGNORE_AFP_LOCK_ERRORS",
--#endif
--#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS
--  "IGNORE_FLOCK_LOCK_ERRORS",
--#endif
--#ifdef SQLITE_INT64_TYPE
--  "INT64_TYPE",
--#endif
--#if SQLITE_LOCK_TRACE
--  "LOCK_TRACE",
--#endif
--#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc)
--  "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE),
--#endif
--#ifdef SQLITE_MAX_SCHEMA_RETRY
--  "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
--#endif
--#if SQLITE_MEMDEBUG
--  "MEMDEBUG",
--#endif
--#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
--  "MIXED_ENDIAN_64BIT_FLOAT",
--#endif
--#if SQLITE_NO_SYNC
--  "NO_SYNC",
--#endif
--#if SQLITE_OMIT_ALTERTABLE
--  "OMIT_ALTERTABLE",
--#endif
--#if SQLITE_OMIT_ANALYZE
--  "OMIT_ANALYZE",
--#endif
--#if SQLITE_OMIT_ATTACH
--  "OMIT_ATTACH",
--#endif
--#if SQLITE_OMIT_AUTHORIZATION
--  "OMIT_AUTHORIZATION",
--#endif
--#if SQLITE_OMIT_AUTOINCREMENT
--  "OMIT_AUTOINCREMENT",
--#endif
--#if SQLITE_OMIT_AUTOINIT
--  "OMIT_AUTOINIT",
--#endif
--#if SQLITE_OMIT_AUTOMATIC_INDEX
--  "OMIT_AUTOMATIC_INDEX",
--#endif
--#if SQLITE_OMIT_AUTORESET
--  "OMIT_AUTORESET",
--#endif
--#if SQLITE_OMIT_AUTOVACUUM
--  "OMIT_AUTOVACUUM",
--#endif
--#if SQLITE_OMIT_BETWEEN_OPTIMIZATION
--  "OMIT_BETWEEN_OPTIMIZATION",
--#endif
--#if SQLITE_OMIT_BLOB_LITERAL
--  "OMIT_BLOB_LITERAL",
--#endif
--#if SQLITE_OMIT_BTREECOUNT
--  "OMIT_BTREECOUNT",
--#endif
--#if SQLITE_OMIT_BUILTIN_TEST
--  "OMIT_BUILTIN_TEST",
--#endif
--#if SQLITE_OMIT_CAST
--  "OMIT_CAST",
--#endif
--#if SQLITE_OMIT_CHECK
--  "OMIT_CHECK",
--#endif
--#if SQLITE_OMIT_COMPLETE
--  "OMIT_COMPLETE",
--#endif
--#if SQLITE_OMIT_COMPOUND_SELECT
--  "OMIT_COMPOUND_SELECT",
--#endif
--#if SQLITE_OMIT_CTE
--  "OMIT_CTE",
--#endif
--#if SQLITE_OMIT_DATETIME_FUNCS
--  "OMIT_DATETIME_FUNCS",
--#endif
--#if SQLITE_OMIT_DECLTYPE
--  "OMIT_DECLTYPE",
--#endif
--#if SQLITE_OMIT_DEPRECATED
--  "OMIT_DEPRECATED",
--#endif
--#if SQLITE_OMIT_DISKIO
--  "OMIT_DISKIO",
--#endif
--#if SQLITE_OMIT_EXPLAIN
--  "OMIT_EXPLAIN",
--#endif
--#if SQLITE_OMIT_FLAG_PRAGMAS
--  "OMIT_FLAG_PRAGMAS",
--#endif
--#if SQLITE_OMIT_FLOATING_POINT
--  "OMIT_FLOATING_POINT",
--#endif
--#if SQLITE_OMIT_FOREIGN_KEY
--  "OMIT_FOREIGN_KEY",
--#endif
--#if SQLITE_OMIT_GET_TABLE
--  "OMIT_GET_TABLE",
--#endif
--#if SQLITE_OMIT_INCRBLOB
--  "OMIT_INCRBLOB",
--#endif
--#if SQLITE_OMIT_INTEGRITY_CHECK
--  "OMIT_INTEGRITY_CHECK",
--#endif
--#if SQLITE_OMIT_LIKE_OPTIMIZATION
--  "OMIT_LIKE_OPTIMIZATION",
--#endif
--#if SQLITE_OMIT_LOAD_EXTENSION
--  "OMIT_LOAD_EXTENSION",
--#endif
--#if SQLITE_OMIT_LOCALTIME
--  "OMIT_LOCALTIME",
--#endif
--#if SQLITE_OMIT_LOOKASIDE
--  "OMIT_LOOKASIDE",
--#endif
--#if SQLITE_OMIT_MEMORYDB
--  "OMIT_MEMORYDB",
--#endif
--#if SQLITE_OMIT_OR_OPTIMIZATION
--  "OMIT_OR_OPTIMIZATION",
--#endif
--#if SQLITE_OMIT_PAGER_PRAGMAS
--  "OMIT_PAGER_PRAGMAS",
--#endif
--#if SQLITE_OMIT_PRAGMA
--  "OMIT_PRAGMA",
--#endif
--#if SQLITE_OMIT_PROGRESS_CALLBACK
--  "OMIT_PROGRESS_CALLBACK",
--#endif
--#if SQLITE_OMIT_QUICKBALANCE
--  "OMIT_QUICKBALANCE",
--#endif
--#if SQLITE_OMIT_REINDEX
--  "OMIT_REINDEX",
--#endif
--#if SQLITE_OMIT_SCHEMA_PRAGMAS
--  "OMIT_SCHEMA_PRAGMAS",
--#endif
--#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
--  "OMIT_SCHEMA_VERSION_PRAGMAS",
--#endif
--#if SQLITE_OMIT_SHARED_CACHE
--  "OMIT_SHARED_CACHE",
--#endif
--#if SQLITE_OMIT_SUBQUERY
--  "OMIT_SUBQUERY",
--#endif
--#if SQLITE_OMIT_TCL_VARIABLE
--  "OMIT_TCL_VARIABLE",
--#endif
--#if SQLITE_OMIT_TEMPDB
--  "OMIT_TEMPDB",
--#endif
--#if SQLITE_OMIT_TRACE
--  "OMIT_TRACE",
--#endif
--#if SQLITE_OMIT_TRIGGER
--  "OMIT_TRIGGER",
--#endif
--#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION
--  "OMIT_TRUNCATE_OPTIMIZATION",
--#endif
--#if SQLITE_OMIT_UTF16
--  "OMIT_UTF16",
--#endif
--#if SQLITE_OMIT_VACUUM
--  "OMIT_VACUUM",
--#endif
--#if SQLITE_OMIT_VIEW
--  "OMIT_VIEW",
--#endif
--#if SQLITE_OMIT_VIRTUALTABLE
--  "OMIT_VIRTUALTABLE",
--#endif
--#if SQLITE_OMIT_WAL
--  "OMIT_WAL",
--#endif
--#if SQLITE_OMIT_WSD
--  "OMIT_WSD",
--#endif
--#if SQLITE_OMIT_XFER_OPT
--  "OMIT_XFER_OPT",
--#endif
--#if SQLITE_PERFORMANCE_TRACE
--  "PERFORMANCE_TRACE",
--#endif
--#if SQLITE_PROXY_DEBUG
--  "PROXY_DEBUG",
--#endif
--#if SQLITE_RTREE_INT_ONLY
--  "RTREE_INT_ONLY",
--#endif
--#if SQLITE_SECURE_DELETE
--  "SECURE_DELETE",
--#endif
--#if SQLITE_SMALL_STACK
--  "SMALL_STACK",
--#endif
--#if SQLITE_SOUNDEX
--  "SOUNDEX",
--#endif
--#if SQLITE_SYSTEM_MALLOC
--  "SYSTEM_MALLOC",
--#endif
--#if SQLITE_TCL
--  "TCL",
--#endif
--#if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc)
--  "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
--#endif
--#if SQLITE_TEST
--  "TEST",
--#endif
--#if defined(SQLITE_THREADSAFE)
--  "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
--#endif
--#if SQLITE_USE_ALLOCA
--  "USE_ALLOCA",
--#endif
--#if SQLITE_USER_AUTHENTICATION
--  "USER_AUTHENTICATION",
--#endif
--#if SQLITE_WIN32_MALLOC
--  "WIN32_MALLOC",
--#endif
--#if SQLITE_ZERO_MALLOC
--  "ZERO_MALLOC"
--#endif
--};
-+/* END SQLCIPHER */
- 
--/*
--** Given the name of a compile-time option, return true if that option
--** was used and false if not.
--**
--** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
--** is not required for a match.
--*/
--SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){
--  int i, n;
-+/************** End of crypto.h **********************************************/
-+/************** Continuing where we left off in crypto.c *********************/
- 
--#if SQLITE_ENABLE_API_ARMOR
--  if( zOptName==0 ){
--    (void)SQLITE_MISUSE_BKPT;
--    return 0;
-+static const char* codec_get_cipher_version() {
-+  return CIPHER_VERSION;
-+}
++/*
++** CAPI3REF: Add A Changeset To A Changegroup
++**
++** Add all changes within the changeset (or patchset) in buffer pData (size
++** nData bytes) to the changegroup. 
++**
++** If the buffer contains a patchset, then all prior calls to this function
++** on the same changegroup object must also have specified patchsets. Or, if
++** the buffer contains a changeset, so must have the earlier calls to this
++** function. Otherwise, SQLITE_ERROR is returned and no changes are added
++** to the changegroup.
++**
++** Rows within the changeset and changegroup are identified by the values in
++** their PRIMARY KEY columns. A change in the changeset is considered to
++** apply to the same row as a change already present in the changegroup if
++** the two rows have the same primary key.
++**
++** Changes to rows that do not already appear in the changegroup are
++** simply copied into it. Or, if both the new changeset and the changegroup
++** contain changes that apply to a single row, the final contents of the
++** changegroup depends on the type of each change, as follows:
++**
++** <table border=1 style="margin-left:8ex;margin-right:8ex">
++**   <tr><th style="white-space:pre">Existing Change  </th>
++**       <th style="white-space:pre">New Change       </th>
++**       <th>Output Change
++**   <tr><td>INSERT <td>INSERT <td>
++**       The new change is ignored. This case does not occur if the new
++**       changeset was recorded immediately after the changesets already
++**       added to the changegroup.
++**   <tr><td>INSERT <td>UPDATE <td>
++**       The INSERT change remains in the changegroup. The values in the 
++**       INSERT change are modified as if the row was inserted by the
++**       existing change and then updated according to the new change.
++**   <tr><td>INSERT <td>DELETE <td>
++**       The existing INSERT is removed from the changegroup. The DELETE is
++**       not added.
++**   <tr><td>UPDATE <td>INSERT <td>
++**       The new change is ignored. This case does not occur if the new
++**       changeset was recorded immediately after the changesets already
++**       added to the changegroup.
++**   <tr><td>UPDATE <td>UPDATE <td>
++**       The existing UPDATE remains within the changegroup. It is amended 
++**       so that the accompanying values are as if the row was updated once 
++**       by the existing change and then again by the new change.
++**   <tr><td>UPDATE <td>DELETE <td>
++**       The existing UPDATE is replaced by the new DELETE within the
++**       changegroup.
++**   <tr><td>DELETE <td>INSERT <td>
++**       If one or more of the column values in the row inserted by the
++**       new change differ from those in the row deleted by the existing 
++**       change, the existing DELETE is replaced by an UPDATE within the
++**       changegroup. Otherwise, if the inserted row is exactly the same 
++**       as the deleted row, the existing DELETE is simply discarded.
++**   <tr><td>DELETE <td>UPDATE <td>
++**       The new change is ignored. This case does not occur if the new
++**       changeset was recorded immediately after the changesets already
++**       added to the changegroup.
++**   <tr><td>DELETE <td>DELETE <td>
++**       The new change is ignored. This case does not occur if the new
++**       changeset was recorded immediately after the changesets already
++**       added to the changegroup.
++** </table>
++**
++** If the new changeset contains changes to a table that is already present
++** in the changegroup, then the number of columns and the position of the
++** primary key columns for the table must be consistent. If this is not the
++** case, this function fails with SQLITE_SCHEMA. If the input changeset
++** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
++** returned. Or, if an out-of-memory condition occurs during processing, this
++** function returns SQLITE_NOMEM. In all cases, if an error occurs the
++** final contents of the changegroup is undefined.
++**
++** If no error occurs, SQLITE_OK is returned.
++*/
++SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
 +
-+/* Generate code to return a string value */
-+static void codec_vdbe_return_static_string(Parse *pParse, const char *zLabel, const char *value){
-+  Vdbe *v = sqlite3GetVdbe(pParse);
-+  sqlite3VdbeSetNumCols(v, 1);
-+  sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
-+  sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, value, 0);
-+  sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
-+}
++/*
++** CAPI3REF: Obtain A Composite Changeset From A Changegroup
++**
++** Obtain a buffer containing a changeset (or patchset) representing the
++** current contents of the changegroup. If the inputs to the changegroup
++** were themselves changesets, the output is a changeset. Or, if the
++** inputs were patchsets, the output is also a patchset.
++**
++** As with the output of the sqlite3session_changeset() and
++** sqlite3session_patchset() functions, all changes related to a single
++** table are grouped together in the output of this function. Tables appear
++** in the same order as for the very first changeset added to the changegroup.
++** If the second or subsequent changesets added to the changegroup contain
++** changes for tables that do not appear in the first changeset, they are
++** appended onto the end of the output changeset, again in the order in
++** which they are first encountered.
++**
++** If an error occurs, an SQLite error code is returned and the output
++** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK
++** is returned and the output variables are set to the size of and a 
++** pointer to the output buffer, respectively. In this case it is the
++** responsibility of the caller to eventually free the buffer using a
++** call to sqlite3_free().
++*/
++SQLITE_API int sqlite3changegroup_output(
++  sqlite3_changegroup*,
++  int *pnData,                    /* OUT: Size of output buffer in bytes */
++  void **ppData                   /* OUT: Pointer to output buffer */
++);
 +
-+static int codec_set_btree_to_codec_pagesize(sqlite3 *db, Db *pDb, codec_ctx *ctx) {
-+  int rc, page_sz, reserve_sz; 
++/*
++** CAPI3REF: Delete A Changegroup Object
++*/
++SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
 +
-+  page_sz = sqlcipher_codec_ctx_get_pagesize(ctx);
-+  reserve_sz = sqlcipher_codec_ctx_get_reservesize(ctx);
++/*
++** CAPI3REF: Apply A Changeset To A Database
++**
++** Apply a changeset to a database. This function attempts to update the
++** "main" database attached to handle db with the changes found in the
++** changeset passed via the second and third arguments.
++**
++** The fourth argument (xFilter) passed to this function is the "filter
++** callback". If it is not NULL, then for each table affected by at least one
++** change in the changeset, the filter callback is invoked with
++** the table name as the second argument, and a copy of the context pointer
++** passed as the sixth argument to this function as the first. If the "filter
++** callback" returns zero, then no attempt is made to apply any changes to 
++** the table. Otherwise, if the return value is non-zero or the xFilter
++** argument to this function is NULL, all changes related to the table are
++** attempted.
++**
++** For each table that is not excluded by the filter callback, this function 
++** tests that the target database contains a compatible table. A table is 
++** considered compatible if all of the following are true:
++**
++** <ul>
++**   <li> The table has the same name as the name recorded in the 
++**        changeset, and
++**   <li> The table has at least as many columns as recorded in the 
++**        changeset, and
++**   <li> The table has primary key columns in the same position as 
++**        recorded in the changeset.
++** </ul>
++**
++** If there is no compatible table, it is not an error, but none of the
++** changes associated with the table are applied. A warning message is issued
++** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most
++** one such warning is issued for each table in the changeset.
++**
++** For each change for which there is a compatible table, an attempt is made 
++** to modify the table contents according to the UPDATE, INSERT or DELETE 
++** change. If a change cannot be applied cleanly, the conflict handler 
++** function passed as the fifth argument to sqlite3changeset_apply() may be 
++** invoked. A description of exactly when the conflict handler is invoked for 
++** each type of change is below.
++**
++** Unlike the xFilter argument, xConflict may not be passed NULL. The results
++** of passing anything other than a valid function pointer as the xConflict
++** argument are undefined.
++**
++** Each time the conflict handler function is invoked, it must return one
++** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or 
++** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned
++** if the second argument passed to the conflict handler is either
++** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler
++** returns an illegal value, any changes already made are rolled back and
++** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different 
++** actions are taken by sqlite3changeset_apply() depending on the value
++** returned by each invocation of the conflict-handler function. Refer to
++** the documentation for the three 
++** [SQLITE_CHANGESET_OMIT|available return values] for details.
++**
++** <dl>
++** <dt>DELETE Changes<dd>
++**   For each DELETE change, this function checks if the target database 
++**   contains a row with the same primary key value (or values) as the 
++**   original row values stored in the changeset. If it does, and the values 
++**   stored in all non-primary key columns also match the values stored in 
++**   the changeset the row is deleted from the target database.
++**
++**   If a row with matching primary key values is found, but one or more of
++**   the non-primary key fields contains a value different from the original
++**   row value stored in the changeset, the conflict-handler function is
++**   invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the
++**   database table has more columns than are recorded in the changeset,
++**   only the values of those non-primary key fields are compared against
++**   the current database contents - any trailing database table columns
++**   are ignored.
++**
++**   If no row with matching primary key values is found in the database,
++**   the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
++**   passed as the second argument.
++**
++**   If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT
++**   (which can only happen if a foreign key constraint is violated), the
++**   conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT]
++**   passed as the second argument. This includes the case where the DELETE
++**   operation is attempted because an earlier call to the conflict handler
++**   function returned [SQLITE_CHANGESET_REPLACE].
++**
++** <dt>INSERT Changes<dd>
++**   For each INSERT change, an attempt is made to insert the new row into
++**   the database. If the changeset row contains fewer fields than the
++**   database table, the trailing fields are populated with their default
++**   values.
++**
++**   If the attempt to insert the row fails because the database already 
++**   contains a row with the same primary key values, the conflict handler
++**   function is invoked with the second argument set to 
++**   [SQLITE_CHANGESET_CONFLICT].
++**
++**   If the attempt to insert the row fails because of some other constraint
++**   violation (e.g. NOT NULL or UNIQUE), the conflict handler function is 
++**   invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT].
++**   This includes the case where the INSERT operation is re-attempted because 
++**   an earlier call to the conflict handler function returned 
++**   [SQLITE_CHANGESET_REPLACE].
++**
++** <dt>UPDATE Changes<dd>
++**   For each UPDATE change, this function checks if the target database 
++**   contains a row with the same primary key value (or values) as the 
++**   original row values stored in the changeset. If it does, and the values 
++**   stored in all modified non-primary key columns also match the values
++**   stored in the changeset the row is updated within the target database.
++**
++**   If a row with matching primary key values is found, but one or more of
++**   the modified non-primary key fields contains a value different from an
++**   original row value stored in the changeset, the conflict-handler function
++**   is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
++**   UPDATE changes only contain values for non-primary key fields that are
++**   to be modified, only those fields need to match the original values to
++**   avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
++**
++**   If no row with matching primary key values is found in the database,
++**   the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
++**   passed as the second argument.
++**
++**   If the UPDATE operation is attempted, but SQLite returns 
++**   SQLITE_CONSTRAINT, the conflict-handler function is invoked with 
++**   [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument.
++**   This includes the case where the UPDATE operation is attempted after 
++**   an earlier call to the conflict handler function returned
++**   [SQLITE_CHANGESET_REPLACE].  
++** </dl>
++**
++** It is safe to execute SQL statements, including those that write to the
++** table that the callback related to, from within the xConflict callback.
++** This can be used to further customize the applications conflict
++** resolution strategy.
++**
++** All changes made by this function are enclosed in a savepoint transaction.
++** If any other error (aside from a constraint failure when attempting to
++** write to the target database) occurs, then the savepoint transaction is
++** rolled back, restoring the target database to its original state, and an 
++** SQLite error code returned.
++*/
++SQLITE_API int sqlite3changeset_apply(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  int nChangeset,                 /* Size of changeset in bytes */
++  void *pChangeset,               /* Changeset blob */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx                      /* First argument passed to xConflict */
++);
 +
-+  sqlite3_mutex_enter(db->mutex);
-+  db->nextPagesize = page_sz; 
++/* 
++** CAPI3REF: Constants Passed To The Conflict Handler
++**
++** Values that may be passed as the second argument to a conflict-handler.
++**
++** <dl>
++** <dt>SQLITE_CHANGESET_DATA<dd>
++**   The conflict handler is invoked with CHANGESET_DATA as the second argument
++**   when processing a DELETE or UPDATE change if a row with the required
++**   PRIMARY KEY fields is present in the database, but one or more other 
++**   (non primary-key) fields modified by the update do not contain the 
++**   expected "before" values.
++** 
++**   The conflicting row, in this case, is the database row with the matching
++**   primary key.
++** 
++** <dt>SQLITE_CHANGESET_NOTFOUND<dd>
++**   The conflict handler is invoked with CHANGESET_NOTFOUND as the second
++**   argument when processing a DELETE or UPDATE change if a row with the
++**   required PRIMARY KEY fields is not present in the database.
++** 
++**   There is no conflicting row in this case. The results of invoking the
++**   sqlite3changeset_conflict() API are undefined.
++** 
++** <dt>SQLITE_CHANGESET_CONFLICT<dd>
++**   CHANGESET_CONFLICT is passed as the second argument to the conflict
++**   handler while processing an INSERT change if the operation would result 
++**   in duplicate primary key values.
++** 
++**   The conflicting row in this case is the database row with the matching
++**   primary key.
++**
++** <dt>SQLITE_CHANGESET_FOREIGN_KEY<dd>
++**   If foreign key handling is enabled, and applying a changeset leaves the
++**   database in a state containing foreign key violations, the conflict 
++**   handler is invoked with CHANGESET_FOREIGN_KEY as the second argument
++**   exactly once before the changeset is committed. If the conflict handler
++**   returns CHANGESET_OMIT, the changes, including those that caused the
++**   foreign key constraint violation, are committed. Or, if it returns
++**   CHANGESET_ABORT, the changeset is rolled back.
++**
++**   No current or conflicting row information is provided. The only function
++**   it is possible to call on the supplied sqlite3_changeset_iter handle
++**   is sqlite3changeset_fk_conflicts().
++** 
++** <dt>SQLITE_CHANGESET_CONSTRAINT<dd>
++**   If any other constraint violation occurs while applying a change (i.e. 
++**   a UNIQUE, CHECK or NOT NULL constraint), the conflict handler is 
++**   invoked with CHANGESET_CONSTRAINT as the second argument.
++** 
++**   There is no conflicting row in this case. The results of invoking the
++**   sqlite3changeset_conflict() API are undefined.
++**
++** </dl>
++*/
++#define SQLITE_CHANGESET_DATA        1
++#define SQLITE_CHANGESET_NOTFOUND    2
++#define SQLITE_CHANGESET_CONFLICT    3
++#define SQLITE_CHANGESET_CONSTRAINT  4
++#define SQLITE_CHANGESET_FOREIGN_KEY 5
 +
-+  /* before forcing the page size we need to unset the BTS_PAGESIZE_FIXED flag, else  
-+     sqliteBtreeSetPageSize will block the change  */
-+  pDb->pBt->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
-+  CODEC_TRACE(("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d\n", 
page_sz, reserve_sz));
-+  rc = sqlite3BtreeSetPageSize(pDb->pBt, page_sz, reserve_sz, 0);
-+  sqlite3_mutex_leave(db->mutex);
-+  return rc;
-+}
++/* 
++** CAPI3REF: Constants Returned By The Conflict Handler
++**
++** A conflict handler callback must return one of the following three values.
++**
++** <dl>
++** <dt>SQLITE_CHANGESET_OMIT<dd>
++**   If a conflict handler returns this value no special action is taken. The
++**   change that caused the conflict is not applied. The session module 
++**   continues to the next change in the changeset.
++**
++** <dt>SQLITE_CHANGESET_REPLACE<dd>
++**   This value may only be returned if the second argument to the conflict
++**   handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this
++**   is not the case, any changes applied so far are rolled back and the 
++**   call to sqlite3changeset_apply() returns SQLITE_MISUSE.
++**
++**   If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict
++**   handler, then the conflicting row is either updated or deleted, depending
++**   on the type of change.
++**
++**   If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict
++**   handler, then the conflicting row is removed from the database and a
++**   second attempt to apply the change is made. If this second attempt fails,
++**   the original row is restored to the database before continuing.
++**
++** <dt>SQLITE_CHANGESET_ABORT<dd>
++**   If this value is returned, any changes applied so far are rolled back 
++**   and the call to sqlite3changeset_apply() returns SQLITE_ABORT.
++** </dl>
++*/
++#define SQLITE_CHANGESET_OMIT       0
++#define SQLITE_CHANGESET_REPLACE    1
++#define SQLITE_CHANGESET_ABORT      2
 +
-+static int codec_set_pass_key(sqlite3* db, int nDb, const void *zKey, int nKey, int for_ctx) {
-+  struct Db *pDb = &db->aDb[nDb];
-+  CODEC_TRACE(("codec_set_pass_key: entered db=%p nDb=%d zKey=%s nKey=%d for_ctx=%d\n", db, nDb, (char 
*)zKey, nKey, for_ctx));
-+  if(pDb->pBt) {
-+    codec_ctx *ctx;
-+    sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
-+    if(ctx) return sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, for_ctx);
-   }
--#endif
--  if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
--  n = sqlite3Strlen30(zOptName);
-+  return SQLITE_ERROR;
-+} 
- 
--  /* Since ArraySize(azCompileOpt) is normally in single digits, a
--  ** linear search is adequate.  No need for a binary search. */
--  for(i=0; i<ArraySize(azCompileOpt); i++){
--    if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
--     && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
--    ){
--      return 1;
-+int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const char *zRight) {
-+  struct Db *pDb = &db->aDb[iDb];
-+  codec_ctx *ctx = NULL;
-+  int rc;
++/*
++** CAPI3REF: Streaming Versions of API functions.
++**
++** The six streaming API xxx_strm() functions serve similar purposes to the 
++** corresponding non-streaming API functions:
++**
++** <table border=1 style="margin-left:8ex;margin-right:8ex">
++**   <tr><th>Streaming function<th>Non-streaming equivalent</th>
++**   <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply] 
++**   <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat] 
++**   <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert] 
++**   <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start] 
++**   <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset] 
++**   <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset] 
++** </table>
++**
++** Non-streaming functions that accept changesets (or patchsets) as input
++** require that the entire changeset be stored in a single buffer in memory. 
++** Similarly, those that return a changeset or patchset do so by returning 
++** a pointer to a single large buffer allocated using sqlite3_malloc(). 
++** Normally this is convenient. However, if an application running in a 
++** low-memory environment is required to handle very large changesets, the
++** large contiguous memory allocations required can become onerous.
++**
++** In order to avoid this problem, instead of a single large buffer, input
++** is passed to a streaming API functions by way of a callback function that
++** the sessions module invokes to incrementally request input data as it is
++** required. In all cases, a pair of API function parameters such as
++**
++**  <pre>
++**  &nbsp;     int nChangeset,
++**  &nbsp;     void *pChangeset,
++**  </pre>
++**
++** Is replaced by:
++**
++**  <pre>
++**  &nbsp;     int (*xInput)(void *pIn, void *pData, int *pnData),
++**  &nbsp;     void *pIn,
++**  </pre>
++**
++** Each time the xInput callback is invoked by the sessions module, the first
++** argument passed is a copy of the supplied pIn context pointer. The second 
++** argument, pData, points to a buffer (*pnData) bytes in size. Assuming no 
++** error occurs the xInput method should copy up to (*pnData) bytes of data 
++** into the buffer and set (*pnData) to the actual number of bytes copied 
++** before returning SQLITE_OK. If the input is completely exhausted, (*pnData) 
++** should be set to zero to indicate this. Or, if an error occurs, an SQLite 
++** error code should be returned. In all cases, if an xInput callback returns
++** an error, all processing is abandoned and the streaming API function
++** returns a copy of the error code to the caller.
++**
++** In the case of sqlite3changeset_start_strm(), the xInput callback may be
++** invoked by the sessions module at any point during the lifetime of the
++** iterator. If such an xInput callback returns an error, the iterator enters
++** an error state, whereby all subsequent calls to iterator functions 
++** immediately fail with the same error code as returned by xInput.
++**
++** Similarly, streaming API functions that return changesets (or patchsets)
++** return them in chunks by way of a callback function instead of via a
++** pointer to a single large buffer. In this case, a pair of parameters such
++** as:
++**
++**  <pre>
++**  &nbsp;     int *pnChangeset,
++**  &nbsp;     void **ppChangeset,
++**  </pre>
++**
++** Is replaced by:
++**
++**  <pre>
++**  &nbsp;     int (*xOutput)(void *pOut, const void *pData, int nData),
++**  &nbsp;     void *pOut
++**  </pre>
++**
++** The xOutput callback is invoked zero or more times to return data to
++** the application. The first parameter passed to each call is a copy of the
++** pOut pointer supplied by the application. The second parameter, pData,
++** points to a buffer nData bytes in size containing the chunk of output
++** data being returned. If the xOutput callback successfully processes the
++** supplied data, it should return SQLITE_OK to indicate success. Otherwise,
++** it should return some other SQLite error code. In this case processing
++** is immediately abandoned and the streaming API function returns a copy
++** of the xOutput error code to the application.
++**
++** The sessions module never invokes an xOutput callback with the third 
++** parameter set to a value less than or equal to zero. Other than this,
++** no guarantees are made as to the size of the chunks of data returned.
++*/
++SQLITE_API int sqlite3changeset_apply_strm(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
++  void *pIn,                                          /* First arg for xInput */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx                      /* First argument passed to xConflict */
++);
++SQLITE_API int sqlite3changeset_concat_strm(
++  int (*xInputA)(void *pIn, void *pData, int *pnData),
++  void *pInA,
++  int (*xInputB)(void *pIn, void *pData, int *pnData),
++  void *pInB,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++);
++SQLITE_API int sqlite3changeset_invert_strm(
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++);
++SQLITE_API int sqlite3changeset_start_strm(
++  sqlite3_changeset_iter **pp,
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn
++);
++SQLITE_API int sqlite3session_changeset_strm(
++  sqlite3_session *pSession,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++);
++SQLITE_API int sqlite3session_patchset_strm(
++  sqlite3_session *pSession,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++);
++SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*, 
++    int (*xInput)(void *pIn, void *pData, int *pnData),
++    void *pIn
++);
++SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
++    int (*xOutput)(void *pOut, const void *pData, int nData), 
++    void *pOut
++);
 +
-+  if(pDb->pBt) {
-+    sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
-+  }
 +
-+  CODEC_TRACE(("sqlcipher_codec_pragma: entered db=%p iDb=%d pParse=%p zLeft=%s zRight=%s ctx=%p\n", db, 
iDb, pParse, zLeft, zRight, ctx));
-+  
-+  if( sqlite3StrICmp(zLeft, "cipher_fips_status")== 0 && !zRight ){
-+    if(ctx) {
-+      char *fips_mode_status = sqlite3_mprintf("%d", sqlcipher_codec_fips_status(ctx));
-+      codec_vdbe_return_static_string(pParse, "cipher_fips_status", fips_mode_status);
-+      sqlite3_free(fips_mode_status);
-+    }
-+  } else
-+  if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && zRight ) {
-+    if(ctx) {
-+      sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1));
-+    }
-+  } else
-+  if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && !zRight ) {
-+    if(ctx){
-+      char *store_pass_value = sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx));
-+      codec_vdbe_return_static_string(pParse, "cipher_store_pass", store_pass_value);
-+      sqlite3_free(store_pass_value);
-     }
-   }
--  return 0;
-+  if( sqlite3StrICmp(zLeft, "cipher_profile")== 0 && zRight ){
-+      char *profile_status = sqlite3_mprintf("%d", sqlcipher_cipher_profile(db, zRight));
-+      codec_vdbe_return_static_string(pParse, "cipher_profile", profile_status);
-+      sqlite3_free(profile_status);
-+  } else
-+  if( sqlite3StrICmp(zLeft, "cipher_add_random")==0 && zRight ){
-+    if(ctx) {
-+      char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, 
sqlite3Strlen30(zRight)));
-+      codec_vdbe_return_static_string(pParse, "cipher_add_random", add_random_status);
-+      sqlite3_free(add_random_status);
-+    }
-+  } else
-+  if( sqlite3StrICmp(zLeft, "cipher_migrate")==0 && !zRight ){
-+    if(ctx){
-+      char *migrate_status = sqlite3_mprintf("%d", sqlcipher_codec_ctx_migrate(ctx));
-+      codec_vdbe_return_static_string(pParse, "cipher_migrate", migrate_status);
-+      sqlite3_free(migrate_status);
-+    }
-+  } else
-+  if( sqlite3StrICmp(zLeft, "cipher_provider")==0 && !zRight ){
-+    if(ctx) { codec_vdbe_return_static_string(pParse, "cipher_provider",
-+                                              sqlcipher_codec_get_cipher_provider(ctx));
-+    }
-+  } else
-+  if( sqlite3StrICmp(zLeft, "cipher_version")==0 && !zRight ){
-+    codec_vdbe_return_static_string(pParse, "cipher_version", codec_get_cipher_version());
-+  }else
-+  if( sqlite3StrICmp(zLeft, "cipher")==0 ){
-+    if(ctx) {
-+      if( zRight ) {
-+        sqlcipher_codec_ctx_set_cipher(ctx, zRight, 2); // change cipher for both
-+      }else {
-+        codec_vdbe_return_static_string(pParse, "cipher",
-+          sqlcipher_codec_ctx_get_cipher(ctx, 2));
-+      }
-+    }
-+  }else
-+  if( sqlite3StrICmp(zLeft, "rekey_cipher")==0 && zRight ){
-+    if(ctx) sqlcipher_codec_ctx_set_cipher(ctx, zRight, 1); // change write cipher only 
-+  }else
-+  if( sqlite3StrICmp(zLeft,"cipher_default_kdf_iter")==0 ){
-+    if( zRight ) {
-+      sqlcipher_set_default_kdf_iter(atoi(zRight)); // change default KDF iterations
-+    } else {
-+      char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter());
-+      codec_vdbe_return_static_string(pParse, "cipher_default_kdf_iter", kdf_iter);
-+      sqlite3_free(kdf_iter);
-+    }
-+  }else
-+  if( sqlite3StrICmp(zLeft, "kdf_iter")==0 ){
-+    if(ctx) {
-+      if( zRight ) {
-+        sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight), 2); // change of RW PBKDF2 iteration 
-+      } else {
-+        char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_kdf_iter(ctx, 2));
-+        codec_vdbe_return_static_string(pParse, "kdf_iter", kdf_iter);
-+        sqlite3_free(kdf_iter);
-+      }
-+    }
-+  }else
-+  if( sqlite3StrICmp(zLeft, "fast_kdf_iter")==0){
-+    if(ctx) {
-+      if( zRight ) {
-+        sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, atoi(zRight), 2); // change of RW PBKDF2 iteration 
-+      } else {
-+        char *fast_kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_fast_kdf_iter(ctx, 2));
-+        codec_vdbe_return_static_string(pParse, "fast_kdf_iter", fast_kdf_iter);
-+        sqlite3_free(fast_kdf_iter);
-+      }
-+    }
-+  }else
-+  if( sqlite3StrICmp(zLeft, "rekey_kdf_iter")==0 && zRight ){
-+    if(ctx) sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight), 1); // write iterations only
-+  }else
-+  if( sqlite3StrICmp(zLeft,"cipher_page_size")==0 ){
-+    if(ctx) {
-+      if( zRight ) {
-+        int size = atoi(zRight);
-+        rc = sqlcipher_codec_ctx_set_pagesize(ctx, size);
-+        if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
-+        rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
-+        if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
-+      } else {
-+        char * page_size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_pagesize(ctx));
-+        codec_vdbe_return_static_string(pParse, "cipher_page_size", page_size);
-+        sqlite3_free(page_size);
-+      }
-+    }
-+  }else
-+  if( sqlite3StrICmp(zLeft,"cipher_default_page_size")==0 ){
-+    if( zRight ) {
-+      sqlcipher_set_default_pagesize(atoi(zRight));
-+    } else {
-+      char *default_page_size = sqlite3_mprintf("%d", sqlcipher_get_default_pagesize());
-+      codec_vdbe_return_static_string(pParse, "cipher_default_page_size", default_page_size);
-+      sqlite3_free(default_page_size);
-+    }
-+  }else
-+  if( sqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){
-+    if( zRight ) {
-+      sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight,1));
-+    } else {
-+      char *default_use_hmac = sqlite3_mprintf("%d", sqlcipher_get_default_use_hmac());
-+      codec_vdbe_return_static_string(pParse, "cipher_default_use_hmac", default_use_hmac);
-+      sqlite3_free(default_use_hmac);
-+    }
-+  }else
-+  if( sqlite3StrICmp(zLeft,"cipher_use_hmac")==0 ){
-+    if(ctx) {
-+      if( zRight ) {
-+        rc = sqlcipher_codec_ctx_set_use_hmac(ctx, sqlite3GetBoolean(zRight,1));
-+        if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
-+        /* since the use of hmac has changed, the page size may also change */
-+        rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
-+        if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
-+      } else {
-+        char *hmac_flag = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_use_hmac(ctx, 2));
-+        codec_vdbe_return_static_string(pParse, "cipher_use_hmac", hmac_flag);
-+        sqlite3_free(hmac_flag);
-+      }
-+    }
-+  }else
-+  if( sqlite3StrICmp(zLeft,"cipher_hmac_pgno")==0 ){
-+    if(ctx) {
-+      if(zRight) {
-+        // clear both pgno endian flags
-+        if(sqlite3StrICmp(zRight, "le") == 0) {
-+          sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
-+          sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_LE_PGNO);
-+        } else if(sqlite3StrICmp(zRight, "be") == 0) {
-+          sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
-+          sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_BE_PGNO);
-+        } else if(sqlite3StrICmp(zRight, "native") == 0) {
-+          sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
-+          sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
-+        }
-+      } else {
-+        if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_LE_PGNO, 2)) {
-+          codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "le");
-+        } else if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_BE_PGNO, 2)) {
-+          codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "be");
-+        } else {
-+          codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "native");
-+        }
-+      }
-+    }
-+  }else
-+  if( sqlite3StrICmp(zLeft,"cipher_hmac_salt_mask")==0 ){
-+    if(ctx) {
-+      if(zRight) {
-+        if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == 5) {
-+          unsigned char mask = 0;
-+          const unsigned char *hex = (const unsigned char *)zRight+2;
-+          cipher_hex2bin(hex,2,&mask);
-+          sqlcipher_set_hmac_salt_mask(mask);
-+        }
-+      } else {
-+          char *hmac_salt_mask = sqlite3_mprintf("%02x", sqlcipher_get_hmac_salt_mask());
-+          codec_vdbe_return_static_string(pParse, "cipher_hmac_salt_mask", hmac_salt_mask);
-+          sqlite3_free(hmac_salt_mask);
-+      }
-+    }
-+  }else {
-+    return 0;
-+  }
-+  return 1;
- }
- 
++/*
++** Make sure we can call this stuff from C++.
++*/
++#ifdef __cplusplus
++}
++#endif
 +
- /*
--** Return the N-th compile-time option string.  If N is out of range,
--** return a NULL pointer.
--*/
--SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N){
--  if( N>=0 && N<ArraySize(azCompileOpt) ){
--    return azCompileOpt[N];
-+ * sqlite3Codec can be called in multiple modes.
-+ * encrypt mode - expected to return a pointer to the 
-+ *   encrypted data without altering pData.
-+ * decrypt mode - expected to return a pointer to pData, with
-+ *   the data decrypted in the input buffer
-+ */
-+void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) {
-+  codec_ctx *ctx = (codec_ctx *) iCtx;
-+  int offset = 0, rc = 0;
-+  int page_sz = sqlcipher_codec_ctx_get_pagesize(ctx); 
-+  unsigned char *pData = (unsigned char *) data;
-+  void *buffer = sqlcipher_codec_ctx_get_data(ctx);
-+  void *kdf_salt = sqlcipher_codec_ctx_get_kdf_salt(ctx);
-+  CODEC_TRACE(("sqlite3Codec: entered pgno=%d, mode=%d, page_sz=%d\n", pgno, mode, page_sz));
++#endif  /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */
 +
-+  /* call to derive keys if not present yet */
-+  if((rc = sqlcipher_codec_key_derive(ctx)) != SQLITE_OK) {
-+   sqlcipher_codec_ctx_set_error(ctx, rc); 
-+   return NULL;
-+  }
++/******** End of sqlite3session.h *********/
++/******** Begin file fts5.h *********/
++/*
++** 2014 May 31
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** Interfaces to extend FTS5. Using the interfaces defined in this file, 
++** FTS5 may be extended with:
++**
++**     * custom tokenizers, and
++**     * custom auxiliary functions.
++*/
 +
-+  if(pgno == 1) offset = FILE_HEADER_SZ; /* adjust starting pointers in data page for header offset on 
first page*/
 +
-+  CODEC_TRACE(("sqlite3Codec: switch mode=%d offset=%d\n",  mode, offset));
-+  switch(mode) {
-+    case 0: /* decrypt */
-+    case 2:
-+    case 3:
-+      if(pgno == 1) memcpy(buffer, SQLITE_FILE_HEADER, FILE_HEADER_SZ); /* copy file header to the first 16 
bytes of the page */ 
-+      rc = sqlcipher_page_cipher(ctx, CIPHER_READ_CTX, pgno, CIPHER_DECRYPT, page_sz - offset, pData + 
offset, (unsigned char*)buffer + offset);
-+      if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
-+      memcpy(pData, buffer, page_sz); /* copy buffer data back to pData and return */
-+      return pData;
-+      break;
-+    case 6: /* encrypt */
-+      if(pgno == 1) memcpy(buffer, kdf_salt, FILE_HEADER_SZ); /* copy salt to output buffer */ 
-+      rc = sqlcipher_page_cipher(ctx, CIPHER_WRITE_CTX, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + 
offset, (unsigned char*)buffer + offset);
-+      if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
-+      return buffer; /* return persistent buffer data, pData remains intact */
-+      break;
-+    case 7:
-+      if(pgno == 1) memcpy(buffer, kdf_salt, FILE_HEADER_SZ); /* copy salt to output buffer */ 
-+      rc = sqlcipher_page_cipher(ctx, CIPHER_READ_CTX, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + 
offset, (unsigned char*)buffer + offset);
-+      if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
-+      return buffer; /* return persistent buffer data, pData remains intact */
-+      break;
-+    default:
-+      return pData;
-+      break;
-+  }
-+}
++#ifndef _FTS5_H
++#define _FTS5_H
 +
-+SQLITE_PRIVATE void sqlite3FreeCodecArg(void *pCodecArg) {
-+  codec_ctx *ctx = (codec_ctx *) pCodecArg;
-+  if(pCodecArg == NULL) return;
-+  sqlcipher_codec_ctx_free(&ctx); // wipe and free allocated memory for the context 
-+  sqlcipher_deactivate(); /* cleanup related structures, OpenSSL etc, when codec is detatched */
-+}
 +
-+SQLITE_PRIVATE int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
-+  struct Db *pDb = &db->aDb[nDb];
++#ifdef __cplusplus
++extern "C" {
++#endif
 +
-+  CODEC_TRACE(("sqlite3CodecAttach: entered nDb=%d zKey=%s, nKey=%d\n", nDb, (char *)zKey, nKey));
++/*************************************************************************
++** CUSTOM AUXILIARY FUNCTIONS
++**
++** Virtual table implementations may overload SQL functions by implementing
++** the sqlite3_module.xFindFunction() method.
++*/
 +
++typedef struct Fts5ExtensionApi Fts5ExtensionApi;
++typedef struct Fts5Context Fts5Context;
++typedef struct Fts5PhraseIter Fts5PhraseIter;
 +
-+  if(nKey && zKey && pDb->pBt) {
-+    int rc;
-+    Pager *pPager = pDb->pBt->pBt->pPager;
-+    sqlite3_file *fd = sqlite3Pager_get_fd(pPager);
-+    codec_ctx *ctx;
++typedef void (*fts5_extension_function)(
++  const Fts5ExtensionApi *pApi,   /* API offered by current FTS version */
++  Fts5Context *pFts,              /* First arg to pass to pApi functions */
++  sqlite3_context *pCtx,          /* Context for returning result/error */
++  int nVal,                       /* Number of values in apVal[] array */
++  sqlite3_value **apVal           /* Array of trailing arguments */
++);
 +
-+    sqlcipher_activate(); /* perform internal initialization for sqlcipher */
++struct Fts5PhraseIter {
++  const unsigned char *a;
++  const unsigned char *b;
++};
 +
-+    sqlite3_mutex_enter(db->mutex);
++/*
++** EXTENSION API FUNCTIONS
++**
++** xUserData(pFts):
++**   Return a copy of the context pointer the extension function was 
++**   registered with.
++**
++** xColumnTotalSize(pFts, iCol, pnToken):
++**   If parameter iCol is less than zero, set output variable *pnToken
++**   to the total number of tokens in the FTS5 table. Or, if iCol is
++**   non-negative but less than the number of columns in the table, return
++**   the total number of tokens in column iCol, considering all rows in 
++**   the FTS5 table.
++**
++**   If parameter iCol is greater than or equal to the number of columns
++**   in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
++**   an OOM condition or IO error), an appropriate SQLite error code is 
++**   returned.
++**
++** xColumnCount(pFts):
++**   Return the number of columns in the table.
++**
++** xColumnSize(pFts, iCol, pnToken):
++**   If parameter iCol is less than zero, set output variable *pnToken
++**   to the total number of tokens in the current row. Or, if iCol is
++**   non-negative but less than the number of columns in the table, set
++**   *pnToken to the number of tokens in column iCol of the current row.
++**
++**   If parameter iCol is greater than or equal to the number of columns
++**   in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
++**   an OOM condition or IO error), an appropriate SQLite error code is 
++**   returned.
++**
++**   This function may be quite inefficient if used with an FTS5 table
++**   created with the "columnsize=0" option.
++**
++** xColumnText:
++**   This function attempts to retrieve the text of column iCol of the
++**   current document. If successful, (*pz) is set to point to a buffer
++**   containing the text in utf-8 encoding, (*pn) is set to the size in bytes
++**   (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
++**   if an error occurs, an SQLite error code is returned and the final values
++**   of (*pz) and (*pn) are undefined.
++**
++** xPhraseCount:
++**   Returns the number of phrases in the current query expression.
++**
++** xPhraseSize:
++**   Returns the number of tokens in phrase iPhrase of the query. Phrases
++**   are numbered starting from zero.
++**
++** xInstCount:
++**   Set *pnInst to the total number of occurrences of all phrases within
++**   the query within the current row. Return SQLITE_OK if successful, or
++**   an error code (i.e. SQLITE_NOMEM) if an error occurs.
++**
++**   This API can be quite slow if used with an FTS5 table created with the
++**   "detail=none" or "detail=column" option. If the FTS5 table is created 
++**   with either "detail=none" or "detail=column" and "content=" option 
++**   (i.e. if it is a contentless table), then this API always returns 0.
++**
++** xInst:
++**   Query for the details of phrase match iIdx within the current row.
++**   Phrase matches are numbered starting from zero, so the iIdx argument
++**   should be greater than or equal to zero and smaller than the value
++**   output by xInstCount().
++**
++**   Usually, output parameter *piPhrase is set to the phrase number, *piCol
++**   to the column in which it occurs and *piOff the token offset of the
++**   first token of the phrase. The exception is if the table was created
++**   with the offsets=0 option specified. In this case *piOff is always
++**   set to -1.
++**
++**   Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM) 
++**   if an error occurs.
++**
++**   This API can be quite slow if used with an FTS5 table created with the
++**   "detail=none" or "detail=column" option. 
++**
++** xRowid:
++**   Returns the rowid of the current row.
++**
++** xTokenize:
++**   Tokenize text using the tokenizer belonging to the FTS5 table.
++**
++** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
++**   This API function is used to query the FTS table for phrase iPhrase
++**   of the current query. Specifically, a query equivalent to:
++**
++**       ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
++**
++**   with $p set to a phrase equivalent to the phrase iPhrase of the
++**   current query is executed. Any column filter that applies to
++**   phrase iPhrase of the current query is included in $p. For each 
++**   row visited, the callback function passed as the fourth argument 
++**   is invoked. The context and API objects passed to the callback 
++**   function may be used to access the properties of each matched row.
++**   Invoking Api.xUserData() returns a copy of the pointer passed as 
++**   the third argument to pUserData.
++**
++**   If the callback function returns any value other than SQLITE_OK, the
++**   query is abandoned and the xQueryPhrase function returns immediately.
++**   If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
++**   Otherwise, the error code is propagated upwards.
++**
++**   If the query runs to completion without incident, SQLITE_OK is returned.
++**   Or, if some error occurs before the query completes or is aborted by
++**   the callback, an SQLite error code is returned.
++**
++**
++** xSetAuxdata(pFts5, pAux, xDelete)
++**
++**   Save the pointer passed as the second argument as the extension functions 
++**   "auxiliary data". The pointer may then be retrieved by the current or any
++**   future invocation of the same fts5 extension function made as part of
++**   of the same MATCH query using the xGetAuxdata() API.
++**
++**   Each extension function is allocated a single auxiliary data slot for
++**   each FTS query (MATCH expression). If the extension function is invoked 
++**   more than once for a single FTS query, then all invocations share a 
++**   single auxiliary data context.
++**
++**   If there is already an auxiliary data pointer when this function is
++**   invoked, then it is replaced by the new pointer. If an xDelete callback
++**   was specified along with the original pointer, it is invoked at this
++**   point.
++**
++**   The xDelete callback, if one is specified, is also invoked on the
++**   auxiliary data pointer after the FTS5 query has finished.
++**
++**   If an error (e.g. an OOM condition) occurs within this function, an
++**   the auxiliary data is set to NULL and an error code returned. If the
++**   xDelete parameter was not NULL, it is invoked on the auxiliary data
++**   pointer before returning.
++**
++**
++** xGetAuxdata(pFts5, bClear)
++**
++**   Returns the current auxiliary data pointer for the fts5 extension 
++**   function. See the xSetAuxdata() method for details.
++**
++**   If the bClear argument is non-zero, then the auxiliary data is cleared
++**   (set to NULL) before this function returns. In this case the xDelete,
++**   if any, is not invoked.
++**
++**
++** xRowCount(pFts5, pnRow)
++**
++**   This function is used to retrieve the total number of rows in the table.
++**   In other words, the same value that would be returned by:
++**
++**        SELECT count(*) FROM ftstable;
++**
++** xPhraseFirst()
++**   This function is used, along with type Fts5PhraseIter and the xPhraseNext
++**   method, to iterate through all instances of a single query phrase within
++**   the current row. This is the same information as is accessible via the
++**   xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
++**   to use, this API may be faster under some circumstances. To iterate 
++**   through instances of phrase iPhrase, use the following code:
++**
++**       Fts5PhraseIter iter;
++**       int iCol, iOff;
++**       for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
++**           iCol>=0;
++**           pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
++**       ){
++**         // An instance of phrase iPhrase at offset iOff of column iCol
++**       }
++**
++**   The Fts5PhraseIter structure is defined above. Applications should not
++**   modify this structure directly - it should only be used as shown above
++**   with the xPhraseFirst() and xPhraseNext() API methods (and by
++**   xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
++**
++**   This API can be quite slow if used with an FTS5 table created with the
++**   "detail=none" or "detail=column" option. If the FTS5 table is created 
++**   with either "detail=none" or "detail=column" and "content=" option 
++**   (i.e. if it is a contentless table), then this API always iterates
++**   through an empty set (all calls to xPhraseFirst() set iCol to -1).
++**
++** xPhraseNext()
++**   See xPhraseFirst above.
++**
++** xPhraseFirstColumn()
++**   This function and xPhraseNextColumn() are similar to the xPhraseFirst()
++**   and xPhraseNext() APIs described above. The difference is that instead
++**   of iterating through all instances of a phrase in the current row, these
++**   APIs are used to iterate through the set of columns in the current row
++**   that contain one or more instances of a specified phrase. For example:
++**
++**       Fts5PhraseIter iter;
++**       int iCol;
++**       for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
++**           iCol>=0;
++**           pApi->xPhraseNextColumn(pFts, &iter, &iCol)
++**       ){
++**         // Column iCol contains at least one instance of phrase iPhrase
++**       }
++**
++**   This API can be quite slow if used with an FTS5 table created with the
++**   "detail=none" option. If the FTS5 table is created with either 
++**   "detail=none" "content=" option (i.e. if it is a contentless table), 
++**   then this API always iterates through an empty set (all calls to 
++**   xPhraseFirstColumn() set iCol to -1).
++**
++**   The information accessed using this API and its companion
++**   xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
++**   (or xInst/xInstCount). The chief advantage of this API is that it is
++**   significantly more efficient than those alternatives when used with
++**   "detail=column" tables.  
++**
++** xPhraseNextColumn()
++**   See xPhraseFirstColumn above.
++*/
++struct Fts5ExtensionApi {
++  int iVersion;                   /* Currently always set to 3 */
 +
-+    /* point the internal codec argument against the contet to be prepared */
-+    rc = sqlcipher_codec_ctx_init(&ctx, pDb, pDb->pBt->pBt->pPager, fd, zKey, nKey); 
++  void *(*xUserData)(Fts5Context*);
 +
-+    if(rc != SQLITE_OK) return rc; /* initialization failed, do not attach potentially corrupted context */
++  int (*xColumnCount)(Fts5Context*);
++  int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
++  int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
 +
-+    sqlite3pager_sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, 
(void *) ctx);
++  int (*xTokenize)(Fts5Context*, 
++    const char *pText, int nText, /* Text to tokenize */
++    void *pCtx,                   /* Context passed to xToken() */
++    int (*xToken)(void*, int, const char*, int, int, int)       /* Callback */
++  );
 +
-+    codec_set_btree_to_codec_pagesize(db, pDb, ctx);
++  int (*xPhraseCount)(Fts5Context*);
++  int (*xPhraseSize)(Fts5Context*, int iPhrase);
 +
-+    /* force secure delete. This has the benefit of wiping internal data when deleted
-+       and also ensures that all pages are written to disk (i.e. not skipped by
-+       sqlite3PagerDontWrite optimizations) */ 
-+    sqlite3BtreeSecureDelete(pDb->pBt, 1); 
++  int (*xInstCount)(Fts5Context*, int *pnInst);
++  int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
 +
-+    /* if fd is null, then this is an in-memory database and
-+       we dont' want to overwrite the AutoVacuum settings
-+       if not null, then set to the default */
-+    if(fd != NULL) { 
-+      sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM);
-+    }
-+    sqlite3_mutex_leave(db->mutex);
-+  }
-+  return SQLITE_OK;
-+}
++  sqlite3_int64 (*xRowid)(Fts5Context*);
++  int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
++  int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
 +
-+SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(const char* in) {
-+  /* do nothing, security enhancements are always active */
-+}
++  int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
++    int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
++  );
++  int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
++  void *(*xGetAuxdata)(Fts5Context*, int bClear);
 +
-+static int sqlcipher_find_db_index(sqlite3 *db, const char *zDb) {
-+  int db_index;
-+  if(zDb == NULL){
-+    return 0;
-+  }
-+  for(db_index = 0; db_index < db->nDb; db_index++) {
-+    struct Db *pDb = &db->aDb[db_index];
-+    if(strcmp(pDb->zName, zDb) == 0) {
-+      return db_index;
-+    }
-   }
-   return 0;
- }
- 
--#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
-+SQLITE_API int SQLITE_STDCALL sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
-+  CODEC_TRACE(("sqlite3_key entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey));
-+  return sqlite3_key_v2(db, "main", pKey, nKey);
-+}
++  int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
++  void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
 +
-+SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
-+  CODEC_TRACE(("sqlite3_key_v2: entered db=%p zDb=%s pKey=%s nKey=%d\n", db, zDb, (char *)pKey, nKey));
-+  /* attach key if db and pKey are not null and nKey is > 0 */
-+  if(db && pKey && nKey) {
-+    int db_index = sqlcipher_find_db_index(db, zDb);
-+    return sqlite3CodecAttach(db, db_index, pKey, nKey); 
-+  }
-+  return SQLITE_ERROR;
-+}
++  int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
++  void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
++};
 +
-+SQLITE_API int SQLITE_STDCALL sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
-+  CODEC_TRACE(("sqlite3_rekey entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey));
-+  return sqlite3_rekey_v2(db, "main", pKey, nKey);
-+}
++/* 
++** CUSTOM AUXILIARY FUNCTIONS
++*************************************************************************/
 +
-+/* sqlite3_rekey_v2
-+** Given a database, this will reencrypt the database using a new key.
-+** There is only one possible modes of operation - to encrypt a database
-+** that is already encrpyted. If the database is not already encrypted
-+** this should do nothing
-+** The proposed logic for this function follows:
-+** 1. Determine if the database is already encryptped
-+** 2. If there is NOT already a key present do nothing
-+** 3. If there is a key present, re-encrypt the database with the new key
++/*************************************************************************
++** CUSTOM TOKENIZERS
++**
++** Applications may also register custom tokenizer types. A tokenizer 
++** is registered by providing fts5 with a populated instance of the 
++** following structure. All structure methods must be defined, setting
++** any member of the fts5_tokenizer struct to NULL leads to undefined
++** behaviour. The structure methods are expected to function as follows:
++**
++** xCreate:
++**   This function is used to allocate and initialize a tokenizer instance.
++**   A tokenizer instance is required to actually tokenize text.
++**
++**   The first argument passed to this function is a copy of the (void*)
++**   pointer provided by the application when the fts5_tokenizer object
++**   was registered with FTS5 (the third argument to xCreateTokenizer()). 
++**   The second and third arguments are an array of nul-terminated strings
++**   containing the tokenizer arguments, if any, specified following the
++**   tokenizer name as part of the CREATE VIRTUAL TABLE statement used
++**   to create the FTS5 table.
++**
++**   The final argument is an output variable. If successful, (*ppOut) 
++**   should be set to point to the new tokenizer handle and SQLITE_OK
++**   returned. If an error occurs, some value other than SQLITE_OK should
++**   be returned. In this case, fts5 assumes that the final value of *ppOut 
++**   is undefined.
++**
++** xDelete:
++**   This function is invoked to delete a tokenizer handle previously
++**   allocated using xCreate(). Fts5 guarantees that this function will
++**   be invoked exactly once for each successful call to xCreate().
++**
++** xTokenize:
++**   This function is expected to tokenize the nText byte string indicated 
++**   by argument pText. pText may or may not be nul-terminated. The first
++**   argument passed to this function is a pointer to an Fts5Tokenizer object
++**   returned by an earlier call to xCreate().
++**
++**   The second argument indicates the reason that FTS5 is requesting
++**   tokenization of the supplied text. This is always one of the following
++**   four values:
++**
++**   <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
++**            or removed from the FTS table. The tokenizer is being invoked to
++**            determine the set of tokens to add to (or delete from) the
++**            FTS index.
++**
++**       <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed 
++**            against the FTS index. The tokenizer is being called to tokenize 
++**            a bareword or quoted string specified as part of the query.
++**
++**       <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
++**            FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
++**            followed by a "*" character, indicating that the last token
++**            returned by the tokenizer will be treated as a token prefix.
++**
++**       <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to 
++**            satisfy an fts5_api.xTokenize() request made by an auxiliary
++**            function. Or an fts5_api.xColumnSize() request made by the same
++**            on a columnsize=0 database.  
++**   </ul>
++**
++**   For each token in the input string, the supplied callback xToken() must
++**   be invoked. The first argument to it should be a copy of the pointer
++**   passed as the second argument to xTokenize(). The third and fourth
++**   arguments are a pointer to a buffer containing the token text, and the
++**   size of the token in bytes. The 4th and 5th arguments are the byte offsets
++**   of the first byte of and first byte immediately following the text from
++**   which the token is derived within the input.
++**
++**   The second argument passed to the xToken() callback ("tflags") should
++**   normally be set to 0. The exception is if the tokenizer supports 
++**   synonyms. In this case see the discussion below for details.
++**
++**   FTS5 assumes the xToken() callback is invoked for each token in the 
++**   order that they occur within the input text.
++**
++**   If an xToken() callback returns any value other than SQLITE_OK, then
++**   the tokenization should be abandoned and the xTokenize() method should
++**   immediately return a copy of the xToken() return value. Or, if the
++**   input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
++**   if an error occurs with the xTokenize() implementation itself, it
++**   may abandon the tokenization and return any error code other than
++**   SQLITE_OK or SQLITE_DONE.
++**
++** SYNONYM SUPPORT
++**
++**   Custom tokenizers may also support synonyms. Consider a case in which a
++**   user wishes to query for a phrase such as "first place". Using the 
++**   built-in tokenizers, the FTS5 query 'first + place' will match instances
++**   of "first place" within the document set, but not alternative forms
++**   such as "1st place". In some applications, it would be better to match
++**   all instances of "first place" or "1st place" regardless of which form
++**   the user specified in the MATCH query text.
++**
++**   There are several ways to approach this in FTS5:
++**
++**   <ol><li> By mapping all synonyms to a single token. In this case, the 
++**            In the above example, this means that the tokenizer returns the
++**            same token for inputs "first" and "1st". Say that token is in
++**            fact "first", so that when the user inserts the document "I won
++**            1st place" entries are added to the index for tokens "i", "won",
++**            "first" and "place". If the user then queries for '1st + place',
++**            the tokenizer substitutes "first" for "1st" and the query works
++**            as expected.
++**
++**       <li> By adding multiple synonyms for a single term to the FTS index.
++**            In this case, when tokenizing query text, the tokenizer may 
++**            provide multiple synonyms for a single term within the document.
++**            FTS5 then queries the index for each synonym individually. For
++**            example, faced with the query:
++**
++**   <codeblock>
++**     ... MATCH 'first place'</codeblock>
++**
++**            the tokenizer offers both "1st" and "first" as synonyms for the
++**            first token in the MATCH query and FTS5 effectively runs a query 
++**            similar to:
++**
++**   <codeblock>
++**     ... MATCH '(first OR 1st) place'</codeblock>
++**
++**            except that, for the purposes of auxiliary functions, the query
++**            still appears to contain just two phrases - "(first OR 1st)" 
++**            being treated as a single phrase.
++**
++**       <li> By adding multiple synonyms for a single term to the FTS index.
++**            Using this method, when tokenizing document text, the tokenizer
++**            provides multiple synonyms for each token. So that when a 
++**            document such as "I won first place" is tokenized, entries are
++**            added to the FTS index for "i", "won", "first", "1st" and
++**            "place".
++**
++**            This way, even if the tokenizer does not provide synonyms
++**            when tokenizing query text (it should not - to do would be
++**            inefficient), it doesn't matter if the user queries for 
++**            'first + place' or '1st + place', as there are entires in the
++**            FTS index corresponding to both forms of the first token.
++**   </ol>
++**
++**   Whether it is parsing document or query text, any call to xToken that
++**   specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
++**   is considered to supply a synonym for the previous token. For example,
++**   when parsing the document "I won first place", a tokenizer that supports
++**   synonyms would call xToken() 5 times, as follows:
++**
++**   <codeblock>
++**       xToken(pCtx, 0, "i",                      1,  0,  1);
++**       xToken(pCtx, 0, "won",                    3,  2,  5);
++**       xToken(pCtx, 0, "first",                  5,  6, 11);
++**       xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3,  6, 11);
++**       xToken(pCtx, 0, "place",                  5, 12, 17);
++**</codeblock>
++**
++**   It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
++**   xToken() is called. Multiple synonyms may be specified for a single token
++**   by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence. 
++**   There is no limit to the number of synonyms that may be provided for a
++**   single token.
++**
++**   In many cases, method (1) above is the best approach. It does not add 
++**   extra data to the FTS index or require FTS5 to query for multiple terms,
++**   so it is efficient in terms of disk space and query speed. However, it
++**   does not support prefix queries very well. If, as suggested above, the
++**   token "first" is subsituted for "1st" by the tokenizer, then the query:
++**
++**   <codeblock>
++**     ... MATCH '1s*'</codeblock>
++**
++**   will not match documents that contain the token "1st" (as the tokenizer
++**   will probably not map "1s" to any prefix of "first").
++**
++**   For full prefix support, method (3) may be preferred. In this case, 
++**   because the index contains entries for both "first" and "1st", prefix
++**   queries such as 'fi*' or '1s*' will match correctly. However, because
++**   extra entries are added to the FTS index, this method uses more space
++**   within the database.
++**
++**   Method (2) offers a midpoint between (1) and (3). Using this method,
++**   a query such as '1s*' will match documents that contain the literal 
++**   token "1st", but not "first" (assuming the tokenizer is not able to
++**   provide synonyms for prefixes). However, a non-prefix query like '1st'
++**   will match against "1st" and "first". This method does not require
++**   extra disk space, as no extra entries are added to the FTS index. 
++**   On the other hand, it may require more CPU cycles to run MATCH queries,
++**   as separate queries of the FTS index are required for each synonym.
++**
++**   When using methods (2) or (3), it is important that the tokenizer only
++**   provide synonyms when tokenizing document text (method (2)) or query
++**   text (method (3)), not both. Doing so will not cause any errors, but is
++**   inefficient.
 +*/
-+SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
-+  CODEC_TRACE(("sqlite3_rekey_v2: entered db=%p zDb=%s pKey=%s, nKey=%d\n", db, zDb, (char *)pKey, nKey));
-+  if(db && pKey && nKey) {
-+    int db_index = sqlcipher_find_db_index(db, zDb);
-+    struct Db *pDb = &db->aDb[db_index];
-+    CODEC_TRACE(("sqlite3_rekey_v2: database pDb=%p db_index:%d\n", pDb, db_index));
-+    if(pDb->pBt) {
-+      codec_ctx *ctx;
-+      int rc, page_count;
-+      Pgno pgno;
-+      PgHdr *page;
-+      Pager *pPager = pDb->pBt->pBt->pPager;
++typedef struct Fts5Tokenizer Fts5Tokenizer;
++typedef struct fts5_tokenizer fts5_tokenizer;
++struct fts5_tokenizer {
++  int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
++  void (*xDelete)(Fts5Tokenizer*);
++  int (*xTokenize)(Fts5Tokenizer*, 
++      void *pCtx,
++      int flags,            /* Mask of FTS5_TOKENIZE_* flags */
++      const char *pText, int nText, 
++      int (*xToken)(
++        void *pCtx,         /* Copy of 2nd argument to xTokenize() */
++        int tflags,         /* Mask of FTS5_TOKEN_* flags */
++        const char *pToken, /* Pointer to buffer containing token */
++        int nToken,         /* Size of token in bytes */
++        int iStart,         /* Byte offset of token within input text */
++        int iEnd            /* Byte offset of end of token within input text */
++      )
++  );
++};
 +
-+      sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
-+     
-+      if(ctx == NULL) { 
-+        /* there was no codec attached to this database, so this should do nothing! */ 
-+        CODEC_TRACE(("sqlite3_rekey_v2: no codec attached to db, exiting\n"));
-+        return SQLITE_OK;
-+      }
++/* Flags that may be passed as the third argument to xTokenize() */
++#define FTS5_TOKENIZE_QUERY     0x0001
++#define FTS5_TOKENIZE_PREFIX    0x0002
++#define FTS5_TOKENIZE_DOCUMENT  0x0004
++#define FTS5_TOKENIZE_AUX       0x0008
 +
-+      sqlite3_mutex_enter(db->mutex);
++/* Flags that may be passed by the tokenizer implementation back to FTS5
++** as the third argument to the supplied xToken callback. */
++#define FTS5_TOKEN_COLOCATED    0x0001      /* Same position as prev. token */
 +
-+      codec_set_pass_key(db, db_index, pKey, nKey, CIPHER_WRITE_CTX);
-+    
-+      /* do stuff here to rewrite the database 
-+      ** 1. Create a transaction on the database
-+      ** 2. Iterate through each page, reading it and then writing it.
-+      ** 3. If that goes ok then commit and put ctx->rekey into ctx->key
-+      **    note: don't deallocate rekey since it may be used in a subsequent iteration 
-+      */
-+      rc = sqlite3BtreeBeginTrans(pDb->pBt, 1); /* begin write transaction */
-+      sqlite3PagerPagecount(pPager, &page_count);
-+      for(pgno = 1; rc == SQLITE_OK && pgno <= (unsigned int)page_count; pgno++) { /* pgno's start at 1 see 
pager.c:pagerAcquire */
-+        if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for 
reasoning) */
-+          rc = sqlite3PagerGet(pPager, pgno, &page);
-+          if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */
-+            rc = sqlite3PagerWrite(page);
-+            if(rc == SQLITE_OK) {
-+              sqlite3PagerUnref(page);
-+            } else {
-+             CODEC_TRACE(("sqlite3_rekey_v2: error %d occurred writing page %d\n", rc, pgno));  
-+            }
-+          } else {
-+             CODEC_TRACE(("sqlite3_rekey_v2: error %d occurred getting page %d\n", rc, pgno));  
-+          }
-+        } 
-+      }
++/*
++** END OF CUSTOM TOKENIZERS
++*************************************************************************/
 +
-+      /* if commit was successful commit and copy the rekey data to current key, else rollback to release 
locks */
-+      if(rc == SQLITE_OK) { 
-+        CODEC_TRACE(("sqlite3_rekey_v2: committing\n"));
-+        rc = sqlite3BtreeCommit(pDb->pBt); 
-+        sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX);
-+      } else {
-+        CODEC_TRACE(("sqlite3_rekey_v2: rollback\n"));
-+        sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK, 0);
-+      }
++/*************************************************************************
++** FTS5 EXTENSION REGISTRATION API
++*/
++typedef struct fts5_api fts5_api;
++struct fts5_api {
++  int iVersion;                   /* Currently always set to 2 */
++
++  /* Create a new tokenizer */
++  int (*xCreateTokenizer)(
++    fts5_api *pApi,
++    const char *zName,
++    void *pContext,
++    fts5_tokenizer *pTokenizer,
++    void (*xDestroy)(void*)
++  );
 +
-+      sqlite3_mutex_leave(db->mutex);
-+    }
-+    return SQLITE_OK;
-+  }
-+  return SQLITE_ERROR;
-+}
++  /* Find an existing tokenizer */
++  int (*xFindTokenizer)(
++    fts5_api *pApi,
++    const char *zName,
++    void **ppContext,
++    fts5_tokenizer *pTokenizer
++  );
 +
-+SQLITE_PRIVATE void sqlite3CodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) {
-+  struct Db *pDb = &db->aDb[nDb];
-+  CODEC_TRACE(("sqlite3CodecGetKey: entered db=%p, nDb=%d\n", db, nDb));
-+  if( pDb->pBt ) {
-+    codec_ctx *ctx;
-+    sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
-+    if(ctx) {
-+      if(sqlcipher_codec_get_store_pass(ctx) == 1) {
-+        sqlcipher_codec_get_pass(ctx, zKey, nKey);
-+      } else {
-+        sqlcipher_codec_get_keyspec(ctx, zKey, nKey);
-+      }
-+    } else {
-+      *zKey = NULL;
-+      *nKey = 0;
-+    }
-+  }
-+}
++  /* Create a new auxiliary function */
++  int (*xCreateFunction)(
++    fts5_api *pApi,
++    const char *zName,
++    void *pContext,
++    fts5_extension_function xFunction,
++    void (*xDestroy)(void*)
++  );
++};
 +
-+#ifndef OMIT_EXPORT
- 
--/************** End of ctime.c ***********************************************/
--/************** Begin file status.c ******************************************/
--/*
--** 2008 June 18
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
--**
--**    May you do good and not evil.
--**    May you find forgiveness for yourself and forgive others.
--**    May you share freely, never taking more than you give.
--**
--*************************************************************************
--**
--** This module implements the sqlite3_status() interface and related
--** functionality.
--*/
--/************** Include vdbeInt.h in the middle of status.c ******************/
--/************** Begin file vdbeInt.h *****************************************/
- /*
--** 2003 September 6
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
--**
--**    May you do good and not evil.
--**    May you find forgiveness for yourself and forgive others.
--**    May you share freely, never taking more than you give.
--**
--*************************************************************************
--** This is the header file for information that is private to the
--** VDBE.  This information used to all be at the top of the single
--** source code file "vdbe.c".  When that file became too big (over
--** 6000 lines long) it was split up into several smaller files and
--** this header information was factored out.
--*/
--#ifndef _VDBEINT_H_
--#define _VDBEINT_H_
-+ * Implementation of an "export" function that allows a caller
-+ * to duplicate the main database to an attached database. This is intended
-+ * as a conveneince for users who need to:
-+ * 
-+ *   1. migrate from an non-encrypted database to an encrypted database
-+ *   2. move from an encrypted database to a non-encrypted database
-+ *   3. convert beween the various flavors of encrypted databases.  
-+ *
-+ * This implementation is based heavily on the procedure and code used
-+ * in vacuum.c, but is exposed as a function that allows export to any
-+ * named attached database.
-+ */
- 
- /*
--** The maximum number of times that a statement will try to reparse
--** itself before giving up and returning SQLITE_SCHEMA.
-+** Finalize a prepared statement.  If there was an error, store the
-+** text of the error message in *pzErrMsg.  Return the result code.
-+** 
-+** Based on vacuumFinalize from vacuum.c
- */
--#ifndef SQLITE_MAX_SCHEMA_RETRY
--# define SQLITE_MAX_SCHEMA_RETRY 50
--#endif
-+static int sqlcipher_finalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
-+  int rc;
-+  rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
-+  if( rc ){
-+    sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
-+  }
-+  return rc;
-+}
- 
- /*
--** SQL is translated into a sequence of instructions to be
--** executed by a virtual machine.  Each instruction is an instance
--** of the following structure.
-+** Execute zSql on database db. Return an error code.
-+** 
-+** Based on execSql from vacuum.c
- */
--typedef struct VdbeOp Op;
-+static int sqlcipher_execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
-+  sqlite3_stmt *pStmt;
-+  VVA_ONLY( int rc; )
-+  if( !zSql ){
-+    return SQLITE_NOMEM;
-+  }
-+  if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
-+    sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
-+    return sqlite3_errcode(db);
-+  }
-+  VVA_ONLY( rc = ) sqlite3_step(pStmt);
-+  assert( rc!=SQLITE_ROW );
-+  return sqlcipher_finalize(db, pStmt, pzErrMsg);
-+}
- 
- /*
--** Boolean values
-+** Execute zSql on database db. The statement returns exactly
-+** one column. Execute this as SQL on the same database.
-+** 
-+** Based on execExecSql from vacuum.c
- */
--typedef unsigned Bool;
--
--/* Opaque type used by code in vdbesort.c */
--typedef struct VdbeSorter VdbeSorter;
-+static int sqlcipher_execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
-+  sqlite3_stmt *pStmt;
-+  int rc;
- 
--/* Opaque type used by the explainer */
--typedef struct Explain Explain;
-+  rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
-+  if( rc!=SQLITE_OK ) return rc;
- 
--/* Elements of the linked list at Vdbe.pAuxData */
--typedef struct AuxData AuxData;
-+  while( SQLITE_ROW==sqlite3_step(pStmt) ){
-+    rc = sqlcipher_execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
-+    if( rc!=SQLITE_OK ){
-+      sqlcipher_finalize(db, pStmt, pzErrMsg);
-+      return rc;
-+    }
-+  }
-+
-+  return sqlcipher_finalize(db, pStmt, pzErrMsg);
-+}
- 
- /*
--** A cursor is a pointer into a single BTree within a database file.
--** The cursor can seek to a BTree entry with a particular key, or
--** loop over all entries of the Btree.  You can also insert new BTree
--** entries or retrieve the key or data from the entry that the cursor
--** is currently pointing to.
--**
--** Cursors can also point to virtual tables, sorters, or "pseudo-tables".
--** A pseudo-table is a single-row table implemented by registers.
--** 
--** Every cursor that the virtual machine has open is represented by an
--** instance of the following structure.
-+ * copy database and schema from the main database to an attached database
-+ * 
-+ * Based on sqlite3RunVacuum from vacuum.c
- */
--struct VdbeCursor {
--  BtCursor *pCursor;    /* The cursor structure of the backend */
--  Btree *pBt;           /* Separate file holding temporary table */
--  KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
--  int seekResult;       /* Result of previous sqlite3BtreeMoveto() */
--  int pseudoTableReg;   /* Register holding pseudotable content. */
--  i16 nField;           /* Number of fields in the header */
--  u16 nHdrParsed;       /* Number of header fields parsed so far */
--#ifdef SQLITE_DEBUG
--  u8 seekOp;            /* Most recent seek operation on this cursor */
-+void sqlcipher_exportFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
-+  sqlite3 *db = sqlite3_context_db_handle(context);
-+  const char* attachedDb = (const char*) sqlite3_value_text(argv[0]);
-+  int saved_flags;        /* Saved value of the db->flags */
-+  int saved_nChange;      /* Saved value of db->nChange */
-+  int saved_nTotalChange; /* Saved value of db->nTotalChange */
-+  void (*saved_xTrace)(void*,const char*);  /* Saved db->xTrace */
-+  int rc = SQLITE_OK;     /* Return code from service routines */
-+  char *zSql = NULL;         /* SQL statements */
-+  char *pzErrMsg = NULL;
-+  
-+  saved_flags = db->flags;
-+  saved_nChange = db->nChange;
-+  saved_nTotalChange = db->nTotalChange;
-+  saved_xTrace = db->xTrace;
-+  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
-+  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
-+  db->xTrace = 0;
-+
-+  /* Query the schema of the main database. Create a mirror schema
-+  ** in the temporary database.
-+  */
-+  zSql = sqlite3_mprintf(
-+    "SELECT 'CREATE TABLE %s.' || substr(sql,14) "
-+    "  FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
-+    "   AND rootpage>0"
-+  , attachedDb);
-+  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); 
-+  if( rc!=SQLITE_OK ) goto end_of_export;
-+  sqlite3_free(zSql);
-+
-+  zSql = sqlite3_mprintf(
-+    "SELECT 'CREATE INDEX %s.' || substr(sql,14)"
-+    "  FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %%' "
-+  , attachedDb);
-+  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); 
-+  if( rc!=SQLITE_OK ) goto end_of_export;
-+  sqlite3_free(zSql);
-+
-+  zSql = sqlite3_mprintf(
-+    "SELECT 'CREATE UNIQUE INDEX %s.' || substr(sql,21) "
-+    "  FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %%'"
-+  , attachedDb);
-+  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); 
-+  if( rc!=SQLITE_OK ) goto end_of_export;
-+  sqlite3_free(zSql);
-+
-+  /* Loop through the tables in the main database. For each, do
-+  ** an "INSERT INTO rekey_db.xxx SELECT * FROM main.xxx;" to copy
-+  ** the contents to the temporary database.
-+  */
-+  zSql = sqlite3_mprintf(
-+    "SELECT 'INSERT INTO %s.' || quote(name) "
-+    "|| ' SELECT * FROM main.' || quote(name) || ';'"
-+    "FROM main.sqlite_master "
-+    "WHERE type = 'table' AND name!='sqlite_sequence' "
-+    "  AND rootpage>0"
-+  , attachedDb);
-+  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); 
-+  if( rc!=SQLITE_OK ) goto end_of_export;
-+  sqlite3_free(zSql);
++/*
++** END OF REGISTRATION API
++*************************************************************************/
 +
-+  /* Copy over the sequence table
-+  */
-+  zSql = sqlite3_mprintf(
-+    "SELECT 'DELETE FROM %s.' || quote(name) || ';' "
-+    "FROM %s.sqlite_master WHERE name='sqlite_sequence' "
-+  , attachedDb, attachedDb);
-+  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); 
-+  if( rc!=SQLITE_OK ) goto end_of_export;
-+  sqlite3_free(zSql);
++#ifdef __cplusplus
++}  /* end of the 'extern "C"' block */
++#endif
 +
-+  zSql = sqlite3_mprintf(
-+    "SELECT 'INSERT INTO %s.' || quote(name) "
-+    "|| ' SELECT * FROM main.' || quote(name) || ';' "
-+    "FROM %s.sqlite_master WHERE name=='sqlite_sequence';"
-+  , attachedDb, attachedDb);
-+  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); 
-+  if( rc!=SQLITE_OK ) goto end_of_export;
-+  sqlite3_free(zSql);
++#endif /* _FTS5_H */
++
++/******** End of fts5.h *********/
+--- sqlite3.c.sqlite   2018-03-07 17:32:12.658688849 -0600
++++ sqlite3.c  2018-03-06 14:53:42.303057341 -0600
+@@ -1,6 +1,6 @@
+ /******************************************************************************
+ ** This file is an amalgamation of many separate C source files from SQLite
+-** version 3.8.10.2.  By combining all the individual C code files into this 
++** version 3.20.1.  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
+@@ -9,7 +9,7 @@
+ **
+ ** This file is all you need to compile SQLite.  To use SQLite in other
+ ** programs, you need this file and the "sqlite3.h" header file that defines
+-** the programming interface to the SQLite library.  (If you do not have 
++** the programming interface to the SQLite library.  (If you do not have
+ ** the "sqlite3.h" header file at hand, you will find a copy embedded within
+ ** the text of this file.  Search for "Begin file sqlite3.h" to find the start
+ ** of the embedded sqlite3.h header file.) Additional code files may be needed
+@@ -22,6 +22,758 @@
+ #ifndef SQLITE_PRIVATE
+ # define SQLITE_PRIVATE static
+ #endif
++/************** Begin file ctime.c *******************************************/
++/*
++** 2010 February 23
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++**
++** This file implements routines used to report what compile-time options
++** SQLite was built with.
++*/
 +
-+  /* Copy the triggers, views, and virtual tables from the main database
-+  ** over to the temporary database.  None of these objects has any
-+  ** associated storage, so all we have to do is copy their entries
-+  ** from the SQLITE_MASTER table.
-+  */
-+  zSql = sqlite3_mprintf(
-+    "INSERT INTO %s.sqlite_master "
-+    "  SELECT type, name, tbl_name, rootpage, sql"
-+    "    FROM main.sqlite_master"
-+    "   WHERE type='view' OR type='trigger'"
-+    "      OR (type='table' AND rootpage=0)"
-+  , attachedDb);
-+  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execSql(db, &pzErrMsg, zSql); 
-+  if( rc!=SQLITE_OK ) goto end_of_export;
-+  sqlite3_free(zSql);
++#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
 +
-+  zSql = NULL;
-+end_of_export:
-+  db->flags = saved_flags;
-+  db->nChange = saved_nChange;
-+  db->nTotalChange = saved_nTotalChange;
-+  db->xTrace = saved_xTrace;
++/*
++** Include the configuration header output by 'configure' if we're using the
++** autoconf-based build
++*/
++#if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H)
++#include "config.h"
++#define SQLITECONFIG_H 1
++#endif
 +
-+  sqlite3_free(zSql);
++/* These macros are provided to "stringify" the value of the define
++** for those options in which the value is meaningful. */
++#define CTIMEOPT_VAL_(opt) #opt
++#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
 +
-+  if(rc) {
-+    if(pzErrMsg != NULL) {
-+      sqlite3_result_error(context, pzErrMsg, -1);
-+      sqlite3DbFree(db, pzErrMsg);
-+    } else {
-+      sqlite3_result_error(context, sqlite3ErrStr(rc), -1);
-+    }
-+  }
-+}
++/*
++** An array of names of all compile-time options.  This array should 
++** be sorted A-Z.
++**
++** This array looks large, but in a typical installation actually uses
++** only a handful of compile-time options, so most times this array is usually
++** rather short and uses little memory space.
++*/
++static const char * const sqlite3azCompileOpt[] = {
 +
- #endif
--  i8 iDb;               /* Index of cursor database in db->aDb[] (or -1) */
--  u8 nullRow;           /* True if pointing to a row with no data */
--  u8 deferredMoveto;    /* A call to sqlite3BtreeMoveto() is needed */
--  Bool isEphemeral:1;   /* True for an ephemeral table */
--  Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
--  Bool isTable:1;       /* True if a table requiring integer keys */
--  Bool isOrdered:1;     /* True if the underlying table is BTREE_UNORDERED */
--  Pgno pgnoRoot;        /* Root page of the open btree cursor */
--  sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
--  i64 seqCount;         /* Sequence counter */
--  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
--  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
- 
--  /* Cached information about the header for the data record that the
--  ** cursor is currently pointing to.  Only valid if cacheStatus matches
--  ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
--  ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
--  ** the cache is out of date.
--  **
--  ** aRow might point to (ephemeral) data for the current row, or it might
--  ** be NULL.
--  */
--  u32 cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
--  u32 payloadSize;      /* Total number of bytes in the record */
--  u32 szRow;            /* Byte available in aRow */
--  u32 iHdrOffset;       /* Offset to next unparsed byte of the header */
--  const u8 *aRow;       /* Data for the current row, if all on one page */
--  u32 *aOffset;         /* Pointer to aType[nField] */
--  u32 aType[1];         /* Type values for all entries in the record */
--  /* 2*nField extra array elements allocated for aType[], beyond the one
--  ** static element declared in the structure.  nField total array slots for
--  ** aType[] and nField+1 array slots for aOffset[] */
--};
--typedef struct VdbeCursor VdbeCursor;
-+/* END SQLCIPHER */
-+#endif
- 
--/*
--** When a sub-program is executed (OP_Program), a structure of this type
--** is allocated to store the current value of the program counter, as
--** well as the current memory cell array and various other frame specific
--** values stored in the Vdbe struct. When the sub-program is finished, 
--** these values are copied back to the Vdbe from the VdbeFrame structure,
--** restoring the state of the VM to as it was before the sub-program
--** began executing.
--**
--** The memory for a VdbeFrame object is allocated and managed by a memory
--** cell in the parent (calling) frame. When the memory cell is deleted or
--** overwritten, the VdbeFrame object is not freed immediately. Instead, it
--** is linked into the Vdbe.pDelFrame list. The contents of the Vdbe.pDelFrame
--** list is deleted when the VM is reset in VdbeHalt(). The reason for doing
--** this instead of deleting the VdbeFrame immediately is to avoid recursive
--** calls to sqlite3VdbeMemRelease() when the memory cells belonging to the
--** child frame are released.
--**
--** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is
--** set to NULL if the currently executing frame is the main program.
-+/************** End of crypto.c **********************************************/
-+/************** Begin file crypto_impl.c *************************************/
-+/* 
-+** SQLCipher
-+** http://sqlcipher.net
-+** 
-+** Copyright (c) 2008 - 2013, ZETETIC LLC
-+** All rights reserved.
-+** 
-+** Redistribution and use in source and binary forms, with or without
-+** modification, are permitted provided that the following conditions are met:
-+**     * Redistributions of source code must retain the above copyright
-+**       notice, this list of conditions and the following disclaimer.
-+**     * Redistributions in binary form must reproduce the above copyright
-+**       notice, this list of conditions and the following disclaimer in the
-+**       documentation and/or other materials provided with the distribution.
-+**     * Neither the name of the ZETETIC LLC nor the
-+**       names of its contributors may be used to endorse or promote products
-+**       derived from this software without specific prior written permission.
-+** 
-+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
-+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
-+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+**  
- */
--typedef struct VdbeFrame VdbeFrame;
--struct VdbeFrame {
--  Vdbe *v;                /* VM this frame belongs to */
--  VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
--  Op *aOp;                /* Program instructions for parent frame */
--  i64 *anExec;            /* Event counters from parent frame */
--  Mem *aMem;              /* Array of memory cells for parent frame */
--  u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
--  VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
--  void *token;            /* Copy of SubProgram.token */
--  i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
--  int nCursor;            /* Number of entries in apCsr */
--  int pc;                 /* Program Counter in parent (calling) frame */
--  int nOp;                /* Size of aOp array */
--  int nMem;               /* Number of entries in aMem */
--  int nOnceFlag;          /* Number of entries in aOnceFlag */
--  int nChildMem;          /* Number of memory cells for child frame */
--  int nChildCsr;          /* Number of cursors for child frame */
--  int nChange;            /* Statement changes (Vdbe.nChange)     */
--  int nDbChange;          /* Value of db->nChange */
--};
--
--#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
-+/* BEGIN SQLCIPHER */
-+#ifdef SQLITE_HAS_CODEC
- 
--/*
--** A value for VdbeCursor.cacheValid that means the cache is always invalid.
-+/************** Include sqlcipher.h in the middle of crypto_impl.c ***********/
-+/************** Begin file sqlcipher.h ***************************************/
 +/* 
-+** SQLCipher
-+** sqlcipher.h developed by Stephen Lombardo (Zetetic LLC) 
-+** sjlombardo at zetetic dot net
-+** http://zetetic.net
-+** 
-+** Copyright (c) 2008, ZETETIC LLC
-+** All rights reserved.
-+** 
-+** Redistribution and use in source and binary forms, with or without
-+** modification, are permitted provided that the following conditions are met:
-+**     * Redistributions of source code must retain the above copyright
-+**       notice, this list of conditions and the following disclaimer.
-+**     * Redistributions in binary form must reproduce the above copyright
-+**       notice, this list of conditions and the following disclaimer in the
-+**       documentation and/or other materials provided with the distribution.
-+**     * Neither the name of the ZETETIC LLC nor the
-+**       names of its contributors may be used to endorse or promote products
-+**       derived from this software without specific prior written permission.
-+** 
-+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
-+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
-+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+**  
- */
--#define CACHE_STALE 0
-+/* BEGIN SQLCIPHER */
-+#ifdef SQLITE_HAS_CODEC
-+#ifndef SQLCIPHER_H
-+#define SQLCIPHER_H
- 
--/*
--** Internally, the vdbe manipulates nearly all SQL values as Mem
--** structures. Each Mem struct may cache multiple representations (string,
--** integer etc.) of the same value.
--*/
--struct Mem {
--  union MemValue {
--    double r;           /* Real value used when MEM_Real is set in flags */
--    i64 i;              /* Integer value used when MEM_Int is set in flags */
--    int nZero;          /* Used when bit MEM_Zero is set in flags */
--    FuncDef *pDef;      /* Used only when flags==MEM_Agg */
--    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
--    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
--  } u;
--  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
--  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
--  int n;              /* Number of characters in string value, excluding '\0' */
--  char *z;            /* String or BLOB value */
--  /* ShallowCopy only needs to copy the information above */
--  char *zMalloc;      /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
--  int szMalloc;       /* Size of the zMalloc allocation */
--  u32 uTemp;          /* Transient storage for serial_type in OP_MakeRecord */
--  sqlite3 *db;        /* The associated database connection */
--  void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
--#ifdef SQLITE_DEBUG
--  Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
--  void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
--#endif
-+
-+typedef struct {
-+  int (*activate)(void *ctx);
-+  int (*deactivate)(void *ctx);
-+  const char* (*get_provider_name)(void *ctx);
-+  int (*add_random)(void *ctx, void *buffer, int length);
-+  int (*random)(void *ctx, void *buffer, int length);
-+  int (*hmac)(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char 
*in2, int in2_sz, unsigned char *out);
-+  int (*kdf)(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int 
workfactor, int key_sz, unsigned char *key);
-+  int (*cipher)(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, 
int in_sz, unsigned char *out);
-+  int (*set_cipher)(void *ctx, const char *cipher_name);
-+  const char* (*get_cipher)(void *ctx);
-+  int (*get_key_sz)(void *ctx);
-+  int (*get_iv_sz)(void *ctx);
-+  int (*get_block_sz)(void *ctx);
-+  int (*get_hmac_sz)(void *ctx);
-+  int (*ctx_copy)(void *target_ctx, void *source_ctx);
-+  int (*ctx_cmp)(void *c1, void *c2);
-+  int (*ctx_init)(void **ctx);
-+  int (*ctx_free)(void **ctx);
-+  int (*fips_status)(void *ctx);
-+} sqlcipher_provider;
-+
-+/* utility functions */
-+void sqlcipher_free(void *ptr, int sz);
-+void* sqlcipher_malloc(int sz);
-+void* sqlcipher_memset(void *v, unsigned char value, int len);
-+int sqlcipher_ismemset(const void *v, unsigned char value, int len);
-+int sqlcipher_memcmp(const void *v0, const void *v1, int len);
-+void sqlcipher_free(void *, int);
-+
-+/* provider interfaces */
-+int sqlcipher_register_provider(sqlcipher_provider *p);
-+sqlcipher_provider* sqlcipher_get_provider();
-+
++** BEGIN CODE GENERATED BY tool/mkctime.tcl 
++*/
++#if SQLITE_32BIT_ROWID
++  "32BIT_ROWID",
 +#endif
++#if SQLITE_4_BYTE_ALIGNED_MALLOC
++  "4_BYTE_ALIGNED_MALLOC",
 +#endif
-+/* END SQLCIPHER */
-+
-+
-+/************** End of sqlcipher.h *******************************************/
-+/************** Continuing where we left off in crypto_impl.c ****************/
-+#ifndef OMIT_MEMLOCK
-+#if defined(__unix__) || defined(__APPLE__) || defined(_AIX)
-+#include <sys/mman.h>
-+#elif defined(_WIN32)
-+# include <windows.h>
++#if SQLITE_64BIT_STATS
++  "64BIT_STATS",
 +#endif
++#if SQLITE_ALLOW_COVERING_INDEX_SCAN
++  "ALLOW_COVERING_INDEX_SCAN",
 +#endif
-+
-+/* the default implementation of SQLCipher uses a cipher_ctx
-+   to keep track of read / write state separately. The following
-+   struct and associated functions are defined here */
-+typedef struct {
-+  int store_pass;
-+  int derive_key;
-+  int kdf_iter;
-+  int fast_kdf_iter;
-+  int key_sz;
-+  int iv_sz;
-+  int block_sz;
-+  int pass_sz;
-+  int reserve_sz;
-+  int hmac_sz;
-+  int keyspec_sz;
-+  unsigned int flags;
-+  unsigned char *key;
-+  unsigned char *hmac_key;
-+  unsigned char *pass;
-+  char *keyspec;
-+  sqlcipher_provider *provider;
-+  void *provider_ctx;
-+} cipher_ctx;
-+
-+static unsigned int default_flags = DEFAULT_CIPHER_FLAGS;
-+static unsigned char hmac_salt_mask = HMAC_SALT_MASK;
-+static int default_kdf_iter = PBKDF2_ITER;
-+static int default_page_size = SQLITE_DEFAULT_PAGE_SIZE;
-+static unsigned int sqlcipher_activate_count = 0;
-+static sqlite3_mutex* sqlcipher_provider_mutex = NULL;
-+static sqlcipher_provider *default_provider = NULL;
-+
-+struct codec_ctx {
-+  int kdf_salt_sz;
-+  int page_sz;
-+  unsigned char *kdf_salt;
-+  unsigned char *hmac_kdf_salt;
-+  unsigned char *buffer;
-+  Btree *pBt;
-+  cipher_ctx *read_ctx;
-+  cipher_ctx *write_ctx;
-+  unsigned int skip_read_hmac;
-+  unsigned int need_kdf_salt;
- };
- 
--/* One or more of the following flags are set to indicate the validOK
--** representations of the value stored in the Mem struct.
--**
--** If the MEM_Null flag is set, then the value is an SQL NULL value.
--** No other flags may be set in this case.
--**
--** If the MEM_Str flag is set then Mem.z points at a string representation.
--** Usually this is encoded in the same unicode encoding as the main
--** database (see below for exceptions). If the MEM_Term flag is also
--** set, then the string is nul terminated. The MEM_Int and MEM_Real 
--** flags may coexist with the MEM_Str flag.
--*/
--#define MEM_Null      0x0001   /* Value is NULL */
--#define MEM_Str       0x0002   /* Value is a string */
--#define MEM_Int       0x0004   /* Value is an integer */
--#define MEM_Real      0x0008   /* Value is a real number */
--#define MEM_Blob      0x0010   /* Value is a BLOB */
--#define MEM_AffMask   0x001f   /* Mask of affinity bits */
--#define MEM_RowSet    0x0020   /* Value is a RowSet object */
--#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
--#define MEM_Undefined 0x0080   /* Value is undefined */
--#define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
--#define MEM_TypeMask  0x01ff   /* Mask of type bits */
-+int sqlcipher_register_provider(sqlcipher_provider *p) {
-+  sqlite3_mutex_enter(sqlcipher_provider_mutex);
-+  if(default_provider != NULL && default_provider != p) {
-+    /* only free the current registerd provider if it has been initialized
-+       and it isn't a pointer to the same provider passed to the function
-+       (i.e. protect against a caller calling register twice for the same provider) */
-+    sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
-+  }
-+  default_provider = p;   
-+  sqlite3_mutex_leave(sqlcipher_provider_mutex);
-+  return SQLITE_OK;
-+}
- 
-+/* return a pointer to the currently registered provider. This will
-+   allow an application to fetch the current registered provider and
-+   make minor changes to it */
-+sqlcipher_provider* sqlcipher_get_provider() {
-+  return default_provider;
-+}
- 
--/* Whenever Mem contains a valid string or blob representation, one of
--** the following flags must be set to determine the memory management
--** policy for Mem.z.  The MEM_Term flag tells us whether or not the
--** string is \000 or \u0000 terminated
--*/
--#define MEM_Term      0x0200   /* String rep is nul terminated */
--#define MEM_Dyn       0x0400   /* Need to call Mem.xDel() on Mem.z */
--#define MEM_Static    0x0800   /* Mem.z points to a static string */
--#define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
--#define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
--#define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
--#ifdef SQLITE_OMIT_INCRBLOB
--  #undef MEM_Zero
--  #define MEM_Zero 0x0000
--#endif
-+void sqlcipher_activate() {
-+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
- 
--/*
--** Clear any existing type flags from a Mem and replace them with f
--*/
--#define MemSetTypeFlag(p, f) \
--   ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
-+  if(sqlcipher_provider_mutex == NULL) {
-+    /* allocate a new mutex to guard access to the provider */
-+    sqlcipher_provider_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
-+  }
- 
--/*
--** Return true if a memory cell is not marked as invalid.  This macro
--** is for use inside assert() statements only.
--*/
--#ifdef SQLITE_DEBUG
--#define memIsValid(M)  ((M)->flags & MEM_Undefined)==0
-+  /* check to see if there is a provider registered at this point
-+     if there no provider registered at this point, register the 
-+     default provider */
-+  if(sqlcipher_get_provider() == NULL) {
-+    sqlcipher_provider *p = sqlcipher_malloc(sizeof(sqlcipher_provider)); 
-+#if defined (SQLCIPHER_CRYPTO_CC)
-+    extern int sqlcipher_cc_setup(sqlcipher_provider *p);
-+    sqlcipher_cc_setup(p);
-+#elif defined (SQLCIPHER_CRYPTO_LIBTOMCRYPT)
-+    extern int sqlcipher_ltc_setup(sqlcipher_provider *p);
-+    sqlcipher_ltc_setup(p);
-+#elif defined (SQLCIPHER_CRYPTO_OPENSSL)
-+    extern int sqlcipher_openssl_setup(sqlcipher_provider *p);
-+    sqlcipher_openssl_setup(p);
-+#else
-+#error "NO DEFAULT SQLCIPHER CRYPTO PROVIDER DEFINED"
- #endif
-+    sqlcipher_register_provider(p);
-+  }
- 
--/*
--** Each auxiliary data pointer stored by a user defined function 
--** implementation calling sqlite3_set_auxdata() is stored in an instance
--** of this structure. All such structures associated with a single VM
--** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
--** when the VM is halted (if not before).
--*/
--struct AuxData {
--  int iOp;                        /* Instruction number of OP_Function opcode */
--  int iArg;                       /* Index of function argument. */
--  void *pAux;                     /* Aux data pointer */
--  void (*xDelete)(void *);        /* Destructor for the aux data */
--  AuxData *pNext;                 /* Next element in list */
--};
-+  sqlcipher_activate_count++; /* increment activation count */
- 
--/*
--** The "context" argument for an installable function.  A pointer to an
--** instance of this structure is the first argument to the routines used
--** implement the SQL functions.
--**
--** There is a typedef for this structure in sqlite.h.  So all routines,
--** even the public interface to SQLite, can use a pointer to this structure.
--** But this file is the only place where the internal details of this
--** structure are known.
--**
--** This structure is defined inside of vdbeInt.h because it uses substructures
--** (Mem) which are only defined there.
--*/
--struct sqlite3_context {
--  Mem *pOut;            /* The return value is stored here */
--  FuncDef *pFunc;       /* Pointer to function information */
--  Mem *pMem;            /* Memory cell used to store aggregate context */
--  Vdbe *pVdbe;          /* The VM that owns this context */
--  int iOp;              /* Instruction number of OP_Function */
--  int isError;          /* Error code returned by the function. */
--  u8 skipFlag;          /* Skip accumulator loading if true */
--  u8 fErrorOrAux;       /* isError!=0 or pVdbe->pAuxData modified */
--};
-+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
-+}
- 
--/*
--** An Explain object accumulates indented output which is helpful
--** in describing recursive data structures.
--*/
--struct Explain {
--  Vdbe *pVdbe;       /* Attach the explanation to this Vdbe */
--  StrAccum str;      /* The string being accumulated */
--  int nIndent;       /* Number of elements in aIndent */
--  u16 aIndent[100];  /* Levels of indentation */
--  char zBase[100];   /* Initial space */
--};
-+void sqlcipher_deactivate() {
-+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
-+  sqlcipher_activate_count--;
-+  /* if no connections are using sqlcipher, cleanup globals */
-+  if(sqlcipher_activate_count < 1) {
-+    sqlite3_mutex_enter(sqlcipher_provider_mutex);
-+    if(default_provider != NULL) {
-+      sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
-+      default_provider = NULL;
-+    }
-+    sqlite3_mutex_leave(sqlcipher_provider_mutex);
-+    
-+    /* last connection closed, free provider mutex*/
-+    sqlite3_mutex_free(sqlcipher_provider_mutex); 
-+    sqlcipher_provider_mutex = NULL;
- 
--/* A bitfield type for use inside of structures.  Always follow with :N where
--** N is the number of bits.
-+    sqlcipher_activate_count = 0; /* reset activation count */
-+  }
-+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
-+}
-+
-+/* constant time memset using volitile to avoid having the memset
-+   optimized out by the compiler. 
-+   Note: As suggested by Joachim Schipper (joachim schipper fox-it com)
- */
--typedef unsigned bft;  /* Bit Field Type */
-+void* sqlcipher_memset(void *v, unsigned char value, int len) {
-+  int i = 0;
-+  volatile unsigned char *a = v;
- 
--typedef struct ScanStatus ScanStatus;
--struct ScanStatus {
--  int addrExplain;                /* OP_Explain for loop */
--  int addrLoop;                   /* Address of "loops" counter */
--  int addrVisit;                  /* Address of "rows visited" counter */
--  int iSelectID;                  /* The "Select-ID" for this loop */
--  LogEst nEst;                    /* Estimated output rows per loop */
--  char *zName;                    /* Name of table or index */
--};
-+  if (v == NULL) return v;
- 
--/*
--** An instance of the virtual machine.  This structure contains the complete
--** state of the virtual machine.
--**
--** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
--** is really a pointer to an instance of this structure.
--*/
--struct Vdbe {
--  sqlite3 *db;            /* The database connection that owns this statement */
--  Op *aOp;                /* Space to hold the virtual machine's program */
--  Mem *aMem;              /* The memory locations */
--  Mem **apArg;            /* Arguments to currently executing user function */
--  Mem *aColName;          /* Column names to return */
--  Mem *pResultSet;        /* Pointer to an array of results */
--  Parse *pParse;          /* Parsing context used to create this Vdbe */
--  int nMem;               /* Number of memory locations currently allocated */
--  int nOp;                /* Number of instructions in the program */
--  int nCursor;            /* Number of slots in apCsr[] */
--  u32 magic;              /* Magic number for sanity checking */
--  char *zErrMsg;          /* Error message written here */
--  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
--  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
--  Mem *aVar;              /* Values for the OP_Variable opcode. */
--  char **azVar;           /* Name of variables */
--  ynVar nVar;             /* Number of entries in aVar[] */
--  ynVar nzVar;            /* Number of entries in azVar[] */
--  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
--  int pc;                 /* The program counter */
--  int rc;                 /* Value to return */
--#ifdef SQLITE_DEBUG
--  int rcApp;              /* errcode set by sqlite3_result_error_code() */
--#endif
--  u16 nResColumn;         /* Number of columns in one row of the result set */
--  u8 errorAction;         /* Recovery action to do in case of an error */
--  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
--  bft explain:2;          /* True if EXPLAIN present on SQL command */
--  bft changeCntOn:1;      /* True to update the change-counter */
--  bft expired:1;          /* True if the VM needs to be recompiled */
--  bft runOnlyOnce:1;      /* Automatically expire on reset */
--  bft usesStmtJournal:1;  /* True if uses a statement journal */
--  bft readOnly:1;         /* True for statements that do not write */
--  bft bIsReader:1;        /* True for statements that read */
--  bft isPrepareV2:1;      /* True if prepared with prepare_v2() */
--  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
--  int nChange;            /* Number of db changes made since last reset */
--  yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
--  yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
--  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
--  u32 aCounter[5];        /* Counters used by sqlite3_stmt_status() */
--#ifndef SQLITE_OMIT_TRACE
--  i64 startTime;          /* Time when query started - used for profiling */
--#endif
--  i64 iCurrentTime;       /* Value of julianday('now') for this statement */
--  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
--  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
--  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
--  char *zSql;             /* Text of the SQL statement that generated this */
--  void *pFree;            /* Free this when deleting the vdbe */
--  VdbeFrame *pFrame;      /* Parent frame */
--  VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
--  int nFrame;             /* Number of frames in pFrame list */
--  u32 expmask;            /* Binding to these vars invalidates VM */
--  SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
--  int nOnceFlag;          /* Size of array aOnceFlag[] */
--  u8 *aOnceFlag;          /* Flags for OP_Once */
--  AuxData *pAuxData;      /* Linked list of auxdata allocations */
--#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
--  i64 *anExec;            /* Number of times each op has been executed */
--  int nScan;              /* Entries in aScan[] */
--  ScanStatus *aScan;      /* Scan definitions for sqlite3_stmt_scanstatus() */
--#endif
--};
-+  for(i = 0; i < len; i++) {
-+    a[i] = value;
-+  }
- 
--/*
--** The following are allowed values for Vdbe.magic
--*/
--#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
--#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
--#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
--#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */
-+  return v;
-+}
- 
--/*
--** Function prototypes
--*/
--SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
--void sqliteVdbePopStack(Vdbe*,int);
--SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
--SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
--#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
--SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
--#endif
--SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
--SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
--SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
--SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
--SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
-+/* constant time memory check tests every position of a memory segement
-+   matches a single value (i.e. the memory is all zeros)
-+   returns 0 if match, 1 of no match */
-+int sqlcipher_ismemset(const void *v, unsigned char value, int len) {
-+  const unsigned char *a = v;
-+  int i = 0, result = 0;
- 
--int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
--SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
--SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
--SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
--SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
--SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
--SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
--SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
--SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*);
--SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
--SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*);
--SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*);
--SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
--SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64);
--#ifdef SQLITE_OMIT_FLOATING_POINT
--# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64
--#else
--SQLITE_PRIVATE   void sqlite3VdbeMemSetDouble(Mem*, double);
--#endif
--SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
--SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
--SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
--SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*);
--SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
--SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
--SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
--SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
--SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
--SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
--SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
--SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
--SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8);
--SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
--SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
--#define VdbeMemDynamic(X)  \
--  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
--SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
--SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
--SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
--SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
--SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
--SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
--SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
--SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
-+  for(i = 0; i < len; i++) {
-+    result |= a[i] ^ value;
-+  }
- 
--SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *);
--SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *);
--SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
--SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
--SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
--SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
--SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
--SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
-+  return (result != 0);
-+}
- 
--#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
--SQLITE_PRIVATE   void sqlite3VdbeEnter(Vdbe*);
--SQLITE_PRIVATE   void sqlite3VdbeLeave(Vdbe*);
--#else
--# define sqlite3VdbeEnter(X)
--# define sqlite3VdbeLeave(X)
--#endif
-+/* constant time memory comparison routine. 
-+   returns 0 if match, 1 if no match */
-+int sqlcipher_memcmp(const void *v0, const void *v1, int len) {
-+  const unsigned char *a0 = v0, *a1 = v1;
-+  int i = 0, result = 0;
- 
--#ifdef SQLITE_DEBUG
--SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*);
--SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem*);
--#endif
-+  for(i = 0; i < len; i++) {
-+    result |= a0[i] ^ a1[i];
-+  }
-+  
-+  return (result != 0);
-+}
- 
--#ifndef SQLITE_OMIT_FOREIGN_KEY
--SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int);
--#else
--# define sqlite3VdbeCheckFk(p,i) 0
-+/**
-+  * Free and wipe memory. Uses SQLites internal sqlite3_free so that memory
-+  * can be countend and memory leak detection works in the test suite. 
-+  * If ptr is not null memory will be freed. 
-+  * If sz is greater than zero, the memory will be overwritten with zero before it is freed
-+  * If sz is > 0, and not compiled with OMIT_MEMLOCK, system will attempt to unlock the
-+  * memory segment so it can be paged
-+  */
-+void sqlcipher_free(void *ptr, int sz) {
-+  if(ptr) {
-+    if(sz > 0) {
-+      sqlcipher_memset(ptr, 0, sz);
-+#ifndef OMIT_MEMLOCK
-+#if defined(__unix__) || defined(__APPLE__) 
-+      munlock(ptr, sz);
-+#elif defined(_WIN32)
-+#if !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == 
WINAPI_FAMILY_APP))
-+VirtualUnlock(ptr, sz);
- #endif
--
--SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8);
--#ifdef SQLITE_DEBUG
--SQLITE_PRIVATE   void sqlite3VdbePrintSql(Vdbe*);
--SQLITE_PRIVATE   void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
- #endif
--SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem);
++#if SQLITE_ALLOW_URI_AUTHORITY
++  "ALLOW_URI_AUTHORITY",
 +#endif
-+    }
-+    sqlite3_free(ptr);
-+  }
-+}
- 
--#ifndef SQLITE_OMIT_INCRBLOB
--SQLITE_PRIVATE   int sqlite3VdbeMemExpandBlob(Mem *);
--  #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)
--#else
--  #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK
--  #define ExpandBlob(P) SQLITE_OK
-+/**
-+  * allocate memory. Uses sqlite's internall malloc wrapper so memory can be 
-+  * reference counted and leak detection works. Unless compiled with OMIT_MEMLOCK
-+  * attempts to lock the memory pages so sensitive information won't be swapped
-+  */
-+void* sqlcipher_malloc(int sz) {
-+  void *ptr = sqlite3Malloc(sz);
-+  sqlcipher_memset(ptr, 0, sz);
-+#ifndef OMIT_MEMLOCK
-+  if(ptr) {
-+#if defined(__unix__) || defined(__APPLE__) 
-+    mlock(ptr, sz);
-+#elif defined(_WIN32)
-+#if !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == 
WINAPI_FAMILY_APP))
-+    VirtualLock(ptr, sz);
++#ifdef SQLITE_BITMASK_TYPE
++  "BITMASK_TYPE=" CTIMEOPT_VAL(SQLITE_BITMASK_TYPE),
 +#endif
- #endif
-+  }
++#if SQLITE_BUG_COMPATIBLE_20160819
++  "BUG_COMPATIBLE_20160819",
 +#endif
-+  return ptr;
-+}
- 
--#endif /* !defined(_VDBEINT_H_) */
- 
--/************** End of vdbeInt.h *********************************************/
--/************** Continuing where we left off in status.c *********************/
-+/**
-+  * Initialize new cipher_ctx struct. This function will allocate memory
-+  * for the cipher context and for the key
-+  * 
-+  * returns SQLITE_OK if initialization was successful
-+  * returns SQLITE_NOMEM if an error occured allocating memory
-+  */
-+static int sqlcipher_cipher_ctx_init(cipher_ctx **iCtx) {
-+  int rc;
-+  cipher_ctx *ctx;
-+  *iCtx = (cipher_ctx *) sqlcipher_malloc(sizeof(cipher_ctx));
-+  ctx = *iCtx;
-+  if(ctx == NULL) return SQLITE_NOMEM;
-+
-+  ctx->provider = (sqlcipher_provider *) sqlcipher_malloc(sizeof(sqlcipher_provider));
-+  if(ctx->provider == NULL) return SQLITE_NOMEM;
-+
-+  /* make a copy of the provider to be used for the duration of the context */
-+  sqlite3_mutex_enter(sqlcipher_provider_mutex);
-+  memcpy(ctx->provider, default_provider, sizeof(sqlcipher_provider));
-+  sqlite3_mutex_leave(sqlcipher_provider_mutex);
-+
-+  if((rc = ctx->provider->ctx_init(&ctx->provider_ctx)) != SQLITE_OK) return rc;
++#if SQLITE_CASE_SENSITIVE_LIKE
++  "CASE_SENSITIVE_LIKE",
++#endif
++#if SQLITE_CHECK_PAGES
++  "CHECK_PAGES",
++#endif
++#if defined(__clang__) && defined(__clang_major__)
++  "COMPILER=clang-" CTIMEOPT_VAL(__clang_major__) "."
++                    CTIMEOPT_VAL(__clang_minor__) "."
++                    CTIMEOPT_VAL(__clang_patchlevel__),
++#elif defined(_MSC_VER)
++  "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER),
++#elif defined(__GNUC__) && defined(__VERSION__)
++  "COMPILER=gcc-" __VERSION__,
++#endif
++#if SQLITE_COVERAGE_TEST
++  "COVERAGE_TEST",
++#endif
++#if SQLITE_DEBUG
++  "DEBUG",
++#endif
++#if SQLITE_DEFAULT_AUTOMATIC_INDEX
++  "DEFAULT_AUTOMATIC_INDEX",
++#endif
++#if SQLITE_DEFAULT_AUTOVACUUM
++  "DEFAULT_AUTOVACUUM",
++#endif
++#ifdef SQLITE_DEFAULT_CACHE_SIZE
++  "DEFAULT_CACHE_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_CACHE_SIZE),
++#endif
++#if SQLITE_DEFAULT_CKPTFULLFSYNC
++  "DEFAULT_CKPTFULLFSYNC",
++#endif
++#ifdef SQLITE_DEFAULT_FILE_FORMAT
++  "DEFAULT_FILE_FORMAT=" CTIMEOPT_VAL(SQLITE_DEFAULT_FILE_FORMAT),
++#endif
++#ifdef SQLITE_DEFAULT_FILE_PERMISSIONS
++  "DEFAULT_FILE_PERMISSIONS=" CTIMEOPT_VAL(SQLITE_DEFAULT_FILE_PERMISSIONS),
++#endif
++#if SQLITE_DEFAULT_FOREIGN_KEYS
++  "DEFAULT_FOREIGN_KEYS",
++#endif
++#ifdef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT
++  "DEFAULT_JOURNAL_SIZE_LIMIT=" CTIMEOPT_VAL(SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT),
++#endif
++#ifdef SQLITE_DEFAULT_LOCKING_MODE
++  "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
++#endif
++#ifdef SQLITE_DEFAULT_LOOKASIDE
++  "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOOKASIDE),
++#endif
++#if SQLITE_DEFAULT_MEMSTATUS
++  "DEFAULT_MEMSTATUS",
++#endif
++#ifdef SQLITE_DEFAULT_MMAP_SIZE
++  "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
++#endif
++#ifdef SQLITE_DEFAULT_PAGE_SIZE
++  "DEFAULT_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_PAGE_SIZE),
++#endif
++#ifdef SQLITE_DEFAULT_PCACHE_INITSZ
++  "DEFAULT_PCACHE_INITSZ=" CTIMEOPT_VAL(SQLITE_DEFAULT_PCACHE_INITSZ),
++#endif
++#ifdef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
++  "DEFAULT_PROXYDIR_PERMISSIONS=" CTIMEOPT_VAL(SQLITE_DEFAULT_PROXYDIR_PERMISSIONS),
++#endif
++#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS
++  "DEFAULT_RECURSIVE_TRIGGERS",
++#endif
++#ifdef SQLITE_DEFAULT_ROWEST
++  "DEFAULT_ROWEST=" CTIMEOPT_VAL(SQLITE_DEFAULT_ROWEST),
++#endif
++#ifdef SQLITE_DEFAULT_SECTOR_SIZE
++  "DEFAULT_SECTOR_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_SECTOR_SIZE),
++#endif
++#ifdef SQLITE_DEFAULT_SYNCHRONOUS
++  "DEFAULT_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_SYNCHRONOUS),
++#endif
++#ifdef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT
++  "DEFAULT_WAL_AUTOCHECKPOINT=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_AUTOCHECKPOINT),
++#endif
++#ifdef SQLITE_DEFAULT_WAL_SYNCHRONOUS
++  "DEFAULT_WAL_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_SYNCHRONOUS),
++#endif
++#ifdef SQLITE_DEFAULT_WORKER_THREADS
++  "DEFAULT_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WORKER_THREADS),
++#endif
++#if SQLITE_DIRECT_OVERFLOW_READ
++  "DIRECT_OVERFLOW_READ",
++#endif
++#if SQLITE_DISABLE_DIRSYNC
++  "DISABLE_DIRSYNC",
++#endif
++#if SQLITE_DISABLE_FTS3_UNICODE
++  "DISABLE_FTS3_UNICODE",
++#endif
++#if SQLITE_DISABLE_FTS4_DEFERRED
++  "DISABLE_FTS4_DEFERRED",
++#endif
++#if SQLITE_DISABLE_INTRINSIC
++  "DISABLE_INTRINSIC",
++#endif
++#if SQLITE_DISABLE_LFS
++  "DISABLE_LFS",
++#endif
++#if SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
++  "DISABLE_PAGECACHE_OVERFLOW_STATS",
++#endif
++#if SQLITE_DISABLE_SKIPAHEAD_DISTINCT
++  "DISABLE_SKIPAHEAD_DISTINCT",
++#endif
++#ifdef SQLITE_ENABLE_8_3_NAMES
++  "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES),
++#endif
++#if SQLITE_ENABLE_API_ARMOR
++  "ENABLE_API_ARMOR",
++#endif
++#if SQLITE_ENABLE_ATOMIC_WRITE
++  "ENABLE_ATOMIC_WRITE",
++#endif
++#if SQLITE_ENABLE_CEROD
++  "ENABLE_CEROD",
++#endif
++#if SQLITE_ENABLE_COLUMN_METADATA
++  "ENABLE_COLUMN_METADATA",
++#endif
++#if SQLITE_ENABLE_COLUMN_USED_MASK
++  "ENABLE_COLUMN_USED_MASK",
++#endif
++#if SQLITE_ENABLE_COSTMULT
++  "ENABLE_COSTMULT",
++#endif
++#if SQLITE_ENABLE_CURSOR_HINTS
++  "ENABLE_CURSOR_HINTS",
++#endif
++#if SQLITE_ENABLE_DBSTAT_VTAB
++  "ENABLE_DBSTAT_VTAB",
++#endif
++#if SQLITE_ENABLE_EXPENSIVE_ASSERT
++  "ENABLE_EXPENSIVE_ASSERT",
++#endif
++#if SQLITE_ENABLE_FTS1
++  "ENABLE_FTS1",
++#endif
++#if SQLITE_ENABLE_FTS2
++  "ENABLE_FTS2",
++#endif
++#if SQLITE_ENABLE_FTS3
++  "ENABLE_FTS3",
++#endif
++#if SQLITE_ENABLE_FTS3_PARENTHESIS
++  "ENABLE_FTS3_PARENTHESIS",
++#endif
++#if SQLITE_ENABLE_FTS3_TOKENIZER
++  "ENABLE_FTS3_TOKENIZER",
++#endif
++#if SQLITE_ENABLE_FTS4
++  "ENABLE_FTS4",
++#endif
++#if SQLITE_ENABLE_FTS5
++  "ENABLE_FTS5",
++#endif
++#if SQLITE_ENABLE_HIDDEN_COLUMNS
++  "ENABLE_HIDDEN_COLUMNS",
++#endif
++#if SQLITE_ENABLE_ICU
++  "ENABLE_ICU",
++#endif
++#if SQLITE_ENABLE_IOTRACE
++  "ENABLE_IOTRACE",
++#endif
++#if SQLITE_ENABLE_JSON1
++  "ENABLE_JSON1",
++#endif
++#if SQLITE_ENABLE_LOAD_EXTENSION
++  "ENABLE_LOAD_EXTENSION",
++#endif
++#ifdef SQLITE_ENABLE_LOCKING_STYLE
++  "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
++#endif
++#if SQLITE_ENABLE_MEMORY_MANAGEMENT
++  "ENABLE_MEMORY_MANAGEMENT",
++#endif
++#if SQLITE_ENABLE_MEMSYS3
++  "ENABLE_MEMSYS3",
++#endif
++#if SQLITE_ENABLE_MEMSYS5
++  "ENABLE_MEMSYS5",
++#endif
++#if SQLITE_ENABLE_MULTIPLEX
++  "ENABLE_MULTIPLEX",
++#endif
++#if SQLITE_ENABLE_NULL_TRIM
++  "ENABLE_NULL_TRIM",
++#endif
++#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
++  "ENABLE_OVERSIZE_CELL_CHECK",
++#endif
++#if SQLITE_ENABLE_PREUPDATE_HOOK
++  "ENABLE_PREUPDATE_HOOK",
++#endif
++#if SQLITE_ENABLE_QPSG
++  "ENABLE_QPSG",
++#endif
++#if SQLITE_ENABLE_RBU
++  "ENABLE_RBU",
++#endif
++#if SQLITE_ENABLE_RTREE
++  "ENABLE_RTREE",
++#endif
++#if SQLITE_ENABLE_SELECTTRACE
++  "ENABLE_SELECTTRACE",
++#endif
++#if SQLITE_ENABLE_SESSION
++  "ENABLE_SESSION",
++#endif
++#if SQLITE_ENABLE_SNAPSHOT
++  "ENABLE_SNAPSHOT",
++#endif
++#if SQLITE_ENABLE_SQLLOG
++  "ENABLE_SQLLOG",
++#endif
++#if defined(SQLITE_ENABLE_STAT4)
++  "ENABLE_STAT4",
++#elif defined(SQLITE_ENABLE_STAT3)
++  "ENABLE_STAT3",
++#endif
++#if SQLITE_ENABLE_STMTVTAB
++  "ENABLE_STMTVTAB",
++#endif
++#if SQLITE_ENABLE_STMT_SCANSTATUS
++  "ENABLE_STMT_SCANSTATUS",
++#endif
++#if SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
++  "ENABLE_UNKNOWN_SQL_FUNCTION",
++#endif
++#if SQLITE_ENABLE_UNLOCK_NOTIFY
++  "ENABLE_UNLOCK_NOTIFY",
++#endif
++#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
++  "ENABLE_UPDATE_DELETE_LIMIT",
++#endif
++#if SQLITE_ENABLE_URI_00_ERROR
++  "ENABLE_URI_00_ERROR",
++#endif
++#if SQLITE_ENABLE_VFSTRACE
++  "ENABLE_VFSTRACE",
++#endif
++#if SQLITE_ENABLE_WHERETRACE
++  "ENABLE_WHERETRACE",
++#endif
++#if SQLITE_ENABLE_ZIPVFS
++  "ENABLE_ZIPVFS",
++#endif
++#if SQLITE_EXPLAIN_ESTIMATED_ROWS
++  "EXPLAIN_ESTIMATED_ROWS",
++#endif
++#if SQLITE_EXTRA_IFNULLROW
++  "EXTRA_IFNULLROW",
++#endif
++#ifdef SQLITE_EXTRA_INIT
++  "EXTRA_INIT=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT),
++#endif
++#ifdef SQLITE_EXTRA_SHUTDOWN
++  "EXTRA_SHUTDOWN=" CTIMEOPT_VAL(SQLITE_EXTRA_SHUTDOWN),
++#endif
++#ifdef SQLITE_FTS3_MAX_EXPR_DEPTH
++  "FTS3_MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_FTS3_MAX_EXPR_DEPTH),
++#endif
++#if SQLITE_FTS5_ENABLE_TEST_MI
++  "FTS5_ENABLE_TEST_MI",
++#endif
++#if SQLITE_FTS5_NO_WITHOUT_ROWID
++  "FTS5_NO_WITHOUT_ROWID",
++#endif
++#if SQLITE_HAS_CODEC
++  "HAS_CODEC",
++#endif
++#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
++  "HAVE_ISNAN",
++#endif
++#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
++  "HOMEGROWN_RECURSIVE_MUTEX",
++#endif
++#if SQLITE_IGNORE_AFP_LOCK_ERRORS
++  "IGNORE_AFP_LOCK_ERRORS",
++#endif
++#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS
++  "IGNORE_FLOCK_LOCK_ERRORS",
++#endif
++#if SQLITE_INLINE_MEMCPY
++  "INLINE_MEMCPY",
++#endif
++#if SQLITE_INT64_TYPE
++  "INT64_TYPE",
++#endif
++#ifdef SQLITE_INTEGRITY_CHECK_ERROR_MAX
++  "INTEGRITY_CHECK_ERROR_MAX=" CTIMEOPT_VAL(SQLITE_INTEGRITY_CHECK_ERROR_MAX),
++#endif
++#if SQLITE_LIKE_DOESNT_MATCH_BLOBS
++  "LIKE_DOESNT_MATCH_BLOBS",
++#endif
++#if SQLITE_LOCK_TRACE
++  "LOCK_TRACE",
++#endif
++#if SQLITE_LOG_CACHE_SPILL
++  "LOG_CACHE_SPILL",
++#endif
++#ifdef SQLITE_MALLOC_SOFT_LIMIT
++  "MALLOC_SOFT_LIMIT=" CTIMEOPT_VAL(SQLITE_MALLOC_SOFT_LIMIT),
++#endif
++#ifdef SQLITE_MAX_ATTACHED
++  "MAX_ATTACHED=" CTIMEOPT_VAL(SQLITE_MAX_ATTACHED),
++#endif
++#ifdef SQLITE_MAX_COLUMN
++  "MAX_COLUMN=" CTIMEOPT_VAL(SQLITE_MAX_COLUMN),
++#endif
++#ifdef SQLITE_MAX_COMPOUND_SELECT
++  "MAX_COMPOUND_SELECT=" CTIMEOPT_VAL(SQLITE_MAX_COMPOUND_SELECT),
++#endif
++#ifdef SQLITE_MAX_DEFAULT_PAGE_SIZE
++  "MAX_DEFAULT_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_DEFAULT_PAGE_SIZE),
++#endif
++#ifdef SQLITE_MAX_EXPR_DEPTH
++  "MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_MAX_EXPR_DEPTH),
++#endif
++#ifdef SQLITE_MAX_FUNCTION_ARG
++  "MAX_FUNCTION_ARG=" CTIMEOPT_VAL(SQLITE_MAX_FUNCTION_ARG),
++#endif
++#ifdef SQLITE_MAX_LENGTH
++  "MAX_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_LENGTH),
++#endif
++#ifdef SQLITE_MAX_LIKE_PATTERN_LENGTH
++  "MAX_LIKE_PATTERN_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_LIKE_PATTERN_LENGTH),
++#endif
++#ifdef SQLITE_MAX_MEMORY
++  "MAX_MEMORY=" CTIMEOPT_VAL(SQLITE_MAX_MEMORY),
++#endif
++#ifdef SQLITE_MAX_MMAP_SIZE
++  "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE),
++#endif
++#ifdef SQLITE_MAX_MMAP_SIZE_
++  "MAX_MMAP_SIZE_=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE_),
++#endif
++#ifdef SQLITE_MAX_PAGE_COUNT
++  "MAX_PAGE_COUNT=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_COUNT),
++#endif
++#ifdef SQLITE_MAX_PAGE_SIZE
++  "MAX_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_SIZE),
++#endif
++#ifdef SQLITE_MAX_SCHEMA_RETRY
++  "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
++#endif
++#ifdef SQLITE_MAX_SQL_LENGTH
++  "MAX_SQL_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_SQL_LENGTH),
++#endif
++#ifdef SQLITE_MAX_TRIGGER_DEPTH
++  "MAX_TRIGGER_DEPTH=" CTIMEOPT_VAL(SQLITE_MAX_TRIGGER_DEPTH),
++#endif
++#ifdef SQLITE_MAX_VARIABLE_NUMBER
++  "MAX_VARIABLE_NUMBER=" CTIMEOPT_VAL(SQLITE_MAX_VARIABLE_NUMBER),
++#endif
++#ifdef SQLITE_MAX_VDBE_OP
++  "MAX_VDBE_OP=" CTIMEOPT_VAL(SQLITE_MAX_VDBE_OP),
++#endif
++#ifdef SQLITE_MAX_WORKER_THREADS
++  "MAX_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_MAX_WORKER_THREADS),
++#endif
++#if SQLITE_MEMDEBUG
++  "MEMDEBUG",
++#endif
++#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
++  "MIXED_ENDIAN_64BIT_FLOAT",
++#endif
++#if SQLITE_MMAP_READWRITE
++  "MMAP_READWRITE",
++#endif
++#if SQLITE_MUTEX_NOOP
++  "MUTEX_NOOP",
++#endif
++#if SQLITE_MUTEX_NREF
++  "MUTEX_NREF",
++#endif
++#if SQLITE_MUTEX_OMIT
++  "MUTEX_OMIT",
++#endif
++#if SQLITE_MUTEX_PTHREADS
++  "MUTEX_PTHREADS",
++#endif
++#if SQLITE_MUTEX_W32
++  "MUTEX_W32",
++#endif
++#if SQLITE_NEED_ERR_NAME
++  "NEED_ERR_NAME",
++#endif
++#if SQLITE_NOINLINE
++  "NOINLINE",
++#endif
++#if SQLITE_NO_SYNC
++  "NO_SYNC",
++#endif
++#if SQLITE_OMIT_ALTERTABLE
++  "OMIT_ALTERTABLE",
++#endif
++#if SQLITE_OMIT_ANALYZE
++  "OMIT_ANALYZE",
++#endif
++#if SQLITE_OMIT_ATTACH
++  "OMIT_ATTACH",
++#endif
++#if SQLITE_OMIT_AUTHORIZATION
++  "OMIT_AUTHORIZATION",
++#endif
++#if SQLITE_OMIT_AUTOINCREMENT
++  "OMIT_AUTOINCREMENT",
++#endif
++#if SQLITE_OMIT_AUTOINIT
++  "OMIT_AUTOINIT",
++#endif
++#if SQLITE_OMIT_AUTOMATIC_INDEX
++  "OMIT_AUTOMATIC_INDEX",
++#endif
++#if SQLITE_OMIT_AUTORESET
++  "OMIT_AUTORESET",
++#endif
++#if SQLITE_OMIT_AUTOVACUUM
++  "OMIT_AUTOVACUUM",
++#endif
++#if SQLITE_OMIT_BETWEEN_OPTIMIZATION
++  "OMIT_BETWEEN_OPTIMIZATION",
++#endif
++#if SQLITE_OMIT_BLOB_LITERAL
++  "OMIT_BLOB_LITERAL",
++#endif
++#if SQLITE_OMIT_BTREECOUNT
++  "OMIT_BTREECOUNT",
++#endif
++#if SQLITE_OMIT_CAST
++  "OMIT_CAST",
++#endif
++#if SQLITE_OMIT_CHECK
++  "OMIT_CHECK",
++#endif
++#if SQLITE_OMIT_COMPLETE
++  "OMIT_COMPLETE",
++#endif
++#if SQLITE_OMIT_COMPOUND_SELECT
++  "OMIT_COMPOUND_SELECT",
++#endif
++#if SQLITE_OMIT_CONFLICT_CLAUSE
++  "OMIT_CONFLICT_CLAUSE",
++#endif
++#if SQLITE_OMIT_CTE
++  "OMIT_CTE",
++#endif
++#if SQLITE_OMIT_DATETIME_FUNCS
++  "OMIT_DATETIME_FUNCS",
++#endif
++#if SQLITE_OMIT_DECLTYPE
++  "OMIT_DECLTYPE",
++#endif
++#if SQLITE_OMIT_DEPRECATED
++  "OMIT_DEPRECATED",
++#endif
++#if SQLITE_OMIT_DISKIO
++  "OMIT_DISKIO",
++#endif
++#if SQLITE_OMIT_EXPLAIN
++  "OMIT_EXPLAIN",
++#endif
++#if SQLITE_OMIT_FLAG_PRAGMAS
++  "OMIT_FLAG_PRAGMAS",
++#endif
++#if SQLITE_OMIT_FLOATING_POINT
++  "OMIT_FLOATING_POINT",
++#endif
++#if SQLITE_OMIT_FOREIGN_KEY
++  "OMIT_FOREIGN_KEY",
++#endif
++#if SQLITE_OMIT_GET_TABLE
++  "OMIT_GET_TABLE",
++#endif
++#if SQLITE_OMIT_HEX_INTEGER
++  "OMIT_HEX_INTEGER",
++#endif
++#if SQLITE_OMIT_INCRBLOB
++  "OMIT_INCRBLOB",
++#endif
++#if SQLITE_OMIT_INTEGRITY_CHECK
++  "OMIT_INTEGRITY_CHECK",
++#endif
++#if SQLITE_OMIT_LIKE_OPTIMIZATION
++  "OMIT_LIKE_OPTIMIZATION",
++#endif
++#if SQLITE_OMIT_LOAD_EXTENSION
++  "OMIT_LOAD_EXTENSION",
++#endif
++#if SQLITE_OMIT_LOCALTIME
++  "OMIT_LOCALTIME",
++#endif
++#if SQLITE_OMIT_LOOKASIDE
++  "OMIT_LOOKASIDE",
++#endif
++#if SQLITE_OMIT_MEMORYDB
++  "OMIT_MEMORYDB",
++#endif
++#if SQLITE_OMIT_OR_OPTIMIZATION
++  "OMIT_OR_OPTIMIZATION",
++#endif
++#if SQLITE_OMIT_PAGER_PRAGMAS
++  "OMIT_PAGER_PRAGMAS",
++#endif
++#if SQLITE_OMIT_PARSER_TRACE
++  "OMIT_PARSER_TRACE",
++#endif
++#if SQLITE_OMIT_POPEN
++  "OMIT_POPEN",
++#endif
++#if SQLITE_OMIT_PRAGMA
++  "OMIT_PRAGMA",
++#endif
++#if SQLITE_OMIT_PROGRESS_CALLBACK
++  "OMIT_PROGRESS_CALLBACK",
++#endif
++#if SQLITE_OMIT_QUICKBALANCE
++  "OMIT_QUICKBALANCE",
++#endif
++#if SQLITE_OMIT_REINDEX
++  "OMIT_REINDEX",
++#endif
++#if SQLITE_OMIT_SCHEMA_PRAGMAS
++  "OMIT_SCHEMA_PRAGMAS",
++#endif
++#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
++  "OMIT_SCHEMA_VERSION_PRAGMAS",
++#endif
++#if SQLITE_OMIT_SHARED_CACHE
++  "OMIT_SHARED_CACHE",
++#endif
++#if SQLITE_OMIT_SHUTDOWN_DIRECTORIES
++  "OMIT_SHUTDOWN_DIRECTORIES",
++#endif
++#if SQLITE_OMIT_SUBQUERY
++  "OMIT_SUBQUERY",
++#endif
++#if SQLITE_OMIT_TCL_VARIABLE
++  "OMIT_TCL_VARIABLE",
++#endif
++#if SQLITE_OMIT_TEMPDB
++  "OMIT_TEMPDB",
++#endif
++#if SQLITE_OMIT_TEST_CONTROL
++  "OMIT_TEST_CONTROL",
++#endif
++#if SQLITE_OMIT_TRACE
++  "OMIT_TRACE",
++#endif
++#if SQLITE_OMIT_TRIGGER
++  "OMIT_TRIGGER",
++#endif
++#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION
++  "OMIT_TRUNCATE_OPTIMIZATION",
++#endif
++#if SQLITE_OMIT_UTF16
++  "OMIT_UTF16",
++#endif
++#if SQLITE_OMIT_VACUUM
++  "OMIT_VACUUM",
++#endif
++#if SQLITE_OMIT_VIEW
++  "OMIT_VIEW",
++#endif
++#if SQLITE_OMIT_VIRTUALTABLE
++  "OMIT_VIRTUALTABLE",
++#endif
++#if SQLITE_OMIT_WAL
++  "OMIT_WAL",
++#endif
++#if SQLITE_OMIT_WSD
++  "OMIT_WSD",
++#endif
++#if SQLITE_OMIT_XFER_OPT
++  "OMIT_XFER_OPT",
++#endif
++#if SQLITE_PCACHE_SEPARATE_HEADER
++  "PCACHE_SEPARATE_HEADER",
++#endif
++#if SQLITE_PERFORMANCE_TRACE
++  "PERFORMANCE_TRACE",
++#endif
++#if SQLITE_POWERSAFE_OVERWRITE
++  "POWERSAFE_OVERWRITE",
++#endif
++#if SQLITE_PREFER_PROXY_LOCKING
++  "PREFER_PROXY_LOCKING",
++#endif
++#if SQLITE_PROXY_DEBUG
++  "PROXY_DEBUG",
++#endif
++#if SQLITE_REVERSE_UNORDERED_SELECTS
++  "REVERSE_UNORDERED_SELECTS",
++#endif
++#if SQLITE_RTREE_INT_ONLY
++  "RTREE_INT_ONLY",
++#endif
++#if SQLITE_SECURE_DELETE
++  "SECURE_DELETE",
++#endif
++#if SQLITE_SMALL_STACK
++  "SMALL_STACK",
++#endif
++#ifdef SQLITE_SORTER_PMASZ
++  "SORTER_PMASZ=" CTIMEOPT_VAL(SQLITE_SORTER_PMASZ),
++#endif
++#if SQLITE_SOUNDEX
++  "SOUNDEX",
++#endif
++#ifdef SQLITE_STAT4_SAMPLES
++  "STAT4_SAMPLES=" CTIMEOPT_VAL(SQLITE_STAT4_SAMPLES),
++#endif
++#ifdef SQLITE_STMTJRNL_SPILL
++  "STMTJRNL_SPILL=" CTIMEOPT_VAL(SQLITE_STMTJRNL_SPILL),
++#endif
++#if SQLITE_SUBSTR_COMPATIBILITY
++  "SUBSTR_COMPATIBILITY",
++#endif
++#if SQLITE_SYSTEM_MALLOC
++  "SYSTEM_MALLOC",
++#endif
++#if SQLITE_TCL
++  "TCL",
++#endif
++#ifdef SQLITE_TEMP_STORE
++  "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
++#endif
++#if SQLITE_TEST
++  "TEST",
++#endif
++#if defined(SQLITE_THREADSAFE)
++  "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
++#elif defined(THREADSAFE)
++  "THREADSAFE=" CTIMEOPT_VAL(THREADSAFE),
++#else
++  "THREADSAFE=1",
++#endif
++#if SQLITE_UNLINK_AFTER_CLOSE
++  "UNLINK_AFTER_CLOSE",
++#endif
++#if SQLITE_UNTESTABLE
++  "UNTESTABLE",
++#endif
++#if SQLITE_USER_AUTHENTICATION
++  "USER_AUTHENTICATION",
++#endif
++#if SQLITE_USE_ALLOCA
++  "USE_ALLOCA",
++#endif
++#if SQLITE_USE_FCNTL_TRACE
++  "USE_FCNTL_TRACE",
++#endif
++#if SQLITE_USE_URI
++  "USE_URI",
++#endif
++#if SQLITE_VDBE_COVERAGE
++  "VDBE_COVERAGE",
++#endif
++#if SQLITE_WIN32_MALLOC
++  "WIN32_MALLOC",
++#endif
++#if SQLITE_ZERO_MALLOC
++  "ZERO_MALLOC",
++#endif
++/* 
++** END CODE GENERATED BY tool/mkctime.tcl 
++*/
++};
++
++SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){
++  *pnOpt = sizeof(sqlite3azCompileOpt) / sizeof(sqlite3azCompileOpt[0]);
++  return (const char**)sqlite3azCompileOpt;
++}
++
++#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
++
++/************** End of ctime.c ***********************************************/
+ /************** Begin file sqliteInt.h ***************************************/
+ /*
+ ** 2001 September 15
+@@ -37,8 +789,51 @@
+ ** Internal interface definitions for SQLite.
+ **
+ */
+-#ifndef _SQLITEINT_H_
+-#define _SQLITEINT_H_
++#ifndef SQLITEINT_H
++#define SQLITEINT_H
++
++/* Special Comments:
++**
++** Some comments have special meaning to the tools that measure test
++** coverage:
++**
++**    NO_TEST                     - The branches on this line are not
++**                                  measured by branch coverage.  This is
++**                                  used on lines of code that actually
++**                                  implement parts of coverage testing.
++**
++**    OPTIMIZATION-IF-TRUE        - This branch is allowed to alway be false
++**                                  and the correct answer is still obtained,
++**                                  though perhaps more slowly.
++**
++**    OPTIMIZATION-IF-FALSE       - This branch is allowed to alway be true
++**                                  and the correct answer is still obtained,
++**                                  though perhaps more slowly.
++**
++**    PREVENTS-HARMLESS-OVERREAD  - This branch prevents a buffer overread
++**                                  that would be harmless and undetectable
++**                                  if it did occur.  
++**
++** In all cases, the special comment must be enclosed in the usual
++** slash-asterisk...asterisk-slash comment marks, with no spaces between the 
++** asterisks and the comment text.
++*/
++
++/*
++** Make sure the Tcl calling convention macro is defined.  This macro is
++** only used by test code and Tcl integration code.
++*/
++#ifndef SQLITE_TCLAPI
++#  define SQLITE_TCLAPI
++#endif
++
++/*
++** Make sure that rand_s() is available on Windows systems with MSVC 2005
++** or higher.
++*/
++#if defined(_MSC_VER) && _MSC_VER>=1400
++#  define _CRT_RAND_S
++#endif
+ 
+ /*
+ ** Include the header file used to customize the compiler options for MSVC.
+@@ -62,8 +857,8 @@
+ **
+ ** This file contains code that is specific to MSVC.
+ */
+-#ifndef _MSVC_H_
+-#define _MSVC_H_
++#ifndef SQLITE_MSVC_H
++#define SQLITE_MSVC_H
+ 
+ #if defined(_MSC_VER)
+ #pragma warning(disable : 4054)
+@@ -83,7 +878,7 @@
+ #pragma warning(disable : 4706)
+ #endif /* defined(_MSC_VER) */
+ 
+-#endif /* _MSVC_H_ */
++#endif /* SQLITE_MSVC_H */
+ 
+ /************** End of msvc.h ************************************************/
+ /************** Continuing where we left off in sqliteInt.h ******************/
+@@ -121,6 +916,9 @@
+ #else
+ /* This is not VxWorks. */
+ #define OS_VXWORKS 0
++#define HAVE_FCHOWN 1
++#define HAVE_READLINK 1
++#define HAVE_LSTAT 1
+ #endif /* defined(_WRS_KERNEL) */
+ 
+ /************** End of vxworks.h *********************************************/
+@@ -158,6 +956,30 @@
+ # define _LARGEFILE_SOURCE 1
+ #endif
+ 
++/* The GCC_VERSION and MSVC_VERSION macros are used to
++** conditionally include optimizations for each of these compilers.  A
++** value of 0 means that compiler is not being used.  The
++** SQLITE_DISABLE_INTRINSIC macro means do not use any compiler-specific
++** optimizations, and hence set all compiler macros to 0
++**
++** There was once also a CLANG_VERSION macro.  However, we learn that the
++** version numbers in clang are for "marketing" only and are inconsistent
++** and unreliable.  Fortunately, all versions of clang also recognize the
++** gcc version numbers and have reasonable settings for gcc version numbers,
++** so the GCC_VERSION macro will be set to a correct non-zero value even
++** when compiling with clang.
++*/
++#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
++# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
++#else
++# define GCC_VERSION 0
++#endif
++#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
++# define MSVC_VERSION _MSC_VER
++#else
++# define MSVC_VERSION 0
++#endif
++
+ /* Needed for various definitions... */
+ #if defined(__GNUC__) && !defined(_GNU_SOURCE)
+ # define _GNU_SOURCE
+@@ -206,7 +1028,7 @@
+ /************** Include sqlite3.h in the middle of sqliteInt.h ***************/
+ /************** Begin file sqlite3.h *****************************************/
+ /*
+-** 2001 September 15
++** 2001-09-15
+ **
+ ** The author disclaims copyright to this source code.  In place of
+ ** a legal notice, here is a blessing:
+@@ -230,15 +1052,15 @@
+ **
+ ** The official C-language API documentation for SQLite is derived
+ ** from comments in this file.  This file is the authoritative source
+-** on how SQLite interfaces are suppose to operate.
++** on how SQLite interfaces are supposed to operate.
+ **
+ ** The name of this file under configuration management is "sqlite.h.in".
+ ** The makefile makes some minor changes to this file (such as inserting
+ ** the version number) and changes its name to "sqlite3.h" as
+ ** part of the build process.
+ */
+-#ifndef _SQLITE3_H_
+-#define _SQLITE3_H_
++#ifndef SQLITE3_H
++#define SQLITE3_H
+ #include <stdarg.h>     /* Needed for the definition of va_list */
+ 
+ /*
+@@ -261,8 +1083,17 @@
+ #ifndef SQLITE_CDECL
+ # define SQLITE_CDECL
+ #endif
++#ifndef SQLITE_APICALL
++# define SQLITE_APICALL
++#endif
+ #ifndef SQLITE_STDCALL
+-# define SQLITE_STDCALL
++# define SQLITE_STDCALL SQLITE_APICALL
++#endif
++#ifndef SQLITE_CALLBACK
++# define SQLITE_CALLBACK
++#endif
++#ifndef SQLITE_SYSAPI
++# define SQLITE_SYSAPI
+ #endif
+ 
+ /*
+@@ -306,32 +1137,33 @@
+ ** be held constant and Z will be incremented or else Y will be incremented
+ ** and Z will be reset to zero.
+ **
+-** Since version 3.6.18, SQLite source code has been stored in the
++** Since [version 3.6.18] ([dateof:3.6.18]), 
++** SQLite source code has been stored in the
+ ** <a href="http://www.fossil-scm.org/";>Fossil configuration management
+ ** system</a>.  ^The SQLITE_SOURCE_ID macro evaluates to
+ ** a string which identifies a particular check-in of SQLite
+ ** within its configuration management system.  ^The SQLITE_SOURCE_ID
+-** string contains the date and time of the check-in (UTC) and an SHA1
+-** hash of the entire source tree.
++** string contains the date and time of the check-in (UTC) and a SHA1
++** or SHA3-256 hash of the entire source tree.
+ **
+ ** See also: [sqlite3_libversion()],
+ ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
+ ** [sqlite_version()] and [sqlite_source_id()].
+ */
+-#define SQLITE_VERSION        "3.8.10.2"
+-#define SQLITE_VERSION_NUMBER 3008010
+-#define SQLITE_SOURCE_ID      "2015-05-20 18:17:19 2ef4f3a5b1d1d0c4338f8243d40a2452cc1f7fe4"
++#define SQLITE_VERSION        "3.20.1"
++#define SQLITE_VERSION_NUMBER 3020001
++#define SQLITE_SOURCE_ID      "2017-08-24 16:21:36 
8d3a7ea6c5690d6b7c3767558f4f01b511c55463e3f9e64506801fe9b74dce34"
+ 
+ /*
+ ** CAPI3REF: Run-Time Library Version Numbers
+-** KEYWORDS: sqlite3_version, sqlite3_sourceid
++** KEYWORDS: sqlite3_version sqlite3_sourceid
+ **
+ ** These interfaces provide the same information as the [SQLITE_VERSION],
+ ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
+ ** but are associated with the library instead of the header file.  ^(Cautious
+ ** programmers might include assert() statements in their application to
+ ** verify that values returned by these interfaces match the macros in
+-** the header, and thus insure that the application is
++** the header, and thus ensure that the application is
+ ** compiled with matching library and header files.
+ **
+ ** <blockquote><pre>
+@@ -353,9 +1185,9 @@
+ ** See also: [sqlite_version()] and [sqlite_source_id()].
+ */
+ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void);
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void);
+-SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void);
++SQLITE_API const char *sqlite3_libversion(void);
++SQLITE_API const char *sqlite3_sourceid(void);
++SQLITE_API int sqlite3_libversion_number(void);
+ 
+ /*
+ ** CAPI3REF: Run-Time Library Compilation Options Diagnostics
+@@ -380,8 +1212,8 @@
+ ** [sqlite_compileoption_get()] and the [compile_options pragma].
+ */
+ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+-SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName);
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N);
++SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
++SQLITE_API const char *sqlite3_compileoption_get(int N);
+ #endif
+ 
+ /*
+@@ -420,7 +1252,7 @@
+ **
+ ** See the [threading mode] documentation for additional information.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void);
++SQLITE_API int sqlite3_threadsafe(void);
+ 
+ /*
+ ** CAPI3REF: Database Connection Handle
+@@ -456,7 +1288,11 @@
+ */
+ #ifdef SQLITE_INT64_TYPE
+   typedef SQLITE_INT64_TYPE sqlite_int64;
+-  typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
++# ifdef SQLITE_UINT64_TYPE
++    typedef SQLITE_UINT64_TYPE sqlite_uint64;
++# else  
++    typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
++# endif
+ #elif defined(_MSC_VER) || defined(__BORLANDC__)
+   typedef __int64 sqlite_int64;
+   typedef unsigned __int64 sqlite_uint64;
+@@ -517,8 +1353,8 @@
+ ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
+ ** argument is a harmless no-op.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*);
++SQLITE_API int sqlite3_close(sqlite3*);
++SQLITE_API int sqlite3_close_v2(sqlite3*);
+ 
+ /*
+ ** The type for a callback function.
+@@ -554,7 +1390,7 @@
+ ** from [sqlite3_malloc()] and passed back through the 5th parameter.
+ ** To avoid memory leaks, the application should invoke [sqlite3_free()]
+ ** on error message strings returned through the 5th parameter of
+-** of sqlite3_exec() after the error message string is no longer needed.
++** sqlite3_exec() after the error message string is no longer needed.
+ ** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors
+ ** occur, then sqlite3_exec() sets the pointer in its 5th parameter to
+ ** NULL before returning.
+@@ -581,7 +1417,7 @@
+ ** Restrictions:
+ **
+ ** <ul>
+-** <li> The application must insure that the 1st parameter to sqlite3_exec()
++** <li> The application must ensure that the 1st parameter to sqlite3_exec()
+ **      is a valid and open [database connection].
+ ** <li> The application must not close the [database connection] specified by
+ **      the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
+@@ -589,7 +1425,7 @@
+ **      the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
+ ** </ul>
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_exec(
++SQLITE_API int sqlite3_exec(
+   sqlite3*,                                  /* An open database */
+   const char *sql,                           /* SQL to be evaluated */
+   int (*callback)(void*,int,char**,char**),  /* Callback function */
+@@ -610,7 +1446,7 @@
+ */
+ #define SQLITE_OK           0   /* Successful result */
+ /* beginning-of-error-codes */
+-#define SQLITE_ERROR        1   /* SQL error or missing database */
++#define SQLITE_ERROR        1   /* Generic error */
+ #define SQLITE_INTERNAL     2   /* Internal logic error in SQLite */
+ #define SQLITE_PERM         3   /* Access permission denied */
+ #define SQLITE_ABORT        4   /* Callback routine requested an abort */
+@@ -625,7 +1461,7 @@
+ #define SQLITE_FULL        13   /* Insertion failed because database is full */
+ #define SQLITE_CANTOPEN    14   /* Unable to open the database file */
+ #define SQLITE_PROTOCOL    15   /* Database lock protocol error */
+-#define SQLITE_EMPTY       16   /* Database is empty */
++#define SQLITE_EMPTY       16   /* Not used */
+ #define SQLITE_SCHEMA      17   /* The database schema changed */
+ #define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */
+ #define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */
+@@ -633,7 +1469,7 @@
+ #define SQLITE_MISUSE      21   /* Library used incorrectly */
+ #define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
+ #define SQLITE_AUTH        23   /* Authorization denied */
+-#define SQLITE_FORMAT      24   /* Auxiliary database format error */
++#define SQLITE_FORMAT      24   /* Not used */
+ #define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */
+ #define SQLITE_NOTADB      26   /* File opened that is not a database file */
+ #define SQLITE_NOTICE      27   /* Notifications from sqlite3_log() */
+@@ -650,7 +1486,8 @@
+ ** [result codes].  However, experience has shown that many of
+ ** these result codes are too coarse-grained.  They do not provide as
+ ** much information about problems as programmers might like.  In an effort to
+-** address this, newer versions of SQLite (version 3.3.8 and later) include
++** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8]
++** and later) include
+ ** support for additional result codes that provide more detailed information
+ ** about errors. These [extended result codes] are enabled or disabled
+ ** on a per database connection basis using the
+@@ -684,6 +1521,8 @@
+ #define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
+ #define SQLITE_IOERR_GETTEMPPATH       (SQLITE_IOERR | (25<<8))
+ #define SQLITE_IOERR_CONVPATH          (SQLITE_IOERR | (26<<8))
++#define SQLITE_IOERR_VNODE             (SQLITE_IOERR | (27<<8))
++#define SQLITE_IOERR_AUTH              (SQLITE_IOERR | (28<<8))
+ #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
+ #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
+ #define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
+@@ -711,6 +1550,7 @@
+ #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
+ #define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
+ #define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
++#define SQLITE_OK_LOAD_PERMANENTLY     (SQLITE_OK | (1<<8))
+ 
+ /*
+ ** CAPI3REF: Flags For File Open Operations
+@@ -765,7 +1605,7 @@
+ ** file that were written at the application level might have changed
+ ** and that adjacent bytes, even bytes within the same sector are
+ ** guaranteed to be unchanged.  The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
+-** flag indicate that a file cannot be deleted when open.  The
++** flag indicates that a file cannot be deleted when open.  The
+ ** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
+ ** read-only media and cannot be changed even by processes with
+ ** elevated privileges.
+@@ -915,6 +1755,9 @@
+ ** <li> [SQLITE_IOCAP_ATOMIC64K]
+ ** <li> [SQLITE_IOCAP_SAFE_APPEND]
+ ** <li> [SQLITE_IOCAP_SEQUENTIAL]
++** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
++** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
++** <li> [SQLITE_IOCAP_IMMUTABLE]
+ ** </ul>
+ **
+ ** The SQLITE_IOCAP_ATOMIC property means that all writes of
+@@ -999,8 +1842,13 @@
+ ** <li>[[SQLITE_FCNTL_FILE_POINTER]]
+ ** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer
+ ** to the [sqlite3_file] object associated with a particular database
+-** connection.  See the [sqlite3_file_control()] documentation for
+-** additional information.
++** connection.  See also [SQLITE_FCNTL_JOURNAL_POINTER].
++**
++** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]]
++** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer
++** to the [sqlite3_file] object associated with the journal file (either
++** the [rollback journal] or the [write-ahead log]) for a particular database
++** connection.  See also [SQLITE_FCNTL_FILE_POINTER].
+ **
+ ** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
+ ** No longer in use.
+@@ -1038,7 +1886,7 @@
+ ** opcode allows these two values (10 retries and 25 milliseconds of delay)
+ ** to be adjusted.  The values are changed for all database connections
+ ** within the same process.  The argument is a pointer to an array of two
+-** integers where the first integer i the new retry count and the second
++** integers where the first integer is the new retry count and the second
+ ** integer is the delay.  If either integer is negative, then the setting
+ ** is not changed but instead the prior value of that setting is written
+ ** into the array entry, allowing the current retry settings to be
+@@ -1087,6 +1935,15 @@
+ ** pointer in case this file-control is not implemented.  This file-control
+ ** is intended for diagnostic use only.
+ **
++** <li>[[SQLITE_FCNTL_VFS_POINTER]]
++** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level
++** [VFSes] currently in use.  ^(The argument X in
++** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be
++** of type "[sqlite3_vfs] **".  This opcodes will set *X
++** to a pointer to the top-level VFS.)^
++** ^When there are multiple VFS shims in the stack, this opcode finds the
++** upper-most shim only.
++**
+ ** <li>[[SQLITE_FCNTL_PRAGMA]]
+ ** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] 
+ ** file control is sent to the open [sqlite3_file] object corresponding
+@@ -1157,6 +2014,12 @@
+ ** on whether or not the file has been renamed, moved, or deleted since it
+ ** was first opened.
+ **
++** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
++** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
++** underlying native file handle associated with a file handle.  This file
++** control interprets its argument as a pointer to a native file handle and
++** writes the resulting value there.
++**
+ ** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
+ ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging.  This
+ ** opcode causes the xFileControl method to swap the file handle with the one
+@@ -1170,6 +2033,14 @@
+ ** circumstances in order to fix a problem with priority inversion.
+ ** Applications should <em>not</em> use this file-control.
+ **
++** <li>[[SQLITE_FCNTL_ZIPVFS]]
++** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other
++** VFS should return SQLITE_NOTFOUND for this opcode.
++**
++** <li>[[SQLITE_FCNTL_RBU]]
++** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by
++** the RBU extension only.  All other VFS should return SQLITE_NOTFOUND for
++** this opcode.  
+ ** </ul>
+ */
+ #define SQLITE_FCNTL_LOCKSTATE               1
+@@ -1195,6 +2066,12 @@
+ #define SQLITE_FCNTL_COMMIT_PHASETWO        22
+ #define SQLITE_FCNTL_WIN32_SET_HANDLE       23
+ #define SQLITE_FCNTL_WAL_BLOCK              24
++#define SQLITE_FCNTL_ZIPVFS                 25
++#define SQLITE_FCNTL_RBU                    26
++#define SQLITE_FCNTL_VFS_POINTER            27
++#define SQLITE_FCNTL_JOURNAL_POINTER        28
++#define SQLITE_FCNTL_WIN32_GET_HANDLE       29
++#define SQLITE_FCNTL_PDB                    30
+ 
+ /* deprecated names */
+ #define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
+@@ -1215,6 +2092,16 @@
+ typedef struct sqlite3_mutex sqlite3_mutex;
+ 
+ /*
++** CAPI3REF: Loadable Extension Thunk
++**
++** A pointer to the opaque sqlite3_api_routines structure is passed as
++** the third parameter to entry points of [loadable extensions].  This
++** structure must be typedefed in order to work around compiler warnings
++** on some platforms.
++*/
++typedef struct sqlite3_api_routines sqlite3_api_routines;
++
++/*
+ ** CAPI3REF: OS Interface Object
+ **
+ ** An instance of the sqlite3_vfs object defines the interface between
+@@ -1407,7 +2294,7 @@
+   const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
+   /*
+   ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
+-  ** New fields may be appended in figure versions.  The iVersion
++  ** New fields may be appended in future versions.  The iVersion
+   ** value will increment whenever this happens. 
+   */
+ };
+@@ -1549,10 +2436,10 @@
+ ** must return [SQLITE_OK] on success and some other [error code] upon
+ ** failure.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void);
+-SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void);
+-SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void);
+-SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
++SQLITE_API int sqlite3_initialize(void);
++SQLITE_API int sqlite3_shutdown(void);
++SQLITE_API int sqlite3_os_init(void);
++SQLITE_API int sqlite3_os_end(void);
+ 
+ /*
+ ** CAPI3REF: Configuring The SQLite Library
+@@ -1563,9 +2450,11 @@
+ ** applications and so this routine is usually not necessary.  It is
+ ** provided to support rare applications with unusual needs.
+ **
+-** The sqlite3_config() interface is not threadsafe.  The application
+-** must insure that no other SQLite interfaces are invoked by other
+-** threads while sqlite3_config() is running.  Furthermore, sqlite3_config()
++** <b>The sqlite3_config() interface is not threadsafe. The application
++** must ensure that no other SQLite interfaces are invoked by other
++** threads while sqlite3_config() is running.</b>
++**
++** The sqlite3_config() interface
+ ** may only be invoked prior to library initialization using
+ ** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
+ ** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
+@@ -1583,7 +2472,7 @@
+ ** ^If the option is unknown or SQLite is unable to set the option
+ ** then this routine returns a non-zero [error code].
+ */
+-SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...);
++SQLITE_API int sqlite3_config(int, ...);
+ 
+ /*
+ ** CAPI3REF: Configure database connections
+@@ -1602,7 +2491,7 @@
+ ** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
+ ** the call is considered successful.
+ */
+-SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...);
++SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
+ 
+ /*
+ ** CAPI3REF: Memory Allocation Routines
+@@ -1792,29 +2681,34 @@
+ ** </dd>
+ **
+ ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
+-** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a static memory buffer
++** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool
+ ** that SQLite can use for the database page cache with the default page
+ ** cache implementation.  
+-** This configuration should not be used if an application-define page
+-** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]
+-** configuration option.
++** This configuration option is a no-op if an application-define page
++** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2].
+ ** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
+-** 8-byte aligned
+-** memory, the size of each page buffer (sz), and the number of pages (N).
++** 8-byte aligned memory (pMem), the size of each page cache line (sz),
++** and the number of cache lines (N).
+ ** The sz argument should be the size of the largest database page
+ ** (a power of two between 512 and 65536) plus some extra bytes for each
+ ** page header.  ^The number of extra bytes needed by the page header
+-** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option 
+-** to [sqlite3_config()].
++** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ].
+ ** ^It is harmless, apart from the wasted memory,
+-** for the sz parameter to be larger than necessary.  The first
+-** argument should pointer to an 8-byte aligned block of memory that
+-** is at least sz*N bytes of memory, otherwise subsequent behavior is
+-** undefined.
+-** ^SQLite will use the memory provided by the first argument to satisfy its
+-** memory needs for the first N pages that it adds to cache.  ^If additional
+-** page cache memory is needed beyond what is provided by this option, then
+-** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>
++** for the sz parameter to be larger than necessary.  The pMem
++** argument must be either a NULL pointer or a pointer to an 8-byte
++** aligned block of memory of at least sz*N bytes, otherwise
++** subsequent behavior is undefined.
++** ^When pMem is not NULL, SQLite will strive to use the memory provided
++** to satisfy page cache needs, falling back to [sqlite3_malloc()] if
++** a page cache line is larger than sz bytes or if all of the pMem buffer
++** is exhausted.
++** ^If pMem is NULL and N is non-zero, then each database connection
++** does an initial bulk allocation for page cache memory
++** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or
++** of -1024*N bytes if N is negative, . ^If additional
++** page cache memory is needed beyond what is provided by the initial
++** allocation, then SQLite goes to [sqlite3_malloc()] separately for each
++** additional cache line. </dd>
+ **
+ ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
+ ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer 
+@@ -1992,6 +2886,20 @@
+ ** is enabled (using the [PRAGMA threads] command) and the amount of content
+ ** to be sorted exceeds the page size times the minimum of the
+ ** [PRAGMA cache_size] setting and this value.
++**
++** [[SQLITE_CONFIG_STMTJRNL_SPILL]]
++** <dt>SQLITE_CONFIG_STMTJRNL_SPILL
++** <dd>^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which
++** becomes the [statement journal] spill-to-disk threshold.  
++** [Statement journals] are held in memory until their size (in bytes)
++** exceeds this threshold, at which point they are written to disk.
++** Or if the threshold is -1, statement journals are always held
++** exclusively in memory.
++** Since many statement journals never become large, setting the spill
++** threshold to a value such as 64KiB can greatly reduce the amount of
++** I/O required to support statement rollback.
++** The default value for this setting is controlled by the
++** [SQLITE_STMTJRNL_SPILL] compile-time option.
+ ** </dl>
+ */
+ #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
+@@ -2019,6 +2927,7 @@
+ #define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
+ #define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
+ #define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
++#define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
+ 
+ /*
+ ** CAPI3REF: Database Connection Configuration Options
+@@ -2076,11 +2985,78 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the trigger setting is not reported back. </dd>
+ **
++** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
++** <dd> ^This option is used to enable or disable the two-argument
++** version of the [fts3_tokenizer()] function which is part of the
++** [FTS3] full-text search engine extension.
++** There should be two additional arguments.
++** The first argument is an integer which is 0 to disable fts3_tokenizer() or
++** positive to enable fts3_tokenizer() or negative to leave the setting
++** unchanged.
++** The second parameter is a pointer to an integer into which
++** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
++** following this call.  The second parameter may be a NULL pointer, in
++** which case the new setting is not reported back. </dd>
++**
++** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
++** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
++** interface independently of the [load_extension()] SQL function.
++** The [sqlite3_enable_load_extension()] API enables or disables both the
++** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
++** There should be two additional arguments.
++** When the first argument to this interface is 1, then only the C-API is
++** enabled and the SQL function remains disabled.  If the first argument to
++** this interface is 0, then both the C-API and the SQL function are disabled.
++** If the first argument is -1, then no changes are made to state of either the
++** C-API or the SQL function.
++** The second parameter is a pointer to an integer into which
++** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
++** is disabled or enabled following this call.  The second parameter may
++** be a NULL pointer, in which case the new setting is not reported back.
++** </dd>
++**
++** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
++** <dd> ^This option is used to change the name of the "main" database
++** schema.  ^The sole argument is a pointer to a constant UTF8 string
++** which will become the new schema name in place of "main".  ^SQLite
++** does not make a copy of the new main schema name string, so the application
++** must ensure that the argument passed into this DBCONFIG option is unchanged
++** until after the database connection closes.
++** </dd>
++**
++** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
++** <dd> Usually, when a database in wal mode is closed or detached from a 
++** database handle, SQLite checks if this will mean that there are now no 
++** connections at all to the database. If so, it performs a checkpoint 
++** operation before closing the connection. This option may be used to
++** override this behaviour. The first parameter passed to this operation
++** is an integer - non-zero to disable checkpoints-on-close, or zero (the
++** default) to enable them. The second parameter is a pointer to an integer
++** into which is written 0 or 1 to indicate whether checkpoints-on-close
++** have been disabled - 0 if they are not disabled, 1 if they are.
++** </dd>
++**
++** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
++** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
++** the [query planner stability guarantee] (QPSG).  When the QPSG is active,
++** a single SQL query statement will always use the same algorithm regardless
++** of values of [bound parameters].)^ The QPSG disables some query optimizations
++** that look at the values of bound parameters, which can make some queries
++** slower.  But the QPSG has the advantage of more predictable behavior.  With
++** the QPSG active, SQLite will always use the same query plan in the field as
++** was used during testing in the lab.
++** </dd>
++**
+ ** </dl>
+ */
+-#define SQLITE_DBCONFIG_LOOKASIDE       1001  /* void* int int */
+-#define SQLITE_DBCONFIG_ENABLE_FKEY     1002  /* int int* */
+-#define SQLITE_DBCONFIG_ENABLE_TRIGGER  1003  /* int int* */
++#define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
++#define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
++#define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
++#define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
++#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
++#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
++#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */
++#define SQLITE_DBCONFIG_ENABLE_QPSG           1007 /* int int* */
+ 
+ 
+ /*
+@@ -2091,7 +3067,7 @@
+ ** [extended result codes] feature of SQLite. ^The extended result
+ ** codes are disabled by default for historical compatibility.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff);
++SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
+ 
+ /*
+ ** CAPI3REF: Last Insert Rowid
+@@ -2105,20 +3081,30 @@
+ ** the table has a column of type [INTEGER PRIMARY KEY] then that column
+ ** is another alias for the rowid.
+ **
+-** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the 
+-** most recent successful [INSERT] into a rowid table or [virtual table]
+-** on database connection D.
+-** ^Inserts into [WITHOUT ROWID] tables are not recorded.
+-** ^If no successful [INSERT]s into rowid tables
+-** have ever occurred on the database connection D, 
+-** then sqlite3_last_insert_rowid(D) returns zero.
+-**
+-** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
+-** method, then this routine will return the [rowid] of the inserted
+-** row as long as the trigger or virtual table method is running.
+-** But once the trigger or virtual table method ends, the value returned 
+-** by this routine reverts to what it was before the trigger or virtual
+-** table method began.)^
++** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
++** the most recent successful [INSERT] into a rowid table or [virtual table]
++** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
++** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred 
++** on the database connection D, then sqlite3_last_insert_rowid(D) returns 
++** zero.
++**
++** As well as being set automatically as rows are inserted into database
++** tables, the value returned by this function may be set explicitly by
++** [sqlite3_set_last_insert_rowid()]
++**
++** Some virtual table implementations may INSERT rows into rowid tables as
++** part of committing a transaction (e.g. to flush data accumulated in memory
++** to disk). In this case subsequent calls to this function return the rowid
++** associated with these internal INSERT operations, which leads to 
++** unintuitive results. Virtual table implementations that do write to rowid
++** tables in this way can avoid this problem by restoring the original 
++** rowid value using [sqlite3_set_last_insert_rowid()] before returning 
++** control to the user.
++**
++** ^(If an [INSERT] occurs within a trigger then this routine will 
++** return the [rowid] of the inserted row as long as the trigger is 
++** running. Once the trigger program ends, the value returned 
++** by this routine reverts to what it was before the trigger was fired.)^
+ **
+ ** ^An [INSERT] that fails due to a constraint violation is not a
+ ** successful [INSERT] and does not change the value returned by this
+@@ -2143,7 +3129,17 @@
+ ** unpredictable and might not equal either the old or the new
+ ** last insert [rowid].
+ */
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*);
++SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
++
++/*
++** CAPI3REF: Set the Last Insert Rowid value.
++** METHOD: sqlite3
++**
++** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
++** set the value returned by calling sqlite3_last_insert_rowid(D) to R 
++** without inserting a row into the database.
++*/
++SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
+ 
+ /*
+ ** CAPI3REF: Count The Number Of Rows Modified
+@@ -2196,7 +3192,7 @@
+ ** while [sqlite3_changes()] is running then the value returned
+ ** is unpredictable and not meaningful.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*);
++SQLITE_API int sqlite3_changes(sqlite3*);
+ 
+ /*
+ ** CAPI3REF: Total Number Of Rows Modified
+@@ -2220,7 +3216,7 @@
+ ** while [sqlite3_total_changes()] is running then the value
+ ** returned is unpredictable and not meaningful.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*);
++SQLITE_API int sqlite3_total_changes(sqlite3*);
+ 
+ /*
+ ** CAPI3REF: Interrupt A Long-Running Query
+@@ -2256,11 +3252,8 @@
+ ** ^A call to sqlite3_interrupt(D) that occurs when there are no running
+ ** SQL statements is a no-op and has no effect on SQL statements
+ ** that are started after the sqlite3_interrupt() call returns.
+-**
+-** If the database connection closes while [sqlite3_interrupt()]
+-** is running then bad things will likely happen.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*);
++SQLITE_API void sqlite3_interrupt(sqlite3*);
+ 
+ /*
+ ** CAPI3REF: Determine If An SQL Statement Is Complete
+@@ -2295,8 +3288,8 @@
+ ** The input to [sqlite3_complete16()] must be a zero-terminated
+ ** UTF-16 string in native byte order.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql);
+-SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql);
++SQLITE_API int sqlite3_complete(const char *sql);
++SQLITE_API int sqlite3_complete16(const void *sql);
+ 
+ /*
+ ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
+@@ -2357,7 +3350,7 @@
+ ** A busy handler must not close the database connection
+ ** or [prepared statement] that invoked the busy handler.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
++SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
+ 
+ /*
+ ** CAPI3REF: Set A Busy Timeout
+@@ -2380,7 +3373,7 @@
+ **
+ ** See also:  [PRAGMA busy_timeout]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms);
++SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
+ 
+ /*
+ ** CAPI3REF: Convenience Routines For Running Queries
+@@ -2455,7 +3448,7 @@
+ ** reflected in subsequent calls to [sqlite3_errcode()] or
+ ** [sqlite3_errmsg()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
++SQLITE_API int sqlite3_get_table(
+   sqlite3 *db,          /* An open database */
+   const char *zSql,     /* SQL to be evaluated */
+   char ***pazResult,    /* Results of the query */
+@@ -2463,7 +3456,7 @@
+   int *pnColumn,        /* Number of result columns written here */
+   char **pzErrmsg       /* Error msg written here */
+ );
+-SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result);
++SQLITE_API void sqlite3_free_table(char **result);
+ 
+ /*
+ ** CAPI3REF: Formatted String Printing Functions
+@@ -2569,10 +3562,10 @@
+ ** addition that after the string has been read and copied into
+ ** the result, [sqlite3_free()] is called on the input string.)^
+ */
+-SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...);
+-SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list);
+-SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...);
+-SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list);
++SQLITE_API char *sqlite3_mprintf(const char*,...);
++SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
++SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
++SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
+ 
+ /*
+ ** CAPI3REF: Memory Allocation Subsystem
+@@ -2662,12 +3655,12 @@
+ ** a block of memory after it has been released using
+ ** [sqlite3_free()] or [sqlite3_realloc()].
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int);
+-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64);
+-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int);
+-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64);
+-SQLITE_API void SQLITE_STDCALL sqlite3_free(void*);
+-SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*);
++SQLITE_API void *sqlite3_malloc(int);
++SQLITE_API void *sqlite3_malloc64(sqlite3_uint64);
++SQLITE_API void *sqlite3_realloc(void*, int);
++SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64);
++SQLITE_API void sqlite3_free(void*);
++SQLITE_API sqlite3_uint64 sqlite3_msize(void*);
+ 
+ /*
+ ** CAPI3REF: Memory Allocator Statistics
+@@ -2692,8 +3685,8 @@
+ ** by [sqlite3_memory_highwater(1)] is the high-water mark
+ ** prior to the reset.
+ */
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void);
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag);
++SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
++SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
+ 
+ /*
+ ** CAPI3REF: Pseudo-Random Number Generator
+@@ -2716,17 +3709,19 @@
+ ** internally and without recourse to the [sqlite3_vfs] xRandomness
+ ** method.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P);
++SQLITE_API void sqlite3_randomness(int N, void *P);
+ 
+ /*
+ ** CAPI3REF: Compile-Time Authorization Callbacks
+ ** METHOD: sqlite3
++** KEYWORDS: {authorizer callback}
+ **
+ ** ^This routine registers an authorizer callback with a particular
+ ** [database connection], supplied in the first argument.
+ ** ^The authorizer callback is invoked as SQL statements are being compiled
+ ** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
+-** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()].  ^At various
++** [sqlite3_prepare_v3()], [sqlite3_prepare16()], [sqlite3_prepare16_v2()],
++** and [sqlite3_prepare16_v3()].  ^At various
+ ** points during the compilation process, as logic is being created
+ ** to perform various actions, the authorizer callback is invoked to
+ ** see if those actions are allowed.  ^The authorizer callback should
+@@ -2748,8 +3743,10 @@
+ ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
+ ** to the callback is an integer [SQLITE_COPY | action code] that specifies
+ ** the particular action to be authorized. ^The third through sixth parameters
+-** to the callback are zero-terminated strings that contain additional
+-** details about the action to be authorized.
++** to the callback are either NULL pointers or zero-terminated strings
++** that contain additional details about the action to be authorized.
++** Applications must always be prepared to encounter a NULL pointer in any
++** of the third through the sixth parameters of the authorization callback.
+ **
+ ** ^If the action code is [SQLITE_READ]
+ ** and the callback returns [SQLITE_IGNORE] then the
+@@ -2758,6 +3755,10 @@
+ ** been read if [SQLITE_OK] had been returned.  The [SQLITE_IGNORE]
+ ** return can be used to deny an untrusted user access to individual
+ ** columns of a table.
++** ^When a table is referenced by a [SELECT] but no column values are
++** extracted from that table (for example in a query like
++** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
++** is invoked once for that table with a column name that is an empty string.
+ ** ^If the action code is [SQLITE_DELETE] and the callback returns
+ ** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
+ ** [truncate optimization] is disabled and all rows are deleted individually.
+@@ -2799,7 +3800,7 @@
+ ** as stated in the previous paragraph, sqlite3_step() invokes
+ ** sqlite3_prepare_v2() to reprepare a statement after a schema change.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
++SQLITE_API int sqlite3_set_authorizer(
+   sqlite3*,
+   int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
+   void *pUserData
+@@ -2879,6 +3880,9 @@
+ ** CAPI3REF: Tracing And Profiling Functions
+ ** METHOD: sqlite3
+ **
++** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
++** instead of the routines described here.
++**
+ ** These routines register callback functions that can be used for
+ ** tracing and profiling the execution of SQL statements.
+ **
+@@ -2904,11 +3908,105 @@
+ ** sqlite3_profile() function is considered experimental and is
+ ** subject to change in future versions of SQLite.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
+-SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*,
++SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
++   void(*xTrace)(void*,const char*), void*);
++SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
+    void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
+ 
+ /*
++** CAPI3REF: SQL Trace Event Codes
++** KEYWORDS: SQLITE_TRACE
++**
++** These constants identify classes of events that can be monitored
++** using the [sqlite3_trace_v2()] tracing logic.  The third argument
++** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
++** the following constants.  ^The first argument to the trace callback
++** is one of the following constants.
++**
++** New tracing constants may be added in future releases.
++**
++** ^A trace callback has four arguments: xCallback(T,C,P,X).
++** ^The T argument is one of the integer type codes above.
++** ^The C argument is a copy of the context pointer passed in as the
++** fourth argument to [sqlite3_trace_v2()].
++** The P and X arguments are pointers whose meanings depend on T.
++**
++** <dl>
++** [[SQLITE_TRACE_STMT]] <dt>SQLITE_TRACE_STMT</dt>
++** <dd>^An SQLITE_TRACE_STMT callback is invoked when a prepared statement
++** first begins running and possibly at other times during the
++** execution of the prepared statement, such as at the start of each
++** trigger subprogram. ^The P argument is a pointer to the
++** [prepared statement]. ^The X argument is a pointer to a string which
++** is the unexpanded SQL text of the prepared statement or an SQL comment 
++** that indicates the invocation of a trigger.  ^The callback can compute
++** the same text that would have been returned by the legacy [sqlite3_trace()]
++** interface by using the X argument when X begins with "--" and invoking
++** [sqlite3_expanded_sql(P)] otherwise.
++**
++** [[SQLITE_TRACE_PROFILE]] <dt>SQLITE_TRACE_PROFILE</dt>
++** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same
++** information as is provided by the [sqlite3_profile()] callback.
++** ^The P argument is a pointer to the [prepared statement] and the
++** X argument points to a 64-bit integer which is the estimated of
++** the number of nanosecond that the prepared statement took to run.
++** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
++**
++** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
++** <dd>^An SQLITE_TRACE_ROW callback is invoked whenever a prepared
++** statement generates a single row of result.  
++** ^The P argument is a pointer to the [prepared statement] and the
++** X argument is unused.
++**
++** [[SQLITE_TRACE_CLOSE]] <dt>SQLITE_TRACE_CLOSE</dt>
++** <dd>^An SQLITE_TRACE_CLOSE callback is invoked when a database
++** connection closes.
++** ^The P argument is a pointer to the [database connection] object
++** and the X argument is unused.
++** </dl>
++*/
++#define SQLITE_TRACE_STMT       0x01
++#define SQLITE_TRACE_PROFILE    0x02
++#define SQLITE_TRACE_ROW        0x04
++#define SQLITE_TRACE_CLOSE      0x08
++
++/*
++** CAPI3REF: SQL Trace Hook
++** METHOD: sqlite3
++**
++** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback
++** function X against [database connection] D, using property mask M
++** and context pointer P.  ^If the X callback is
++** NULL or if the M mask is zero, then tracing is disabled.  The
++** M argument should be the bitwise OR-ed combination of
++** zero or more [SQLITE_TRACE] constants.
++**
++** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides 
++** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2().
++**
++** ^The X callback is invoked whenever any of the events identified by 
++** mask M occur.  ^The integer return value from the callback is currently
++** ignored, though this may change in future releases.  Callback
++** implementations should return zero to ensure future compatibility.
++**
++** ^A trace callback is invoked with four arguments: callback(T,C,P,X).
++** ^The T argument is one of the [SQLITE_TRACE]
++** constants to indicate why the callback was invoked.
++** ^The C argument is a copy of the context pointer.
++** The P and X arguments are pointers whose meanings depend on T.
++**
++** The sqlite3_trace_v2() interface is intended to replace the legacy
++** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
++** are deprecated.
++*/
++SQLITE_API int sqlite3_trace_v2(
++  sqlite3*,
++  unsigned uMask,
++  int(*xCallback)(unsigned,void*,void*,void*),
++  void *pCtx
++);
++
++/*
+ ** CAPI3REF: Query Progress Callbacks
+ ** METHOD: sqlite3
+ **
+@@ -2940,7 +4038,7 @@
+ ** database connections for the meaning of "modify" in this paragraph.
+ **
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
++SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+ 
+ /*
+ ** CAPI3REF: Opening A New Database Connection
+@@ -3169,15 +4267,15 @@
+ **
+ ** See also: [sqlite3_temp_directory]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_open(
++SQLITE_API int sqlite3_open(
+   const char *filename,   /* Database filename (UTF-8) */
+   sqlite3 **ppDb          /* OUT: SQLite db handle */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_open16(
++SQLITE_API int sqlite3_open16(
+   const void *filename,   /* Database filename (UTF-16) */
+   sqlite3 **ppDb          /* OUT: SQLite db handle */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
++SQLITE_API int sqlite3_open_v2(
+   const char *filename,   /* Database filename (UTF-8) */
+   sqlite3 **ppDb,         /* OUT: SQLite db handle */
+   int flags,              /* Flags */
+@@ -3223,9 +4321,9 @@
+ ** VFS method, then the behavior of this routine is undefined and probably
+ ** undesirable.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam);
+-SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
++SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
++SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
++SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
+ 
+ 
+ /*
+@@ -3269,11 +4367,11 @@
+ ** was invoked incorrectly by the application.  In that case, the
+ ** error code and message may or may not be set.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db);
+-SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db);
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*);
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int);
++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: Prepared Statement Object
+@@ -3341,7 +4439,7 @@
+ **
+ ** New run-time limit categories may be added in future releases.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
++SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
+ 
+ /*
+ ** CAPI3REF: Run-Time Limit Categories
+@@ -3372,9 +4470,9 @@
+ **
+ ** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
+ ** <dd>The maximum number of instructions in a virtual machine program
+-** used to implement an SQL statement.  This limit is not currently
+-** enforced, though that might be added in some future release of
+-** SQLite.</dd>)^
++** used to implement an SQL statement.  If [sqlite3_prepare_v2()] or
++** the equivalent tries to allocate space for more than this many opcodes
++** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^
+ **
+ ** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
+ ** <dd>The maximum number of arguments on a function.</dd>)^
+@@ -3413,22 +4511,58 @@
+ #define SQLITE_LIMIT_WORKER_THREADS           11
+ 
+ /*
++** CAPI3REF: Prepare Flags
++**
++** These constants define various flags that can be passed into
++** "prepFlags" parameter of the [sqlite3_prepare_v3()] and
++** [sqlite3_prepare16_v3()] interfaces.
++**
++** New flags may be added in future releases of SQLite.
++**
++** <dl>
++** [[SQLITE_PREPARE_PERSISTENT]] ^(<dt>SQLITE_PREPARE_PERSISTENT</dt>
++** <dd>The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner
++** that the prepared statement will be retained for a long time and
++** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()]
++** and [sqlite3_prepare16_v3()] assume that the prepared statement will 
++** be used just once or at most a few times and then destroyed using
++** [sqlite3_finalize()] relatively soon. The current implementation acts
++** on this hint by avoiding the use of [lookaside memory] so as not to
++** deplete the limited store of lookaside memory. Future versions of
++** SQLite may act on this hint differently.
++** </dl>
++*/
++#define SQLITE_PREPARE_PERSISTENT              0x01
++
++/*
+ ** CAPI3REF: Compiling An SQL Statement
+ ** KEYWORDS: {SQL statement compiler}
+ ** METHOD: sqlite3
+ ** CONSTRUCTOR: sqlite3_stmt
+ **
+-** To execute an SQL query, it must first be compiled into a byte-code
+-** program using one of these routines.
++** To execute an SQL statement, it must first be compiled into a byte-code
++** program using one of these routines.  Or, in other words, these routines
++** are constructors for the [prepared statement] object.
++**
++** The preferred routine to use is [sqlite3_prepare_v2()].  The
++** [sqlite3_prepare()] interface is legacy and should be avoided.
++** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used
++** for special purposes.
++**
++** The use of the UTF-8 interfaces is preferred, as SQLite currently
++** does all parsing using UTF-8.  The UTF-16 interfaces are provided
++** as a convenience.  The UTF-16 interfaces work by converting the
++** input text into UTF-8, then invoking the corresponding UTF-8 interface.
+ **
+ ** The first argument, "db", is a [database connection] obtained from a
+ ** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
+ ** [sqlite3_open16()].  The database connection must not have been closed.
+ **
+ ** The second argument, "zSql", is the statement to be compiled, encoded
+-** as either UTF-8 or UTF-16.  The sqlite3_prepare() and sqlite3_prepare_v2()
+-** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
+-** use UTF-16.
++** as either UTF-8 or UTF-16.  The sqlite3_prepare(), sqlite3_prepare_v2(),
++** and sqlite3_prepare_v3()
++** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(),
++** and sqlite3_prepare16_v3() use UTF-16.
+ **
+ ** ^If the nByte argument is negative, then zSql is read up to the
+ ** first zero terminator. ^If nByte is positive, then it is the
+@@ -3455,10 +4589,11 @@
+ ** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK];
+ ** otherwise an [error code] is returned.
+ **
+-** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
+-** recommended for all new programs. The two older interfaces are retained
+-** for backwards compatibility, but their use is discouraged.
+-** ^In the "v2" interfaces, the prepared statement
++** The sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(),
++** and sqlite3_prepare16_v3() interfaces are recommended for all new programs.
++** The older interfaces (sqlite3_prepare() and sqlite3_prepare16())
++** are retained for backwards compatibility, but their use is discouraged.
++** ^In the "vX" interfaces, the prepared statement
+ ** that is returned (the [sqlite3_stmt] object) contains a copy of the
+ ** original SQL text. This causes the [sqlite3_step()] interface to
+ ** behave differently in three ways:
+@@ -3491,33 +4626,55 @@
+ ** or [GLOB] operator or if the parameter is compared to an indexed column
+ ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
+ ** </li>
++**
++** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
++** the extra prepFlags parameter, which is a bit array consisting of zero or
++** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags.  ^The
++** sqlite3_prepare_v2() interface works exactly the same as
++** sqlite3_prepare_v3() with a zero prepFlags parameter.
+ ** </ol>
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
++SQLITE_API int sqlite3_prepare(
++  sqlite3 *db,            /* Database handle */
++  const char *zSql,       /* SQL statement, UTF-8 encoded */
++  int nByte,              /* Maximum length of zSql in bytes. */
++  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
++  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
++);
++SQLITE_API int sqlite3_prepare_v2(
+   sqlite3 *db,            /* Database handle */
+   const char *zSql,       /* SQL statement, UTF-8 encoded */
+   int nByte,              /* Maximum length of zSql in bytes. */
+   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+   const char **pzTail     /* OUT: Pointer to unused portion of zSql */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
++SQLITE_API int sqlite3_prepare_v3(
+   sqlite3 *db,            /* Database handle */
+   const char *zSql,       /* SQL statement, UTF-8 encoded */
+   int nByte,              /* Maximum length of zSql in bytes. */
++  unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
+   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+   const char **pzTail     /* OUT: Pointer to unused portion of zSql */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
++SQLITE_API int sqlite3_prepare16(
++  sqlite3 *db,            /* Database handle */
++  const void *zSql,       /* SQL statement, UTF-16 encoded */
++  int nByte,              /* Maximum length of zSql in bytes. */
++  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
++  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
++);
++SQLITE_API int sqlite3_prepare16_v2(
+   sqlite3 *db,            /* Database handle */
+   const void *zSql,       /* SQL statement, UTF-16 encoded */
+   int nByte,              /* Maximum length of zSql in bytes. */
+   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+   const void **pzTail     /* OUT: Pointer to unused portion of zSql */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
++SQLITE_API int sqlite3_prepare16_v3(
+   sqlite3 *db,            /* Database handle */
+   const void *zSql,       /* SQL statement, UTF-16 encoded */
+   int nByte,              /* Maximum length of zSql in bytes. */
++  unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
+   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+   const void **pzTail     /* OUT: Pointer to unused portion of zSql */
+ );
+@@ -3526,11 +4683,36 @@
+ ** CAPI3REF: Retrieving Statement SQL
+ ** METHOD: sqlite3_stmt
+ **
+-** ^This interface can be used to retrieve a saved copy of the original
+-** SQL text used to create a [prepared statement] if that statement was
+-** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
++** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8
++** SQL text used to create [prepared statement] P if P was
++** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
++** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
++** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
++** string containing the SQL text of prepared statement P with
++** [bound parameters] expanded.
++**
++** ^(For example, if a prepared statement is created using the SQL
++** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
++** and parameter :xyz is unbound, then sqlite3_sql() will return
++** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
++** will return "SELECT 2345,NULL".)^
++**
++** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory
++** is available to hold the result, or if the result would exceed the
++** the maximum string length determined by the [SQLITE_LIMIT_LENGTH].
++**
++** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
++** bound parameter expansions.  ^The [SQLITE_OMIT_TRACE] compile-time
++** option causes sqlite3_expanded_sql() to always return NULL.
++**
++** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
++** automatically freed when the prepared statement is finalized.
++** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
++** is obtained from [sqlite3_malloc()] and must be free by the application
++** by passing it to [sqlite3_free()].
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt);
++SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
++SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Determine If An SQL Statement Writes The Database
+@@ -3561,8 +4743,12 @@
+ ** sqlite3_stmt_readonly() to return true since, while those statements
+ ** change the configuration of a database connection, they do not make 
+ ** changes to the content of the database files on disk.
++** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since
++** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
++** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
++** sqlite3_stmt_readonly() returns false for those commands.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
++SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
+@@ -3570,7 +4756,8 @@
+ **
+ ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
+ ** [prepared statement] S has been stepped at least once using 
+-** [sqlite3_step(S)] but has not run to completion and/or has not 
++** [sqlite3_step(S)] but has neither run to completion (returned
++** [SQLITE_DONE] from [sqlite3_step(S)]) nor
+ ** been reset using [sqlite3_reset(S)].  ^The sqlite3_stmt_busy(S)
+ ** interface returns false if S is a NULL pointer.  If S is not a 
+ ** NULL pointer and is not a pointer to a valid [prepared statement]
+@@ -3582,7 +4769,7 @@
+ ** for example, in diagnostic routines to search for prepared 
+ ** statements that are holding a transaction open.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*);
++SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
+ 
+ /*
+ ** CAPI3REF: Dynamically Typed Value Object
+@@ -3597,7 +4784,9 @@
+ ** Some interfaces require a protected sqlite3_value.  Other interfaces
+ ** will accept either a protected or an unprotected sqlite3_value.
+ ** Every interface that accepts sqlite3_value arguments specifies
+-** whether or not it requires a protected sqlite3_value.
++** whether or not it requires a protected sqlite3_value.  The
++** [sqlite3_value_dup()] interface can be used to construct a new 
++** protected sqlite3_value from an unprotected sqlite3_value.
+ **
+ ** The terms "protected" and "unprotected" refer to whether or not
+ ** a mutex is held.  An internal mutex is held for a protected
+@@ -3621,7 +4810,7 @@
+ ** The [sqlite3_value_blob | sqlite3_value_type()] family of
+ ** interfaces require protected sqlite3_value objects.
+ */
+-typedef struct Mem sqlite3_value;
++typedef struct sqlite3_value sqlite3_value;
+ 
+ /*
+ ** CAPI3REF: SQL Function Context Object
+@@ -3723,6 +4912,15 @@
+ ** [sqlite3_blob_open | incremental BLOB I/O] routines.
+ ** ^A negative value for the zeroblob results in a zero-length BLOB.
+ **
++** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
++** [prepared statement] S to have an SQL value of NULL, but to also be
++** associated with the pointer P of type T.  ^D is either a NULL pointer or
++** a pointer to a destructor function for P. ^SQLite will invoke the
++** destructor D with a single argument of P when it is finished using
++** P.  The T parameter should be a static string, preferably a string
++** literal. The sqlite3_bind_pointer() routine is part of the
++** [pointer passing interface] added for SQLite 3.20.0.
++**
+ ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
+ ** for the [prepared statement] or with a prepared statement for which
+ ** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
+@@ -3744,19 +4942,21 @@
+ ** See also: [sqlite3_bind_parameter_count()],
+ ** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
++SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
++SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
+                         void(*)(void*));
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double);
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int);
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int);
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
++SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
++SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
++SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
++SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
++SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
++SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
++SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
+                          void(*)(void*), unsigned char encoding);
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
++SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
++SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
++SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
++SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
+ 
+ /*
+ ** CAPI3REF: Number Of SQL Parameters
+@@ -3777,7 +4977,7 @@
+ ** [sqlite3_bind_parameter_name()], and
+ ** [sqlite3_bind_parameter_index()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
++SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
+ 
+ /*
+ ** CAPI3REF: Name Of A Host Parameter
+@@ -3798,14 +4998,14 @@
+ ** ^If the value N is out of range or if the N-th parameter is
+ ** nameless, then NULL is returned.  ^The returned string is
+ ** always in UTF-8 encoding even if the named parameter was
+-** originally specified as UTF-16 in [sqlite3_prepare16()] or
+-** [sqlite3_prepare16_v2()].
++** originally specified as UTF-16 in [sqlite3_prepare16()],
++** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
+ **
+ ** See also: [sqlite3_bind_blob|sqlite3_bind()],
+ ** [sqlite3_bind_parameter_count()], and
+ ** [sqlite3_bind_parameter_index()].
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int);
++SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+ 
+ /*
+ ** CAPI3REF: Index Of A Parameter With A Given Name
+@@ -3816,13 +5016,14 @@
+ ** parameter to [sqlite3_bind_blob|sqlite3_bind()].  ^A zero
+ ** is returned if no matching parameter is found.  ^The parameter
+ ** name must be given in UTF-8 even if the original statement
+-** was prepared from UTF-16 text using [sqlite3_prepare16_v2()].
++** was prepared from UTF-16 text using [sqlite3_prepare16_v2()] or
++** [sqlite3_prepare16_v3()].
+ **
+ ** See also: [sqlite3_bind_blob|sqlite3_bind()],
+ ** [sqlite3_bind_parameter_count()], and
+-** [sqlite3_bind_parameter_index()].
++** [sqlite3_bind_parameter_name()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
++SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+ 
+ /*
+ ** CAPI3REF: Reset All Bindings On A Prepared Statement
+@@ -3832,19 +5033,23 @@
+ ** the [sqlite3_bind_blob | bindings] on a [prepared statement].
+ ** ^Use this routine to reset all host parameters to NULL.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*);
++SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
+ 
+ /*
+ ** CAPI3REF: Number Of Columns In A Result Set
+ ** METHOD: sqlite3_stmt
+ **
+ ** ^Return the number of columns in the result set returned by the
+-** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
+-** statement that does not return data (for example an [UPDATE]).
++** [prepared statement]. ^If this routine returns 0, that means the 
++** [prepared statement] returns no data (for example an [UPDATE]).
++** ^However, just because this routine returns a positive number does not
++** mean that one or more rows of data will be returned.  ^A SELECT statement
++** will always have a positive sqlite3_column_count() but depending on the
++** WHERE clause constraints and the table content, it might return no rows.
+ **
+ ** See also: [sqlite3_data_count()]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt);
++SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Column Names In A Result Set
+@@ -3873,8 +5078,8 @@
+ ** then the name of the column is unspecified and may change from
+ ** one release of SQLite to the next.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N);
++SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
++SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
+ 
+ /*
+ ** CAPI3REF: Source Of Data In A Query Result
+@@ -3922,12 +5127,12 @@
+ ** for the same [prepared statement] and result column
+ ** at the same time then the results are undefined.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int);
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int);
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int);
++SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
++SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
++SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
++SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
++SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
++SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
+ 
+ /*
+ ** CAPI3REF: Declared Datatype Of A Query Result
+@@ -3959,23 +5164,25 @@
+ ** is associated with individual values, not with the containers
+ ** used to hold those values.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int);
++SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
++SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
+ 
+ /*
+ ** CAPI3REF: Evaluate An SQL Statement
+ ** METHOD: sqlite3_stmt
+ **
+-** After a [prepared statement] has been prepared using either
+-** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
++** After a [prepared statement] has been prepared using any of
++** [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()],
++** or [sqlite3_prepare16_v3()] or one of the legacy
+ ** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
+ ** must be called one or more times to evaluate the statement.
+ **
+ ** The details of the behavior of the sqlite3_step() interface depend
+-** on whether the statement was prepared using the newer "v2" interface
+-** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy
+-** interface [sqlite3_prepare()] and [sqlite3_prepare16()].  The use of the
+-** new "v2" interface is recommended for new applications but the legacy
++** on whether the statement was prepared using the newer "vX" interfaces
++** [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()],
++** [sqlite3_prepare16_v2()] or the older legacy
++** interfaces [sqlite3_prepare()] and [sqlite3_prepare16()].  The use of the
++** new "vX" interface is recommended for new applications but the legacy
+ ** interface will continue to be supported.
+ **
+ ** ^In the legacy interface, the return value will be either [SQLITE_BUSY],
+@@ -4021,7 +5228,8 @@
+ ** other than [SQLITE_ROW] before any subsequent invocation of
+ ** sqlite3_step().  Failure to reset the prepared statement using 
+ ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
+-** sqlite3_step().  But after version 3.6.23.1, sqlite3_step() began
++** sqlite3_step().  But after [version 3.6.23.1] ([dateof:3.6.23.1]),
++** sqlite3_step() began
+ ** calling [sqlite3_reset()] automatically in this circumstance rather
+ ** than returning [SQLITE_MISUSE].  This is not considered a compatibility
+ ** break because any application that ever receives an SQLITE_MISUSE error
+@@ -4035,12 +5243,13 @@
+ ** specific [error codes] that better describes the error.
+ ** We admit that this is a goofy design.  The problem has been fixed
+ ** with the "v2" interface.  If you prepare all of your SQL statements
+-** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
++** using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()]
++** or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead
+ ** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
+ ** then the more specific [error codes] are returned directly
+-** by sqlite3_step().  The use of the "v2" interface is recommended.
++** by sqlite3_step().  The use of the "vX" interfaces is recommended.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*);
++SQLITE_API int sqlite3_step(sqlite3_stmt*);
+ 
+ /*
+ ** CAPI3REF: Number of columns in a result set
+@@ -4061,7 +5270,7 @@
+ **
+ ** See also: [sqlite3_column_count()]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
++SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Fundamental Datatypes
+@@ -4100,7 +5309,27 @@
+ ** KEYWORDS: {column access functions}
+ ** METHOD: sqlite3_stmt
+ **
+-** These routines form the "result set" interface.
++** <b>Summary:</b>
++** <blockquote><table border=0 cellpadding=0 cellspacing=0>
++** <tr><td><b>sqlite3_column_blob</b><td>&rarr;<td>BLOB result
++** <tr><td><b>sqlite3_column_double</b><td>&rarr;<td>REAL result
++** <tr><td><b>sqlite3_column_int</b><td>&rarr;<td>32-bit INTEGER result
++** <tr><td><b>sqlite3_column_int64</b><td>&rarr;<td>64-bit INTEGER result
++** <tr><td><b>sqlite3_column_text</b><td>&rarr;<td>UTF-8 TEXT result
++** <tr><td><b>sqlite3_column_text16</b><td>&rarr;<td>UTF-16 TEXT result
++** <tr><td><b>sqlite3_column_value</b><td>&rarr;<td>The result as an 
++** [sqlite3_value|unprotected sqlite3_value] object.
++** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
++** <tr><td><b>sqlite3_column_bytes</b><td>&rarr;<td>Size of a BLOB
++** or a UTF-8 TEXT result in bytes
++** <tr><td><b>sqlite3_column_bytes16&nbsp;&nbsp;</b>
++** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
++** TEXT in bytes
++** <tr><td><b>sqlite3_column_type</b><td>&rarr;<td>Default
++** datatype of the result
++** </table></blockquote>
++**
++** <b>Details:</b>
+ **
+ ** ^These routines return information about a single column of the current
+ ** result row of a query.  ^In every case the first argument is a pointer
+@@ -4123,16 +5352,29 @@
+ ** are called from a different thread while any of these routines
+ ** are pending, then the results are undefined.
+ **
++** The first six interfaces (_blob, _double, _int, _int64, _text, and _text16)
++** each return the value of a result column in a specific data format.  If
++** the result column is not initially in the requested format (for example,
++** if the query returns an integer but the sqlite3_column_text() interface
++** is used to extract the value) then an automatic type conversion is performed.
++**
+ ** ^The sqlite3_column_type() routine returns the
+ ** [SQLITE_INTEGER | datatype code] for the initial data type
+ ** of the result column.  ^The returned value is one of [SQLITE_INTEGER],
+-** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].  The value
+-** returned by sqlite3_column_type() is only meaningful if no type
+-** conversions have occurred as described below.  After a type conversion,
+-** the value returned by sqlite3_column_type() is undefined.  Future
++** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].
++** The return value of sqlite3_column_type() can be used to decide which
++** of the first six interface should be used to extract the column value.
++** The value returned by sqlite3_column_type() is only meaningful if no
++** automatic type conversions have occurred for the value in question.  
++** After a type conversion, the result of calling sqlite3_column_type()
++** is undefined, though harmless.  Future
+ ** versions of SQLite may change the behavior of sqlite3_column_type()
+ ** following a type conversion.
+ **
++** If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes()
++** or sqlite3_column_bytes16() interfaces can be used to determine the size
++** of that BLOB or string.
++**
+ ** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
+ ** routine returns the number of bytes in that BLOB or string.
+ ** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts
+@@ -4161,16 +5403,21 @@
+ ** even empty strings, are always zero-terminated.  ^The return
+ ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
+ **
+-** ^The object returned by [sqlite3_column_value()] is an
+-** [unprotected sqlite3_value] object.  An unprotected sqlite3_value object
+-** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
++** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
++** [unprotected sqlite3_value] object.  In a multithreaded environment,
++** an unprotected sqlite3_value object may only be used safely with
++** [sqlite3_bind_value()] and [sqlite3_result_value()].
+ ** If the [unprotected sqlite3_value] object returned by
+ ** [sqlite3_column_value()] is used in any other way, including calls
+ ** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
+-** or [sqlite3_value_bytes()], then the behavior is undefined.
++** or [sqlite3_value_bytes()], the behavior is not threadsafe.
++** Hence, the sqlite3_column_value() interface
++** is normally only useful within the implementation of 
++** [application-defined SQL functions] or [virtual tables], not within
++** top-level application code.
+ **
+-** These routines attempt to convert the value where appropriate.  ^For
+-** example, if the internal representation is FLOAT and a text result
++** The these routines may attempt to convert the datatype of the result.
++** ^For example, if the internal representation is FLOAT and a text result
+ ** is requested, [sqlite3_snprintf()] is used internally to perform the
+ ** conversion automatically.  ^(The following table details the conversions
+ ** that are applied:
+@@ -4198,12 +5445,6 @@
+ ** </table>
+ ** </blockquote>)^
+ **
+-** The table above makes reference to standard C library functions atoi()
+-** and atof().  SQLite does not really use these functions.  It has its
+-** own equivalent internal routines.  The atoi() and atof() names are
+-** used in the table for brevity and because they are familiar to most
+-** C programmers.
+-**
+ ** Note that when type conversions occur, pointers returned by prior
+ ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
+ ** sqlite3_column_text16() may be invalidated.
+@@ -4228,7 +5469,7 @@
+ ** of conversion are done in place when it is possible, but sometimes they
+ ** are not possible and in those cases prior pointers are invalidated.
+ **
+-** The safest and easiest to remember policy is to invoke these routines
++** The safest policy is to invoke these routines
+ ** in one of the following ways:
+ **
+ ** <ul>
+@@ -4248,7 +5489,7 @@
+ ** ^The pointers returned are valid until a type conversion occurs as
+ ** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
+ ** [sqlite3_finalize()] is called.  ^The memory space used to hold strings
+-** and BLOBs is freed automatically.  Do <b>not</b> pass the pointers returned
++** and BLOBs is freed automatically.  Do not pass the pointers returned
+ ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
+ ** [sqlite3_free()].
+ **
+@@ -4258,16 +5499,16 @@
+ ** pointer.  Subsequent calls to [sqlite3_errcode()] will return
+ ** [SQLITE_NOMEM].)^
+ */
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol);
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+-SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol);
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol);
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol);
+-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol);
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol);
+-SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol);
++SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
++SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
++SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
++SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
++SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
++SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
++SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
++SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
++SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
++SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
+ 
+ /*
+ ** CAPI3REF: Destroy A Prepared Statement Object
+@@ -4295,7 +5536,7 @@
+ ** statement after it has been finalized can result in undefined and
+ ** undesirable behavior such as segfaults and heap corruption.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt);
++SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Reset A Prepared Statement Object
+@@ -4322,7 +5563,7 @@
+ ** ^The [sqlite3_reset(S)] interface does not change the values
+ ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt);
++SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Create Or Redefine SQL Functions
+@@ -4422,7 +5663,7 @@
+ ** close the database connection nor finalize or reset the prepared
+ ** statement in which the function is running.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
++SQLITE_API int sqlite3_create_function(
+   sqlite3 *db,
+   const char *zFunctionName,
+   int nArg,
+@@ -4432,7 +5673,7 @@
+   void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+   void (*xFinal)(sqlite3_context*)
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
++SQLITE_API int sqlite3_create_function16(
+   sqlite3 *db,
+   const void *zFunctionName,
+   int nArg,
+@@ -4442,7 +5683,7 @@
+   void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+   void (*xFinal)(sqlite3_context*)
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
++SQLITE_API int sqlite3_create_function_v2(
+   sqlite3 *db,
+   const char *zFunctionName,
+   int nArg,
+@@ -4488,34 +5729,53 @@
+ ** these functions, we will not explain what they do.
+ */
+ #ifndef SQLITE_OMIT_DEPRECATED
+-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*);
+-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*);
+-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void);
+-SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void);
+-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
++SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
++SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
++SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
++SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
++SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
++SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+                       void*,sqlite3_int64);
+ #endif
+ 
+ /*
+-** CAPI3REF: Obtaining SQL Function Parameter Values
++** CAPI3REF: Obtaining SQL Values
+ ** METHOD: sqlite3_value
+ **
+-** The C-language implementation of SQL functions and aggregates uses
+-** this set of interface routines to access the parameter values on
+-** the function or aggregate.
+-**
+-** The xFunc (for scalar functions) or xStep (for aggregates) parameters
+-** to [sqlite3_create_function()] and [sqlite3_create_function16()]
+-** define callbacks that implement the SQL functions and aggregates.
+-** The 3rd parameter to these callbacks is an array of pointers to
+-** [protected sqlite3_value] objects.  There is one [sqlite3_value] object for
+-** each parameter to the SQL function.  These routines are used to
+-** extract values from the [sqlite3_value] objects.
++** <b>Summary:</b>
++** <blockquote><table border=0 cellpadding=0 cellspacing=0>
++** <tr><td><b>sqlite3_value_blob</b><td>&rarr;<td>BLOB value
++** <tr><td><b>sqlite3_value_double</b><td>&rarr;<td>REAL value
++** <tr><td><b>sqlite3_value_int</b><td>&rarr;<td>32-bit INTEGER value
++** <tr><td><b>sqlite3_value_int64</b><td>&rarr;<td>64-bit INTEGER value
++** <tr><td><b>sqlite3_value_pointer</b><td>&rarr;<td>Pointer value
++** <tr><td><b>sqlite3_value_text</b><td>&rarr;<td>UTF-8 TEXT value
++** <tr><td><b>sqlite3_value_text16</b><td>&rarr;<td>UTF-16 TEXT value in
++** the native byteorder
++** <tr><td><b>sqlite3_value_text16be</b><td>&rarr;<td>UTF-16be TEXT value
++** <tr><td><b>sqlite3_value_text16le</b><td>&rarr;<td>UTF-16le TEXT value
++** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
++** <tr><td><b>sqlite3_value_bytes</b><td>&rarr;<td>Size of a BLOB
++** or a UTF-8 TEXT in bytes
++** <tr><td><b>sqlite3_value_bytes16&nbsp;&nbsp;</b>
++** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
++** TEXT in bytes
++** <tr><td><b>sqlite3_value_type</b><td>&rarr;<td>Default
++** datatype of the value
++** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
++** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
++** </table></blockquote>
++**
++** <b>Details:</b>
++**
++** These routines extract type, size, and content information from
++** [protected sqlite3_value] objects.  Protected sqlite3_value objects
++** are used to pass parameter information into implementation of
++** [application-defined SQL functions] and [virtual tables].
+ **
+ ** These routines work only with [protected sqlite3_value] objects.
+ ** Any attempt to use these routines on an [unprotected sqlite3_value]
+-** object results in undefined behavior.
++** is not threadsafe.
+ **
+ ** ^These routines work just like the corresponding [column access functions]
+ ** except that these routines take a single [protected sqlite3_value] object
+@@ -4526,6 +5786,24 @@
+ ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces
+ ** extract UTF-16 strings as big-endian and little-endian respectively.
+ **
++** ^If [sqlite3_value] object V was initialized 
++** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)]
++** and if X and Y are strings that compare equal according to strcmp(X,Y),
++** then sqlite3_value_pointer(V,Y) will return the pointer P.  ^Otherwise,
++** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer() 
++** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
++**
++** ^(The sqlite3_value_type(V) interface returns the
++** [SQLITE_INTEGER | datatype code] for the initial datatype of the
++** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER],
++** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^
++** Other interfaces might change the datatype for an sqlite3_value object.
++** For example, if the datatype is initially SQLITE_INTEGER and
++** sqlite3_value_text(V) is called to extract a text value for that
++** integer, then subsequent calls to sqlite3_value_type(V) might return
++** SQLITE_TEXT.  Whether or not a persistent internal datatype conversion
++** occurs is undefined and may change from one release of SQLite to the next.
++**
+ ** ^(The sqlite3_value_numeric_type() interface attempts to apply
+ ** numeric affinity to the value.  This means that an attempt is
+ ** made to convert the value to an integer or floating point.  If
+@@ -4543,18 +5821,48 @@
+ ** These routines must be called from the same thread as
+ ** the SQL function that supplied the [sqlite3_value*] parameters.
+ */
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*);
+-SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*);
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*);
+-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
++SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
++SQLITE_API double sqlite3_value_double(sqlite3_value*);
++SQLITE_API int sqlite3_value_int(sqlite3_value*);
++SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
++SQLITE_API void *sqlite3_value_pointer(sqlite3_value*, const char*);
++SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
++SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
++SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
++SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
++SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
++SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
++SQLITE_API int sqlite3_value_type(sqlite3_value*);
++SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
++
++/*
++** CAPI3REF: Finding The Subtype Of SQL Values
++** METHOD: sqlite3_value
++**
++** The sqlite3_value_subtype(V) function returns the subtype for
++** an [application-defined SQL function] argument V.  The subtype
++** information can be used to pass a limited amount of context from
++** one SQL function to another.  Use the [sqlite3_result_subtype()]
++** routine to set the subtype for the return value of an SQL function.
++*/
++SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
++
++/*
++** CAPI3REF: Copy And Free SQL Values
++** METHOD: sqlite3_value
++**
++** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
++** object D and returns a pointer to that copy.  ^The [sqlite3_value] returned
++** is a [protected sqlite3_value] object even if the input is not.
++** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
++** memory allocation fails.
++**
++** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
++** previously obtained from [sqlite3_value_dup()].  ^If V is a NULL pointer
++** then sqlite3_value_free(V) is a harmless no-op.
++*/
++SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
++SQLITE_API void sqlite3_value_free(sqlite3_value*);
+ 
+ /*
+ ** CAPI3REF: Obtain Aggregate Function Context
+@@ -4599,7 +5907,7 @@
+ ** This routine must be called from the same thread in which
+ ** the aggregate SQL function is running.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes);
++SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
+ 
+ /*
+ ** CAPI3REF: User Data For Functions
+@@ -4614,7 +5922,7 @@
+ ** This routine must be called from the same thread in which
+ ** the application-defined function is running.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*);
++SQLITE_API void *sqlite3_user_data(sqlite3_context*);
+ 
+ /*
+ ** CAPI3REF: Database Connection For Functions
+@@ -4626,7 +5934,7 @@
+ ** and [sqlite3_create_function16()] routines that originally
+ ** registered the application defined function.
+ */
+-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*);
++SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
+ 
+ /*
+ ** CAPI3REF: Function Auxiliary Data
+@@ -4643,10 +5951,11 @@
+ ** the compiled regular expression can be reused on multiple
+ ** invocations of the same function.
+ **
+-** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
+-** associated by the sqlite3_set_auxdata() function with the Nth argument
+-** value to the application-defined function. ^If there is no metadata
+-** associated with the function argument, this sqlite3_get_auxdata() interface
++** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
++** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
++** value to the application-defined function.  ^N is zero for the left-most
++** function argument.  ^If there is no metadata
++** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
+ ** returns a NULL pointer.
+ **
+ ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
+@@ -4658,12 +5967,13 @@
+ ** SQLite will invoke the destructor function X with parameter P exactly
+ ** once, when the metadata is discarded.
+ ** SQLite is free to discard the metadata at any time, including: <ul>
+-** <li> when the corresponding function parameter changes, or
+-** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+-**      SQL statement, or
+-** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
+-** <li> during the original sqlite3_set_auxdata() call when a memory 
+-**      allocation error occurs. </ul>)^
++** <li> ^(when the corresponding function parameter changes)^, or
++** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
++**      SQL statement)^, or
++** <li> ^(when sqlite3_set_auxdata() is invoked again on the same
++**       parameter)^, or
++** <li> ^(during the original sqlite3_set_auxdata() call when a memory 
++**      allocation error occurs.)^ </ul>
+ **
+ ** Note the last bullet in particular.  The destructor X in 
+ ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
+@@ -4676,11 +5986,15 @@
+ ** function parameters that are compile-time constants, including literal
+ ** values and [parameters] and expressions composed from the same.)^
+ **
++** The value of the N parameter to these interfaces should be non-negative.
++** Future enhancements may make use of negative N values to define new
++** kinds of function caching behavior.
++**
+ ** These routines must be called from the same thread in which
+ ** the SQL function is running.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N);
+-SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
++SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
++SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
+ 
+ 
+ /*
+@@ -4719,9 +6033,9 @@
+ ** to by the second parameter and which is N bytes long where N is the
+ ** third parameter.
+ **
+-** ^The sqlite3_result_zeroblob() interfaces set the result of
+-** the application-defined function to be a BLOB containing all zero
+-** bytes and N bytes in size, where N is the value of the 2nd parameter.
++** ^The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N)
++** interfaces set the result of the application-defined function to be
++** a BLOB containing all zero bytes and N bytes in size.
+ **
+ ** ^The sqlite3_result_double() interface sets the result from
+ ** an application-defined function to be a floating point value specified
+@@ -4799,11 +6113,11 @@
+ ** when it has finished using that result.
+ ** ^If the 4th parameter to the sqlite3_result_text* interfaces
+ ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
+-** then SQLite makes a copy of the result into space obtained from
++** then SQLite makes a copy of the result into space obtained
+ ** from [sqlite3_malloc()] before it returns.
+ **
+ ** ^The sqlite3_result_value() interface sets the result of
+-** the application-defined function to be a copy the
++** the application-defined function to be a copy of the
+ ** [unprotected sqlite3_value] object specified by the 2nd parameter.  ^The
+ ** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
+ ** so that the [sqlite3_value] specified in the parameter may change or
+@@ -4812,30 +6126,58 @@
+ ** [unprotected sqlite3_value] object is required, so either
+ ** kind of [sqlite3_value] object can be used with this interface.
+ **
++** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an
++** SQL NULL value, just like [sqlite3_result_null(C)], except that it
++** also associates the host-language pointer P or type T with that 
++** NULL value such that the pointer can be retrieved within an
++** [application-defined SQL function] using [sqlite3_value_pointer()].
++** ^If the D parameter is not NULL, then it is a pointer to a destructor
++** for the P parameter.  ^SQLite invokes D with P as its only argument
++** when SQLite is finished with P.  The T parameter should be a static
++** string and preferably a string literal. The sqlite3_result_pointer()
++** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
++**
+ ** If these routines are called from within the different thread
+ ** than the one containing the application-defined function that received
+ ** the [sqlite3_context] pointer, the results are undefined.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*,
++SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
++SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
+                            sqlite3_uint64,void(*)(void*));
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
++SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
++SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
++SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
++SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
++SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
++SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
++SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
++SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
++SQLITE_API void sqlite3_result_null(sqlite3_context*);
++SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
++SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
+                            void(*)(void*), unsigned char encoding);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
++SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
++SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
++SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
++SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
++SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*));
++SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
++SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
++
++
++/*
++** CAPI3REF: Setting The Subtype Of An SQL Function
++** METHOD: sqlite3_context
++**
++** The sqlite3_result_subtype(C,T) function causes the subtype of
++** the result from the [application-defined SQL function] with 
++** [sqlite3_context] C to be the value T.  Only the lower 8 bits 
++** of the subtype T are preserved in current versions of SQLite;
++** higher order bits are discarded.
++** The number of subtype bytes preserved by SQLite might increase
++** in future releases of SQLite.
++*/
++SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
+ 
+ /*
+ ** CAPI3REF: Define New Collating Sequences
+@@ -4917,14 +6259,14 @@
+ **
+ ** See also:  [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
++SQLITE_API int sqlite3_create_collation(
+   sqlite3*, 
+   const char *zName, 
+   int eTextRep, 
+   void *pArg,
+   int(*xCompare)(void*,int,const void*,int,const void*)
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
++SQLITE_API int sqlite3_create_collation_v2(
+   sqlite3*, 
+   const char *zName, 
+   int eTextRep, 
+@@ -4932,7 +6274,7 @@
+   int(*xCompare)(void*,int,const void*,int,const void*),
+   void(*xDestroy)(void*)
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
++SQLITE_API int sqlite3_create_collation16(
+   sqlite3*, 
+   const void *zName,
+   int eTextRep, 
+@@ -4967,12 +6309,12 @@
+ ** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
+ ** [sqlite3_create_collation_v2()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
++SQLITE_API int sqlite3_collation_needed(
+   sqlite3*, 
+   void*, 
+   void(*)(void*,sqlite3*,int eTextRep,const char*)
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
++SQLITE_API int sqlite3_collation_needed16(
+   sqlite3*, 
+   void*,
+   void(*)(void*,sqlite3*,int eTextRep,const void*)
+@@ -4986,11 +6328,11 @@
+ ** The code to implement this API is not available in the public release
+ ** of SQLite.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_key(
++SQLITE_API int sqlite3_key(
+   sqlite3 *db,                   /* Database to be rekeyed */
+   const void *pKey, int nKey     /* The key */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(
++SQLITE_API int sqlite3_key_v2(
+   sqlite3 *db,                   /* Database to be rekeyed */
+   const char *zDbName,           /* Name of the database */
+   const void *pKey, int nKey     /* The key */
+@@ -5004,11 +6346,11 @@
+ ** The code to implement this API is not available in the public release
+ ** of SQLite.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_rekey(
++SQLITE_API int sqlite3_rekey(
+   sqlite3 *db,                   /* Database to be rekeyed */
+   const void *pKey, int nKey     /* The new key */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(
++SQLITE_API int sqlite3_rekey_v2(
+   sqlite3 *db,                   /* Database to be rekeyed */
+   const char *zDbName,           /* Name of the database */
+   const void *pKey, int nKey     /* The new key */
+@@ -5018,7 +6360,7 @@
+ ** Specify the activation key for a SEE database.  Unless 
+ ** activated, none of the SEE routines will work.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(
++SQLITE_API void sqlite3_activate_see(
+   const char *zPassPhrase        /* Activation phrase */
+ );
+ #endif
+@@ -5028,7 +6370,7 @@
+ ** Specify the activation key for a CEROD database.  Unless 
+ ** activated, none of the CEROD routines will work.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod(
++SQLITE_API void sqlite3_activate_cerod(
+   const char *zPassPhrase        /* Activation phrase */
+ );
+ #endif
+@@ -5050,7 +6392,7 @@
+ ** all, then the behavior of sqlite3_sleep() may deviate from the description
+ ** in the previous paragraphs.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int);
++SQLITE_API int sqlite3_sleep(int);
+ 
+ /*
+ ** CAPI3REF: Name Of The Folder Holding Temporary Files
+@@ -5169,7 +6511,7 @@
+ ** connection while this routine is running, then the return value
+ ** is undefined.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
++SQLITE_API int sqlite3_get_autocommit(sqlite3*);
+ 
+ /*
+ ** CAPI3REF: Find The Database Handle Of A Prepared Statement
+@@ -5182,7 +6524,7 @@
+ ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
+ ** create the statement in the first place.
+ */
+-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
++SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
+ 
+ /*
+ ** CAPI3REF: Return The Filename For A Database Connection
+@@ -5199,7 +6541,7 @@
+ ** will be an absolute pathname, even if the filename used
+ ** to open the database originally was a URI or relative pathname.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName);
++SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
+ 
+ /*
+ ** CAPI3REF: Determine if a database is read-only
+@@ -5209,7 +6551,7 @@
+ ** of connection D is read-only, 0 if it is read/write, or -1 if N is not
+ ** the name of a database on connection D.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
++SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
+ 
+ /*
+ ** CAPI3REF: Find the next prepared statement
+@@ -5225,7 +6567,7 @@
+ ** [sqlite3_next_stmt(D,S)] must refer to an open database
+ ** connection and in particular must not be a NULL pointer.
+ */
+-SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
++SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Commit And Rollback Notification Callbacks
+@@ -5274,8 +6616,8 @@
+ **
+ ** See also the [sqlite3_update_hook()] interface.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+-SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
++SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
++SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
+ 
+ /*
+ ** CAPI3REF: Data Change Notification Callbacks
+@@ -5284,7 +6626,7 @@
+ ** ^The sqlite3_update_hook() interface registers a callback function
+ ** with the [database connection] identified by the first argument
+ ** to be invoked whenever a row is updated, inserted or deleted in
+-** a rowid table.
++** a [rowid table].
+ ** ^Any callback set by a previous call to this function
+ ** for the same database connection is overridden.
+ **
+@@ -5305,7 +6647,7 @@
+ ** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
+ **
+ ** ^In the current implementation, the update hook
+-** is not invoked when duplication rows are deleted because of an
++** is not invoked when conflicting rows are deleted because of an
+ ** [ON CONFLICT | ON CONFLICT REPLACE] clause.  ^Nor is the update hook
+ ** invoked when rows are deleted using the [truncate optimization].
+ ** The exceptions defined in this paragraph might change in a future
+@@ -5323,10 +6665,10 @@
+ ** on the same [database connection] D, or NULL for
+ ** the first call on D.
+ **
+-** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
+-** interfaces.
++** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()],
++** and [sqlite3_preupdate_hook()] interfaces.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
++SQLITE_API void *sqlite3_update_hook(
+   sqlite3*, 
+   void(*)(void *,int ,char const *,char const *,sqlite3_int64),
+   void*
+@@ -5341,7 +6683,8 @@
+ ** and disabled if the argument is false.)^
+ **
+ ** ^Cache sharing is enabled and disabled for an entire process.
+-** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
++** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). 
++** In prior versions of SQLite,
+ ** sharing was enabled or disabled for each thread separately.
+ **
+ ** ^(The cache sharing mode set by this interface effects all subsequent
+@@ -5366,7 +6709,7 @@
+ **
+ ** See Also:  [SQLite Shared-Cache Mode]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int);
++SQLITE_API int sqlite3_enable_shared_cache(int);
+ 
+ /*
+ ** CAPI3REF: Attempt To Free Heap Memory
+@@ -5382,7 +6725,7 @@
+ **
+ ** See also: [sqlite3_db_release_memory()]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int);
++SQLITE_API int sqlite3_release_memory(int);
+ 
+ /*
+ ** CAPI3REF: Free Memory Used By A Database Connection
+@@ -5396,7 +6739,7 @@
+ **
+ ** See also: [sqlite3_release_memory()]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
++SQLITE_API int sqlite3_db_release_memory(sqlite3*);
+ 
+ /*
+ ** CAPI3REF: Impose A Limit On Heap Size
+@@ -5435,7 +6778,8 @@
+ **      from the heap.
+ ** </ul>)^
+ **
+-** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
++** Beginning with SQLite [version 3.7.3] ([dateof:3.7.3]), 
++** the soft heap limit is enforced
+ ** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT]
+ ** compile-time option is invoked.  With [SQLITE_ENABLE_MEMORY_MANAGEMENT],
+ ** the soft heap limit is enforced on every memory allocation.  Without
+@@ -5448,7 +6792,7 @@
+ ** The circumstances under which SQLite will enforce the soft heap limit may
+ ** changes in future releases of SQLite.
+ */
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N);
++SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
+ 
+ /*
+ ** CAPI3REF: Deprecated Soft Heap Limit Interface
+@@ -5459,7 +6803,7 @@
+ ** only.  All new applications should use the
+ ** [sqlite3_soft_heap_limit64()] interface rather than this one.
+ */
+-SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N);
++SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
+ 
+ 
+ /*
+@@ -5474,9 +6818,11 @@
+ ** column exists.  ^The sqlite3_table_column_metadata() interface returns
+ ** SQLITE_ERROR and if the specified column does not exist.
+ ** ^If the column-name parameter to sqlite3_table_column_metadata() is a
+-** NULL pointer, then this routine simply checks for the existance of the
++** NULL pointer, then this routine simply checks for the existence of the
+ ** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
+-** does not.
++** does not.  If the table name parameter T in a call to
++** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is
++** undefined behavior.
+ **
+ ** ^The column is identified by the second, third and fourth parameters to
+ ** this function. ^(The second parameter is either the name of the database
+@@ -5529,7 +6875,7 @@
+ ** parsed, if that has not already been done, and returns an error if
+ ** any errors are encountered while loading the schema.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
++SQLITE_API int sqlite3_table_column_metadata(
+   sqlite3 *db,                /* Connection handle */
+   const char *zDbName,        /* Database name or NULL */
+   const char *zTableName,     /* Table name */
+@@ -5571,12 +6917,21 @@
+ ** should free this memory by calling [sqlite3_free()].
+ **
+ ** ^Extension loading must be enabled using
+-** [sqlite3_enable_load_extension()] prior to calling this API,
++** [sqlite3_enable_load_extension()] or
++** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
++** prior to calling this API,
+ ** otherwise an error will be returned.
+ **
++** <b>Security warning:</b> It is recommended that the 
++** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
++** interface.  The use of the [sqlite3_enable_load_extension()] interface
++** should be avoided.  This will keep the SQL function [load_extension()]
++** disabled and prevent SQL injections from giving attackers
++** access to extension loading capabilities.
++**
+ ** See also the [load_extension() SQL function].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
++SQLITE_API int sqlite3_load_extension(
+   sqlite3 *db,          /* Load the extension into this database connection */
+   const char *zFile,    /* Name of the shared library containing extension */
+   const char *zProc,    /* Entry point.  Derived from zFile if 0 */
+@@ -5596,8 +6951,19 @@
+ ** ^Call the sqlite3_enable_load_extension() routine with onoff==1
+ ** to turn extension loading on and call it with onoff==0 to turn
+ ** it back off again.
++**
++** ^This interface enables or disables both the C-API
++** [sqlite3_load_extension()] and the SQL function [load_extension()].
++** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
++** to enable or disable only the C-API.)^
++**
++** <b>Security warning:</b> It is recommended that extension loading
++** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
++** rather than this interface, so the [load_extension()] SQL function
++** remains disabled. This will prevent SQL injections from giving attackers
++** access to extension loading capabilities.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff);
++SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
+ 
+ /*
+ ** CAPI3REF: Automatically Load Statically Linked Extensions
+@@ -5609,7 +6975,7 @@
+ **
+ ** ^(Even though the function prototype shows that xEntryPoint() takes
+ ** no arguments and returns void, SQLite invokes xEntryPoint() with three
+-** arguments and expects and integer result as if the signature of the
++** arguments and expects an integer result as if the signature of the
+ ** entry point where as follows:
+ **
+ ** <blockquote><pre>
+@@ -5635,7 +7001,7 @@
+ ** See also: [sqlite3_reset_auto_extension()]
+ ** and [sqlite3_cancel_auto_extension()]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void));
++SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void));
+ 
+ /*
+ ** CAPI3REF: Cancel Automatic Extension Loading
+@@ -5647,7 +7013,7 @@
+ ** unregistered and it returns 0 if X was not on the list of initialization
+ ** routines.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
++SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
+ 
+ /*
+ ** CAPI3REF: Reset Automatic Extension Loading
+@@ -5655,7 +7021,7 @@
+ ** ^This interface disables all automatic extensions previously
+ ** registered using [sqlite3_auto_extension()].
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void);
++SQLITE_API void sqlite3_reset_auto_extension(void);
+ 
+ /*
+ ** The interface to the virtual-table mechanism is currently considered
+@@ -5757,6 +7123,17 @@
+ ** ^Information about the ORDER BY clause is stored in aOrderBy[].
+ ** ^Each term of aOrderBy records a column of the ORDER BY clause.
+ **
++** The colUsed field indicates which columns of the virtual table may be
++** required by the current scan. Virtual table columns are numbered from
++** zero in the order in which they appear within the CREATE TABLE statement
++** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
++** the corresponding bit is set within the colUsed mask if the column may be
++** required by SQLite. If the table has at least 64 columns and any column
++** to the right of the first 63 is required, then bit 63 of colUsed is also
++** set. In other words, column iCol may be required if the expression
++** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to 
++** non-zero.
++**
+ ** The [xBestIndex] method must fill aConstraintUsage[] with information
+ ** about what parameters to pass to xFilter.  ^If argvIndex>0 then
+ ** the right-hand side of the corresponding aConstraint[] is evaluated
+@@ -5782,19 +7159,39 @@
+ ** ^The estimatedRows value is an estimate of the number of rows that
+ ** will be returned by the strategy.
+ **
++** The xBestIndex method may optionally populate the idxFlags field with a 
++** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
++** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
++** assumes that the strategy may visit at most one row. 
++**
++** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
++** SQLite also assumes that if a call to the xUpdate() method is made as
++** part of the same statement to delete or update a virtual table row and the
++** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
++** any database changes. In other words, if the xUpdate() returns
++** SQLITE_CONSTRAINT, the database contents must be exactly as they were
++** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
++** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
++** the xUpdate method are automatically rolled back by SQLite.
++**
+ ** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
+-** structure for SQLite version 3.8.2. If a virtual table extension is
++** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). 
++** If a virtual table extension is
+ ** used with an SQLite version earlier than 3.8.2, the results of attempting 
+ ** to read or write the estimatedRows field are undefined (but are likely 
+ ** to included crashing the application). The estimatedRows field should
+ ** therefore only be used if [sqlite3_libversion_number()] returns a
+-** value greater than or equal to 3008002.
++** value greater than or equal to 3008002. Similarly, the idxFlags field
++** was added for [version 3.9.0] ([dateof:3.9.0]). 
++** It may therefore only be used if
++** sqlite3_libversion_number() returns a value greater than or equal to
++** 3009000.
+ */
+ struct sqlite3_index_info {
+   /* Inputs */
+   int nConstraint;           /* Number of entries in aConstraint */
+   struct sqlite3_index_constraint {
+-     int iColumn;              /* Column on left-hand side of constraint */
++     int iColumn;              /* Column constrained.  -1 for ROWID */
+      unsigned char op;         /* Constraint operator */
+      unsigned char usable;     /* True if this constraint is usable */
+      int iTermOffset;          /* Used internally - xBestIndex should ignore */
+@@ -5816,9 +7213,18 @@
+   double estimatedCost;           /* Estimated cost of using this index */
+   /* Fields below are only available in SQLite 3.8.2 and later */
+   sqlite3_int64 estimatedRows;    /* Estimated number of rows returned */
++  /* Fields below are only available in SQLite 3.9.0 and later */
++  int idxFlags;              /* Mask of SQLITE_INDEX_SCAN_* flags */
++  /* Fields below are only available in SQLite 3.10.0 and later */
++  sqlite3_uint64 colUsed;    /* Input: Mask of columns used by statement */
+ };
+ 
+ /*
++** CAPI3REF: Virtual Table Scan Flags
++*/
++#define SQLITE_INDEX_SCAN_UNIQUE      1     /* Scan visits at most 1 row */
++
++/*
+ ** CAPI3REF: Virtual Table Constraint Operator Codes
+ **
+ ** These macros defined the allowed values for the
+@@ -5826,12 +7232,15 @@
+ ** an operator that is part of a constraint term in the wHERE clause of
+ ** a query that uses a [virtual table].
+ */
+-#define SQLITE_INDEX_CONSTRAINT_EQ    2
+-#define SQLITE_INDEX_CONSTRAINT_GT    4
+-#define SQLITE_INDEX_CONSTRAINT_LE    8
+-#define SQLITE_INDEX_CONSTRAINT_LT    16
+-#define SQLITE_INDEX_CONSTRAINT_GE    32
+-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
++#define SQLITE_INDEX_CONSTRAINT_EQ      2
++#define SQLITE_INDEX_CONSTRAINT_GT      4
++#define SQLITE_INDEX_CONSTRAINT_LE      8
++#define SQLITE_INDEX_CONSTRAINT_LT     16
++#define SQLITE_INDEX_CONSTRAINT_GE     32
++#define SQLITE_INDEX_CONSTRAINT_MATCH  64
++#define SQLITE_INDEX_CONSTRAINT_LIKE   65
++#define SQLITE_INDEX_CONSTRAINT_GLOB   66
++#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
+ 
+ /*
+ ** CAPI3REF: Register A Virtual Table Implementation
+@@ -5859,13 +7268,13 @@
+ ** interface is equivalent to sqlite3_create_module_v2() with a NULL
+ ** destructor.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
++SQLITE_API int sqlite3_create_module(
+   sqlite3 *db,               /* SQLite connection to register module with */
+   const char *zName,         /* Name of the module */
+   const sqlite3_module *p,   /* Methods for the module */
+   void *pClientData          /* Client data for xCreate/xConnect */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
++SQLITE_API int sqlite3_create_module_v2(
+   sqlite3 *db,               /* SQLite connection to register module with */
+   const char *zName,         /* Name of the module */
+   const sqlite3_module *p,   /* Methods for the module */
+@@ -5928,7 +7337,7 @@
+ ** to declare the format (the names and datatypes of the columns) of
+ ** the virtual tables they implement.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL);
++SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
+ 
+ /*
+ ** CAPI3REF: Overload A Function For A Virtual Table
+@@ -5947,7 +7356,7 @@
+ ** purpose is to be a placeholder function that can be overloaded
+ ** by a [virtual table].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
++SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+ 
+ /*
+ ** The interface to the virtual-table mechanism defined above (back up
+@@ -6022,6 +7431,12 @@
+ ** [database connection] error code and message accessible via 
+ ** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 
+ **
++** A BLOB referenced by sqlite3_blob_open() may be read using the
++** [sqlite3_blob_read()] interface and modified by using
++** [sqlite3_blob_write()].  The [BLOB handle] can be moved to a
++** different row of the same table using the [sqlite3_blob_reopen()]
++** interface.  However, the column, table, or database of a [BLOB handle]
++** cannot be changed after the [BLOB handle] is opened.
+ **
+ ** ^(If the row that a BLOB handle points to is modified by an
+ ** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
+@@ -6045,8 +7460,12 @@
+ **
+ ** To avoid a resource leak, every open [BLOB handle] should eventually
+ ** be released by a call to [sqlite3_blob_close()].
++**
++** See also: [sqlite3_blob_close()],
++** [sqlite3_blob_reopen()], [sqlite3_blob_read()],
++** [sqlite3_blob_bytes()], [sqlite3_blob_write()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
++SQLITE_API int sqlite3_blob_open(
+   sqlite3*,
+   const char *zDb,
+   const char *zTable,
+@@ -6060,11 +7479,11 @@
+ ** CAPI3REF: Move a BLOB Handle to a New Row
+ ** METHOD: sqlite3_blob
+ **
+-** ^This function is used to move an existing blob handle so that it points
++** ^This function is used to move an existing [BLOB handle] so that it points
+ ** to a different row of the same database table. ^The new row is identified
+ ** by the rowid value passed as the second argument. Only the row can be
+ ** changed. ^The database, table and column on which the blob handle is open
+-** remain the same. Moving an existing blob handle to a new row can be
++** remain the same. Moving an existing [BLOB handle] to a new row is
+ ** faster than closing the existing handle and opening a new one.
+ **
+ ** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
+@@ -6079,7 +7498,7 @@
+ **
+ ** ^This function sets the database handle error code and message.
+ */
+-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
++SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
+ 
+ /*
+ ** CAPI3REF: Close A BLOB Handle
+@@ -6102,7 +7521,7 @@
+ ** is passed a valid open blob handle, the values returned by the 
+ ** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *);
++SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
+ 
+ /*
+ ** CAPI3REF: Return The Size Of An Open BLOB
+@@ -6118,7 +7537,7 @@
+ ** been closed by [sqlite3_blob_close()].  Passing any other pointer in
+ ** to this routine results in undefined and probably undesirable behavior.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *);
++SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
+ 
+ /*
+ ** CAPI3REF: Read Data From A BLOB Incrementally
+@@ -6147,7 +7566,7 @@
+ **
+ ** See also: [sqlite3_blob_write()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
++SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
+ 
+ /*
+ ** CAPI3REF: Write Data Into A BLOB Incrementally
+@@ -6189,7 +7608,7 @@
+ **
+ ** See also: [sqlite3_blob_read()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
++SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
+ 
+ /*
+ ** CAPI3REF: Virtual File System Objects
+@@ -6220,9 +7639,9 @@
+ ** ^(If the default VFS is unregistered, another VFS is chosen as
+ ** the default.  The choice for the new VFS is arbitrary.)^
+ */
+-SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName);
+-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
++SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
++SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
++SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
+ 
+ /*
+ ** CAPI3REF: Mutexes
+@@ -6275,6 +7694,9 @@
+ ** <li>  SQLITE_MUTEX_STATIC_APP1
+ ** <li>  SQLITE_MUTEX_STATIC_APP2
+ ** <li>  SQLITE_MUTEX_STATIC_APP3
++** <li>  SQLITE_MUTEX_STATIC_VFS1
++** <li>  SQLITE_MUTEX_STATIC_VFS2
++** <li>  SQLITE_MUTEX_STATIC_VFS3
+ ** </ul>
+ **
+ ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
+@@ -6335,11 +7757,11 @@
+ **
+ ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
+ */
+-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int);
+-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*);
+-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*);
+-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*);
++SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
++SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
++SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
++SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
++SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
+ 
+ /*
+ ** CAPI3REF: Mutex Methods Object
+@@ -6449,8 +7871,8 @@
+ ** interface should also return 1 when given a NULL pointer.
+ */
+ #ifndef NDEBUG
+-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*);
+-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
++SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
++SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
+ #endif
+ 
+ /*
+@@ -6469,13 +7891,16 @@
+ #define SQLITE_MUTEX_STATIC_MEM       3  /* sqlite3_malloc() */
+ #define SQLITE_MUTEX_STATIC_MEM2      4  /* NOT USED */
+ #define SQLITE_MUTEX_STATIC_OPEN      4  /* sqlite3BtreeOpen() */
+-#define SQLITE_MUTEX_STATIC_PRNG      5  /* sqlite3_random() */
++#define SQLITE_MUTEX_STATIC_PRNG      5  /* sqlite3_randomness() */
+ #define SQLITE_MUTEX_STATIC_LRU       6  /* lru page list */
+ #define SQLITE_MUTEX_STATIC_LRU2      7  /* NOT USED */
+ #define SQLITE_MUTEX_STATIC_PMEM      7  /* sqlite3PageMalloc() */
+ #define SQLITE_MUTEX_STATIC_APP1      8  /* For use by application */
+ #define SQLITE_MUTEX_STATIC_APP2      9  /* For use by application */
+ #define SQLITE_MUTEX_STATIC_APP3     10  /* For use by application */
++#define SQLITE_MUTEX_STATIC_VFS1     11  /* For use by built-in VFS */
++#define SQLITE_MUTEX_STATIC_VFS2     12  /* For use by extension VFS */
++#define SQLITE_MUTEX_STATIC_VFS3     13  /* For use by application VFS */
+ 
+ /*
+ ** CAPI3REF: Retrieve the mutex for a database connection
+@@ -6487,7 +7912,7 @@
+ ** ^If the [threading mode] is Single-thread or Multi-thread then this
+ ** routine returns a NULL pointer.
+ */
+-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*);
++SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
+ 
+ /*
+ ** CAPI3REF: Low-Level Control Of Database Files
+@@ -6522,7 +7947,7 @@
+ **
+ ** See also: [SQLITE_FCNTL_LOCKSTATE]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
++SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+ 
+ /*
+ ** CAPI3REF: Testing Interface
+@@ -6541,7 +7966,7 @@
+ ** Unlike most of the SQLite API, this function is not guaranteed to
+ ** operate consistently from one release to the next.
+ */
+-SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
++SQLITE_API int sqlite3_test_control(int op, ...);
+ 
+ /*
+ ** CAPI3REF: Testing Interface Operation Codes
+@@ -6570,6 +7995,7 @@
+ #define SQLITE_TESTCTRL_SCRATCHMALLOC           17
+ #define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
+ #define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
++#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD    19
+ #define SQLITE_TESTCTRL_NEVER_CORRUPT           20
+ #define SQLITE_TESTCTRL_VDBE_COVERAGE           21
+ #define SQLITE_TESTCTRL_BYTEORDER               22
+@@ -6604,8 +8030,8 @@
+ **
+ ** See also: [sqlite3_db_status()]
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+-SQLITE_API int SQLITE_STDCALL sqlite3_status64(
++SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
++SQLITE_API int sqlite3_status64(
+   int op,
+   sqlite3_int64 *pCurrent,
+   sqlite3_int64 *pHighwater,
+@@ -6689,7 +8115,8 @@
+ ** The value written into the *pCurrent parameter is undefined.</dd>)^
+ **
+ ** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
+-** <dd>This parameter records the deepest parser stack.  It is only
++** <dd>The *pHighwater parameter records the deepest parser stack. 
++** The *pCurrent value is undefined.  The *pHighwater value is only
+ ** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
+ ** </dl>
+ **
+@@ -6729,7 +8156,7 @@
+ **
+ ** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
++SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+ 
+ /*
+ ** CAPI3REF: Status Parameters for database connections
+@@ -6775,6 +8202,18 @@
+ ** memory used by all pager caches associated with the database connection.)^
+ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
+ **
++** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] 
++** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt>
++** <dd>This parameter is similar to DBSTATUS_CACHE_USED, except that if a
++** pager cache is shared between two or more connections the bytes of heap
++** memory used by that pager cache is divided evenly between the attached
++** connections.)^  In other words, if none of the pager caches associated
++** with the database connection are shared, this request returns the same
++** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are
++** shared, the value returned by this call will be smaller than that returned
++** by DBSTATUS_CACHE_USED. ^The highwater mark associated with
++** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.
++**
+ ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
+ ** <dd>This parameter returns the approximate number of bytes of heap
+ ** memory used to store the schema for all databases associated
+@@ -6832,7 +8271,8 @@
+ #define SQLITE_DBSTATUS_CACHE_MISS           8
+ #define SQLITE_DBSTATUS_CACHE_WRITE          9
+ #define SQLITE_DBSTATUS_DEFERRED_FKS        10
+-#define SQLITE_DBSTATUS_MAX                 10   /* Largest defined DBSTATUS */
++#define SQLITE_DBSTATUS_CACHE_USED_SHARED   11
++#define SQLITE_DBSTATUS_MAX                 11   /* Largest defined DBSTATUS */
+ 
+ 
+ /*
+@@ -6859,7 +8299,7 @@
+ **
+ ** See also: [sqlite3_status()] and [sqlite3_db_status()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
++SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+ 
+ /*
+ ** CAPI3REF: Status Parameters for prepared statements
+@@ -6895,6 +8335,24 @@
+ ** used as a proxy for the total work done by the prepared statement.
+ ** If the number of virtual machine operations exceeds 2147483647
+ ** then the value returned by this statement status code is undefined.
++**
++** [[SQLITE_STMTSTATUS_REPREPARE]] <dt>SQLITE_STMTSTATUS_REPREPARE</dt>
++** <dd>^This is the number of times that the prepare statement has been
++** automatically regenerated due to schema changes or change to 
++** [bound parameters] that might affect the query plan.
++**
++** [[SQLITE_STMTSTATUS_RUN]] <dt>SQLITE_STMTSTATUS_RUN</dt>
++** <dd>^This is the number of times that the prepared statement has
++** been run.  A single "run" for the purposes of this counter is one
++** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
++** The counter is incremented on the first [sqlite3_step()] call of each
++** cycle.
++**
++** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
++** <dd>^This is the approximate number of bytes of heap memory
++** used to store the prepared statement.  ^This value is not actually
++** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
++** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
+ ** </dd>
+ ** </dl>
+ */
+@@ -6902,6 +8360,9 @@
+ #define SQLITE_STMTSTATUS_SORT              2
+ #define SQLITE_STMTSTATUS_AUTOINDEX         3
+ #define SQLITE_STMTSTATUS_VM_STEP           4
++#define SQLITE_STMTSTATUS_REPREPARE         5
++#define SQLITE_STMTSTATUS_RUN               6
++#define SQLITE_STMTSTATUS_MEMUSED           99
+ 
+ /*
+ ** CAPI3REF: Custom Page Cache Object
+@@ -7186,7 +8647,7 @@
+ ** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
+ ** an error.
+ **
+-** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if 
++** ^A call to sqlite3_backup_init() will fail, returning NULL, if 
+ ** there is already a read or read-write transaction open on the 
+ ** destination database.
+ **
+@@ -7328,16 +8789,16 @@
+ ** same time as another thread is invoking sqlite3_backup_step() it is
+ ** possible that they return invalid values.
+ */
+-SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
++SQLITE_API sqlite3_backup *sqlite3_backup_init(
+   sqlite3 *pDest,                        /* Destination database handle */
+   const char *zDestName,                 /* Destination database name */
+   sqlite3 *pSource,                      /* Source database handle */
+   const char *zSourceName                /* Source database name */
+ );
+-SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage);
+-SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p);
+-SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p);
+-SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p);
++SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
++SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
++SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
++SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
+ 
+ /*
+ ** CAPI3REF: Unlock Notification
+@@ -7454,7 +8915,7 @@
+ ** the special "DROP TABLE/INDEX" case, the extended error code is just 
+ ** SQLITE_LOCKED.)^
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
++SQLITE_API int sqlite3_unlock_notify(
+   sqlite3 *pBlocked,                          /* Waiting connection */
+   void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
+   void *pNotifyArg                            /* Argument to pass to xNotify */
+@@ -7469,23 +8930,48 @@
+ ** strings in a case-independent fashion, using the same definition of "case
+ ** independence" that SQLite uses internally when comparing identifiers.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *);
+-SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
++SQLITE_API int sqlite3_stricmp(const char *, const char *);
++SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
+ 
+ /*
+ ** CAPI3REF: String Globbing
+ *
+-** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches
+-** the glob pattern P, and it returns non-zero if string X does not match
+-** the glob pattern P.  ^The definition of glob pattern matching used in
++** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if
++** string X matches the [GLOB] pattern P.
++** ^The definition of [GLOB] pattern matching used in
+ ** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the
+-** SQL dialect used by SQLite.  ^The sqlite3_strglob(P,X) function is case
+-** sensitive.
++** SQL dialect understood by SQLite.  ^The [sqlite3_strglob(P,X)] function
++** is case sensitive.
++**
++** Note that this routine returns zero on a match and non-zero if the strings
++** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
++**
++** See also: [sqlite3_strlike()].
++*/
++SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
++
++/*
++** CAPI3REF: String LIKE Matching
++*
++** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if
++** string X matches the [LIKE] pattern P with escape character E.
++** ^The definition of [LIKE] pattern matching used in
++** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
++** operator in the SQL dialect understood by SQLite.  ^For "X LIKE P" without
++** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
++** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case
++** insensitive - equivalent upper and lower case ASCII characters match
++** one another.
++**
++** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
++** only ASCII characters are case folded.
+ **
+ ** Note that this routine returns zero on a match and non-zero if the strings
+ ** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
++**
++** See also: [sqlite3_strglob()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr);
++SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
+ 
+ /*
+ ** CAPI3REF: Error Logging Interface
+@@ -7508,7 +8994,7 @@
+ ** a few hundred characters, it will be truncated to the length of the
+ ** buffer.
+ */
+-SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...);
++SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
+ 
+ /*
+ ** CAPI3REF: Write-Ahead Log Commit Hook
+@@ -7542,9 +9028,9 @@
+ ** previously registered write-ahead log callback. ^Note that the
+ ** [sqlite3_wal_autocheckpoint()] interface and the
+ ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
+-** those overwrite any prior [sqlite3_wal_hook()] settings.
++** overwrite any prior [sqlite3_wal_hook()] settings.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
++SQLITE_API void *sqlite3_wal_hook(
+   sqlite3*, 
+   int(*)(void *,sqlite3*,const char*,int),
+   void*
+@@ -7579,7 +9065,7 @@
+ ** is only necessary if the default setting is found to be suboptimal
+ ** for a particular application.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
++SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
+ 
+ /*
+ ** CAPI3REF: Checkpoint a database
+@@ -7601,7 +9087,7 @@
+ ** start a callback but which do not need the full power (and corresponding
+ ** complication) of [sqlite3_wal_checkpoint_v2()].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
++SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+ 
+ /*
+ ** CAPI3REF: Checkpoint a database
+@@ -7695,7 +9181,7 @@
+ ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
+ ** from SQL.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
++SQLITE_API int sqlite3_wal_checkpoint_v2(
+   sqlite3 *db,                    /* Database handle */
+   const char *zDb,                /* Name of attached database (or NULL) */
+   int eMode,                      /* SQLITE_CHECKPOINT_* value */
+@@ -7731,7 +9217,7 @@
+ ** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].)  Further options
+ ** may be added in the future.
+ */
+-SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...);
++SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
+ 
+ /*
+ ** CAPI3REF: Virtual Table Configuration Options
+@@ -7784,7 +9270,7 @@
+ ** of the SQL statement that triggered the call to the [xUpdate] method of the
+ ** [virtual table].
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
++SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
+ 
+ /*
+ ** CAPI3REF: Conflict resolution modes
+@@ -7889,7 +9375,7 @@
+ **
+ ** See also: [sqlite3_stmt_scanstatus_reset()]
+ */
+-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus(
++SQLITE_API int sqlite3_stmt_scanstatus(
+   sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
+   int idx,                  /* Index of loop to report on */
+   int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
+@@ -7905,8 +9391,332 @@
+ ** This API is only available if the library is built with pre-processor
+ ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
+ */
+-SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
++SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
++
++/*
++** CAPI3REF: Flush caches to disk mid-transaction
++**
++** ^If a write-transaction is open on [database connection] D when the
++** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
++** pages in the pager-cache that are not currently in use are written out 
++** to disk. A dirty page may be in use if a database cursor created by an
++** active SQL statement is reading from it, or if it is page 1 of a database
++** file (page 1 is always "in use").  ^The [sqlite3_db_cacheflush(D)]
++** interface flushes caches for all schemas - "main", "temp", and
++** any [attached] databases.
++**
++** ^If this function needs to obtain extra database locks before dirty pages 
++** can be flushed to disk, it does so. ^If those locks cannot be obtained 
++** immediately and there is a busy-handler callback configured, it is invoked
++** in the usual manner. ^If the required lock still cannot be obtained, then
++** the database is skipped and an attempt made to flush any dirty pages
++** belonging to the next (if any) database. ^If any databases are skipped
++** because locks cannot be obtained, but no other error occurs, this
++** function returns SQLITE_BUSY.
++**
++** ^If any other error occurs while flushing dirty pages to disk (for
++** example an IO error or out-of-memory condition), then processing is
++** abandoned and an SQLite [error code] is returned to the caller immediately.
++**
++** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK.
++**
++** ^This function does not set the database handle error code or message
++** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
++*/
++SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
++
++/*
++** CAPI3REF: The pre-update hook.
++**
++** ^These interfaces are only available if SQLite is compiled using the
++** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
++**
++** ^The [sqlite3_preupdate_hook()] interface registers a callback function
++** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
++** on a database table.
++** ^At most one preupdate hook may be registered at a time on a single
++** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
++** the previous setting.
++** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()]
++** with a NULL pointer as the second parameter.
++** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
++** the first parameter to callbacks.
++**
++** ^The preupdate hook only fires for changes to real database tables; the
++** preupdate hook is not invoked for changes to [virtual tables] or to
++** system tables like sqlite_master or sqlite_stat1.
++**
++** ^The second parameter to the preupdate callback is a pointer to
++** the [database connection] that registered the preupdate hook.
++** ^The third parameter to the preupdate callback is one of the constants
++** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to identify the
++** kind of update operation that is about to occur.
++** ^(The fourth parameter to the preupdate callback is the name of the
++** database within the database connection that is being modified.  This
++** will be "main" for the main database or "temp" for TEMP tables or 
++** the name given after the AS keyword in the [ATTACH] statement for attached
++** databases.)^
++** ^The fifth parameter to the preupdate callback is the name of the
++** table that is being modified.
++**
++** For an UPDATE or DELETE operation on a [rowid table], the sixth
++** parameter passed to the preupdate callback is the initial [rowid] of the 
++** row being modified or deleted. For an INSERT operation on a rowid table,
++** or any operation on a WITHOUT ROWID table, the value of the sixth 
++** parameter is undefined. For an INSERT or UPDATE on a rowid table the
++** seventh parameter is the final rowid value of the row being inserted
++** or updated. The value of the seventh parameter passed to the callback
++** function is not defined for operations on WITHOUT ROWID tables, or for
++** INSERT operations on rowid tables.
++**
++** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
++** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
++** provide additional information about a preupdate event. These routines
++** may only be called from within a preupdate callback.  Invoking any of
++** these routines from outside of a preupdate callback or with a
++** [database connection] pointer that is different from the one supplied
++** to the preupdate callback results in undefined and probably undesirable
++** behavior.
++**
++** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns
++** in the row that is being inserted, updated, or deleted.
++**
++** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to
++** a [protected sqlite3_value] that contains the value of the Nth column of
++** the table row before it is updated.  The N parameter must be between 0
++** and one less than the number of columns or the behavior will be
++** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE
++** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the
++** behavior is undefined.  The [sqlite3_value] that P points to
++** will be destroyed when the preupdate callback returns.
++**
++** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to
++** a [protected sqlite3_value] that contains the value of the Nth column of
++** the table row after it is updated.  The N parameter must be between 0
++** and one less than the number of columns or the behavior will be
++** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE
++** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the
++** behavior is undefined.  The [sqlite3_value] that P points to
++** will be destroyed when the preupdate callback returns.
++**
++** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate
++** callback was invoked as a result of a direct insert, update, or delete
++** operation; or 1 for inserts, updates, or deletes invoked by top-level 
++** triggers; or 2 for changes resulting from triggers called by top-level
++** triggers; and so forth.
++**
++** See also:  [sqlite3_update_hook()]
++*/
++#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
++SQLITE_API void *sqlite3_preupdate_hook(
++  sqlite3 *db,
++  void(*xPreUpdate)(
++    void *pCtx,                   /* Copy of third arg to preupdate_hook() */
++    sqlite3 *db,                  /* Database handle */
++    int op,                       /* SQLITE_UPDATE, DELETE or INSERT */
++    char const *zDb,              /* Database name */
++    char const *zName,            /* Table name */
++    sqlite3_int64 iKey1,          /* Rowid of row about to be deleted/updated */
++    sqlite3_int64 iKey2           /* New rowid value (for a rowid UPDATE) */
++  ),
++  void*
++);
++SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
++SQLITE_API int sqlite3_preupdate_count(sqlite3 *);
++SQLITE_API int sqlite3_preupdate_depth(sqlite3 *);
++SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
++#endif
++
++/*
++** CAPI3REF: Low-level system error code
++**
++** ^Attempt to return the underlying operating system error code or error
++** number that caused the most recent I/O error or failure to open a file.
++** The return value is OS-dependent.  For example, on unix systems, after
++** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be
++** called to get back the underlying "errno" that caused the problem, such
++** as ENOSPC, EAUTH, EISDIR, and so forth.  
++*/
++SQLITE_API int sqlite3_system_errno(sqlite3*);
++
++/*
++** CAPI3REF: Database Snapshot
++** KEYWORDS: {snapshot} {sqlite3_snapshot}
++** EXPERIMENTAL
++**
++** An instance of the snapshot object records the state of a [WAL mode]
++** database for some specific point in history.
++**
++** In [WAL mode], multiple [database connections] that are open on the
++** same database file can each be reading a different historical version
++** of the database file.  When a [database connection] begins a read
++** transaction, that connection sees an unchanging copy of the database
++** as it existed for the point in time when the transaction first started.
++** Subsequent changes to the database from other connections are not seen
++** by the reader until a new read transaction is started.
++**
++** The sqlite3_snapshot object records state information about an historical
++** version of the database file so that it is possible to later open a new read
++** transaction that sees that historical version of the database rather than
++** the most recent version.
++**
++** The constructor for this object is [sqlite3_snapshot_get()].  The
++** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
++** to an historical snapshot (if possible).  The destructor for 
++** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
++*/
++typedef struct sqlite3_snapshot {
++  unsigned char hidden[48];
++} sqlite3_snapshot;
++
++/*
++** CAPI3REF: Record A Database Snapshot
++** EXPERIMENTAL
++**
++** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
++** new [sqlite3_snapshot] object that records the current state of
++** schema S in database connection D.  ^On success, the
++** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
++** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
++** If there is not already a read-transaction open on schema S when
++** this function is called, one is opened automatically. 
++**
++** The following must be true for this function to succeed. If any of
++** the following statements are false when sqlite3_snapshot_get() is
++** called, SQLITE_ERROR is returned. The final value of *P is undefined
++** in this case. 
++**
++** <ul>
++**   <li> The database handle must be in [autocommit mode].
++**
++**   <li> Schema S of [database connection] D must be a [WAL mode] database.
++**
++**   <li> There must not be a write transaction open on schema S of database
++**        connection D.
++**
++**   <li> One or more transactions must have been written to the current wal
++**        file since it was created on disk (by any connection). This means
++**        that a snapshot cannot be taken on a wal mode database with no wal 
++**        file immediately after it is first opened. At least one transaction
++**        must be written to it first.
++** </ul>
++**
++** This function may also return SQLITE_NOMEM.  If it is called with the
++** database handle in autocommit mode but fails for some other reason, 
++** whether or not a read transaction is opened on schema S is undefined.
++**
++** The [sqlite3_snapshot] object returned from a successful call to
++** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
++** to avoid a memory leak.
++**
++** The [sqlite3_snapshot_get()] interface is only available when the
++** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++*/
++SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
++  sqlite3 *db,
++  const char *zSchema,
++  sqlite3_snapshot **ppSnapshot
++);
++
++/*
++** CAPI3REF: Start a read transaction on an historical snapshot
++** EXPERIMENTAL
++**
++** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
++** read transaction for schema S of
++** [database connection] D such that the read transaction
++** refers to historical [snapshot] P, rather than the most
++** recent change to the database.
++** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
++** or an appropriate [error code] if it fails.
++**
++** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
++** the first operation following the [BEGIN] that takes the schema S
++** out of [autocommit mode].
++** ^In other words, schema S must not currently be in
++** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
++** database connection D must be out of [autocommit mode].
++** ^A [snapshot] will fail to open if it has been overwritten by a
++** [checkpoint].
++** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
++** database connection D does not know that the database file for
++** schema S is in [WAL mode].  A database connection might not know
++** that the database file is in [WAL mode] if there has been no prior
++** I/O on that database connection, or if the database entered [WAL mode] 
++** after the most recent I/O on the database connection.)^
++** (Hint: Run "[PRAGMA application_id]" against a newly opened
++** database connection in order to make it ready to use snapshots.)
++**
++** The [sqlite3_snapshot_open()] interface is only available when the
++** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++*/
++SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
++  sqlite3 *db,
++  const char *zSchema,
++  sqlite3_snapshot *pSnapshot
++);
++
++/*
++** CAPI3REF: Destroy a snapshot
++** EXPERIMENTAL
++**
++** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
++** The application must eventually free every [sqlite3_snapshot] object
++** using this routine to avoid a memory leak.
++**
++** The [sqlite3_snapshot_free()] interface is only available when the
++** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++*/
++SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
++
++/*
++** CAPI3REF: Compare the ages of two snapshot handles.
++** EXPERIMENTAL
++**
++** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
++** of two valid snapshot handles. 
++**
++** If the two snapshot handles are not associated with the same database 
++** file, the result of the comparison is undefined. 
++**
++** Additionally, the result of the comparison is only valid if both of the
++** snapshot handles were obtained by calling sqlite3_snapshot_get() since the
++** last time the wal file was deleted. The wal file is deleted when the
++** database is changed back to rollback mode or when the number of database
++** clients drops to zero. If either snapshot handle was obtained before the 
++** wal file was last deleted, the value returned by this function 
++** is undefined.
++**
++** Otherwise, this API returns a negative value if P1 refers to an older
++** snapshot than P2, zero if the two handles refer to the same database
++** snapshot, and a positive value if P1 is a newer snapshot than P2.
++*/
++SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
++  sqlite3_snapshot *p1,
++  sqlite3_snapshot *p2
++);
+ 
++/*
++** CAPI3REF: Recover snapshots from a wal file
++** EXPERIMENTAL
++**
++** If all connections disconnect from a database file but do not perform
++** a checkpoint, the existing wal file is opened along with the database
++** file the next time the database is opened. At this point it is only
++** possible to successfully call sqlite3_snapshot_open() to open the most
++** recent snapshot of the database (the one at the head of the wal file),
++** even though the wal file may contain other valid snapshots for which
++** clients have sqlite3_snapshot handles.
++**
++** This function attempts to scan the wal file associated with database zDb
++** of database handle db and make all valid snapshots available to
++** sqlite3_snapshot_open(). It is an error if there is already a read
++** transaction open on the database, or if the database is not a wal mode
++** database.
++**
++** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
++*/
++SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
+ 
+ /*
+ ** Undo the hack that converts floating point types to integer for
+@@ -7919,8 +9729,9 @@
+ #if 0
+ }  /* End of the 'extern "C"' block */
+ #endif
+-#endif /* _SQLITE3_H_ */
++#endif /* SQLITE3_H */
+ 
++/******** Begin file sqlite3rtree.h *********/
+ /*
+ ** 2010 August 30
+ **
+@@ -7960,7 +9771,7 @@
+ **
+ **   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
++SQLITE_API int sqlite3_rtree_geometry_callback(
+   sqlite3 *db,
+   const char *zGeom,
+   int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
+@@ -7986,7 +9797,7 @@
+ **
+ **   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
++SQLITE_API int sqlite3_rtree_query_callback(
+   sqlite3 *db,
+   const char *zQueryFunc,
+   int (*xQueryFunc)(sqlite3_rtree_query_info*),
+@@ -8020,6 +9831,8 @@
+   int eParentWithin;                /* Visibility of parent node */
+   int eWithin;                      /* OUT: Visiblity */
+   sqlite3_rtree_dbl rScore;         /* OUT: Write the score here */
++  /* The following fields are only available in 3.8.11 and later */
++  sqlite3_value **apSqlParam;       /* Original SQL values of parameters */
+ };
+ 
+ /*
+@@ -8036,6 +9849,1878 @@
+ 
+ #endif  /* ifndef _SQLITE3RTREE_H_ */
+ 
++/******** End of sqlite3rtree.h *********/
++/******** Begin file sqlite3session.h *********/
++
++#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION)
++#define __SQLITESESSION_H_ 1
++
++/*
++** Make sure we can call this stuff from C++.
++*/
++#if 0
++extern "C" {
++#endif
++
++
++/*
++** CAPI3REF: Session Object Handle
++*/
++typedef struct sqlite3_session sqlite3_session;
++
++/*
++** CAPI3REF: Changeset Iterator Handle
++*/
++typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
++
++/*
++** CAPI3REF: Create A New Session Object
++**
++** Create a new session object attached to database handle db. If successful,
++** a pointer to the new object is written to *ppSession and SQLITE_OK is
++** returned. If an error occurs, *ppSession is set to NULL and an SQLite
++** error code (e.g. SQLITE_NOMEM) is returned.
++**
++** It is possible to create multiple session objects attached to a single
++** database handle.
++**
++** Session objects created using this function should be deleted using the
++** [sqlite3session_delete()] function before the database handle that they
++** are attached to is itself closed. If the database handle is closed before
++** the session object is deleted, then the results of calling any session
++** module function, including [sqlite3session_delete()] on the session object
++** are undefined.
++**
++** Because the session module uses the [sqlite3_preupdate_hook()] API, it
++** is not possible for an application to register a pre-update hook on a
++** database handle that has one or more session objects attached. Nor is
++** it possible to create a session object attached to a database handle for
++** which a pre-update hook is already defined. The results of attempting 
++** either of these things are undefined.
++**
++** The session object will be used to create changesets for tables in
++** database zDb, where zDb is either "main", or "temp", or the name of an
++** attached database. It is not an error if database zDb is not attached
++** to the database when the session object is created.
++*/
++SQLITE_API int sqlite3session_create(
++  sqlite3 *db,                    /* Database handle */
++  const char *zDb,                /* Name of db (e.g. "main") */
++  sqlite3_session **ppSession     /* OUT: New session object */
++);
++
++/*
++** CAPI3REF: Delete A Session Object
++**
++** Delete a session object previously allocated using 
++** [sqlite3session_create()]. Once a session object has been deleted, the
++** results of attempting to use pSession with any other session module
++** function are undefined.
++**
++** Session objects must be deleted before the database handle to which they
++** are attached is closed. Refer to the documentation for 
++** [sqlite3session_create()] for details.
++*/
++SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
++
++
++/*
++** CAPI3REF: Enable Or Disable A Session Object
++**
++** Enable or disable the recording of changes by a session object. When
++** enabled, a session object records changes made to the database. When
++** disabled - it does not. A newly created session object is enabled.
++** Refer to the documentation for [sqlite3session_changeset()] for further
++** details regarding how enabling and disabling a session object affects
++** the eventual changesets.
++**
++** Passing zero to this function disables the session. Passing a value
++** greater than zero enables it. Passing a value less than zero is a 
++** no-op, and may be used to query the current state of the session.
++**
++** The return value indicates the final state of the session object: 0 if 
++** the session is disabled, or 1 if it is enabled.
++*/
++SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
++
++/*
++** CAPI3REF: Set Or Clear the Indirect Change Flag
++**
++** Each change recorded by a session object is marked as either direct or
++** indirect. A change is marked as indirect if either:
++**
++** <ul>
++**   <li> The session object "indirect" flag is set when the change is
++**        made, or
++**   <li> The change is made by an SQL trigger or foreign key action 
++**        instead of directly as a result of a users SQL statement.
++** </ul>
++**
++** If a single row is affected by more than one operation within a session,
++** then the change is considered indirect if all operations meet the criteria
++** for an indirect change above, or direct otherwise.
++**
++** This function is used to set, clear or query the session object indirect
++** flag.  If the second argument passed to this function is zero, then the
++** indirect flag is cleared. If it is greater than zero, the indirect flag
++** is set. Passing a value less than zero does not modify the current value
++** of the indirect flag, and may be used to query the current state of the 
++** indirect flag for the specified session object.
++**
++** The return value indicates the final state of the indirect flag: 0 if 
++** it is clear, or 1 if it is set.
++*/
++SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
++
++/*
++** CAPI3REF: Attach A Table To A Session Object
++**
++** If argument zTab is not NULL, then it is the name of a table to attach
++** to the session object passed as the first argument. All subsequent changes 
++** made to the table while the session object is enabled will be recorded. See 
++** documentation for [sqlite3session_changeset()] for further details.
++**
++** Or, if argument zTab is NULL, then changes are recorded for all tables
++** in the database. If additional tables are added to the database (by 
++** executing "CREATE TABLE" statements) after this call is made, changes for 
++** the new tables are also recorded.
++**
++** Changes can only be recorded for tables that have a PRIMARY KEY explicitly
++** defined as part of their CREATE TABLE statement. It does not matter if the 
++** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY
++** KEY may consist of a single column, or may be a composite key.
++** 
++** It is not an error if the named table does not exist in the database. Nor
++** is it an error if the named table does not have a PRIMARY KEY. However,
++** no changes will be recorded in either of these scenarios.
++**
++** Changes are not recorded for individual rows that have NULL values stored
++** in one or more of their PRIMARY KEY columns.
++**
++** SQLITE_OK is returned if the call completes without error. Or, if an error 
++** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
++*/
++SQLITE_API int sqlite3session_attach(
++  sqlite3_session *pSession,      /* Session object */
++  const char *zTab                /* Table name */
++);
++
++/*
++** CAPI3REF: Set a table filter on a Session Object.
++**
++** The second argument (xFilter) is the "filter callback". For changes to rows 
++** in tables that are not attached to the Session object, the filter is called
++** to determine whether changes to the table's rows should be tracked or not. 
++** If xFilter returns 0, changes is not tracked. Note that once a table is 
++** attached, xFilter will not be called again.
++*/
++SQLITE_API void sqlite3session_table_filter(
++  sqlite3_session *pSession,      /* Session object */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of third arg to _filter_table() */
++    const char *zTab              /* Table name */
++  ),
++  void *pCtx                      /* First argument passed to xFilter */
++);
++
++/*
++** CAPI3REF: Generate A Changeset From A Session Object
++**
++** Obtain a changeset containing changes to the tables attached to the 
++** session object passed as the first argument. If successful, 
++** set *ppChangeset to point to a buffer containing the changeset 
++** and *pnChangeset to the size of the changeset in bytes before returning
++** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to
++** zero and return an SQLite error code.
++**
++** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes,
++** each representing a change to a single row of an attached table. An INSERT
++** change contains the values of each field of a new database row. A DELETE
++** contains the original values of each field of a deleted database row. An
++** UPDATE change contains the original values of each field of an updated
++** database row along with the updated values for each updated non-primary-key
++** column. It is not possible for an UPDATE change to represent a change that
++** modifies the values of primary key columns. If such a change is made, it
++** is represented in a changeset as a DELETE followed by an INSERT.
++**
++** Changes are not recorded for rows that have NULL values stored in one or 
++** more of their PRIMARY KEY columns. If such a row is inserted or deleted,
++** no corresponding change is present in the changesets returned by this
++** function. If an existing row with one or more NULL values stored in
++** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL,
++** only an INSERT is appears in the changeset. Similarly, if an existing row
++** with non-NULL PRIMARY KEY values is updated so that one or more of its
++** PRIMARY KEY columns are set to NULL, the resulting changeset contains a
++** DELETE change only.
++**
++** The contents of a changeset may be traversed using an iterator created
++** using the [sqlite3changeset_start()] API. A changeset may be applied to
++** a database with a compatible schema using the [sqlite3changeset_apply()]
++** API.
++**
++** Within a changeset generated by this function, all changes related to a
++** single table are grouped together. In other words, when iterating through
++** a changeset or when applying a changeset to a database, all changes related
++** to a single table are processed before moving on to the next table. Tables
++** are sorted in the same order in which they were attached (or auto-attached)
++** to the sqlite3_session object. The order in which the changes related to
++** a single table are stored is undefined.
++**
++** Following a successful call to this function, it is the responsibility of
++** the caller to eventually free the buffer that *ppChangeset points to using
++** [sqlite3_free()].
++**
++** <h3>Changeset Generation</h3>
++**
++** Once a table has been attached to a session object, the session object
++** records the primary key values of all new rows inserted into the table.
++** It also records the original primary key and other column values of any
++** deleted or updated rows. For each unique primary key value, data is only
++** recorded once - the first time a row with said primary key is inserted,
++** updated or deleted in the lifetime of the session.
++**
++** There is one exception to the previous paragraph: when a row is inserted,
++** updated or deleted, if one or more of its primary key columns contain a
++** NULL value, no record of the change is made.
++**
++** The session object therefore accumulates two types of records - those
++** that consist of primary key values only (created when the user inserts
++** a new record) and those that consist of the primary key values and the
++** original values of other table columns (created when the users deletes
++** or updates a record).
++**
++** When this function is called, the requested changeset is created using
++** both the accumulated records and the current contents of the database
++** file. Specifically:
++**
++** <ul>
++**   <li> For each record generated by an insert, the database is queried
++**        for a row with a matching primary key. If one is found, an INSERT
++**        change is added to the changeset. If no such row is found, no change 
++**        is added to the changeset.
++**
++**   <li> For each record generated by an update or delete, the database is 
++**        queried for a row with a matching primary key. If such a row is
++**        found and one or more of the non-primary key fields have been
++**        modified from their original values, an UPDATE change is added to 
++**        the changeset. Or, if no such row is found in the table, a DELETE 
++**        change is added to the changeset. If there is a row with a matching
++**        primary key in the database, but all fields contain their original
++**        values, no change is added to the changeset.
++** </ul>
++**
++** This means, amongst other things, that if a row is inserted and then later
++** deleted while a session object is active, neither the insert nor the delete
++** will be present in the changeset. Or if a row is deleted and then later a 
++** row with the same primary key values inserted while a session object is
++** active, the resulting changeset will contain an UPDATE change instead of
++** a DELETE and an INSERT.
++**
++** When a session object is disabled (see the [sqlite3session_enable()] API),
++** it does not accumulate records when rows are inserted, updated or deleted.
++** This may appear to have some counter-intuitive effects if a single row
++** is written to more than once during a session. For example, if a row
++** is inserted while a session object is enabled, then later deleted while 
++** the same session object is disabled, no INSERT record will appear in the
++** changeset, even though the delete took place while the session was disabled.
++** Or, if one field of a row is updated while a session is disabled, and 
++** another field of the same row is updated while the session is enabled, the
++** resulting changeset will contain an UPDATE change that updates both fields.
++*/
++SQLITE_API int sqlite3session_changeset(
++  sqlite3_session *pSession,      /* Session object */
++  int *pnChangeset,               /* OUT: Size of buffer at *ppChangeset */
++  void **ppChangeset              /* OUT: Buffer containing changeset */
++);
++
++/*
++** CAPI3REF: Load The Difference Between Tables Into A Session 
++**
++** If it is not already attached to the session object passed as the first
++** argument, this function attaches table zTbl in the same manner as the
++** [sqlite3session_attach()] function. If zTbl does not exist, or if it
++** does not have a primary key, this function is a no-op (but does not return
++** an error).
++**
++** Argument zFromDb must be the name of a database ("main", "temp" etc.)
++** attached to the same database handle as the session object that contains 
++** a table compatible with the table attached to the session by this function.
++** A table is considered compatible if it:
++**
++** <ul>
++**   <li> Has the same name,
++**   <li> Has the same set of columns declared in the same order, and
++**   <li> Has the same PRIMARY KEY definition.
++** </ul>
++**
++** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables
++** are compatible but do not have any PRIMARY KEY columns, it is not an error
++** but no changes are added to the session object. As with other session
++** APIs, tables without PRIMARY KEYs are simply ignored.
++**
++** This function adds a set of changes to the session object that could be
++** used to update the table in database zFrom (call this the "from-table") 
++** so that its content is the same as the table attached to the session 
++** object (call this the "to-table"). Specifically:
++**
++** <ul>
++**   <li> For each row (primary key) that exists in the to-table but not in 
++**     the from-table, an INSERT record is added to the session object.
++**
++**   <li> For each row (primary key) that exists in the to-table but not in 
++**     the from-table, a DELETE record is added to the session object.
++**
++**   <li> For each row (primary key) that exists in both tables, but features 
++**     different non-PK values in each, an UPDATE record is added to the
++**     session.  
++** </ul>
++**
++** To clarify, if this function is called and then a changeset constructed
++** using [sqlite3session_changeset()], then after applying that changeset to 
++** database zFrom the contents of the two compatible tables would be 
++** identical.
++**
++** It an error if database zFrom does not exist or does not contain the
++** required compatible table.
++**
++** If the operation successful, SQLITE_OK is returned. Otherwise, an SQLite
++** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
++** may be set to point to a buffer containing an English language error 
++** message. It is the responsibility of the caller to free this buffer using
++** sqlite3_free().
++*/
++SQLITE_API int sqlite3session_diff(
++  sqlite3_session *pSession,
++  const char *zFromDb,
++  const char *zTbl,
++  char **pzErrMsg
++);
++
++
++/*
++** CAPI3REF: Generate A Patchset From A Session Object
++**
++** The differences between a patchset and a changeset are that:
++**
++** <ul>
++**   <li> DELETE records consist of the primary key fields only. The 
++**        original values of other fields are omitted.
++**   <li> The original values of any modified fields are omitted from 
++**        UPDATE records.
++** </ul>
++**
++** A patchset blob may be used with up to date versions of all 
++** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(), 
++** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly,
++** attempting to use a patchset blob with old versions of the
++** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error. 
++**
++** Because the non-primary key "old.*" fields are omitted, no 
++** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset
++** is passed to the sqlite3changeset_apply() API. Other conflict types work
++** in the same way as for changesets.
++**
++** Changes within a patchset are ordered in the same way as for changesets
++** generated by the sqlite3session_changeset() function (i.e. all changes for
++** a single table are grouped together, tables appear in the order in which
++** they were attached to the session object).
++*/
++SQLITE_API int sqlite3session_patchset(
++  sqlite3_session *pSession,      /* Session object */
++  int *pnPatchset,                /* OUT: Size of buffer at *ppChangeset */
++  void **ppPatchset               /* OUT: Buffer containing changeset */
++);
++
++/*
++** CAPI3REF: Test if a changeset has recorded any changes.
++**
++** Return non-zero if no changes to attached tables have been recorded by 
++** the session object passed as the first argument. Otherwise, if one or 
++** more changes have been recorded, return zero.
++**
++** Even if this function returns zero, it is possible that calling
++** [sqlite3session_changeset()] on the session handle may still return a
++** changeset that contains no changes. This can happen when a row in 
++** an attached table is modified and then later on the original values 
++** are restored. However, if this function returns non-zero, then it is
++** guaranteed that a call to sqlite3session_changeset() will return a 
++** changeset containing zero changes.
++*/
++SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
++
++/*
++** CAPI3REF: Create An Iterator To Traverse A Changeset 
++**
++** Create an iterator used to iterate through the contents of a changeset.
++** If successful, *pp is set to point to the iterator handle and SQLITE_OK
++** is returned. Otherwise, if an error occurs, *pp is set to zero and an
++** SQLite error code is returned.
++**
++** The following functions can be used to advance and query a changeset 
++** iterator created by this function:
++**
++** <ul>
++**   <li> [sqlite3changeset_next()]
++**   <li> [sqlite3changeset_op()]
++**   <li> [sqlite3changeset_new()]
++**   <li> [sqlite3changeset_old()]
++** </ul>
++**
++** It is the responsibility of the caller to eventually destroy the iterator
++** by passing it to [sqlite3changeset_finalize()]. The buffer containing the
++** changeset (pChangeset) must remain valid until after the iterator is
++** destroyed.
++**
++** Assuming the changeset blob was created by one of the
++** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
++** [sqlite3changeset_invert()] functions, all changes within the changeset 
++** that apply to a single table are grouped together. This means that when 
++** an application iterates through a changeset using an iterator created by 
++** this function, all changes that relate to a single table are visited 
++** consecutively. There is no chance that the iterator will visit a change 
++** the applies to table X, then one for table Y, and then later on visit 
++** another change for table X.
++*/
++SQLITE_API int sqlite3changeset_start(
++  sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
++  int nChangeset,                 /* Size of changeset blob in bytes */
++  void *pChangeset                /* Pointer to blob containing changeset */
++);
++
++
++/*
++** CAPI3REF: Advance A Changeset Iterator
++**
++** This function may only be used with iterators created by function
++** [sqlite3changeset_start()]. If it is called on an iterator passed to
++** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
++** is returned and the call has no effect.
++**
++** Immediately after an iterator is created by sqlite3changeset_start(), it
++** does not point to any change in the changeset. Assuming the changeset
++** is not empty, the first call to this function advances the iterator to
++** point to the first change in the changeset. Each subsequent call advances
++** the iterator to point to the next change in the changeset (if any). If
++** no error occurs and the iterator points to a valid change after a call
++** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned. 
++** Otherwise, if all changes in the changeset have already been visited,
++** SQLITE_DONE is returned.
++**
++** If an error occurs, an SQLite error code is returned. Possible error 
++** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or 
++** SQLITE_NOMEM.
++*/
++SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
++
++/*
++** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
++**
++** The pIter argument passed to this function may either be an iterator
++** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
++** created by [sqlite3changeset_start()]. In the latter case, the most recent
++** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this
++** is not the case, this function returns [SQLITE_MISUSE].
++**
++** If argument pzTab is not NULL, then *pzTab is set to point to a
++** nul-terminated utf-8 encoded string containing the name of the table
++** affected by the current change. The buffer remains valid until either
++** sqlite3changeset_next() is called on the iterator or until the 
++** conflict-handler function returns. If pnCol is not NULL, then *pnCol is 
++** set to the number of columns in the table affected by the change. If
++** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change
++** is an indirect change, or false (0) otherwise. See the documentation for
++** [sqlite3session_indirect()] for a description of direct and indirect
++** changes. Finally, if pOp is not NULL, then *pOp is set to one of 
++** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the 
++** type of change that the iterator currently points to.
++**
++** If no error occurs, SQLITE_OK is returned. If an error does occur, an
++** SQLite error code is returned. The values of the output variables may not
++** be trusted in this case.
++*/
++SQLITE_API int sqlite3changeset_op(
++  sqlite3_changeset_iter *pIter,  /* Iterator object */
++  const char **pzTab,             /* OUT: Pointer to table name */
++  int *pnCol,                     /* OUT: Number of columns in table */
++  int *pOp,                       /* OUT: SQLITE_INSERT, DELETE or UPDATE */
++  int *pbIndirect                 /* OUT: True for an 'indirect' change */
++);
++
++/*
++** CAPI3REF: Obtain The Primary Key Definition Of A Table
++**
++** For each modified table, a changeset includes the following:
++**
++** <ul>
++**   <li> The number of columns in the table, and
++**   <li> Which of those columns make up the tables PRIMARY KEY.
++** </ul>
++**
++** This function is used to find which columns comprise the PRIMARY KEY of
++** the table modified by the change that iterator pIter currently points to.
++** If successful, *pabPK is set to point to an array of nCol entries, where
++** nCol is the number of columns in the table. Elements of *pabPK are set to
++** 0x01 if the corresponding column is part of the tables primary key, or
++** 0x00 if it is not.
++**
++** If argument pnCol is not NULL, then *pnCol is set to the number of columns
++** in the table.
++**
++** If this function is called when the iterator does not point to a valid
++** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
++** SQLITE_OK is returned and the output variables populated as described
++** above.
++*/
++SQLITE_API int sqlite3changeset_pk(
++  sqlite3_changeset_iter *pIter,  /* Iterator object */
++  unsigned char **pabPK,          /* OUT: Array of boolean - true for PK cols */
++  int *pnCol                      /* OUT: Number of entries in output array */
++);
++
++/*
++** CAPI3REF: Obtain old.* Values From A Changeset Iterator
++**
++** The pIter argument passed to this function may either be an iterator
++** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
++** created by [sqlite3changeset_start()]. In the latter case, the most recent
++** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. 
++** Furthermore, it may only be called if the type of change that the iterator
++** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise,
++** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
++**
++** Argument iVal must be greater than or equal to 0, and less than the number
++** of columns in the table affected by the current change. Otherwise,
++** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
++**
++** If successful, this function sets *ppValue to point to a protected
++** sqlite3_value object containing the iVal'th value from the vector of 
++** original row values stored as part of the UPDATE or DELETE change and
++** returns SQLITE_OK. The name of the function comes from the fact that this 
++** is similar to the "old.*" columns available to update or delete triggers.
++**
++** If some other error occurs (e.g. an OOM condition), an SQLite error code
++** is returned and *ppValue is set to NULL.
++*/
++SQLITE_API int sqlite3changeset_old(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int iVal,                       /* Column number */
++  sqlite3_value **ppValue         /* OUT: Old value (or NULL pointer) */
++);
++
++/*
++** CAPI3REF: Obtain new.* Values From A Changeset Iterator
++**
++** The pIter argument passed to this function may either be an iterator
++** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
++** created by [sqlite3changeset_start()]. In the latter case, the most recent
++** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. 
++** Furthermore, it may only be called if the type of change that the iterator
++** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise,
++** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
++**
++** Argument iVal must be greater than or equal to 0, and less than the number
++** of columns in the table affected by the current change. Otherwise,
++** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
++**
++** If successful, this function sets *ppValue to point to a protected
++** sqlite3_value object containing the iVal'th value from the vector of 
++** new row values stored as part of the UPDATE or INSERT change and
++** returns SQLITE_OK. If the change is an UPDATE and does not include
++** a new value for the requested column, *ppValue is set to NULL and 
++** SQLITE_OK returned. The name of the function comes from the fact that 
++** this is similar to the "new.*" columns available to update or delete 
++** triggers.
++**
++** If some other error occurs (e.g. an OOM condition), an SQLite error code
++** is returned and *ppValue is set to NULL.
++*/
++SQLITE_API int sqlite3changeset_new(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int iVal,                       /* Column number */
++  sqlite3_value **ppValue         /* OUT: New value (or NULL pointer) */
++);
++
++/*
++** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
++**
++** This function should only be used with iterator objects passed to a
++** conflict-handler callback by [sqlite3changeset_apply()] with either
++** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function
++** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue
++** is set to NULL.
++**
++** Argument iVal must be greater than or equal to 0, and less than the number
++** of columns in the table affected by the current change. Otherwise,
++** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
++**
++** If successful, this function sets *ppValue to point to a protected
++** sqlite3_value object containing the iVal'th value from the 
++** "conflicting row" associated with the current conflict-handler callback
++** and returns SQLITE_OK.
++**
++** If some other error occurs (e.g. an OOM condition), an SQLite error code
++** is returned and *ppValue is set to NULL.
++*/
++SQLITE_API int sqlite3changeset_conflict(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int iVal,                       /* Column number */
++  sqlite3_value **ppValue         /* OUT: Value from conflicting row */
++);
++
++/*
++** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
++**
++** This function may only be called with an iterator passed to an
++** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
++** it sets the output variable to the total number of known foreign key
++** violations in the destination database and returns SQLITE_OK.
++**
++** In all other cases this function returns SQLITE_MISUSE.
++*/
++SQLITE_API int sqlite3changeset_fk_conflicts(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int *pnOut                      /* OUT: Number of FK violations */
++);
++
++
++/*
++** CAPI3REF: Finalize A Changeset Iterator
++**
++** This function is used to finalize an iterator allocated with
++** [sqlite3changeset_start()].
++**
++** This function should only be called on iterators created using the
++** [sqlite3changeset_start()] function. If an application calls this
++** function with an iterator passed to a conflict-handler by
++** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the
++** call has no effect.
++**
++** If an error was encountered within a call to an sqlite3changeset_xxx()
++** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an 
++** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding
++** to that error is returned by this function. Otherwise, SQLITE_OK is
++** returned. This is to allow the following pattern (pseudo-code):
++**
++**   sqlite3changeset_start();
++**   while( SQLITE_ROW==sqlite3changeset_next() ){
++**     // Do something with change.
++**   }
++**   rc = sqlite3changeset_finalize();
++**   if( rc!=SQLITE_OK ){
++**     // An error has occurred 
++**   }
++*/
++SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
++
++/*
++** CAPI3REF: Invert A Changeset
++**
++** This function is used to "invert" a changeset object. Applying an inverted
++** changeset to a database reverses the effects of applying the uninverted
++** changeset. Specifically:
++**
++** <ul>
++**   <li> Each DELETE change is changed to an INSERT, and
++**   <li> Each INSERT change is changed to a DELETE, and
++**   <li> For each UPDATE change, the old.* and new.* values are exchanged.
++** </ul>
++**
++** This function does not change the order in which changes appear within
++** the changeset. It merely reverses the sense of each individual change.
++**
++** If successful, a pointer to a buffer containing the inverted changeset
++** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and
++** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are
++** zeroed and an SQLite error code returned.
++**
++** It is the responsibility of the caller to eventually call sqlite3_free()
++** on the *ppOut pointer to free the buffer allocation following a successful 
++** call to this function.
++**
++** WARNING/TODO: This function currently assumes that the input is a valid
++** changeset. If it is not, the results are undefined.
++*/
++SQLITE_API int sqlite3changeset_invert(
++  int nIn, const void *pIn,       /* Input changeset */
++  int *pnOut, void **ppOut        /* OUT: Inverse of input */
++);
++
++/*
++** CAPI3REF: Concatenate Two Changeset Objects
++**
++** This function is used to concatenate two changesets, A and B, into a 
++** single changeset. The result is a changeset equivalent to applying
++** changeset A followed by changeset B. 
++**
++** This function combines the two input changesets using an 
++** sqlite3_changegroup object. Calling it produces similar results as the
++** following code fragment:
++**
++**   sqlite3_changegroup *pGrp;
++**   rc = sqlite3_changegroup_new(&pGrp);
++**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
++**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB);
++**   if( rc==SQLITE_OK ){
++**     rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
++**   }else{
++**     *ppOut = 0;
++**     *pnOut = 0;
++**   }
++**
++** Refer to the sqlite3_changegroup documentation below for details.
++*/
++SQLITE_API int sqlite3changeset_concat(
++  int nA,                         /* Number of bytes in buffer pA */
++  void *pA,                       /* Pointer to buffer containing changeset A */
++  int nB,                         /* Number of bytes in buffer pB */
++  void *pB,                       /* Pointer to buffer containing changeset B */
++  int *pnOut,                     /* OUT: Number of bytes in output changeset */
++  void **ppOut                    /* OUT: Buffer containing output changeset */
++);
++
++
++/*
++** CAPI3REF: Changegroup Handle
++*/
++typedef struct sqlite3_changegroup sqlite3_changegroup;
++
++/*
++** CAPI3REF: Create A New Changegroup Object
++**
++** An sqlite3_changegroup object is used to combine two or more changesets
++** (or patchsets) into a single changeset (or patchset). A single changegroup
++** object may combine changesets or patchsets, but not both. The output is
++** always in the same format as the input.
++**
++** If successful, this function returns SQLITE_OK and populates (*pp) with
++** a pointer to a new sqlite3_changegroup object before returning. The caller
++** should eventually free the returned object using a call to 
++** sqlite3changegroup_delete(). If an error occurs, an SQLite error code
++** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL.
++**
++** The usual usage pattern for an sqlite3_changegroup object is as follows:
++**
++** <ul>
++**   <li> It is created using a call to sqlite3changegroup_new().
++**
++**   <li> Zero or more changesets (or patchsets) are added to the object
++**        by calling sqlite3changegroup_add().
++**
++**   <li> The result of combining all input changesets together is obtained 
++**        by the application via a call to sqlite3changegroup_output().
++**
++**   <li> The object is deleted using a call to sqlite3changegroup_delete().
++** </ul>
++**
++** Any number of calls to add() and output() may be made between the calls to
++** new() and delete(), and in any order.
++**
++** As well as the regular sqlite3changegroup_add() and 
++** sqlite3changegroup_output() functions, also available are the streaming
++** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
++*/
++SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
++
++/*
++** CAPI3REF: Add A Changeset To A Changegroup
++**
++** Add all changes within the changeset (or patchset) in buffer pData (size
++** nData bytes) to the changegroup. 
++**
++** If the buffer contains a patchset, then all prior calls to this function
++** on the same changegroup object must also have specified patchsets. Or, if
++** the buffer contains a changeset, so must have the earlier calls to this
++** function. Otherwise, SQLITE_ERROR is returned and no changes are added
++** to the changegroup.
++**
++** Rows within the changeset and changegroup are identified by the values in
++** their PRIMARY KEY columns. A change in the changeset is considered to
++** apply to the same row as a change already present in the changegroup if
++** the two rows have the same primary key.
++**
++** Changes to rows that do not already appear in the changegroup are
++** simply copied into it. Or, if both the new changeset and the changegroup
++** contain changes that apply to a single row, the final contents of the
++** changegroup depends on the type of each change, as follows:
++**
++** <table border=1 style="margin-left:8ex;margin-right:8ex">
++**   <tr><th style="white-space:pre">Existing Change  </th>
++**       <th style="white-space:pre">New Change       </th>
++**       <th>Output Change
++**   <tr><td>INSERT <td>INSERT <td>
++**       The new change is ignored. This case does not occur if the new
++**       changeset was recorded immediately after the changesets already
++**       added to the changegroup.
++**   <tr><td>INSERT <td>UPDATE <td>
++**       The INSERT change remains in the changegroup. The values in the 
++**       INSERT change are modified as if the row was inserted by the
++**       existing change and then updated according to the new change.
++**   <tr><td>INSERT <td>DELETE <td>
++**       The existing INSERT is removed from the changegroup. The DELETE is
++**       not added.
++**   <tr><td>UPDATE <td>INSERT <td>
++**       The new change is ignored. This case does not occur if the new
++**       changeset was recorded immediately after the changesets already
++**       added to the changegroup.
++**   <tr><td>UPDATE <td>UPDATE <td>
++**       The existing UPDATE remains within the changegroup. It is amended 
++**       so that the accompanying values are as if the row was updated once 
++**       by the existing change and then again by the new change.
++**   <tr><td>UPDATE <td>DELETE <td>
++**       The existing UPDATE is replaced by the new DELETE within the
++**       changegroup.
++**   <tr><td>DELETE <td>INSERT <td>
++**       If one or more of the column values in the row inserted by the
++**       new change differ from those in the row deleted by the existing 
++**       change, the existing DELETE is replaced by an UPDATE within the
++**       changegroup. Otherwise, if the inserted row is exactly the same 
++**       as the deleted row, the existing DELETE is simply discarded.
++**   <tr><td>DELETE <td>UPDATE <td>
++**       The new change is ignored. This case does not occur if the new
++**       changeset was recorded immediately after the changesets already
++**       added to the changegroup.
++**   <tr><td>DELETE <td>DELETE <td>
++**       The new change is ignored. This case does not occur if the new
++**       changeset was recorded immediately after the changesets already
++**       added to the changegroup.
++** </table>
++**
++** If the new changeset contains changes to a table that is already present
++** in the changegroup, then the number of columns and the position of the
++** primary key columns for the table must be consistent. If this is not the
++** case, this function fails with SQLITE_SCHEMA. If the input changeset
++** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
++** returned. Or, if an out-of-memory condition occurs during processing, this
++** function returns SQLITE_NOMEM. In all cases, if an error occurs the
++** final contents of the changegroup is undefined.
++**
++** If no error occurs, SQLITE_OK is returned.
++*/
++SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
++
++/*
++** CAPI3REF: Obtain A Composite Changeset From A Changegroup
++**
++** Obtain a buffer containing a changeset (or patchset) representing the
++** current contents of the changegroup. If the inputs to the changegroup
++** were themselves changesets, the output is a changeset. Or, if the
++** inputs were patchsets, the output is also a patchset.
++**
++** As with the output of the sqlite3session_changeset() and
++** sqlite3session_patchset() functions, all changes related to a single
++** table are grouped together in the output of this function. Tables appear
++** in the same order as for the very first changeset added to the changegroup.
++** If the second or subsequent changesets added to the changegroup contain
++** changes for tables that do not appear in the first changeset, they are
++** appended onto the end of the output changeset, again in the order in
++** which they are first encountered.
++**
++** If an error occurs, an SQLite error code is returned and the output
++** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK
++** is returned and the output variables are set to the size of and a 
++** pointer to the output buffer, respectively. In this case it is the
++** responsibility of the caller to eventually free the buffer using a
++** call to sqlite3_free().
++*/
++SQLITE_API int sqlite3changegroup_output(
++  sqlite3_changegroup*,
++  int *pnData,                    /* OUT: Size of output buffer in bytes */
++  void **ppData                   /* OUT: Pointer to output buffer */
++);
++
++/*
++** CAPI3REF: Delete A Changegroup Object
++*/
++SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
++
++/*
++** CAPI3REF: Apply A Changeset To A Database
++**
++** Apply a changeset to a database. This function attempts to update the
++** "main" database attached to handle db with the changes found in the
++** changeset passed via the second and third arguments.
++**
++** The fourth argument (xFilter) passed to this function is the "filter
++** callback". If it is not NULL, then for each table affected by at least one
++** change in the changeset, the filter callback is invoked with
++** the table name as the second argument, and a copy of the context pointer
++** passed as the sixth argument to this function as the first. If the "filter
++** callback" returns zero, then no attempt is made to apply any changes to 
++** the table. Otherwise, if the return value is non-zero or the xFilter
++** argument to this function is NULL, all changes related to the table are
++** attempted.
++**
++** For each table that is not excluded by the filter callback, this function 
++** tests that the target database contains a compatible table. A table is 
++** considered compatible if all of the following are true:
++**
++** <ul>
++**   <li> The table has the same name as the name recorded in the 
++**        changeset, and
++**   <li> The table has at least as many columns as recorded in the 
++**        changeset, and
++**   <li> The table has primary key columns in the same position as 
++**        recorded in the changeset.
++** </ul>
++**
++** If there is no compatible table, it is not an error, but none of the
++** changes associated with the table are applied. A warning message is issued
++** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most
++** one such warning is issued for each table in the changeset.
++**
++** For each change for which there is a compatible table, an attempt is made 
++** to modify the table contents according to the UPDATE, INSERT or DELETE 
++** change. If a change cannot be applied cleanly, the conflict handler 
++** function passed as the fifth argument to sqlite3changeset_apply() may be 
++** invoked. A description of exactly when the conflict handler is invoked for 
++** each type of change is below.
++**
++** Unlike the xFilter argument, xConflict may not be passed NULL. The results
++** of passing anything other than a valid function pointer as the xConflict
++** argument are undefined.
++**
++** Each time the conflict handler function is invoked, it must return one
++** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or 
++** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned
++** if the second argument passed to the conflict handler is either
++** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler
++** returns an illegal value, any changes already made are rolled back and
++** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different 
++** actions are taken by sqlite3changeset_apply() depending on the value
++** returned by each invocation of the conflict-handler function. Refer to
++** the documentation for the three 
++** [SQLITE_CHANGESET_OMIT|available return values] for details.
++**
++** <dl>
++** <dt>DELETE Changes<dd>
++**   For each DELETE change, this function checks if the target database 
++**   contains a row with the same primary key value (or values) as the 
++**   original row values stored in the changeset. If it does, and the values 
++**   stored in all non-primary key columns also match the values stored in 
++**   the changeset the row is deleted from the target database.
++**
++**   If a row with matching primary key values is found, but one or more of
++**   the non-primary key fields contains a value different from the original
++**   row value stored in the changeset, the conflict-handler function is
++**   invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the
++**   database table has more columns than are recorded in the changeset,
++**   only the values of those non-primary key fields are compared against
++**   the current database contents - any trailing database table columns
++**   are ignored.
++**
++**   If no row with matching primary key values is found in the database,
++**   the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
++**   passed as the second argument.
++**
++**   If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT
++**   (which can only happen if a foreign key constraint is violated), the
++**   conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT]
++**   passed as the second argument. This includes the case where the DELETE
++**   operation is attempted because an earlier call to the conflict handler
++**   function returned [SQLITE_CHANGESET_REPLACE].
++**
++** <dt>INSERT Changes<dd>
++**   For each INSERT change, an attempt is made to insert the new row into
++**   the database. If the changeset row contains fewer fields than the
++**   database table, the trailing fields are populated with their default
++**   values.
++**
++**   If the attempt to insert the row fails because the database already 
++**   contains a row with the same primary key values, the conflict handler
++**   function is invoked with the second argument set to 
++**   [SQLITE_CHANGESET_CONFLICT].
++**
++**   If the attempt to insert the row fails because of some other constraint
++**   violation (e.g. NOT NULL or UNIQUE), the conflict handler function is 
++**   invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT].
++**   This includes the case where the INSERT operation is re-attempted because 
++**   an earlier call to the conflict handler function returned 
++**   [SQLITE_CHANGESET_REPLACE].
++**
++** <dt>UPDATE Changes<dd>
++**   For each UPDATE change, this function checks if the target database 
++**   contains a row with the same primary key value (or values) as the 
++**   original row values stored in the changeset. If it does, and the values 
++**   stored in all modified non-primary key columns also match the values
++**   stored in the changeset the row is updated within the target database.
++**
++**   If a row with matching primary key values is found, but one or more of
++**   the modified non-primary key fields contains a value different from an
++**   original row value stored in the changeset, the conflict-handler function
++**   is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
++**   UPDATE changes only contain values for non-primary key fields that are
++**   to be modified, only those fields need to match the original values to
++**   avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
++**
++**   If no row with matching primary key values is found in the database,
++**   the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
++**   passed as the second argument.
++**
++**   If the UPDATE operation is attempted, but SQLite returns 
++**   SQLITE_CONSTRAINT, the conflict-handler function is invoked with 
++**   [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument.
++**   This includes the case where the UPDATE operation is attempted after 
++**   an earlier call to the conflict handler function returned
++**   [SQLITE_CHANGESET_REPLACE].  
++** </dl>
++**
++** It is safe to execute SQL statements, including those that write to the
++** table that the callback related to, from within the xConflict callback.
++** This can be used to further customize the applications conflict
++** resolution strategy.
++**
++** All changes made by this function are enclosed in a savepoint transaction.
++** If any other error (aside from a constraint failure when attempting to
++** write to the target database) occurs, then the savepoint transaction is
++** rolled back, restoring the target database to its original state, and an 
++** SQLite error code returned.
++*/
++SQLITE_API int sqlite3changeset_apply(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  int nChangeset,                 /* Size of changeset in bytes */
++  void *pChangeset,               /* Changeset blob */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx                      /* First argument passed to xConflict */
++);
++
++/* 
++** CAPI3REF: Constants Passed To The Conflict Handler
++**
++** Values that may be passed as the second argument to a conflict-handler.
++**
++** <dl>
++** <dt>SQLITE_CHANGESET_DATA<dd>
++**   The conflict handler is invoked with CHANGESET_DATA as the second argument
++**   when processing a DELETE or UPDATE change if a row with the required
++**   PRIMARY KEY fields is present in the database, but one or more other 
++**   (non primary-key) fields modified by the update do not contain the 
++**   expected "before" values.
++** 
++**   The conflicting row, in this case, is the database row with the matching
++**   primary key.
++** 
++** <dt>SQLITE_CHANGESET_NOTFOUND<dd>
++**   The conflict handler is invoked with CHANGESET_NOTFOUND as the second
++**   argument when processing a DELETE or UPDATE change if a row with the
++**   required PRIMARY KEY fields is not present in the database.
++** 
++**   There is no conflicting row in this case. The results of invoking the
++**   sqlite3changeset_conflict() API are undefined.
++** 
++** <dt>SQLITE_CHANGESET_CONFLICT<dd>
++**   CHANGESET_CONFLICT is passed as the second argument to the conflict
++**   handler while processing an INSERT change if the operation would result 
++**   in duplicate primary key values.
++** 
++**   The conflicting row in this case is the database row with the matching
++**   primary key.
++**
++** <dt>SQLITE_CHANGESET_FOREIGN_KEY<dd>
++**   If foreign key handling is enabled, and applying a changeset leaves the
++**   database in a state containing foreign key violations, the conflict 
++**   handler is invoked with CHANGESET_FOREIGN_KEY as the second argument
++**   exactly once before the changeset is committed. If the conflict handler
++**   returns CHANGESET_OMIT, the changes, including those that caused the
++**   foreign key constraint violation, are committed. Or, if it returns
++**   CHANGESET_ABORT, the changeset is rolled back.
++**
++**   No current or conflicting row information is provided. The only function
++**   it is possible to call on the supplied sqlite3_changeset_iter handle
++**   is sqlite3changeset_fk_conflicts().
++** 
++** <dt>SQLITE_CHANGESET_CONSTRAINT<dd>
++**   If any other constraint violation occurs while applying a change (i.e. 
++**   a UNIQUE, CHECK or NOT NULL constraint), the conflict handler is 
++**   invoked with CHANGESET_CONSTRAINT as the second argument.
++** 
++**   There is no conflicting row in this case. The results of invoking the
++**   sqlite3changeset_conflict() API are undefined.
++**
++** </dl>
++*/
++#define SQLITE_CHANGESET_DATA        1
++#define SQLITE_CHANGESET_NOTFOUND    2
++#define SQLITE_CHANGESET_CONFLICT    3
++#define SQLITE_CHANGESET_CONSTRAINT  4
++#define SQLITE_CHANGESET_FOREIGN_KEY 5
++
++/* 
++** CAPI3REF: Constants Returned By The Conflict Handler
++**
++** A conflict handler callback must return one of the following three values.
++**
++** <dl>
++** <dt>SQLITE_CHANGESET_OMIT<dd>
++**   If a conflict handler returns this value no special action is taken. The
++**   change that caused the conflict is not applied. The session module 
++**   continues to the next change in the changeset.
++**
++** <dt>SQLITE_CHANGESET_REPLACE<dd>
++**   This value may only be returned if the second argument to the conflict
++**   handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this
++**   is not the case, any changes applied so far are rolled back and the 
++**   call to sqlite3changeset_apply() returns SQLITE_MISUSE.
++**
++**   If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict
++**   handler, then the conflicting row is either updated or deleted, depending
++**   on the type of change.
++**
++**   If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict
++**   handler, then the conflicting row is removed from the database and a
++**   second attempt to apply the change is made. If this second attempt fails,
++**   the original row is restored to the database before continuing.
++**
++** <dt>SQLITE_CHANGESET_ABORT<dd>
++**   If this value is returned, any changes applied so far are rolled back 
++**   and the call to sqlite3changeset_apply() returns SQLITE_ABORT.
++** </dl>
++*/
++#define SQLITE_CHANGESET_OMIT       0
++#define SQLITE_CHANGESET_REPLACE    1
++#define SQLITE_CHANGESET_ABORT      2
++
++/*
++** CAPI3REF: Streaming Versions of API functions.
++**
++** The six streaming API xxx_strm() functions serve similar purposes to the 
++** corresponding non-streaming API functions:
++**
++** <table border=1 style="margin-left:8ex;margin-right:8ex">
++**   <tr><th>Streaming function<th>Non-streaming equivalent</th>
++**   <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply] 
++**   <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat] 
++**   <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert] 
++**   <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start] 
++**   <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset] 
++**   <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset] 
++** </table>
++**
++** Non-streaming functions that accept changesets (or patchsets) as input
++** require that the entire changeset be stored in a single buffer in memory. 
++** Similarly, those that return a changeset or patchset do so by returning 
++** a pointer to a single large buffer allocated using sqlite3_malloc(). 
++** Normally this is convenient. However, if an application running in a 
++** low-memory environment is required to handle very large changesets, the
++** large contiguous memory allocations required can become onerous.
++**
++** In order to avoid this problem, instead of a single large buffer, input
++** is passed to a streaming API functions by way of a callback function that
++** the sessions module invokes to incrementally request input data as it is
++** required. In all cases, a pair of API function parameters such as
++**
++**  <pre>
++**  &nbsp;     int nChangeset,
++**  &nbsp;     void *pChangeset,
++**  </pre>
++**
++** Is replaced by:
++**
++**  <pre>
++**  &nbsp;     int (*xInput)(void *pIn, void *pData, int *pnData),
++**  &nbsp;     void *pIn,
++**  </pre>
++**
++** Each time the xInput callback is invoked by the sessions module, the first
++** argument passed is a copy of the supplied pIn context pointer. The second 
++** argument, pData, points to a buffer (*pnData) bytes in size. Assuming no 
++** error occurs the xInput method should copy up to (*pnData) bytes of data 
++** into the buffer and set (*pnData) to the actual number of bytes copied 
++** before returning SQLITE_OK. If the input is completely exhausted, (*pnData) 
++** should be set to zero to indicate this. Or, if an error occurs, an SQLite 
++** error code should be returned. In all cases, if an xInput callback returns
++** an error, all processing is abandoned and the streaming API function
++** returns a copy of the error code to the caller.
++**
++** In the case of sqlite3changeset_start_strm(), the xInput callback may be
++** invoked by the sessions module at any point during the lifetime of the
++** iterator. If such an xInput callback returns an error, the iterator enters
++** an error state, whereby all subsequent calls to iterator functions 
++** immediately fail with the same error code as returned by xInput.
++**
++** Similarly, streaming API functions that return changesets (or patchsets)
++** return them in chunks by way of a callback function instead of via a
++** pointer to a single large buffer. In this case, a pair of parameters such
++** as:
++**
++**  <pre>
++**  &nbsp;     int *pnChangeset,
++**  &nbsp;     void **ppChangeset,
++**  </pre>
++**
++** Is replaced by:
++**
++**  <pre>
++**  &nbsp;     int (*xOutput)(void *pOut, const void *pData, int nData),
++**  &nbsp;     void *pOut
++**  </pre>
++**
++** The xOutput callback is invoked zero or more times to return data to
++** the application. The first parameter passed to each call is a copy of the
++** pOut pointer supplied by the application. The second parameter, pData,
++** points to a buffer nData bytes in size containing the chunk of output
++** data being returned. If the xOutput callback successfully processes the
++** supplied data, it should return SQLITE_OK to indicate success. Otherwise,
++** it should return some other SQLite error code. In this case processing
++** is immediately abandoned and the streaming API function returns a copy
++** of the xOutput error code to the application.
++**
++** The sessions module never invokes an xOutput callback with the third 
++** parameter set to a value less than or equal to zero. Other than this,
++** no guarantees are made as to the size of the chunks of data returned.
++*/
++SQLITE_API int sqlite3changeset_apply_strm(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
++  void *pIn,                                          /* First arg for xInput */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx                      /* First argument passed to xConflict */
++);
++SQLITE_API int sqlite3changeset_concat_strm(
++  int (*xInputA)(void *pIn, void *pData, int *pnData),
++  void *pInA,
++  int (*xInputB)(void *pIn, void *pData, int *pnData),
++  void *pInB,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++);
++SQLITE_API int sqlite3changeset_invert_strm(
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++);
++SQLITE_API int sqlite3changeset_start_strm(
++  sqlite3_changeset_iter **pp,
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn
++);
++SQLITE_API int sqlite3session_changeset_strm(
++  sqlite3_session *pSession,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++);
++SQLITE_API int sqlite3session_patchset_strm(
++  sqlite3_session *pSession,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++);
++SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*, 
++    int (*xInput)(void *pIn, void *pData, int *pnData),
++    void *pIn
++);
++SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
++    int (*xOutput)(void *pOut, const void *pData, int nData), 
++    void *pOut
++);
++
++
++/*
++** Make sure we can call this stuff from C++.
++*/
++#if 0
++}
++#endif
++
++#endif  /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */
++
++/******** End of sqlite3session.h *********/
++/******** Begin file fts5.h *********/
++/*
++** 2014 May 31
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** Interfaces to extend FTS5. Using the interfaces defined in this file, 
++** FTS5 may be extended with:
++**
++**     * custom tokenizers, and
++**     * custom auxiliary functions.
++*/
++
++
++#ifndef _FTS5_H
++#define _FTS5_H
++
++
++#if 0
++extern "C" {
++#endif
++
++/*************************************************************************
++** CUSTOM AUXILIARY FUNCTIONS
++**
++** Virtual table implementations may overload SQL functions by implementing
++** the sqlite3_module.xFindFunction() method.
++*/
++
++typedef struct Fts5ExtensionApi Fts5ExtensionApi;
++typedef struct Fts5Context Fts5Context;
++typedef struct Fts5PhraseIter Fts5PhraseIter;
++
++typedef void (*fts5_extension_function)(
++  const Fts5ExtensionApi *pApi,   /* API offered by current FTS version */
++  Fts5Context *pFts,              /* First arg to pass to pApi functions */
++  sqlite3_context *pCtx,          /* Context for returning result/error */
++  int nVal,                       /* Number of values in apVal[] array */
++  sqlite3_value **apVal           /* Array of trailing arguments */
++);
++
++struct Fts5PhraseIter {
++  const unsigned char *a;
++  const unsigned char *b;
++};
++
++/*
++** EXTENSION API FUNCTIONS
++**
++** xUserData(pFts):
++**   Return a copy of the context pointer the extension function was 
++**   registered with.
++**
++** xColumnTotalSize(pFts, iCol, pnToken):
++**   If parameter iCol is less than zero, set output variable *pnToken
++**   to the total number of tokens in the FTS5 table. Or, if iCol is
++**   non-negative but less than the number of columns in the table, return
++**   the total number of tokens in column iCol, considering all rows in 
++**   the FTS5 table.
++**
++**   If parameter iCol is greater than or equal to the number of columns
++**   in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
++**   an OOM condition or IO error), an appropriate SQLite error code is 
++**   returned.
++**
++** xColumnCount(pFts):
++**   Return the number of columns in the table.
++**
++** xColumnSize(pFts, iCol, pnToken):
++**   If parameter iCol is less than zero, set output variable *pnToken
++**   to the total number of tokens in the current row. Or, if iCol is
++**   non-negative but less than the number of columns in the table, set
++**   *pnToken to the number of tokens in column iCol of the current row.
++**
++**   If parameter iCol is greater than or equal to the number of columns
++**   in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
++**   an OOM condition or IO error), an appropriate SQLite error code is 
++**   returned.
++**
++**   This function may be quite inefficient if used with an FTS5 table
++**   created with the "columnsize=0" option.
++**
++** xColumnText:
++**   This function attempts to retrieve the text of column iCol of the
++**   current document. If successful, (*pz) is set to point to a buffer
++**   containing the text in utf-8 encoding, (*pn) is set to the size in bytes
++**   (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
++**   if an error occurs, an SQLite error code is returned and the final values
++**   of (*pz) and (*pn) are undefined.
++**
++** xPhraseCount:
++**   Returns the number of phrases in the current query expression.
++**
++** xPhraseSize:
++**   Returns the number of tokens in phrase iPhrase of the query. Phrases
++**   are numbered starting from zero.
++**
++** xInstCount:
++**   Set *pnInst to the total number of occurrences of all phrases within
++**   the query within the current row. Return SQLITE_OK if successful, or
++**   an error code (i.e. SQLITE_NOMEM) if an error occurs.
++**
++**   This API can be quite slow if used with an FTS5 table created with the
++**   "detail=none" or "detail=column" option. If the FTS5 table is created 
++**   with either "detail=none" or "detail=column" and "content=" option 
++**   (i.e. if it is a contentless table), then this API always returns 0.
++**
++** xInst:
++**   Query for the details of phrase match iIdx within the current row.
++**   Phrase matches are numbered starting from zero, so the iIdx argument
++**   should be greater than or equal to zero and smaller than the value
++**   output by xInstCount().
++**
++**   Usually, output parameter *piPhrase is set to the phrase number, *piCol
++**   to the column in which it occurs and *piOff the token offset of the
++**   first token of the phrase. The exception is if the table was created
++**   with the offsets=0 option specified. In this case *piOff is always
++**   set to -1.
++**
++**   Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM) 
++**   if an error occurs.
++**
++**   This API can be quite slow if used with an FTS5 table created with the
++**   "detail=none" or "detail=column" option. 
++**
++** xRowid:
++**   Returns the rowid of the current row.
++**
++** xTokenize:
++**   Tokenize text using the tokenizer belonging to the FTS5 table.
++**
++** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
++**   This API function is used to query the FTS table for phrase iPhrase
++**   of the current query. Specifically, a query equivalent to:
++**
++**       ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
++**
++**   with $p set to a phrase equivalent to the phrase iPhrase of the
++**   current query is executed. Any column filter that applies to
++**   phrase iPhrase of the current query is included in $p. For each 
++**   row visited, the callback function passed as the fourth argument 
++**   is invoked. The context and API objects passed to the callback 
++**   function may be used to access the properties of each matched row.
++**   Invoking Api.xUserData() returns a copy of the pointer passed as 
++**   the third argument to pUserData.
++**
++**   If the callback function returns any value other than SQLITE_OK, the
++**   query is abandoned and the xQueryPhrase function returns immediately.
++**   If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
++**   Otherwise, the error code is propagated upwards.
++**
++**   If the query runs to completion without incident, SQLITE_OK is returned.
++**   Or, if some error occurs before the query completes or is aborted by
++**   the callback, an SQLite error code is returned.
++**
++**
++** xSetAuxdata(pFts5, pAux, xDelete)
++**
++**   Save the pointer passed as the second argument as the extension functions 
++**   "auxiliary data". The pointer may then be retrieved by the current or any
++**   future invocation of the same fts5 extension function made as part of
++**   of the same MATCH query using the xGetAuxdata() API.
++**
++**   Each extension function is allocated a single auxiliary data slot for
++**   each FTS query (MATCH expression). If the extension function is invoked 
++**   more than once for a single FTS query, then all invocations share a 
++**   single auxiliary data context.
++**
++**   If there is already an auxiliary data pointer when this function is
++**   invoked, then it is replaced by the new pointer. If an xDelete callback
++**   was specified along with the original pointer, it is invoked at this
++**   point.
++**
++**   The xDelete callback, if one is specified, is also invoked on the
++**   auxiliary data pointer after the FTS5 query has finished.
++**
++**   If an error (e.g. an OOM condition) occurs within this function, an
++**   the auxiliary data is set to NULL and an error code returned. If the
++**   xDelete parameter was not NULL, it is invoked on the auxiliary data
++**   pointer before returning.
++**
++**
++** xGetAuxdata(pFts5, bClear)
++**
++**   Returns the current auxiliary data pointer for the fts5 extension 
++**   function. See the xSetAuxdata() method for details.
++**
++**   If the bClear argument is non-zero, then the auxiliary data is cleared
++**   (set to NULL) before this function returns. In this case the xDelete,
++**   if any, is not invoked.
++**
++**
++** xRowCount(pFts5, pnRow)
++**
++**   This function is used to retrieve the total number of rows in the table.
++**   In other words, the same value that would be returned by:
++**
++**        SELECT count(*) FROM ftstable;
++**
++** xPhraseFirst()
++**   This function is used, along with type Fts5PhraseIter and the xPhraseNext
++**   method, to iterate through all instances of a single query phrase within
++**   the current row. This is the same information as is accessible via the
++**   xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
++**   to use, this API may be faster under some circumstances. To iterate 
++**   through instances of phrase iPhrase, use the following code:
++**
++**       Fts5PhraseIter iter;
++**       int iCol, iOff;
++**       for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
++**           iCol>=0;
++**           pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
++**       ){
++**         // An instance of phrase iPhrase at offset iOff of column iCol
++**       }
++**
++**   The Fts5PhraseIter structure is defined above. Applications should not
++**   modify this structure directly - it should only be used as shown above
++**   with the xPhraseFirst() and xPhraseNext() API methods (and by
++**   xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
++**
++**   This API can be quite slow if used with an FTS5 table created with the
++**   "detail=none" or "detail=column" option. If the FTS5 table is created 
++**   with either "detail=none" or "detail=column" and "content=" option 
++**   (i.e. if it is a contentless table), then this API always iterates
++**   through an empty set (all calls to xPhraseFirst() set iCol to -1).
++**
++** xPhraseNext()
++**   See xPhraseFirst above.
++**
++** xPhraseFirstColumn()
++**   This function and xPhraseNextColumn() are similar to the xPhraseFirst()
++**   and xPhraseNext() APIs described above. The difference is that instead
++**   of iterating through all instances of a phrase in the current row, these
++**   APIs are used to iterate through the set of columns in the current row
++**   that contain one or more instances of a specified phrase. For example:
++**
++**       Fts5PhraseIter iter;
++**       int iCol;
++**       for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
++**           iCol>=0;
++**           pApi->xPhraseNextColumn(pFts, &iter, &iCol)
++**       ){
++**         // Column iCol contains at least one instance of phrase iPhrase
++**       }
++**
++**   This API can be quite slow if used with an FTS5 table created with the
++**   "detail=none" option. If the FTS5 table is created with either 
++**   "detail=none" "content=" option (i.e. if it is a contentless table), 
++**   then this API always iterates through an empty set (all calls to 
++**   xPhraseFirstColumn() set iCol to -1).
++**
++**   The information accessed using this API and its companion
++**   xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
++**   (or xInst/xInstCount). The chief advantage of this API is that it is
++**   significantly more efficient than those alternatives when used with
++**   "detail=column" tables.  
++**
++** xPhraseNextColumn()
++**   See xPhraseFirstColumn above.
++*/
++struct Fts5ExtensionApi {
++  int iVersion;                   /* Currently always set to 3 */
++
++  void *(*xUserData)(Fts5Context*);
++
++  int (*xColumnCount)(Fts5Context*);
++  int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
++  int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
++
++  int (*xTokenize)(Fts5Context*, 
++    const char *pText, int nText, /* Text to tokenize */
++    void *pCtx,                   /* Context passed to xToken() */
++    int (*xToken)(void*, int, const char*, int, int, int)       /* Callback */
++  );
++
++  int (*xPhraseCount)(Fts5Context*);
++  int (*xPhraseSize)(Fts5Context*, int iPhrase);
++
++  int (*xInstCount)(Fts5Context*, int *pnInst);
++  int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
++
++  sqlite3_int64 (*xRowid)(Fts5Context*);
++  int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
++  int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
++
++  int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
++    int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
++  );
++  int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
++  void *(*xGetAuxdata)(Fts5Context*, int bClear);
++
++  int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
++  void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
++
++  int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
++  void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
++};
++
++/* 
++** CUSTOM AUXILIARY FUNCTIONS
++*************************************************************************/
++
++/*************************************************************************
++** CUSTOM TOKENIZERS
++**
++** Applications may also register custom tokenizer types. A tokenizer 
++** is registered by providing fts5 with a populated instance of the 
++** following structure. All structure methods must be defined, setting
++** any member of the fts5_tokenizer struct to NULL leads to undefined
++** behaviour. The structure methods are expected to function as follows:
++**
++** xCreate:
++**   This function is used to allocate and initialize a tokenizer instance.
++**   A tokenizer instance is required to actually tokenize text.
++**
++**   The first argument passed to this function is a copy of the (void*)
++**   pointer provided by the application when the fts5_tokenizer object
++**   was registered with FTS5 (the third argument to xCreateTokenizer()). 
++**   The second and third arguments are an array of nul-terminated strings
++**   containing the tokenizer arguments, if any, specified following the
++**   tokenizer name as part of the CREATE VIRTUAL TABLE statement used
++**   to create the FTS5 table.
++**
++**   The final argument is an output variable. If successful, (*ppOut) 
++**   should be set to point to the new tokenizer handle and SQLITE_OK
++**   returned. If an error occurs, some value other than SQLITE_OK should
++**   be returned. In this case, fts5 assumes that the final value of *ppOut 
++**   is undefined.
++**
++** xDelete:
++**   This function is invoked to delete a tokenizer handle previously
++**   allocated using xCreate(). Fts5 guarantees that this function will
++**   be invoked exactly once for each successful call to xCreate().
++**
++** xTokenize:
++**   This function is expected to tokenize the nText byte string indicated 
++**   by argument pText. pText may or may not be nul-terminated. The first
++**   argument passed to this function is a pointer to an Fts5Tokenizer object
++**   returned by an earlier call to xCreate().
++**
++**   The second argument indicates the reason that FTS5 is requesting
++**   tokenization of the supplied text. This is always one of the following
++**   four values:
++**
++**   <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
++**            or removed from the FTS table. The tokenizer is being invoked to
++**            determine the set of tokens to add to (or delete from) the
++**            FTS index.
++**
++**       <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed 
++**            against the FTS index. The tokenizer is being called to tokenize 
++**            a bareword or quoted string specified as part of the query.
++**
++**       <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
++**            FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
++**            followed by a "*" character, indicating that the last token
++**            returned by the tokenizer will be treated as a token prefix.
++**
++**       <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to 
++**            satisfy an fts5_api.xTokenize() request made by an auxiliary
++**            function. Or an fts5_api.xColumnSize() request made by the same
++**            on a columnsize=0 database.  
++**   </ul>
++**
++**   For each token in the input string, the supplied callback xToken() must
++**   be invoked. The first argument to it should be a copy of the pointer
++**   passed as the second argument to xTokenize(). The third and fourth
++**   arguments are a pointer to a buffer containing the token text, and the
++**   size of the token in bytes. The 4th and 5th arguments are the byte offsets
++**   of the first byte of and first byte immediately following the text from
++**   which the token is derived within the input.
++**
++**   The second argument passed to the xToken() callback ("tflags") should
++**   normally be set to 0. The exception is if the tokenizer supports 
++**   synonyms. In this case see the discussion below for details.
++**
++**   FTS5 assumes the xToken() callback is invoked for each token in the 
++**   order that they occur within the input text.
++**
++**   If an xToken() callback returns any value other than SQLITE_OK, then
++**   the tokenization should be abandoned and the xTokenize() method should
++**   immediately return a copy of the xToken() return value. Or, if the
++**   input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
++**   if an error occurs with the xTokenize() implementation itself, it
++**   may abandon the tokenization and return any error code other than
++**   SQLITE_OK or SQLITE_DONE.
++**
++** SYNONYM SUPPORT
++**
++**   Custom tokenizers may also support synonyms. Consider a case in which a
++**   user wishes to query for a phrase such as "first place". Using the 
++**   built-in tokenizers, the FTS5 query 'first + place' will match instances
++**   of "first place" within the document set, but not alternative forms
++**   such as "1st place". In some applications, it would be better to match
++**   all instances of "first place" or "1st place" regardless of which form
++**   the user specified in the MATCH query text.
++**
++**   There are several ways to approach this in FTS5:
++**
++**   <ol><li> By mapping all synonyms to a single token. In this case, the 
++**            In the above example, this means that the tokenizer returns the
++**            same token for inputs "first" and "1st". Say that token is in
++**            fact "first", so that when the user inserts the document "I won
++**            1st place" entries are added to the index for tokens "i", "won",
++**            "first" and "place". If the user then queries for '1st + place',
++**            the tokenizer substitutes "first" for "1st" and the query works
++**            as expected.
++**
++**       <li> By adding multiple synonyms for a single term to the FTS index.
++**            In this case, when tokenizing query text, the tokenizer may 
++**            provide multiple synonyms for a single term within the document.
++**            FTS5 then queries the index for each synonym individually. For
++**            example, faced with the query:
++**
++**   <codeblock>
++**     ... MATCH 'first place'</codeblock>
++**
++**            the tokenizer offers both "1st" and "first" as synonyms for the
++**            first token in the MATCH query and FTS5 effectively runs a query 
++**            similar to:
++**
++**   <codeblock>
++**     ... MATCH '(first OR 1st) place'</codeblock>
++**
++**            except that, for the purposes of auxiliary functions, the query
++**            still appears to contain just two phrases - "(first OR 1st)" 
++**            being treated as a single phrase.
++**
++**       <li> By adding multiple synonyms for a single term to the FTS index.
++**            Using this method, when tokenizing document text, the tokenizer
++**            provides multiple synonyms for each token. So that when a 
++**            document such as "I won first place" is tokenized, entries are
++**            added to the FTS index for "i", "won", "first", "1st" and
++**            "place".
++**
++**            This way, even if the tokenizer does not provide synonyms
++**            when tokenizing query text (it should not - to do would be
++**            inefficient), it doesn't matter if the user queries for 
++**            'first + place' or '1st + place', as there are entires in the
++**            FTS index corresponding to both forms of the first token.
++**   </ol>
++**
++**   Whether it is parsing document or query text, any call to xToken that
++**   specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
++**   is considered to supply a synonym for the previous token. For example,
++**   when parsing the document "I won first place", a tokenizer that supports
++**   synonyms would call xToken() 5 times, as follows:
++**
++**   <codeblock>
++**       xToken(pCtx, 0, "i",                      1,  0,  1);
++**       xToken(pCtx, 0, "won",                    3,  2,  5);
++**       xToken(pCtx, 0, "first",                  5,  6, 11);
++**       xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3,  6, 11);
++**       xToken(pCtx, 0, "place",                  5, 12, 17);
++**</codeblock>
++**
++**   It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
++**   xToken() is called. Multiple synonyms may be specified for a single token
++**   by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence. 
++**   There is no limit to the number of synonyms that may be provided for a
++**   single token.
++**
++**   In many cases, method (1) above is the best approach. It does not add 
++**   extra data to the FTS index or require FTS5 to query for multiple terms,
++**   so it is efficient in terms of disk space and query speed. However, it
++**   does not support prefix queries very well. If, as suggested above, the
++**   token "first" is subsituted for "1st" by the tokenizer, then the query:
++**
++**   <codeblock>
++**     ... MATCH '1s*'</codeblock>
++**
++**   will not match documents that contain the token "1st" (as the tokenizer
++**   will probably not map "1s" to any prefix of "first").
++**
++**   For full prefix support, method (3) may be preferred. In this case, 
++**   because the index contains entries for both "first" and "1st", prefix
++**   queries such as 'fi*' or '1s*' will match correctly. However, because
++**   extra entries are added to the FTS index, this method uses more space
++**   within the database.
++**
++**   Method (2) offers a midpoint between (1) and (3). Using this method,
++**   a query such as '1s*' will match documents that contain the literal 
++**   token "1st", but not "first" (assuming the tokenizer is not able to
++**   provide synonyms for prefixes). However, a non-prefix query like '1st'
++**   will match against "1st" and "first". This method does not require
++**   extra disk space, as no extra entries are added to the FTS index. 
++**   On the other hand, it may require more CPU cycles to run MATCH queries,
++**   as separate queries of the FTS index are required for each synonym.
++**
++**   When using methods (2) or (3), it is important that the tokenizer only
++**   provide synonyms when tokenizing document text (method (2)) or query
++**   text (method (3)), not both. Doing so will not cause any errors, but is
++**   inefficient.
++*/
++typedef struct Fts5Tokenizer Fts5Tokenizer;
++typedef struct fts5_tokenizer fts5_tokenizer;
++struct fts5_tokenizer {
++  int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
++  void (*xDelete)(Fts5Tokenizer*);
++  int (*xTokenize)(Fts5Tokenizer*, 
++      void *pCtx,
++      int flags,            /* Mask of FTS5_TOKENIZE_* flags */
++      const char *pText, int nText, 
++      int (*xToken)(
++        void *pCtx,         /* Copy of 2nd argument to xTokenize() */
++        int tflags,         /* Mask of FTS5_TOKEN_* flags */
++        const char *pToken, /* Pointer to buffer containing token */
++        int nToken,         /* Size of token in bytes */
++        int iStart,         /* Byte offset of token within input text */
++        int iEnd            /* Byte offset of end of token within input text */
++      )
++  );
++};
++
++/* Flags that may be passed as the third argument to xTokenize() */
++#define FTS5_TOKENIZE_QUERY     0x0001
++#define FTS5_TOKENIZE_PREFIX    0x0002
++#define FTS5_TOKENIZE_DOCUMENT  0x0004
++#define FTS5_TOKENIZE_AUX       0x0008
++
++/* Flags that may be passed by the tokenizer implementation back to FTS5
++** as the third argument to the supplied xToken callback. */
++#define FTS5_TOKEN_COLOCATED    0x0001      /* Same position as prev. token */
++
++/*
++** END OF CUSTOM TOKENIZERS
++*************************************************************************/
++
++/*************************************************************************
++** FTS5 EXTENSION REGISTRATION API
++*/
++typedef struct fts5_api fts5_api;
++struct fts5_api {
++  int iVersion;                   /* Currently always set to 2 */
++
++  /* Create a new tokenizer */
++  int (*xCreateTokenizer)(
++    fts5_api *pApi,
++    const char *zName,
++    void *pContext,
++    fts5_tokenizer *pTokenizer,
++    void (*xDestroy)(void*)
++  );
++
++  /* Find an existing tokenizer */
++  int (*xFindTokenizer)(
++    fts5_api *pApi,
++    const char *zName,
++    void **ppContext,
++    fts5_tokenizer *pTokenizer
++  );
++
++  /* Create a new auxiliary function */
++  int (*xCreateFunction)(
++    fts5_api *pApi,
++    const char *zName,
++    void *pContext,
++    fts5_extension_function xFunction,
++    void (*xDestroy)(void*)
++  );
++};
++
++/*
++** END OF REGISTRATION API
++*************************************************************************/
++
++#if 0
++}  /* end of the 'extern "C"' block */
++#endif
++
++#endif /* _FTS5_H */
++
++/******** End of fts5.h *********/
+ 
+ /************** End of sqlite3.h *********************************************/
+ /************** Continuing where we left off in sqliteInt.h ******************/
+@@ -8044,8 +11729,9 @@
+ ** Include the configuration header output by 'configure' if we're using the
+ ** autoconf-based build
+ */
+-#ifdef _HAVE_SQLITE_CONFIG_H
+-#include "config.h"
++#if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H)
++/* #include "config.h" */
++#define SQLITECONFIG_H 1
+ #endif
+ 
+ /************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/
+@@ -8139,7 +11825,7 @@
+ ** Not currently enforced.
+ */
+ #ifndef SQLITE_MAX_VDBE_OP
+-# define SQLITE_MAX_VDBE_OP 25000
++# define SQLITE_MAX_VDBE_OP 250000000
+ #endif
+ 
+ /*
+@@ -8153,13 +11839,13 @@
+ ** The suggested maximum number of in-memory pages to use for
+ ** the main database table and for temporary tables.
+ **
+-** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size
+-** is 2000 pages.
++** IMPLEMENTATION-OF: R-30185-15359 The default suggested cache size is -2000,
++** which means the cache size is limited to 2048000 bytes of memory.
+ ** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be
+ ** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options.
+ */
+ #ifndef SQLITE_DEFAULT_CACHE_SIZE
+-# define SQLITE_DEFAULT_CACHE_SIZE  2000
++# define SQLITE_DEFAULT_CACHE_SIZE  -2000
+ #endif
+ 
+ /*
+@@ -8172,8 +11858,9 @@
+ 
+ /*
+ ** The maximum number of attached databases.  This must be between 0
+-** and 62.  The upper bound on 62 is because a 64-bit integer bitmap
+-** is used internally to track attached databases.
++** and 125.  The upper bound of 125 is because the attached databases are
++** counted using a signed 8-bit integer which has a maximum value of 127
++** and we have to allow 2 extra counts for the "main" and "temp" databases.
+ */
+ #ifndef SQLITE_MAX_ATTACHED
+ # define SQLITE_MAX_ATTACHED 10
+@@ -8208,7 +11895,7 @@
+ ** The default size of a database page.
+ */
+ #ifndef SQLITE_DEFAULT_PAGE_SIZE
+-# define SQLITE_DEFAULT_PAGE_SIZE 1024
++# define SQLITE_DEFAULT_PAGE_SIZE 4096
+ #endif
+ #if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
+ # undef SQLITE_DEFAULT_PAGE_SIZE
+@@ -8289,7 +11976,7 @@
+ ** to the next, so we have developed the following set of #if statements
+ ** to generate appropriate macros for a wide range of compilers.
+ **
+-** The correct "ANSI" way to do this is to use the intptr_t type. 
++** The correct "ANSI" way to do this is to use the intptr_t type.
+ ** Unfortunately, that typedef is not available on all compilers, or
+ ** if it is available, it requires an #include of specific headers
+ ** that vary from one machine to the next.
+@@ -8326,6 +12013,25 @@
+ #endif
+ 
+ /*
++** Make sure that the compiler intrinsics we desire are enabled when
++** compiling with an appropriate version of MSVC unless prevented by
++** the SQLITE_DISABLE_INTRINSIC define.
++*/
++#if !defined(SQLITE_DISABLE_INTRINSIC)
++#  if defined(_MSC_VER) && _MSC_VER>=1400
++#    if !defined(_WIN32_WCE)
++#      include <intrin.h>
++#      pragma intrinsic(_byteswap_ushort)
++#      pragma intrinsic(_byteswap_ulong)
++#      pragma intrinsic(_byteswap_uint64)
++#      pragma intrinsic(_ReadWriteBarrier)
++#    else
++#      include <cmnintrin.h>
++#    endif
++#  endif
++#endif
++
++/*
+ ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
+ ** 0 means mutexes are permanently disable and the library is never
+ ** threadsafe.  1 means the library is serialized which is the highest
+@@ -8335,6 +12041,11 @@
+ **
+ ** Older versions of SQLite used an optional THREADSAFE macro.
+ ** We support that for legacy.
++**
++** To ensure that the correct value of "THREADSAFE" is reported when querying
++** for compile-time options at runtime (e.g. "PRAGMA compile_options"), this
++** logic is partially replicated in ctime.c. If it is updated here, it should
++** also be updated there.
+ */
+ #if !defined(SQLITE_THREADSAFE)
+ # if defined(THREADSAFE)
+@@ -8423,7 +12134,7 @@
+ ** is set.  Thus NDEBUG becomes an opt-in rather than an opt-out
+ ** feature.
+ */
+-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) 
++#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
+ # define NDEBUG 1
+ #endif
+ #if defined(NDEBUG) && defined(SQLITE_DEBUG)
+@@ -8438,7 +12149,7 @@
+ #endif
+ 
+ /*
+-** The testcase() macro is used to aid in coverage testing.  When 
++** The testcase() macro is used to aid in coverage testing.  When
+ ** doing coverage testing, the condition inside the argument to
+ ** testcase() must be evaluated both true and false in order to
+ ** get full branch coverage.  The testcase() macro is inserted
+@@ -8484,7 +12195,7 @@
+ #endif
+ 
+ /*
+-** The ALWAYS and NEVER macros surround boolean expressions which 
++** The ALWAYS and NEVER macros surround boolean expressions which
+ ** are intended to always be true or false, respectively.  Such
+ ** expressions could be omitted from the code completely.  But they
+ ** are included in a few cases in order to enhance the resilience
+@@ -8498,7 +12209,7 @@
+ ** be true and false so that the unreachable code they specify will
+ ** not be counted as untested code.
+ */
+-#if defined(SQLITE_COVERAGE_TEST)
++#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
+ # define ALWAYS(X)      (1)
+ # define NEVER(X)       (0)
+ #elif !defined(NDEBUG)
+@@ -8510,6 +12221,21 @@
+ #endif
+ 
+ /*
++** Some malloc failures are only possible if SQLITE_TEST_REALLOC_STRESS is
++** defined.  We need to defend against those failures when testing with
++** SQLITE_TEST_REALLOC_STRESS, but we don't want the unreachable branches
++** during a normal build.  The following macro can be used to disable tests
++** that are always false except when SQLITE_TEST_REALLOC_STRESS is set.
++*/
++#if defined(SQLITE_TEST_REALLOC_STRESS)
++# define ONLY_IF_REALLOC_STRESS(X)  (X)
++#elif !defined(NDEBUG)
++# define ONLY_IF_REALLOC_STRESS(X)  ((X)?(assert(0),1):0)
++#else
++# define ONLY_IF_REALLOC_STRESS(X)  (0)
++#endif
++
++/*
+ ** Declarations used for tracing the operating system interfaces.
+ */
+ #if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \
+@@ -8536,6 +12262,13 @@
+ #endif
+ 
+ /*
++** SQLITE_ENABLE_EXPLAIN_COMMENTS is incompatible with SQLITE_OMIT_EXPLAIN
++*/
++#ifdef SQLITE_OMIT_EXPLAIN
++# undef SQLITE_ENABLE_EXPLAIN_COMMENTS
++#endif
++
++/*
+ ** Return true (non-zero) if the input is an integer that is too large
+ ** to fit in 32-bits.  This macro is used inside of various testcase()
+ ** macros to verify that we have tested SQLite for large-file support.
+@@ -8568,8 +12301,8 @@
+ ** This is the header file for the generic hash-table implementation
+ ** used in SQLite.
+ */
+-#ifndef _SQLITE_HASH_H_
+-#define _SQLITE_HASH_H_
++#ifndef SQLITE_HASH_H
++#define SQLITE_HASH_H
+ 
+ /* Forward declarations of structures. */
+ typedef struct Hash Hash;
+@@ -8649,7 +12382,7 @@
+ */
+ /* #define sqliteHashCount(H)  ((H)->count) // NOT USED */
+ 
+-#endif /* _SQLITE_HASH_H_ */
++#endif /* SQLITE_HASH_H */
+ 
+ /************** End of hash.h ************************************************/
+ /************** Continuing where we left off in sqliteInt.h ******************/
+@@ -8682,75 +12415,75 @@
+ #define TK_WITHOUT                         25
+ #define TK_COMMA                           26
+ #define TK_ID                              27
+-#define TK_INDEXED                         28
+-#define TK_ABORT                           29
+-#define TK_ACTION                          30
+-#define TK_AFTER                           31
+-#define TK_ANALYZE                         32
+-#define TK_ASC                             33
+-#define TK_ATTACH                          34
+-#define TK_BEFORE                          35
+-#define TK_BY                              36
+-#define TK_CASCADE                         37
+-#define TK_CAST                            38
+-#define TK_COLUMNKW                        39
+-#define TK_CONFLICT                        40
+-#define TK_DATABASE                        41
+-#define TK_DESC                            42
+-#define TK_DETACH                          43
+-#define TK_EACH                            44
+-#define TK_FAIL                            45
+-#define TK_FOR                             46
+-#define TK_IGNORE                          47
+-#define TK_INITIALLY                       48
+-#define TK_INSTEAD                         49
+-#define TK_LIKE_KW                         50
+-#define TK_MATCH                           51
+-#define TK_NO                              52
+-#define TK_KEY                             53
+-#define TK_OF                              54
+-#define TK_OFFSET                          55
+-#define TK_PRAGMA                          56
+-#define TK_RAISE                           57
+-#define TK_RECURSIVE                       58
+-#define TK_REPLACE                         59
+-#define TK_RESTRICT                        60
+-#define TK_ROW                             61
+-#define TK_TRIGGER                         62
+-#define TK_VACUUM                          63
+-#define TK_VIEW                            64
+-#define TK_VIRTUAL                         65
+-#define TK_WITH                            66
+-#define TK_REINDEX                         67
+-#define TK_RENAME                          68
+-#define TK_CTIME_KW                        69
+-#define TK_ANY                             70
+-#define TK_OR                              71
+-#define TK_AND                             72
+-#define TK_IS                              73
+-#define TK_BETWEEN                         74
+-#define TK_IN                              75
+-#define TK_ISNULL                          76
+-#define TK_NOTNULL                         77
+-#define TK_NE                              78
+-#define TK_EQ                              79
+-#define TK_GT                              80
+-#define TK_LE                              81
+-#define TK_LT                              82
+-#define TK_GE                              83
+-#define TK_ESCAPE                          84
+-#define TK_BITAND                          85
+-#define TK_BITOR                           86
+-#define TK_LSHIFT                          87
+-#define TK_RSHIFT                          88
+-#define TK_PLUS                            89
+-#define TK_MINUS                           90
+-#define TK_STAR                            91
+-#define TK_SLASH                           92
+-#define TK_REM                             93
+-#define TK_CONCAT                          94
+-#define TK_COLLATE                         95
+-#define TK_BITNOT                          96
++#define TK_ABORT                           28
++#define TK_ACTION                          29
++#define TK_AFTER                           30
++#define TK_ANALYZE                         31
++#define TK_ASC                             32
++#define TK_ATTACH                          33
++#define TK_BEFORE                          34
++#define TK_BY                              35
++#define TK_CASCADE                         36
++#define TK_CAST                            37
++#define TK_COLUMNKW                        38
++#define TK_CONFLICT                        39
++#define TK_DATABASE                        40
++#define TK_DESC                            41
++#define TK_DETACH                          42
++#define TK_EACH                            43
++#define TK_FAIL                            44
++#define TK_FOR                             45
++#define TK_IGNORE                          46
++#define TK_INITIALLY                       47
++#define TK_INSTEAD                         48
++#define TK_LIKE_KW                         49
++#define TK_MATCH                           50
++#define TK_NO                              51
++#define TK_KEY                             52
++#define TK_OF                              53
++#define TK_OFFSET                          54
++#define TK_PRAGMA                          55
++#define TK_RAISE                           56
++#define TK_RECURSIVE                       57
++#define TK_REPLACE                         58
++#define TK_RESTRICT                        59
++#define TK_ROW                             60
++#define TK_TRIGGER                         61
++#define TK_VACUUM                          62
++#define TK_VIEW                            63
++#define TK_VIRTUAL                         64
++#define TK_WITH                            65
++#define TK_REINDEX                         66
++#define TK_RENAME                          67
++#define TK_CTIME_KW                        68
++#define TK_ANY                             69
++#define TK_OR                              70
++#define TK_AND                             71
++#define TK_IS                              72
++#define TK_BETWEEN                         73
++#define TK_IN                              74
++#define TK_ISNULL                          75
++#define TK_NOTNULL                         76
++#define TK_NE                              77
++#define TK_EQ                              78
++#define TK_GT                              79
++#define TK_LE                              80
++#define TK_LT                              81
++#define TK_GE                              82
++#define TK_ESCAPE                          83
++#define TK_BITAND                          84
++#define TK_BITOR                           85
++#define TK_LSHIFT                          86
++#define TK_RSHIFT                          87
++#define TK_PLUS                            88
++#define TK_MINUS                           89
++#define TK_STAR                            90
++#define TK_SLASH                           91
++#define TK_REM                             92
++#define TK_CONCAT                          93
++#define TK_COLLATE                         94
++#define TK_BITNOT                          95
++#define TK_INDEXED                         96
+ #define TK_STRING                          97
+ #define TK_JOIN_KW                         98
+ #define TK_CONSTRAINT                      99
+@@ -8786,9 +12519,9 @@
+ #define TK_LIMIT                          129
+ #define TK_WHERE                          130
+ #define TK_INTO                           131
+-#define TK_INTEGER                        132
+-#define TK_FLOAT                          133
+-#define TK_BLOB                           134
++#define TK_FLOAT                          132
++#define TK_BLOB                           133
++#define TK_INTEGER                        134
+ #define TK_VARIABLE                       135
+ #define TK_CASE                           136
+ #define TK_WHEN                           137
+@@ -8804,16 +12537,28 @@
+ #define TK_TO_REAL                        147
+ #define TK_ISNOT                          148
+ #define TK_END_OF_FILE                    149
+-#define TK_ILLEGAL                        150
+-#define TK_SPACE                          151
+-#define TK_UNCLOSED_STRING                152
+-#define TK_FUNCTION                       153
+-#define TK_COLUMN                         154
+-#define TK_AGG_FUNCTION                   155
+-#define TK_AGG_COLUMN                     156
+-#define TK_UMINUS                         157
+-#define TK_UPLUS                          158
+-#define TK_REGISTER                       159
++#define TK_UNCLOSED_STRING                150
++#define TK_FUNCTION                       151
++#define TK_COLUMN                         152
++#define TK_AGG_FUNCTION                   153
++#define TK_AGG_COLUMN                     154
++#define TK_UMINUS                         155
++#define TK_UPLUS                          156
++#define TK_REGISTER                       157
++#define TK_VECTOR                         158
++#define TK_SELECT_COLUMN                  159
++#define TK_IF_NULL_ROW                    160
++#define TK_ASTERISK                       161
++#define TK_SPAN                           162
++#define TK_SPACE                          163
++#define TK_ILLEGAL                        164
++
++/* The token codes above must all fit in 8 bits */
++#define TKFLG_MASK           0xff  
++
++/* Flags that can be added to a token code when it is not
++** being stored in a u8: */
++#define TKFLG_DONTFOLD       0x100  /* Omit constant folding optimizations */
+ 
+ /************** End of parse.h ***********************************************/
+ /************** Continuing where we left off in sqliteInt.h ******************/
+@@ -8824,6 +12569,18 @@
+ #include <stddef.h>
+ 
+ /*
++** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY.
++** This allows better measurements of where memcpy() is used when running
++** cachegrind.  But this macro version of memcpy() is very slow so it
++** should not be used in production.  This is a performance measurement
++** hack only.
++*/
++#ifdef SQLITE_INLINE_MEMCPY
++# define memcpy(D,S,N) {char*xxd=(char*)(D);const char*xxs=(const char*)(S);\
++                        int xxn=(N);while(xxn-->0)*(xxd++)=*(xxs++);}
++#endif
++
++/*
+ ** If compiling for a processor that lacks floating point support,
+ ** substitute integer for floating-point
+ */
+@@ -8845,7 +12602,7 @@
+ 
+ /*
+ ** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0
+-** afterward. Having this macro allows us to cause the C compiler 
++** afterward. Having this macro allows us to cause the C compiler
+ ** to omit code used by TEMP tables without messy #ifndef statements.
+ */
+ #ifdef SQLITE_OMIT_TEMPDB
+@@ -8879,12 +12636,11 @@
+ */
+ #ifndef SQLITE_TEMP_STORE
+ # define SQLITE_TEMP_STORE 1
+-# define SQLITE_TEMP_STORE_xc 1  /* Exclude from ctime.c */
+ #endif
+ 
+ /*
+ ** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if
+-** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it 
++** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it
+ ** to zero.
+ */
+ #if SQLITE_TEMP_STORE==3 || SQLITE_THREADSAFE==0
+@@ -8902,6 +12658,18 @@
+ # define SQLITE_MAX_WORKER_THREADS SQLITE_DEFAULT_WORKER_THREADS
+ #endif
+ 
++/*
++** The default initial allocation for the pagecache when using separate
++** pagecaches for each database connection.  A positive number is the
++** number of pages.  A negative number N translations means that a buffer
++** of -1024*N bytes is allocated and used for as many pages as it will hold.
++**
++** The default value of "20" was choosen to minimize the run-time of the
++** speedtest1 test program with options: --shrink-memory --reprepare
++*/
++#ifndef SQLITE_DEFAULT_PCACHE_INITSZ
++# define SQLITE_DEFAULT_PCACHE_INITSZ 20
++#endif
+ 
+ /*
+ ** GCC does not define the offsetof() macro so we'll have to do it
+@@ -8914,8 +12682,12 @@
+ /*
+ ** Macros to compute minimum and maximum of two numbers.
+ */
+-#define MIN(A,B) ((A)<(B)?(A):(B))
+-#define MAX(A,B) ((A)>(B)?(A):(B))
++#ifndef MIN
++# define MIN(A,B) ((A)<(B)?(A):(B))
++#endif
++#ifndef MAX
++# define MAX(A,B) ((A)>(B)?(A):(B))
++#endif
+ 
+ /*
+ ** Swap two objects of type TYPE.
+@@ -9023,7 +12795,7 @@
+ **      4 -> 20           1000 -> 99        1048576 -> 200
+ **     10 -> 33           1024 -> 100    4294967296 -> 320
+ **
+-** The LogEst can be negative to indicate fractional values. 
++** The LogEst can be negative to indicate fractional values.
+ ** Examples:
+ **
+ **    0.5 -> -10           0.1 -> -33        0.0625 -> -40
+@@ -9044,38 +12816,62 @@
+ # endif
+ #endif
+ 
++/* The uptr type is an unsigned integer large enough to hold a pointer
++*/
++#if defined(HAVE_STDINT_H)
++  typedef uintptr_t uptr;
++#elif SQLITE_PTRSIZE==4
++  typedef u32 uptr;
++#else
++  typedef u64 uptr;
++#endif
++
++/*
++** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to
++** something between S (inclusive) and E (exclusive).
++**
++** In other words, S is a buffer and E is a pointer to the first byte after
++** the end of buffer S.  This macro returns true if P points to something
++** contained within the buffer S.
++*/
++#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E)))
++
++
+ /*
+ ** Macros to determine whether the machine is big or little endian,
+ ** and whether or not that determination is run-time or compile-time.
+ **
+ ** For best performance, an attempt is made to guess at the byte-order
+ ** using C-preprocessor macros.  If that is unsuccessful, or if
+-** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
++** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined
+ ** at run-time.
+ */
+-#ifdef SQLITE_AMALGAMATION
+-SQLITE_PRIVATE const int sqlite3one = 1;
+-#else
+-SQLITE_PRIVATE const int sqlite3one;
+-#endif
+-#if (defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
++#ifndef SQLITE_BYTEORDER
++# if defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
+      defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)  ||    \
+      defined(_M_AMD64) || defined(_M_ARM)     || defined(__x86)   ||    \
+-     defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER)
+-# define SQLITE_BYTEORDER    1234
+-# define SQLITE_BIGENDIAN    0
+-# define SQLITE_LITTLEENDIAN 1
+-# define SQLITE_UTF16NATIVE  SQLITE_UTF16LE
++     defined(__arm__)
++#   define SQLITE_BYTEORDER    1234
++# elif defined(sparc)    || defined(__ppc__)
++#   define SQLITE_BYTEORDER    4321
++# else
++#   define SQLITE_BYTEORDER 0
++# endif
+ #endif
+-#if (defined(sparc)    || defined(__ppc__))  \
+-    && !defined(SQLITE_RUNTIME_BYTEORDER)
+-# define SQLITE_BYTEORDER    4321
++#if SQLITE_BYTEORDER==4321
+ # define SQLITE_BIGENDIAN    1
+ # define SQLITE_LITTLEENDIAN 0
+ # define SQLITE_UTF16NATIVE  SQLITE_UTF16BE
+-#endif
+-#if !defined(SQLITE_BYTEORDER)
+-# define SQLITE_BYTEORDER    0     /* 0 means "unknown at compile-time" */
++#elif SQLITE_BYTEORDER==1234
++# define SQLITE_BIGENDIAN    0
++# define SQLITE_LITTLEENDIAN 1
++# define SQLITE_UTF16NATIVE  SQLITE_UTF16LE
++#else
++# ifdef SQLITE_AMALGAMATION
++  const int sqlite3one = 1;
++# else
++  extern const int sqlite3one;
++# endif
+ # define SQLITE_BIGENDIAN    (*(char *)(&sqlite3one)==0)
+ # define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
+ # define SQLITE_UTF16NATIVE  (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
+@@ -9089,7 +12885,7 @@
+ #define LARGEST_INT64  (0xffffffff|(((i64)0x7fffffff)<<32))
+ #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
+ 
+-/* 
++/*
+ ** Round up a number to the next larger multiple of 8.  This is used
+ ** to force 8-byte alignment on 64-bit architectures.
+ */
+@@ -9128,21 +12924,18 @@
+ */
+ #ifdef __APPLE__
+ # include <TargetConditionals.h>
+-# if TARGET_OS_IPHONE
+-#   undef SQLITE_MAX_MMAP_SIZE
+-#   define SQLITE_MAX_MMAP_SIZE 0
+-# endif
+ #endif
+ #ifndef SQLITE_MAX_MMAP_SIZE
+ # if defined(__linux__) \
+   || defined(_WIN32) \
+   || (defined(__APPLE__) && defined(__MACH__)) \
+-  || defined(__sun)
++  || defined(__sun) \
++  || defined(__FreeBSD__) \
++  || defined(__DragonFly__)
+ #   define SQLITE_MAX_MMAP_SIZE 0x7fff0000  /* 2147418112 */
+ # else
+ #   define SQLITE_MAX_MMAP_SIZE 0
+ # endif
+-# define SQLITE_MAX_MMAP_SIZE_xc 1 /* exclude from ctime.c */
+ #endif
+ 
+ /*
+@@ -9152,7 +12945,6 @@
+ */
+ #ifndef SQLITE_DEFAULT_MMAP_SIZE
+ # define SQLITE_DEFAULT_MMAP_SIZE 0
+-# define SQLITE_DEFAULT_MMAP_SIZE_xc 1  /* Exclude from ctime.c */
+ #endif
+ #if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE
+ # undef SQLITE_DEFAULT_MMAP_SIZE
+@@ -9185,7 +12977,7 @@
+ 
+ /*
+ ** An instance of the following structure is used to store the busy-handler
+-** callback for a given sqlite handle. 
++** callback for a given sqlite handle.
+ **
+ ** The sqlite.busyHandler member of the sqlite struct contains the busy
+ ** callback for the database handle. Each pager opened via the sqlite
+@@ -9230,9 +13022,9 @@
+ 
+ /*
+ ** The following value as a destructor means to use sqlite3DbFree().
+-** The sqlite3DbFree() routine requires two parameters instead of the 
+-** one parameter that destructors normally want.  So we have to introduce 
+-** this magic value that the code knows to handle differently.  Any 
++** The sqlite3DbFree() routine requires two parameters instead of the
++** one parameter that destructors normally want.  So we have to introduce
++** this magic value that the code knows to handle differently.  Any
+ ** pointer will work here as long as it is distinct from SQLITE_STATIC
+ ** and SQLITE_TRANSIENT.
+ */
+@@ -9256,19 +13048,19 @@
+   #define SQLITE_WSD const
+   #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v)))
+   #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config)
+-SQLITE_API int SQLITE_STDCALL sqlite3_wsd_init(int N, int J);
+-SQLITE_API void *SQLITE_STDCALL sqlite3_wsd_find(void *K, int L);
++SQLITE_API int sqlite3_wsd_init(int N, int J);
++SQLITE_API void *sqlite3_wsd_find(void *K, int L);
+ #else
+-  #define SQLITE_WSD 
++  #define SQLITE_WSD
+   #define GLOBAL(t,v) v
+   #define sqlite3GlobalConfig sqlite3Config
+ #endif
+ 
+ /*
+ ** The following macros are used to suppress compiler warnings and to
+-** make it clear to human readers when a function parameter is deliberately 
++** make it clear to human readers when a function parameter is deliberately
+ ** left unused within the body of a function. This usually happens when
+-** a function is called via a function pointer. For example the 
++** a function is called via a function pointer. For example the
+ ** implementation of an SQL aggregate step callback may not use the
+ ** parameter indicating the number of arguments passed to the aggregate,
+ ** if it knows that this is enforced elsewhere.
+@@ -9311,6 +13103,7 @@
+ typedef struct Module Module;
+ typedef struct NameContext NameContext;
+ typedef struct Parse Parse;
++typedef struct PreUpdate PreUpdate;
+ typedef struct PrintfArguments PrintfArguments;
+ typedef struct RowSet RowSet;
+ typedef struct Savepoint Savepoint;
+@@ -9333,8 +13126,16 @@
+ typedef struct WhereInfo WhereInfo;
+ typedef struct With With;
+ 
++/* A VList object records a mapping between parameters/variables/wildcards
++** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
++** variable number associated with that parameter.  See the format description
++** on the sqlite3VListAdd() routine for more information.  A VList is really
++** just an array of integers.
++*/
++typedef int VList;
++
+ /*
+-** Defer sourcing vdbe.h and btree.h until after the "u8" and 
++** Defer sourcing vdbe.h and btree.h until after the "u8" and
+ ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
+ ** pointer types (i.e. FuncDef) defined above.
+ */
+@@ -9355,8 +13156,8 @@
+ ** subsystem.  See comments in the source code for a detailed description
+ ** of what each interface routine does.
+ */
+-#ifndef _BTREE_H_
+-#define _BTREE_H_
++#ifndef SQLITE_BTREE_H
++#define SQLITE_BTREE_H
+ 
+ /* TODO: This definition is just included so other modules compile. It
+ ** needs to be revisited.
+@@ -9381,6 +13182,7 @@
+ typedef struct Btree Btree;
+ typedef struct BtCursor BtCursor;
+ typedef struct BtShared BtShared;
++typedef struct BtreePayload BtreePayload;
+ 
+ 
+ SQLITE_PRIVATE int sqlite3BtreeOpen(
+@@ -9405,11 +13207,11 @@
+ 
+ SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
+ SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
++SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree*,int);
+ #if SQLITE_MAX_MMAP_SIZE>0
+ SQLITE_PRIVATE   int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
+ #endif
+ SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
+-SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
+ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
+ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
+ SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
+@@ -9431,7 +13233,9 @@
+ SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*);
+ SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
+ SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree);
++#ifndef SQLITE_OMIT_SHARED_CACHE
+ SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
++#endif
+ SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int);
+ 
+ SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *);
+@@ -9492,8 +13296,37 @@
+ #define BTREE_DATA_VERSION        15  /* A virtual meta-value */
+ 
+ /*
+-** Values that may be OR'd together to form the second argument of an
+-** sqlite3BtreeCursorHints() call.
++** Kinds of hints that can be passed into the sqlite3BtreeCursorHint()
++** interface.
++**
++** BTREE_HINT_RANGE  (arguments: Expr*, Mem*)
++**
++**     The first argument is an Expr* (which is guaranteed to be constant for
++**     the lifetime of the cursor) that defines constraints on which rows
++**     might be fetched with this cursor.  The Expr* tree may contain
++**     TK_REGISTER nodes that refer to values stored in the array of registers
++**     passed as the second parameter.  In other words, if Expr.op==TK_REGISTER
++**     then the value of the node is the value in Mem[pExpr.iTable].  Any
++**     TK_COLUMN node in the expression tree refers to the Expr.iColumn-th
++**     column of the b-tree of the cursor.  The Expr tree will not contain
++**     any function calls nor subqueries nor references to b-trees other than
++**     the cursor being hinted.
++**
++**     The design of the _RANGE hint is aid b-tree implementations that try
++**     to prefetch content from remote machines - to provide those
++**     implementations with limits on what needs to be prefetched and thereby
++**     reduce network bandwidth.
++**
++** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by
++** standard SQLite.  The other hints are provided for extentions that use
++** the SQLite parser and code generator but substitute their own storage
++** engine.
++*/
++#define BTREE_HINT_RANGE 0       /* Range constraints on queries */
++
++/*
++** Values that may be OR'd together to form the argument to the
++** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint():
+ **
+ ** The BTREE_BULKLOAD flag is set on index cursors when the index is going
+ ** to be filled with content that is already in sorted order.
+@@ -9507,6 +13340,32 @@
+ #define BTREE_BULKLOAD 0x00000001  /* Used to full index in sorted order */
+ #define BTREE_SEEK_EQ  0x00000002  /* EQ seeks only - no range seeks */
+ 
++/* 
++** Flags passed as the third argument to sqlite3BtreeCursor().
++**
++** For read-only cursors the wrFlag argument is always zero. For read-write
++** cursors it may be set to either (BTREE_WRCSR|BTREE_FORDELETE) or just
++** (BTREE_WRCSR). If the BTREE_FORDELETE bit is set, then the cursor will
++** only be used by SQLite for the following:
++**
++**   * to seek to and then delete specific entries, and/or
++**
++**   * to read values that will be used to create keys that other
++**     BTREE_FORDELETE cursors will seek to and delete.
++**
++** The BTREE_FORDELETE flag is an optimization hint.  It is not used by
++** by this, the native b-tree engine of SQLite, but it is available to
++** alternative storage engines that might be substituted in place of this
++** b-tree system.  For alternative storage engines in which a delete of
++** the main table row automatically deletes corresponding index rows,
++** the FORDELETE flag hint allows those alternative storage engines to
++** skip a lot of work.  Namely:  FORDELETE cursors may treat all SEEK
++** and DELETE operations as no-ops, and any READ operation against a
++** FORDELETE cursor may return a null row: 0x01 0x00.
++*/
++#define BTREE_WRCSR     0x00000004     /* read-write cursor */
++#define BTREE_FORDELETE 0x00000008     /* Cursor is for seek/delete only */
++
+ SQLITE_PRIVATE int sqlite3BtreeCursor(
+   Btree*,                              /* BTree containing table to open */
+   int iTable,                          /* Index of root page */
+@@ -9516,6 +13375,10 @@
+ );
+ SQLITE_PRIVATE int sqlite3BtreeCursorSize(void);
+ SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*);
++SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
++#ifdef SQLITE_ENABLE_CURSOR_HINTS
++SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor*, int, ...);
++#endif
+ 
+ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*);
+ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
+@@ -9527,39 +13390,72 @@
+ );
+ SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*);
+ SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*);
+-SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*);
+-SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
+-                                  const void *pData, int nData,
+-                                  int nZero, int bias, int seekResult);
++SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags);
++
++/* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */
++#define BTREE_SAVEPOSITION 0x02  /* Leave cursor pointing at NEXT or PREV */
++#define BTREE_AUXDELETE    0x04  /* not the primary delete operation */
++#define BTREE_APPEND       0x08  /* Insert is likely an append */
++
++/* An instance of the BtreePayload object describes the content of a single
++** entry in either an index or table btree.
++**
++** Index btrees (used for indexes and also WITHOUT ROWID tables) contain
++** an arbitrary key and no data.  These btrees have pKey,nKey set to their
++** key and pData,nData,nZero set to zero.
++**
++** Table btrees (used for rowid tables) contain an integer rowid used as
++** the key and passed in the nKey field.  The pKey field is zero.  
++** pData,nData hold the content of the new entry.  nZero extra zero bytes
++** are appended to the end of the content when constructing the entry.
++**
++** This object is used to pass information into sqlite3BtreeInsert().  The
++** same information used to be passed as five separate parameters.  But placing
++** the information into this object helps to keep the interface more 
++** organized and understandable, and it also helps the resulting code to
++** run a little faster by using fewer registers for parameter passing.
++*/
++struct BtreePayload {
++  const void *pKey;       /* Key content for indexes.  NULL for tables */
++  sqlite3_int64 nKey;     /* Size of pKey for indexes.  PRIMARY KEY for tabs */
++  const void *pData;      /* Data for tables.  NULL for indexes */
++  sqlite3_value *aMem;    /* First of nMem value in the unpacked pKey */
++  u16 nMem;               /* Number of aMem[] value.  Might be zero */
++  int nData;              /* Size of pData.  0 if none. */
++  int nZero;              /* Extra zero data appended after pData,nData */
++};
++
++SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
++                       int flags, int seekResult);
+ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
+ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
+-SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int *pRes);
++SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags);
+ SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
+-SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes);
+-SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
+-SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
+-SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, u32 *pAmt);
+-SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, u32 *pAmt);
+-SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
+-SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
++SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags);
++SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
++SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
++SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
++SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
+ 
+ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
+ SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
++SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*);
+ 
++#ifndef SQLITE_OMIT_INCRBLOB
++SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*);
+ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
+ SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *);
++#endif
+ SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
+ SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
+-SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
+-#ifdef SQLITE_DEBUG
+ SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
+-#endif
+ SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt);
+ SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void);
+ 
+ #ifndef NDEBUG
+ SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
+ #endif
++SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*);
+ 
+ #ifndef SQLITE_OMIT_BTREECOUNT
+ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *);
+@@ -9582,15 +13478,19 @@
+ #ifndef SQLITE_OMIT_SHARED_CACHE
+ SQLITE_PRIVATE   void sqlite3BtreeEnter(Btree*);
+ SQLITE_PRIVATE   void sqlite3BtreeEnterAll(sqlite3*);
++SQLITE_PRIVATE   int sqlite3BtreeSharable(Btree*);
++SQLITE_PRIVATE   void sqlite3BtreeEnterCursor(BtCursor*);
++SQLITE_PRIVATE   int sqlite3BtreeConnectionCount(Btree*);
+ #else
+ # define sqlite3BtreeEnter(X) 
+ # define sqlite3BtreeEnterAll(X)
++# define sqlite3BtreeSharable(X) 0
++# define sqlite3BtreeEnterCursor(X)
++# define sqlite3BtreeConnectionCount(X) 1
+ #endif
+ 
+ #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
+-SQLITE_PRIVATE   int sqlite3BtreeSharable(Btree*);
+ SQLITE_PRIVATE   void sqlite3BtreeLeave(Btree*);
+-SQLITE_PRIVATE   void sqlite3BtreeEnterCursor(BtCursor*);
+ SQLITE_PRIVATE   void sqlite3BtreeLeaveCursor(BtCursor*);
+ SQLITE_PRIVATE   void sqlite3BtreeLeaveAll(sqlite3*);
+ #ifndef NDEBUG
+@@ -9601,9 +13501,7 @@
+ #endif
+ #else
+ 
+-# define sqlite3BtreeSharable(X) 0
+ # define sqlite3BtreeLeave(X)
+-# define sqlite3BtreeEnterCursor(X)
+ # define sqlite3BtreeLeaveCursor(X)
+ # define sqlite3BtreeLeaveAll(X)
+ 
+@@ -9613,7 +13511,7 @@
+ #endif
+ 
+ 
+-#endif /* _BTREE_H_ */
++#endif /* SQLITE_BTREE_H */
+ 
+ /************** End of btree.h ***********************************************/
+ /************** Continuing where we left off in sqliteInt.h ******************/
+@@ -9636,8 +13534,8 @@
+ ** or VDBE.  The VDBE implements an abstract machine that runs a
+ ** simple program to access and modify the underlying database.
+ */
+-#ifndef _SQLITE_VDBE_H_
+-#define _SQLITE_VDBE_H_
++#ifndef SQLITE_VDBE_H
++#define SQLITE_VDBE_H
+ /* #include <stdio.h> */
+ 
+ /*
+@@ -9651,7 +13549,7 @@
+ ** The names of the following types declared in vdbeInt.h are required
+ ** for the VdbeOp definition.
+ */
+-typedef struct Mem Mem;
++typedef struct sqlite3_value Mem;
+ typedef struct SubProgram SubProgram;
+ 
+ /*
+@@ -9662,25 +13560,29 @@
+ struct VdbeOp {
+   u8 opcode;          /* What operation to perform */
+   signed char p4type; /* One of the P4_xxx constants for p4 */
+-  u8 opflags;         /* Mask of the OPFLG_* flags in opcodes.h */
+-  u8 p5;              /* Fifth parameter is an unsigned character */
++  u16 p5;             /* Fifth parameter is an unsigned 16-bit integer */
+   int p1;             /* First operand */
+   int p2;             /* Second parameter (often the jump destination) */
+   int p3;             /* The third parameter */
+-  union {             /* fourth parameter */
++  union p4union {     /* fourth parameter */
+     int i;                 /* Integer value if p4type==P4_INT32 */
+     void *p;               /* Generic pointer */
+     char *z;               /* Pointer to data for string (char array) types */
+     i64 *pI64;             /* Used when p4type is P4_INT64 */
+     double *pReal;         /* Used when p4type is P4_REAL */
+     FuncDef *pFunc;        /* Used when p4type is P4_FUNCDEF */
++    sqlite3_context *pCtx; /* Used when p4type is P4_FUNCCTX */
+     CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
+     Mem *pMem;             /* Used when p4type is P4_MEM */
+     VTable *pVtab;         /* Used when p4type is P4_VTAB */
+     KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
+     int *ai;               /* Used when p4type is P4_INTARRAY */
+     SubProgram *pProgram;  /* Used when p4type is P4_SUBPROGRAM */
+-    int (*xAdvance)(BtCursor *, int *);
++    Table *pTab;           /* Used when p4type is P4_TABLE */
++#ifdef SQLITE_ENABLE_CURSOR_HINTS
++    Expr *pExpr;           /* Used when p4type is P4_EXPR */
++#endif
++    int (*xAdvance)(BtCursor *, int);
+   } p4;
+ #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+   char *zComment;          /* Comment to improve readability */
+@@ -9704,7 +13606,7 @@
+   int nOp;                      /* Elements in aOp[] */
+   int nMem;                     /* Number of memory cells required */
+   int nCsr;                     /* Number of cursors required */
+-  int nOnce;                    /* Number of OP_Once instructions */
++  u8 *aOnce;                    /* Array of OP_Once flags */
+   void *token;                  /* id that may be used to recursive triggers */
+   SubProgram *pNext;            /* Next sub-program already visited */
+ };
+@@ -9724,22 +13626,26 @@
+ /*
+ ** Allowed values of VdbeOp.p4type
+ */
+-#define P4_NOTUSED    0   /* The P4 parameter is not used */
+-#define P4_DYNAMIC  (-1)  /* Pointer to a string obtained from sqliteMalloc() */
+-#define P4_STATIC   (-2)  /* Pointer to a static string */
+-#define P4_COLLSEQ  (-4)  /* P4 is a pointer to a CollSeq structure */
+-#define P4_FUNCDEF  (-5)  /* P4 is a pointer to a FuncDef structure */
+-#define P4_KEYINFO  (-6)  /* P4 is a pointer to a KeyInfo structure */
+-#define P4_MEM      (-8)  /* P4 is a pointer to a Mem*    structure */
+-#define P4_TRANSIENT  0   /* P4 is a pointer to a transient string */
+-#define P4_VTAB     (-10) /* P4 is a pointer to an sqlite3_vtab structure */
+-#define P4_MPRINTF  (-11) /* P4 is a string obtained from sqlite3_mprintf() */
+-#define P4_REAL     (-12) /* P4 is a 64-bit floating point value */
+-#define P4_INT64    (-13) /* P4 is a 64-bit signed integer */
+-#define P4_INT32    (-14) /* P4 is a 32-bit signed integer */
+-#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
+-#define P4_SUBPROGRAM  (-18) /* P4 is a pointer to a SubProgram structure */
+-#define P4_ADVANCE  (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */
++#define P4_NOTUSED      0   /* The P4 parameter is not used */
++#define P4_TRANSIENT    0   /* P4 is a pointer to a transient string */
++#define P4_STATIC     (-1)  /* Pointer to a static string */
++#define P4_COLLSEQ    (-2)  /* P4 is a pointer to a CollSeq structure */
++#define P4_INT32      (-3)  /* P4 is a 32-bit signed integer */
++#define P4_SUBPROGRAM (-4)  /* P4 is a pointer to a SubProgram structure */
++#define P4_ADVANCE    (-5)  /* P4 is a pointer to BtreeNext() or BtreePrev() */
++#define P4_TABLE      (-6)  /* P4 is a pointer to a Table structure */
++/* Above do not own any resources.  Must free those below */
++#define P4_FREE_IF_LE (-7)
++#define P4_DYNAMIC    (-7)  /* Pointer to memory from sqliteMalloc() */
++#define P4_FUNCDEF    (-8)  /* P4 is a pointer to a FuncDef structure */
++#define P4_KEYINFO    (-9)  /* P4 is a pointer to a KeyInfo structure */
++#define P4_EXPR       (-10) /* P4 is a pointer to an Expr tree */
++#define P4_MEM        (-11) /* P4 is a pointer to a Mem*    structure */
++#define P4_VTAB       (-12) /* P4 is a pointer to an sqlite3_vtab structure */
++#define P4_REAL       (-13) /* P4 is a 64-bit floating point value */
++#define P4_INT64      (-14) /* P4 is a 64-bit signed integer */
++#define P4_INTARRAY   (-15) /* P4 is a vector of 32-bit integers */
++#define P4_FUNCCTX    (-16) /* P4 is a pointer to an sqlite3_context object */
+ 
+ /* Error message codes for OP_Halt */
+ #define P5_ConstraintNotNull 1
+@@ -9781,202 +13687,228 @@
+ /************** Include opcodes.h in the middle of vdbe.h ********************/
+ /************** Begin file opcodes.h *****************************************/
+ /* Automatically generated.  Do not edit */
+-/* See the mkopcodeh.awk script for details */
+-#define OP_Function        1 /* synopsis: r[P3]=func(r[P2@P5])             */
+-#define OP_Savepoint       2
+-#define OP_AutoCommit      3
+-#define OP_Transaction     4
+-#define OP_SorterNext      5
+-#define OP_PrevIfOpen      6
+-#define OP_NextIfOpen      7
+-#define OP_Prev            8
+-#define OP_Next            9
+-#define OP_AggStep        10 /* synopsis: accum=r[P3] step(r[P2@P5])       */
+-#define OP_Checkpoint     11
+-#define OP_JournalMode    12
+-#define OP_Vacuum         13
+-#define OP_VFilter        14 /* synopsis: iplan=r[P3] zplan='P4'           */
+-#define OP_VUpdate        15 /* synopsis: data=r[P3@P2]                    */
+-#define OP_Goto           16
+-#define OP_Gosub          17
+-#define OP_Return         18
++/* See the tool/mkopcodeh.tcl script for details */
++#define OP_Savepoint       0
++#define OP_AutoCommit      1
++#define OP_Transaction     2
++#define OP_SorterNext      3
++#define OP_PrevIfOpen      4
++#define OP_NextIfOpen      5
++#define OP_Prev            6
++#define OP_Next            7
++#define OP_Checkpoint      8
++#define OP_JournalMode     9
++#define OP_Vacuum         10
++#define OP_VFilter        11 /* synopsis: iplan=r[P3] zplan='P4'           */
++#define OP_VUpdate        12 /* synopsis: data=r[P3@P2]                    */
++#define OP_Goto           13
++#define OP_Gosub          14
++#define OP_InitCoroutine  15
++#define OP_Yield          16
++#define OP_MustBeInt      17
++#define OP_Jump           18
+ #define OP_Not            19 /* same as TK_NOT, synopsis: r[P2]= !r[P1]    */
+-#define OP_InitCoroutine  20
+-#define OP_EndCoroutine   21
+-#define OP_Yield          22
+-#define OP_HaltIfNull     23 /* synopsis: if r[P3]=null halt               */
+-#define OP_Halt           24
+-#define OP_Integer        25 /* synopsis: r[P2]=P1                         */
+-#define OP_Int64          26 /* synopsis: r[P2]=P4                         */
+-#define OP_String         27 /* synopsis: r[P2]='P4' (len=P1)              */
+-#define OP_Null           28 /* synopsis: r[P2..P3]=NULL                   */
+-#define OP_SoftNull       29 /* synopsis: r[P1]=NULL                       */
+-#define OP_Blob           30 /* synopsis: r[P2]=P4 (len=P1)                */
+-#define OP_Variable       31 /* synopsis: r[P2]=parameter(P1,P4)           */
+-#define OP_Move           32 /* synopsis: r[P2@P3]=r[P1@P3]                */
+-#define OP_Copy           33 /* synopsis: r[P2@P3+1]=r[P1@P3+1]            */
+-#define OP_SCopy          34 /* synopsis: r[P2]=r[P1]                      */
+-#define OP_ResultRow      35 /* synopsis: output=r[P1@P2]                  */
+-#define OP_CollSeq        36
+-#define OP_AddImm         37 /* synopsis: r[P1]=r[P1]+P2                   */
+-#define OP_MustBeInt      38
+-#define OP_RealAffinity   39
+-#define OP_Cast           40 /* synopsis: affinity(r[P1])                  */
+-#define OP_Permutation    41
+-#define OP_Compare        42 /* synopsis: r[P1@P3] <-> r[P2@P3]            */
+-#define OP_Jump           43
+-#define OP_Once           44
+-#define OP_If             45
+-#define OP_IfNot          46
+-#define OP_Column         47 /* synopsis: r[P3]=PX                         */
+-#define OP_Affinity       48 /* synopsis: affinity(r[P1@P2])               */
+-#define OP_MakeRecord     49 /* synopsis: r[P3]=mkrec(r[P1@P2])            */
+-#define OP_Count          50 /* synopsis: r[P2]=count()                    */
+-#define OP_ReadCookie     51
+-#define OP_SetCookie      52
+-#define OP_ReopenIdx      53 /* synopsis: root=P2 iDb=P3                   */
+-#define OP_OpenRead       54 /* synopsis: root=P2 iDb=P3                   */
+-#define OP_OpenWrite      55 /* synopsis: root=P2 iDb=P3                   */
+-#define OP_OpenAutoindex  56 /* synopsis: nColumn=P2                       */
+-#define OP_OpenEphemeral  57 /* synopsis: nColumn=P2                       */
+-#define OP_SorterOpen     58
+-#define OP_SequenceTest   59 /* synopsis: if( cursor[P1].ctr++ ) pc = P2   */
+-#define OP_OpenPseudo     60 /* synopsis: P3 columns in r[P2]              */
+-#define OP_Close          61
+-#define OP_SeekLT         62 /* synopsis: key=r[P3@P4]                     */
+-#define OP_SeekLE         63 /* synopsis: key=r[P3@P4]                     */
+-#define OP_SeekGE         64 /* synopsis: key=r[P3@P4]                     */
+-#define OP_SeekGT         65 /* synopsis: key=r[P3@P4]                     */
+-#define OP_Seek           66 /* synopsis: intkey=r[P2]                     */
+-#define OP_NoConflict     67 /* synopsis: key=r[P3@P4]                     */
+-#define OP_NotFound       68 /* synopsis: key=r[P3@P4]                     */
+-#define OP_Found          69 /* synopsis: key=r[P3@P4]                     */
+-#define OP_NotExists      70 /* synopsis: intkey=r[P3]                     */
+-#define OP_Or             71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
+-#define OP_And            72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
+-#define OP_Sequence       73 /* synopsis: r[P2]=cursor[P1].ctr++           */
+-#define OP_NewRowid       74 /* synopsis: r[P2]=rowid                      */
+-#define OP_Insert         75 /* synopsis: intkey=r[P3] data=r[P2]          */
+-#define OP_IsNull         76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+-#define OP_NotNull        77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+-#define OP_Ne             78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */
+-#define OP_Eq             79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */
+-#define OP_Gt             80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */
+-#define OP_Le             81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */
+-#define OP_Lt             82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */
+-#define OP_Ge             83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */
+-#define OP_InsertInt      84 /* synopsis: intkey=P3 data=r[P2]             */
+-#define OP_BitAnd         85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+-#define OP_BitOr          86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+-#define OP_ShiftLeft      87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
+-#define OP_ShiftRight     88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
+-#define OP_Add            89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+-#define OP_Subtract       90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+-#define OP_Multiply       91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+-#define OP_Divide         92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+-#define OP_Remainder      93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+-#define OP_Concat         94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+-#define OP_Delete         95
+-#define OP_BitNot         96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
++#define OP_Once           20
++#define OP_If             21
++#define OP_IfNot          22
++#define OP_IfNullRow      23 /* synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
++#define OP_SeekLT         24 /* synopsis: key=r[P3@P4]                     */
++#define OP_SeekLE         25 /* synopsis: key=r[P3@P4]                     */
++#define OP_SeekGE         26 /* synopsis: key=r[P3@P4]                     */
++#define OP_SeekGT         27 /* synopsis: key=r[P3@P4]                     */
++#define OP_NoConflict     28 /* synopsis: key=r[P3@P4]                     */
++#define OP_NotFound       29 /* synopsis: key=r[P3@P4]                     */
++#define OP_Found          30 /* synopsis: key=r[P3@P4]                     */
++#define OP_SeekRowid      31 /* synopsis: intkey=r[P3]                     */
++#define OP_NotExists      32 /* synopsis: intkey=r[P3]                     */
++#define OP_Last           33
++#define OP_IfSmaller      34
++#define OP_SorterSort     35
++#define OP_Sort           36
++#define OP_Rewind         37
++#define OP_IdxLE          38 /* synopsis: key=r[P3@P4]                     */
++#define OP_IdxGT          39 /* synopsis: key=r[P3@P4]                     */
++#define OP_IdxLT          40 /* synopsis: key=r[P3@P4]                     */
++#define OP_IdxGE          41 /* synopsis: key=r[P3@P4]                     */
++#define OP_RowSetRead     42 /* synopsis: r[P3]=rowset(P1)                 */
++#define OP_RowSetTest     43 /* synopsis: if r[P3] in rowset(P1) goto P2   */
++#define OP_Program        44
++#define OP_FkIfZero       45 /* synopsis: if fkctr[P1]==0 goto P2          */
++#define OP_IfPos          46 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
++#define OP_IfNotZero      47 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
++#define OP_DecrJumpZero   48 /* synopsis: if (--r[P1])==0 goto P2          */
++#define OP_IncrVacuum     49
++#define OP_VNext          50
++#define OP_Init           51 /* synopsis: Start at P2                      */
++#define OP_Return         52
++#define OP_EndCoroutine   53
++#define OP_HaltIfNull     54 /* synopsis: if r[P3]=null halt               */
++#define OP_Halt           55
++#define OP_Integer        56 /* synopsis: r[P2]=P1                         */
++#define OP_Int64          57 /* synopsis: r[P2]=P4                         */
++#define OP_String         58 /* synopsis: r[P2]='P4' (len=P1)              */
++#define OP_Null           59 /* synopsis: r[P2..P3]=NULL                   */
++#define OP_SoftNull       60 /* synopsis: r[P1]=NULL                       */
++#define OP_Blob           61 /* synopsis: r[P2]=P4 (len=P1)                */
++#define OP_Variable       62 /* synopsis: r[P2]=parameter(P1,P4)           */
++#define OP_Move           63 /* synopsis: r[P2@P3]=r[P1@P3]                */
++#define OP_Copy           64 /* synopsis: r[P2@P3+1]=r[P1@P3+1]            */
++#define OP_SCopy          65 /* synopsis: r[P2]=r[P1]                      */
++#define OP_IntCopy        66 /* synopsis: r[P2]=r[P1]                      */
++#define OP_ResultRow      67 /* synopsis: output=r[P1@P2]                  */
++#define OP_CollSeq        68
++#define OP_AddImm         69 /* synopsis: r[P1]=r[P1]+P2                   */
++#define OP_Or             70 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
++#define OP_And            71 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
++#define OP_RealAffinity   72
++#define OP_Cast           73 /* synopsis: affinity(r[P1])                  */
++#define OP_Permutation    74
++#define OP_IsNull         75 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
++#define OP_NotNull        76 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
++#define OP_Ne             77 /* same as TK_NE, synopsis: IF r[P3]!=r[P1]   */
++#define OP_Eq             78 /* same as TK_EQ, synopsis: IF r[P3]==r[P1]   */
++#define OP_Gt             79 /* same as TK_GT, synopsis: IF r[P3]>r[P1]    */
++#define OP_Le             80 /* same as TK_LE, synopsis: IF r[P3]<=r[P1]   */
++#define OP_Lt             81 /* same as TK_LT, synopsis: IF r[P3]<r[P1]    */
++#define OP_Ge             82 /* same as TK_GE, synopsis: IF r[P3]>=r[P1]   */
++#define OP_ElseNotEq      83 /* same as TK_ESCAPE                          */
++#define OP_BitAnd         84 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
++#define OP_BitOr          85 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
++#define OP_ShiftLeft      86 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
++#define OP_ShiftRight     87 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
++#define OP_Add            88 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
++#define OP_Subtract       89 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
++#define OP_Multiply       90 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
++#define OP_Divide         91 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
++#define OP_Remainder      92 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
++#define OP_Concat         93 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
++#define OP_Compare        94 /* synopsis: r[P1@P3] <-> r[P2@P3]            */
++#define OP_BitNot         95 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
++#define OP_Column         96 /* synopsis: r[P3]=PX                         */
+ #define OP_String8        97 /* same as TK_STRING, synopsis: r[P2]='P4'    */
+-#define OP_ResetCount     98
+-#define OP_SorterCompare  99 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+-#define OP_SorterData    100 /* synopsis: r[P2]=data                       */
+-#define OP_RowKey        101 /* synopsis: r[P2]=key                        */
+-#define OP_RowData       102 /* synopsis: r[P2]=data                       */
+-#define OP_Rowid         103 /* synopsis: r[P2]=rowid                      */
+-#define OP_NullRow       104
+-#define OP_Last          105
+-#define OP_SorterSort    106
+-#define OP_Sort          107
+-#define OP_Rewind        108
+-#define OP_SorterInsert  109
+-#define OP_IdxInsert     110 /* synopsis: key=r[P2]                        */
+-#define OP_IdxDelete     111 /* synopsis: key=r[P2@P3]                     */
+-#define OP_IdxRowid      112 /* synopsis: r[P2]=rowid                      */
+-#define OP_IdxLE         113 /* synopsis: key=r[P3@P4]                     */
+-#define OP_IdxGT         114 /* synopsis: key=r[P3@P4]                     */
+-#define OP_IdxLT         115 /* synopsis: key=r[P3@P4]                     */
+-#define OP_IdxGE         116 /* synopsis: key=r[P3@P4]                     */
+-#define OP_Destroy       117
+-#define OP_Clear         118
+-#define OP_ResetSorter   119
+-#define OP_CreateIndex   120 /* synopsis: r[P2]=root iDb=P1                */
+-#define OP_CreateTable   121 /* synopsis: r[P2]=root iDb=P1                */
+-#define OP_ParseSchema   122
+-#define OP_LoadAnalysis  123
+-#define OP_DropTable     124
+-#define OP_DropIndex     125
+-#define OP_DropTrigger   126
+-#define OP_IntegrityCk   127
+-#define OP_RowSetAdd     128 /* synopsis: rowset(P1)=r[P2]                 */
+-#define OP_RowSetRead    129 /* synopsis: r[P3]=rowset(P1)                 */
+-#define OP_RowSetTest    130 /* synopsis: if r[P3] in rowset(P1) goto P2   */
+-#define OP_Program       131
+-#define OP_Param         132
+-#define OP_Real          133 /* same as TK_FLOAT, synopsis: r[P2]=P4       */
+-#define OP_FkCounter     134 /* synopsis: fkctr[P1]+=P2                    */
+-#define OP_FkIfZero      135 /* synopsis: if fkctr[P1]==0 goto P2          */
+-#define OP_MemMax        136 /* synopsis: r[P1]=max(r[P1],r[P2])           */
+-#define OP_IfPos         137 /* synopsis: if r[P1]>0 goto P2               */
+-#define OP_IfNeg         138 /* synopsis: r[P1]+=P3, if r[P1]<0 goto P2    */
+-#define OP_IfNotZero     139 /* synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2 */
+-#define OP_DecrJumpZero  140 /* synopsis: if (--r[P1])==0 goto P2          */
+-#define OP_JumpZeroIncr  141 /* synopsis: if (r[P1]++)==0 ) goto P2        */
+-#define OP_AggFinal      142 /* synopsis: accum=r[P1] N=P2                 */
+-#define OP_IncrVacuum    143
+-#define OP_Expire        144
+-#define OP_TableLock     145 /* synopsis: iDb=P1 root=P2 write=P3          */
+-#define OP_VBegin        146
+-#define OP_VCreate       147
+-#define OP_VDestroy      148
+-#define OP_VOpen         149
+-#define OP_VColumn       150 /* synopsis: r[P3]=vcolumn(P2)                */
+-#define OP_VNext         151
+-#define OP_VRename       152
+-#define OP_Pagecount     153
+-#define OP_MaxPgcnt      154
+-#define OP_Init          155 /* synopsis: Start at P2                      */
+-#define OP_Noop          156
+-#define OP_Explain       157
+-
++#define OP_Affinity       98 /* synopsis: affinity(r[P1@P2])               */
++#define OP_MakeRecord     99 /* synopsis: r[P3]=mkrec(r[P1@P2])            */
++#define OP_Count         100 /* synopsis: r[P2]=count()                    */
++#define OP_ReadCookie    101
++#define OP_SetCookie     102
++#define OP_ReopenIdx     103 /* synopsis: root=P2 iDb=P3                   */
++#define OP_OpenRead      104 /* synopsis: root=P2 iDb=P3                   */
++#define OP_OpenWrite     105 /* synopsis: root=P2 iDb=P3                   */
++#define OP_OpenDup       106
++#define OP_OpenAutoindex 107 /* synopsis: nColumn=P2                       */
++#define OP_OpenEphemeral 108 /* synopsis: nColumn=P2                       */
++#define OP_SorterOpen    109
++#define OP_SequenceTest  110 /* synopsis: if( cursor[P1].ctr++ ) pc = P2   */
++#define OP_OpenPseudo    111 /* synopsis: P3 columns in r[P2]              */
++#define OP_Close         112
++#define OP_ColumnsUsed   113
++#define OP_Sequence      114 /* synopsis: r[P2]=cursor[P1].ctr++           */
++#define OP_NewRowid      115 /* synopsis: r[P2]=rowid                      */
++#define OP_Insert        116 /* synopsis: intkey=r[P3] data=r[P2]          */
++#define OP_InsertInt     117 /* synopsis: intkey=P3 data=r[P2]             */
++#define OP_Delete        118
++#define OP_ResetCount    119
++#define OP_SorterCompare 120 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
++#define OP_SorterData    121 /* synopsis: r[P2]=data                       */
++#define OP_RowData       122 /* synopsis: r[P2]=data                       */
++#define OP_Rowid         123 /* synopsis: r[P2]=rowid                      */
++#define OP_NullRow       124
++#define OP_SorterInsert  125 /* synopsis: key=r[P2]                        */
++#define OP_IdxInsert     126 /* synopsis: key=r[P2]                        */
++#define OP_IdxDelete     127 /* synopsis: key=r[P2@P3]                     */
++#define OP_DeferredSeek  128 /* synopsis: Move P3 to P1.rowid if needed    */
++#define OP_IdxRowid      129 /* synopsis: r[P2]=rowid                      */
++#define OP_Destroy       130
++#define OP_Clear         131
++#define OP_Real          132 /* same as TK_FLOAT, synopsis: r[P2]=P4       */
++#define OP_ResetSorter   133
++#define OP_CreateIndex   134 /* synopsis: r[P2]=root iDb=P1                */
++#define OP_CreateTable   135 /* synopsis: r[P2]=root iDb=P1                */
++#define OP_SqlExec       136
++#define OP_ParseSchema   137
++#define OP_LoadAnalysis  138
++#define OP_DropTable     139
++#define OP_DropIndex     140
++#define OP_DropTrigger   141
++#define OP_IntegrityCk   142
++#define OP_RowSetAdd     143 /* synopsis: rowset(P1)=r[P2]                 */
++#define OP_Param         144
++#define OP_FkCounter     145 /* synopsis: fkctr[P1]+=P2                    */
++#define OP_MemMax        146 /* synopsis: r[P1]=max(r[P1],r[P2])           */
++#define OP_OffsetLimit   147 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
++#define OP_AggStep0      148 /* synopsis: accum=r[P3] step(r[P2@P5])       */
++#define OP_AggStep       149 /* synopsis: accum=r[P3] step(r[P2@P5])       */
++#define OP_AggFinal      150 /* synopsis: accum=r[P1] N=P2                 */
++#define OP_Expire        151
++#define OP_TableLock     152 /* synopsis: iDb=P1 root=P2 write=P3          */
++#define OP_VBegin        153
++#define OP_VCreate       154
++#define OP_VDestroy      155
++#define OP_VOpen         156
++#define OP_VColumn       157 /* synopsis: r[P3]=vcolumn(P2)                */
++#define OP_VRename       158
++#define OP_Pagecount     159
++#define OP_MaxPgcnt      160
++#define OP_PureFunc0     161
++#define OP_Function0     162 /* synopsis: r[P3]=func(r[P2@P5])             */
++#define OP_PureFunc      163
++#define OP_Function      164 /* synopsis: r[P3]=func(r[P2@P5])             */
++#define OP_CursorHint    165
++#define OP_Noop          166
++#define OP_Explain       167
+ 
+ /* Properties such as "out2" or "jump" that are specified in
+ ** comments following the "case" for each opcode in the vdbe.c
+ ** are encoded into bitvectors as follows:
+ */
+-#define OPFLG_JUMP            0x0001  /* jump:  P2 holds jmp target */
+-#define OPFLG_IN1             0x0002  /* in1:   P1 is an input */
+-#define OPFLG_IN2             0x0004  /* in2:   P2 is an input */
+-#define OPFLG_IN3             0x0008  /* in3:   P3 is an input */
+-#define OPFLG_OUT2            0x0010  /* out2:  P2 is an output */
+-#define OPFLG_OUT3            0x0020  /* out3:  P3 is an output */
++#define OPFLG_JUMP        0x01  /* jump:  P2 holds jmp target */
++#define OPFLG_IN1         0x02  /* in1:   P1 is an input */
++#define OPFLG_IN2         0x04  /* in2:   P2 is an input */
++#define OPFLG_IN3         0x08  /* in3:   P3 is an input */
++#define OPFLG_OUT2        0x10  /* out2:  P2 is an output */
++#define OPFLG_OUT3        0x20  /* out3:  P3 is an output */
+ #define OPFLG_INITIALIZER {\
+-/*   0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
+-/*   8 */ 0x01, 0x01, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\
+-/*  16 */ 0x01, 0x01, 0x02, 0x12, 0x01, 0x02, 0x03, 0x08,\
+-/*  24 */ 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10,\
+-/*  32 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x03, 0x02,\
+-/*  40 */ 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x00,\
+-/*  48 */ 0x00, 0x00, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00,\
+-/*  56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09,\
+-/*  64 */ 0x09, 0x09, 0x04, 0x09, 0x09, 0x09, 0x09, 0x26,\
+-/*  72 */ 0x26, 0x10, 0x10, 0x00, 0x03, 0x03, 0x0b, 0x0b,\
+-/*  80 */ 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x26, 0x26, 0x26,\
+-/*  88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\
+-/*  96 */ 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
+-/* 104 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x00,\
+-/* 112 */ 0x10, 0x01, 0x01, 0x01, 0x01, 0x10, 0x00, 0x00,\
+-/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+-/* 128 */ 0x06, 0x23, 0x0b, 0x01, 0x10, 0x10, 0x00, 0x01,\
+-/* 136 */ 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x01,\
+-/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\
+-/* 152 */ 0x00, 0x10, 0x10, 0x01, 0x00, 0x00,}
++/*   0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,\
++/*   8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,\
++/*  16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x01,\
++/*  24 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\
++/*  32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
++/*  40 */ 0x01, 0x01, 0x23, 0x0b, 0x01, 0x01, 0x03, 0x03,\
++/*  48 */ 0x03, 0x01, 0x01, 0x01, 0x02, 0x02, 0x08, 0x00,\
++/*  56 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\
++/*  64 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x02, 0x26, 0x26,\
++/*  72 */ 0x02, 0x02, 0x00, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\
++/*  80 */ 0x0b, 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26,\
++/*  88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\
++/*  96 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
++/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
++/* 112 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,\
++/* 120 */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00,\
++/* 128 */ 0x00, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10,\
++/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,\
++/* 144 */ 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00,\
++/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
++/* 160 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
++}
++
++/* The sqlite3P2Values() routine is able to run faster if it knows
++** the value of the largest JUMP opcode.  The smaller the maximum
++** JUMP opcode the better, so the mkopcodeh.tcl script that
++** generated this include file strives to group all JUMP opcodes
++** together near the beginning of the list.
++*/
++#define SQLITE_MX_JUMP_OPCODE  83  /* Maximum JUMP opcode */
+ 
+ /************** End of opcodes.h *********************************************/
+ /************** Continuing where we left off in vdbe.h ***********************/
+ 
+ /*
++** Additional non-public SQLITE_PREPARE_* flags
++*/
++#define SQLITE_PREPARE_SAVESQL  0x80  /* Preserve SQL text */
++#define SQLITE_PREPARE_MASK     0x0f  /* Mask of public flags */
++
++/*
+ ** Prototypes for the VDBE interface.  See comments on the implementation
+ ** for a description of what each of these routines does.
+ */
+@@ -9984,24 +13916,39 @@
+ SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int);
+ SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int);
+ SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
++SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe*,int);
++SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe*,int,const char*);
++SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...);
+ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
+ SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
++SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int);
+ SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
+-SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
++SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe*,int);
++#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
++SQLITE_PRIVATE   void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N);
++SQLITE_PRIVATE   void sqlite3VdbeVerifyNoResultRow(Vdbe *p);
++#else
++# define sqlite3VdbeVerifyNoMallocRequired(A,B)
++# define sqlite3VdbeVerifyNoResultRow(A)
++#endif
++SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
+ SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
++SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
+ SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
+ SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
+ SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
+-SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
++SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
+ SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr);
+-SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
++SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
+ SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
+ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
++SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);
+ SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
+ SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
+ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
+ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*);
+ SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
++SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*);
+ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
+ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
+ SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*);
+@@ -10018,7 +13965,8 @@
+ SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
+ SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
+ SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
+-SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
++SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe*);
++SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8);
+ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
+ SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
+ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
+@@ -10031,7 +13979,7 @@
+ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
+ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
+ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
+-SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
++SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*);
+ 
+ typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);
+ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
+@@ -10040,6 +13988,8 @@
+ SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
+ #endif
+ 
++SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*);
++
+ /* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
+ ** each VDBE opcode.
+ **
+@@ -10106,7 +14056,7 @@
+ # define sqlite3VdbeScanStatus(a,b,c,d,e)
+ #endif
+ 
+-#endif
++#endif /* SQLITE_VDBE_H */
+ 
+ /************** End of vdbe.h ************************************************/
+ /************** Continuing where we left off in sqliteInt.h ******************/
+@@ -10128,8 +14078,8 @@
+ ** at a time and provides a journal for rollback.
+ */
+ 
+-#ifndef _PAGER_H_
+-#define _PAGER_H_
++#ifndef SQLITE_PAGER_H
++#define SQLITE_PAGER_H
+ 
+ /*
+ ** Default maximum size for persistent journal files. A negative 
+@@ -10182,7 +14132,11 @@
+ #define PAGER_LOCKINGMODE_EXCLUSIVE   1
+ 
+ /*
+-** Numeric constants that encode the journalmode.  
++** Numeric constants that encode the journalmode.
++**
++** The numeric values encoded here (other than PAGER_JOURNALMODE_QUERY)
++** are exposed in the API via the "PRAGMA journal_mode" command and
++** therefore cannot be changed without a compatibility break.
+ */
+ #define PAGER_JOURNALMODE_QUERY     (-1)  /* Query the value of journalmode */
+ #define PAGER_JOURNALMODE_DELETE      0   /* Commit by deleting journal file */
+@@ -10193,22 +14147,28 @@
+ #define PAGER_JOURNALMODE_WAL         5   /* Use write-ahead logging */
+ 
+ /*
+-** Flags that make up the mask passed to sqlite3PagerAcquire().
++** Flags that make up the mask passed to sqlite3PagerGet().
+ */
+ #define PAGER_GET_NOCONTENT     0x01  /* Do not load data from disk */
+ #define PAGER_GET_READONLY      0x02  /* Read-only page is acceptable */
+ 
+ /*
+ ** Flags for sqlite3PagerSetFlags()
++**
++** Value constraints (enforced via assert()):
++**    PAGER_FULLFSYNC      == SQLITE_FullFSync
++**    PAGER_CKPT_FULLFSYNC == SQLITE_CkptFullFSync
++**    PAGER_CACHE_SPILL    == SQLITE_CacheSpill
+ */
+ #define PAGER_SYNCHRONOUS_OFF       0x01  /* PRAGMA synchronous=OFF */
+ #define PAGER_SYNCHRONOUS_NORMAL    0x02  /* PRAGMA synchronous=NORMAL */
+ #define PAGER_SYNCHRONOUS_FULL      0x03  /* PRAGMA synchronous=FULL */
+-#define PAGER_SYNCHRONOUS_MASK      0x03  /* Mask for three values above */
+-#define PAGER_FULLFSYNC             0x04  /* PRAGMA fullfsync=ON */
+-#define PAGER_CKPT_FULLFSYNC        0x08  /* PRAGMA checkpoint_fullfsync=ON */
+-#define PAGER_CACHESPILL            0x10  /* PRAGMA cache_spill=ON */
+-#define PAGER_FLAGS_MASK            0x1c  /* All above except SYNCHRONOUS */
++#define PAGER_SYNCHRONOUS_EXTRA     0x04  /* PRAGMA synchronous=EXTRA */
++#define PAGER_SYNCHRONOUS_MASK      0x07  /* Mask for four values above */
++#define PAGER_FULLFSYNC             0x08  /* PRAGMA fullfsync=ON */
++#define PAGER_CKPT_FULLFSYNC        0x10  /* PRAGMA checkpoint_fullfsync=ON */
++#define PAGER_CACHESPILL            0x20  /* PRAGMA cache_spill=ON */
++#define PAGER_FLAGS_MASK            0x38  /* All above except SYNCHRONOUS */
+ 
+ /*
+ ** The remainder of this file contains the declarations of the functions
+@@ -10226,14 +14186,18 @@
+   int,
+   void(*)(DbPage*)
+ );
+-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager);
++SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3*);
+ SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
+ 
+ /* Functions used to configure a Pager object. */
+ SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
+ SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int);
++#ifdef SQLITE_HAS_CODEC
++SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager*,Pager*);
++#endif
+ SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
+ SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
++SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager*, int);
+ SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
+ SQLITE_PRIVATE void sqlite3PagerShrink(Pager*);
+ SQLITE_PRIVATE void sqlite3PagerSetFlags(Pager*,unsigned);
+@@ -10243,10 +14207,10 @@
+ SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*);
+ SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
+ SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*);
++SQLITE_PRIVATE int sqlite3PagerFlush(Pager*);
+ 
+ /* Functions used to obtain and release page references. */ 
+-SQLITE_PRIVATE int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
+-#define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0)
++SQLITE_PRIVATE int sqlite3PagerGet(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
+ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
+ SQLITE_PRIVATE void sqlite3PagerRef(DbPage*);
+ SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*);
+@@ -10273,11 +14237,21 @@
+ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager);
+ 
+ #ifndef SQLITE_OMIT_WAL
+-SQLITE_PRIVATE   int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
++SQLITE_PRIVATE   int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, 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);
++SQLITE_PRIVATE   int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
++# ifdef SQLITE_DIRECT_OVERFLOW_READ
++SQLITE_PRIVATE   int sqlite3PagerUseWal(Pager *pPager, Pgno);
++# endif
++# ifdef SQLITE_ENABLE_SNAPSHOT
++SQLITE_PRIVATE   int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
++SQLITE_PRIVATE   int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
++SQLITE_PRIVATE   int sqlite3PagerSnapshotRecover(Pager *pPager);
++# endif
++#else
++# define sqlite3PagerUseWal(x,y) 0
+ #endif
+ 
+ #ifdef SQLITE_ENABLE_ZIPVFS
+@@ -10287,17 +14261,19 @@
+ /* Functions used to query pager state and configuration. */
+ SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
+ SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager*);
+-SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE   int sqlite3PagerRefcount(Pager*);
++#endif
+ SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*);
+ SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int);
+-SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*);
++SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager*);
+ SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
++SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*);
+ SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
+-SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
+ 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 void sqlite3PagerClearCache(Pager*);
+ SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
+ 
+ /* Functions used to truncate the database file. */
+@@ -10324,7 +14300,7 @@
+ # define enable_simulated_io_errors()
+ #endif
+ 
+-#endif /* _PAGER_H_ */
++#endif /* SQLITE_PAGER_H */
+ 
+ /************** End of pager.h ***********************************************/
+ /************** Continuing where we left off in sqliteInt.h ******************/
+@@ -10358,7 +14334,8 @@
+   sqlite3_pcache_page *pPage;    /* Pcache object page handle */
+   void *pData;                   /* Page data */
+   void *pExtra;                  /* Extra content */
+-  PgHdr *pDirty;                 /* Transient list of dirty pages */
++  PCache *pCache;                /* PRIVATE: Cache that owns this page */
++  PgHdr *pDirty;                 /* Transient list of dirty sorted by pgno */
+   Pager *pPager;                 /* The pager this page is part of */
+   Pgno pgno;                     /* Page number for this page */
+ #ifdef SQLITE_CHECK_PAGES
+@@ -10367,25 +14344,25 @@
+   u16 flags;                     /* PGHDR flags defined below */
+ 
+   /**********************************************************************
+-  ** Elements above are public.  All that follows is private to pcache.c
+-  ** and should not be accessed by other modules.
++  ** Elements above, except pCache, are public.  All that follow are 
++  ** private to pcache.c and should not be accessed by other modules.
++  ** pCache is grouped with the public elements for efficiency.
+   */
+   i16 nRef;                      /* Number of users of this page */
+-  PCache *pCache;                /* Cache that owns this page */
+-
+   PgHdr *pDirtyNext;             /* Next element in list of dirty pages */
+   PgHdr *pDirtyPrev;             /* Previous element in list of dirty pages */
+ };
+ 
+ /* Bit values for PgHdr.flags */
+-#define PGHDR_DIRTY             0x002  /* Page has changed */
+-#define PGHDR_NEED_SYNC         0x004  /* Fsync the rollback journal before
+-                                       ** writing this page to the database */
+-#define PGHDR_NEED_READ         0x008  /* Content is unread */
+-#define PGHDR_REUSE_UNLIKELY    0x010  /* A hint that reuse is unlikely */
+-#define PGHDR_DONT_WRITE        0x020  /* Do not write content to disk */
++#define PGHDR_CLEAN           0x001  /* Page not on the PCache.pDirty list */
++#define PGHDR_DIRTY           0x002  /* Page is on the PCache.pDirty list */
++#define PGHDR_WRITEABLE       0x004  /* Journaled and ready to modify */
++#define PGHDR_NEED_SYNC       0x008  /* Fsync the rollback journal before
++                                     ** writing this page to the database */
++#define PGHDR_DONT_WRITE      0x010  /* Do not write content to disk */
++#define PGHDR_MMAP            0x020  /* This is an mmap page object */
+ 
+-#define PGHDR_MMAP              0x040  /* This is an mmap page object */
++#define PGHDR_WAL_APPEND      0x040  /* Appended to wal file */
+ 
+ /* Initialize and shutdown the page cache subsystem */
+ SQLITE_PRIVATE int sqlite3PcacheInitialize(void);
+@@ -10429,6 +14406,7 @@
+ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr*);    /* Make sure page is marked dirty */
+ SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr*);    /* Mark a single page as clean */
+ SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache*);    /* Mark all dirty list pages as clean */
++SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache*);
+ 
+ /* Change a page number.  Used by incr-vacuum. */
+ SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr*, Pgno);
+@@ -10467,6 +14445,11 @@
+ SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *));
+ #endif
+ 
++#if defined(SQLITE_DEBUG)
++/* Check invariants on a PgHdr object */
++SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr*);
++#endif
++
+ /* Set and get the suggested cache-size for the specified pager-cache.
+ **
+ ** If no global maximum is configured, then the system attempts to limit
+@@ -10478,6 +14461,13 @@
+ SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *);
+ #endif
+ 
++/* Set or get the suggested spill-size for the specified pager-cache.
++**
++** The spill-size is the minimum number of pages in cache before the cache
++** will attempt to spill dirty pages by calling xStress.
++*/
++SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *, int);
++
+ /* Free up as much memory as possible from the page cache */
+ SQLITE_PRIVATE void sqlite3PcacheShrink(PCache*);
+ 
+@@ -10496,11 +14486,13 @@
+ SQLITE_PRIVATE int sqlite3HeaderSizePcache(void);
+ SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void);
+ 
++/* Number of dirty pages as a percentage of the configured cache size */
++SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*);
++
+ #endif /* _PCACHE_H_ */
+ 
+ /************** End of pcache.h **********************************************/
+ /************** Continuing where we left off in sqliteInt.h ******************/
+-
+ /************** Include os.h in the middle of sqliteInt.h ********************/
+ /************** Begin file os.h **********************************************/
+ /*
+@@ -10546,8 +14538,8 @@
+ ** This file contains pre-processor directives related to operating system
+ ** detection and/or setup.
+ */
+-#ifndef _OS_SETUP_H_
+-#define _OS_SETUP_H_
++#ifndef SQLITE_OS_SETUP_H
++#define SQLITE_OS_SETUP_H
+ 
+ /*
+ ** Figure out if we are dealing with Unix, Windows, or some other operating
+@@ -10587,7 +14579,7 @@
+ #  endif
+ #endif
+ 
+-#endif /* _OS_SETUP_H_ */
++#endif /* SQLITE_OS_SETUP_H */
+ 
+ /************** End of os_setup.h ********************************************/
+ /************** Continuing where we left off in os.h *************************/
+@@ -10726,7 +14718,7 @@
+ /* 
+ ** Functions for accessing sqlite3_file methods 
+ */
+-SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file*);
++SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*);
+ SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
+ SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
+ SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size);
+@@ -10763,6 +14755,7 @@
+ #endif /* SQLITE_OMIT_LOAD_EXTENSION */
+ SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *);
+ SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int);
++SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*);
+ SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*);
+ 
+ /*
+@@ -10770,7 +14763,7 @@
+ ** sqlite3_malloc() to obtain space for the file-handle structure.
+ */
+ SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*);
+-SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
++SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *);
+ 
+ #endif /* _SQLITE_OS_H_ */
+ 
+@@ -10852,6 +14845,36 @@
+ /************** End of mutex.h ***********************************************/
+ /************** Continuing where we left off in sqliteInt.h ******************/
+ 
++/* The SQLITE_EXTRA_DURABLE compile-time option used to set the default
++** synchronous setting to EXTRA.  It is no longer supported.
++*/
++#ifdef SQLITE_EXTRA_DURABLE
++# warning Use SQLITE_DEFAULT_SYNCHRONOUS=3 instead of SQLITE_EXTRA_DURABLE
++# define SQLITE_DEFAULT_SYNCHRONOUS 3
++#endif
++
++/*
++** Default synchronous levels.
++**
++** Note that (for historcal reasons) the PAGER_SYNCHRONOUS_* macros differ
++** from the SQLITE_DEFAULT_SYNCHRONOUS value by 1.
++**
++**           PAGER_SYNCHRONOUS       DEFAULT_SYNCHRONOUS
++**   OFF           1                         0
++**   NORMAL        2                         1
++**   FULL          3                         2
++**   EXTRA         4                         3
++**
++** The "PRAGMA synchronous" statement also uses the zero-based numbers.
++** In other words, the zero-based numbers are used for all external interfaces
++** and the one-based values are used internally.
++*/
++#ifndef SQLITE_DEFAULT_SYNCHRONOUS
++# define SQLITE_DEFAULT_SYNCHRONOUS 2
++#endif
++#ifndef SQLITE_DEFAULT_WAL_SYNCHRONOUS
++# define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS
++#endif
+ 
+ /*
+ ** Each database file to be accessed by the system is an instance
+@@ -10861,9 +14884,10 @@
+ ** databases may be attached.
+ */
+ struct Db {
+-  char *zName;         /* Name of this database */
++  char *zDbSName;      /* Name of this database. (schema name, not filename) */
+   Btree *pBt;          /* The B*Tree structure for this database file */
+   u8 safety_level;     /* How aggressive at syncing data to disk */
++  u8 bSyncSet;         /* True if "PRAGMA synchronous=N" has been run */
+   Schema *pSchema;     /* Pointer to database schema (possibly shared) */
+ };
+ 
+@@ -10874,7 +14898,7 @@
+ ** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing.
+ ** In shared cache mode, a single Schema object can be shared by multiple
+ ** Btrees that refer to the same underlying BtShared object.
+-** 
++**
+ ** Schema objects are automatically deallocated when the last Btree that
+ ** references them is destroyed.   The TEMP Schema is manually freed by
+ ** sqlite3_close().
+@@ -10899,7 +14923,7 @@
+ };
+ 
+ /*
+-** These macros can be used to test, set, or clear bits in the 
++** These macros can be used to test, set, or clear bits in the
+ ** Db.pSchema->flags field.
+ */
+ #define DbHasProperty(D,I,P)     (((D)->aDb[I].pSchema->schemaFlags&(P))==(P))
+@@ -10948,8 +14972,8 @@
+ ** lookaside allocations are not used to construct the schema objects.
+ */
+ struct Lookaside {
++  u32 bDisable;           /* Only operate the lookaside when zero */
+   u16 sz;                 /* Size of each buffer in bytes */
+-  u8 bEnabled;            /* False to disable new lookaside allocations */
+   u8 bMalloced;           /* True if pStart obtained from sqlite3_malloc() */
+   int nOut;               /* Number of buffers currently checked out */
+   int mxOut;              /* Highwater mark for nOut */
+@@ -10963,13 +14987,15 @@
+ };
+ 
+ /*
+-** A hash table for function definitions.
++** A hash table for built-in function definitions.  (Application-defined
++** functions use a regular table table from hash.h.)
+ **
+ ** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
+-** Collisions are on the FuncDef.pHash chain.
++** Collisions are on the FuncDef.u.pHash chain.
+ */
++#define SQLITE_FUNC_HASH_SZ 23
+ struct FuncDefHash {
+-  FuncDef *a[23];       /* Hash table for functions */
++  FuncDef *a[SQLITE_FUNC_HASH_SZ];       /* Hash table for functions */
+ };
+ 
+ #ifdef SQLITE_USER_AUTHENTICATION
+@@ -11010,6 +15036,15 @@
+                                const char*);
+ #endif
+ 
++#ifndef SQLITE_OMIT_DEPRECATED
++/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing
++** in the style of sqlite3_trace()
++*/
++#define SQLITE_TRACE_LEGACY  0x80
++#else
++#define SQLITE_TRACE_LEGACY  0
++#endif /* SQLITE_OMIT_DEPRECATED */
++
+ 
+ /*
+ ** Each database connection is an instance of the following structure.
+@@ -11027,16 +15062,21 @@
+   unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
+   int errCode;                  /* Most recent error code (SQLITE_*) */
+   int errMask;                  /* & result codes with this before returning */
++  int iSysErrno;                /* Errno value from last system error */
+   u16 dbOptFlags;               /* Flags to enable/disable optimizations */
+   u8 enc;                       /* Text encoding */
+   u8 autoCommit;                /* The auto-commit flag. */
+   u8 temp_store;                /* 1: file 2: memory 0: default */
+   u8 mallocFailed;              /* True if we have seen a malloc failure */
++  u8 bBenignMalloc;             /* Do not require OOMs if true */
+   u8 dfltLockMode;              /* Default locking-mode for attached dbs */
+   signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
+   u8 suppressErr;               /* Do not issue error messages if true */
+   u8 vtabOnConflict;            /* Value to return for s3_vtab_on_conflict() */
+   u8 isTransactionSavepoint;    /* True if the outermost savepoint is a TS */
++  u8 mTrace;                    /* zero or more SQLITE_TRACE flags */
++  u8 skipBtreeMutex;            /* True if no shared-cache backends */
++  u8 nSqlExec;                  /* Number of pending OP_SqlExec opcodes */
+   int nextPagesize;             /* Pagesize after VACUUM if >0 */
+   u32 magic;                    /* Magic number for detect library misuse */
+   int nChange;                  /* Value returned by sqlite3_changes() */
+@@ -11057,16 +15097,23 @@
+   int nVDestroy;                /* Number of active OP_VDestroy operations */
+   int nExtension;               /* Number of loaded extensions */
+   void **aExtension;            /* Array of shared library handles */
+-  void (*xTrace)(void*,const char*);        /* Trace function */
++  int (*xTrace)(u32,void*,void*,void*);     /* Trace function */
+   void *pTraceArg;                          /* Argument to the trace function */
+   void (*xProfile)(void*,const char*,u64);  /* Profiling function */
+   void *pProfileArg;                        /* Argument to profile function */
+-  void *pCommitArg;                 /* Argument to xCommitCallback() */   
++  void *pCommitArg;                 /* Argument to xCommitCallback() */
+   int (*xCommitCallback)(void*);    /* Invoked at every commit. */
+-  void *pRollbackArg;               /* Argument to xRollbackCallback() */   
++  void *pRollbackArg;               /* Argument to xRollbackCallback() */
+   void (*xRollbackCallback)(void*); /* Invoked at every commit. */
+   void *pUpdateArg;
+   void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++  void *pPreUpdateArg;          /* First argument to xPreUpdateCallback */
++  void (*xPreUpdateCallback)(   /* Registered using sqlite3_preupdate_hook() */
++    void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64
++  );
++  PreUpdate *pPreUpdate;        /* Context for active pre-update callback */
++#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+ #ifndef SQLITE_OMIT_WAL
+   int (*xWalCallback)(void *, sqlite3 *, const char *, int);
+   void *pWalArg;
+@@ -11096,7 +15143,7 @@
+   VTable **aVTrans;             /* Virtual tables with open transactions */
+   VTable *pDisconnect;    /* Disconnect these in next sqlite3_prepare() */
+ #endif
+-  FuncDefHash aFunc;            /* Hash table of connection functions */
++  Hash aFunc;                   /* Hash table of connection functions */
+   Hash aCollSeq;                /* All collating sequences */
+   BusyHandler busyHandler;      /* Busy callback */
+   Db aDbStatic[2];              /* Static space for the 2 default backends */
+@@ -11108,8 +15155,8 @@
+   i64 nDeferredImmCons;         /* Net deferred immediate constraints */
+   int *pnBytesFreed;            /* If not NULL, increment this in DbFree() */
+ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
+-  /* The following variables are all protected by the STATIC_MASTER 
+-  ** mutex, not by sqlite3.mutex. They are used by code in notify.c. 
++  /* The following variables are all protected by the STATIC_MASTER
++  ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
+   **
+   ** When X.pUnlockConnection==Y, that means that X is waiting for Y to
+   ** unlock so that it can proceed.
+@@ -11137,38 +15184,52 @@
+ 
+ /*
+ ** Possible values for the sqlite3.flags.
+-*/
+-#define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */
+-#define SQLITE_InternChanges  0x00000002  /* Uncommitted Hash table changes */
+-#define SQLITE_FullFSync      0x00000004  /* Use full fsync on the backend */
+-#define SQLITE_CkptFullFSync  0x00000008  /* Use full fsync for checkpoint */
+-#define SQLITE_CacheSpill     0x00000010  /* OK to spill pager cache */
+-#define SQLITE_FullColNames   0x00000020  /* Show full column names on SELECT */
++**
++** Value constraints (enforced via assert()):
++**      SQLITE_FullFSync     == PAGER_FULLFSYNC
++**      SQLITE_CkptFullFSync == PAGER_CKPT_FULLFSYNC
++**      SQLITE_CacheSpill    == PAGER_CACHE_SPILL
++*/
++#define SQLITE_WriteSchema    0x00000001  /* OK to update SQLITE_MASTER */
++#define SQLITE_LegacyFileFmt  0x00000002  /* Create new databases in format 1 */
++#define SQLITE_FullColNames   0x00000004  /* Show full column names on SELECT */
++#define SQLITE_FullFSync      0x00000008  /* Use full fsync on the backend */
++#define SQLITE_CkptFullFSync  0x00000010  /* Use full fsync for checkpoint */
++#define SQLITE_CacheSpill     0x00000020  /* OK to spill pager cache */
+ #define SQLITE_ShortColNames  0x00000040  /* Show short columns names */
+ #define SQLITE_CountRows      0x00000080  /* Count rows changed by INSERT, */
+                                           /*   DELETE, or UPDATE and return */
+                                           /*   the count using a callback. */
+ #define SQLITE_NullCallback   0x00000100  /* Invoke the callback once if the */
+                                           /*   result set is empty */
+-#define SQLITE_SqlTrace       0x00000200  /* Debug print SQL as it executes */
+-#define SQLITE_VdbeListing    0x00000400  /* Debug listings of VDBE programs */
+-#define SQLITE_WriteSchema    0x00000800  /* OK to update SQLITE_MASTER */
+-#define SQLITE_VdbeAddopTrace 0x00001000  /* Trace sqlite3VdbeAddOp() calls */
+-#define SQLITE_IgnoreChecks   0x00002000  /* Do not enforce check constraints */
+-#define SQLITE_ReadUncommitted 0x0004000  /* For shared-cache mode */
+-#define SQLITE_LegacyFileFmt  0x00008000  /* Create new databases in format 1 */
+-#define SQLITE_RecoveryMode   0x00010000  /* Ignore schema errors */
+-#define SQLITE_ReverseOrder   0x00020000  /* Reverse unordered SELECTs */
+-#define SQLITE_RecTriggers    0x00040000  /* Enable recursive triggers */
+-#define SQLITE_ForeignKeys    0x00080000  /* Enforce foreign key constraints  */
+-#define SQLITE_AutoIndex      0x00100000  /* Enable automatic indexes */
+-#define SQLITE_PreferBuiltin  0x00200000  /* Preference to built-in funcs */
+-#define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
+-#define SQLITE_EnableTrigger  0x00800000  /* True to enable triggers */
+-#define SQLITE_DeferFKs       0x01000000  /* Defer all FK constraints */
+-#define SQLITE_QueryOnly      0x02000000  /* Disable database changes */
+-#define SQLITE_VdbeEQP        0x04000000  /* Debug EXPLAIN QUERY PLAN */
+-#define SQLITE_Vacuum         0x08000000  /* Currently in a VACUUM */
++#define SQLITE_IgnoreChecks   0x00000200  /* Do not enforce check constraints */
++#define SQLITE_ReadUncommit   0x00000400  /* READ UNCOMMITTED in shared-cache */
++#define SQLITE_NoCkptOnClose  0x00000800  /* No checkpoint on close()/DETACH */
++#define SQLITE_ReverseOrder   0x00001000  /* Reverse unordered SELECTs */
++#define SQLITE_RecTriggers    0x00002000  /* Enable recursive triggers */
++#define SQLITE_ForeignKeys    0x00004000  /* Enforce foreign key constraints  */
++#define SQLITE_AutoIndex      0x00008000  /* Enable automatic indexes */
++#define SQLITE_LoadExtension  0x00010000  /* Enable load_extension */
++#define SQLITE_EnableTrigger  0x00020000  /* True to enable triggers */
++#define SQLITE_DeferFKs       0x00040000  /* Defer all FK constraints */
++#define SQLITE_QueryOnly      0x00080000  /* Disable database changes */
++#define SQLITE_CellSizeCk     0x00100000  /* Check btree cell sizes on load */
++#define SQLITE_Fts3Tokenizer  0x00200000  /* Enable fts3_tokenizer(2) */
++#define SQLITE_EnableQPSG     0x00400000  /* Query Planner Stability Guarantee */
++/* The next four values are not used by PRAGMAs or by sqlite3_dbconfig() and
++** could be factored out into a separate bit vector of the sqlite3 object. */
++#define SQLITE_InternChanges  0x00800000  /* Uncommitted Hash table changes */
++#define SQLITE_LoadExtFunc    0x01000000  /* Enable load_extension() SQL func */
++#define SQLITE_PreferBuiltin  0x02000000  /* Preference to built-in funcs */
++#define SQLITE_Vacuum         0x04000000  /* Currently in a VACUUM */
++/* Flags used only if debugging */
++#ifdef SQLITE_DEBUG
++#define SQLITE_SqlTrace       0x08000000  /* Debug print SQL as it executes */
++#define SQLITE_VdbeListing    0x10000000  /* Debug listings of VDBE programs */
++#define SQLITE_VdbeTrace      0x20000000  /* True to trace VDBE execution */
++#define SQLITE_VdbeAddopTrace 0x40000000  /* Trace sqlite3VdbeAddOp() calls */
++#define SQLITE_VdbeEQP        0x80000000  /* Debug EXPLAIN QUERY PLAN */
++#endif
+ 
+ 
+ /*
+@@ -11188,18 +15249,15 @@
+ #define SQLITE_Transitive     0x0200   /* Transitive constraints */
+ #define SQLITE_OmitNoopJoin   0x0400   /* Omit unused tables in joins */
+ #define SQLITE_Stat34         0x0800   /* Use STAT3 or STAT4 data */
++#define SQLITE_CountOfView    0x1000   /* The count-of-view optimization */
++#define SQLITE_CursorHints    0x2000   /* Add OP_CursorHint opcodes */
+ #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
+ 
+ /*
+ ** Return true if it OK to factor constant expressions into the initialization
+@@ -11221,28 +15279,33 @@
+ 
+ /*
+ ** Each SQL function is defined by an instance of the following
+-** structure.  A pointer to this structure is stored in the sqlite.aFunc
+-** hash table.  When multiple functions have the same name, the hash table
+-** points to a linked list of these structures.
++** structure.  For global built-in functions (ex: substr(), max(), count())
++** a pointer to this structure is held in the sqlite3BuiltinFunctions object.
++** For per-connection application-defined functions, a pointer to this
++** structure is held in the db->aHash hash table.
++**
++** The u.pHash field is used by the global built-ins.  The u.pDestructor
++** field is used by per-connection app-def functions.
+ */
+ struct FuncDef {
+-  i16 nArg;            /* Number of arguments.  -1 means unlimited */
++  i8 nArg;             /* Number of arguments.  -1 means unlimited */
+   u16 funcFlags;       /* Some combination of SQLITE_FUNC_* */
+   void *pUserData;     /* User data parameter */
+   FuncDef *pNext;      /* Next function with same name */
+-  void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */
+-  void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */
+-  void (*xFinalize)(sqlite3_context*);                /* Aggregate finalizer */
+-  char *zName;         /* SQL name of the function. */
+-  FuncDef *pHash;      /* Next with a different name but the same hash */
+-  FuncDestructor *pDestructor;   /* Reference counted destructor function */
++  void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */
++  void (*xFinalize)(sqlite3_context*);                  /* Agg finalizer */
++  const char *zName;   /* SQL name of the function. */
++  union {
++    FuncDef *pHash;      /* Next with a different name but the same hash */
++    FuncDestructor *pDestructor;   /* Reference counted destructor function */
++  } u;
+ };
+ 
+ /*
+ ** This structure encapsulates a user-function destructor callback (as
+ ** configured using create_function_v2()) and a reference counter. When
+ ** create_function_v2() is called to create a function with a destructor,
+-** a single object of this type is allocated. FuncDestructor.nRef is set to 
++** a single object of this type is allocated. FuncDestructor.nRef is set to
+ ** the number of FuncDef objects created (either 1 or 3, depending on whether
+ ** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor
+ ** member of each of the new FuncDef objects is set to point to the allocated
+@@ -11260,36 +15323,60 @@
+ 
+ /*
+ ** Possible values for FuncDef.flags.  Note that the _LENGTH and _TYPEOF
+-** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG.  There
++** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG.  And
++** SQLITE_FUNC_CONSTANT must be the same as SQLITE_DETERMINISTIC.  There
+ ** are assert() statements in the code to verify this.
+-*/
+-#define SQLITE_FUNC_ENCMASK  0x003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
+-#define SQLITE_FUNC_LIKE     0x004 /* Candidate for the LIKE optimization */
+-#define SQLITE_FUNC_CASE     0x008 /* Case-sensitive LIKE-type function */
+-#define SQLITE_FUNC_EPHEM    0x010 /* Ephemeral.  Delete with VDBE */
+-#define SQLITE_FUNC_NEEDCOLL 0x020 /* sqlite3GetFuncCollSeq() might be called */
+-#define SQLITE_FUNC_LENGTH   0x040 /* Built-in length() function */
+-#define SQLITE_FUNC_TYPEOF   0x080 /* Built-in typeof() function */
+-#define SQLITE_FUNC_COUNT    0x100 /* Built-in count(*) aggregate */
+-#define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */
+-#define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */
+-#define SQLITE_FUNC_CONSTANT 0x800 /* Constant inputs give a constant output */
+-#define SQLITE_FUNC_MINMAX  0x1000 /* True for min() and max() aggregates */
++**
++** Value constraints (enforced via assert()):
++**     SQLITE_FUNC_MINMAX    ==  NC_MinMaxAgg      == SF_MinMaxAgg
++**     SQLITE_FUNC_LENGTH    ==  OPFLAG_LENGTHARG
++**     SQLITE_FUNC_TYPEOF    ==  OPFLAG_TYPEOFARG
++**     SQLITE_FUNC_CONSTANT  ==  SQLITE_DETERMINISTIC from the API
++**     SQLITE_FUNC_ENCMASK   depends on SQLITE_UTF* macros in the API
++*/
++#define SQLITE_FUNC_ENCMASK  0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
++#define SQLITE_FUNC_LIKE     0x0004 /* Candidate for the LIKE optimization */
++#define SQLITE_FUNC_CASE     0x0008 /* Case-sensitive LIKE-type function */
++#define SQLITE_FUNC_EPHEM    0x0010 /* Ephemeral.  Delete with VDBE */
++#define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/
++#define SQLITE_FUNC_LENGTH   0x0040 /* Built-in length() function */
++#define SQLITE_FUNC_TYPEOF   0x0080 /* Built-in typeof() function */
++#define SQLITE_FUNC_COUNT    0x0100 /* Built-in count(*) aggregate */
++#define SQLITE_FUNC_COALESCE 0x0200 /* Built-in coalesce() or ifnull() */
++#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */
++#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
++#define SQLITE_FUNC_MINMAX   0x1000 /* True for min() and max() aggregates */
++#define SQLITE_FUNC_SLOCHNG  0x2000 /* "Slow Change". Value constant during a
++                                    ** single query - might change over time */
++#define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
+ 
+ /*
+ ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
+ ** used to create the initializers for the FuncDef structures.
+ **
+ **   FUNCTION(zName, nArg, iArg, bNC, xFunc)
+-**     Used to create a scalar function definition of a function zName 
++**     Used to create a scalar function definition of a function zName
+ **     implemented by C function xFunc that accepts nArg arguments. The
+ **     value passed as iArg is cast to a (void*) and made available
+-**     as the user-data (sqlite3_user_data()) for the function. If 
++**     as the user-data (sqlite3_user_data()) for the function. If
+ **     argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
+ **
+ **   VFUNCTION(zName, nArg, iArg, bNC, xFunc)
+ **     Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag.
+ **
++**   DFUNCTION(zName, nArg, iArg, bNC, xFunc)
++**     Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and
++**     adds the SQLITE_FUNC_SLOCHNG flag.  Used for date & time functions
++**     and functions like sqlite_version() that can change, but not during
++**     a single query.  The iArg is ignored.  The user-data is always set
++**     to a NULL pointer.  The bNC parameter is not used.
++**
++**   PURE_DATE(zName, nArg, iArg, bNC, xFunc)
++**     Used for "pure" date/time functions, this macro is like DFUNCTION
++**     except that it does set the SQLITE_FUNC_CONSTANT flags.  iArg is
++**     ignored and the user-data for these functions is set to an 
++**     arbitrary non-NULL pointer.  The bNC parameter is not used.
++**
+ **   AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal)
+ **     Used to create an aggregate function definition implemented by
+ **     the C functions xStep and xFinal. The first four parameters
+@@ -11297,8 +15384,8 @@
+ **     FUNCTION().
+ **
+ **   LIKEFUNC(zName, nArg, pArg, flags)
+-**     Used to create a scalar function definition of a function zName 
+-**     that accepts nArg arguments and is implemented by a call to C 
++**     Used to create a scalar function definition of a function zName
++**     that accepts nArg arguments and is implemented by a call to C
+ **     function likeFunc. Argument pArg is cast to a (void *) and made
+ **     available as the function user-data (sqlite3_user_data()). The
+ **     FuncDef.flags variable is set to the value passed as the flags
+@@ -11306,25 +15393,31 @@
+ */
+ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
+   {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
++   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
+ #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
+   {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
++   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
++#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
++  {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \
++   0, 0, xFunc, 0, #zName, {0} }
++#define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \
++  {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
++   (void*)&sqlite3Config, 0, xFunc, 0, #zName, {0} }
+ #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
+   {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
+-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
++   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
+ #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
+-  {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+-   pArg, 0, xFunc, 0, 0, #zName, 0, 0}
++  {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
++   pArg, 0, xFunc, 0, #zName, }
+ #define LIKEFUNC(zName, nArg, arg, flags) \
+   {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
+-   (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0}
++   (void *)arg, 0, likeFunc, 0, #zName, {0} }
+ #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
+   {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
+-   SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
++   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
+ #define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
+   {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
+-   SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
++   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
+ 
+ /*
+ ** All current savepoints are stored in a linked list starting at
+@@ -11358,6 +15451,7 @@
+   const char *zName;                   /* Name passed to create_module() */
+   void *pAux;                          /* pAux passed to create_module() */
+   void (*xDestroy)(void *);            /* Module destructor function */
++  Table *pEpoTab;                      /* Eponymous table for this module */
+ };
+ 
+ /*
+@@ -11365,14 +15459,12 @@
+ ** of this structure.
+ */
+ struct Column {
+-  char *zName;     /* Name of this column */
++  char *zName;     /* Name of this column, \000, then the type */
+   Expr *pDflt;     /* Default value of this 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;      /* An OE_ code for handling a NOT NULL constraint */
+   char affinity;   /* One of the SQLITE_AFF_... values */
+-  u8 szEst;        /* Estimated size of this column.  INT==1 */
++  u8 szEst;        /* Estimated size of value in this column. sizeof(INT)==1 */
+   u8 colFlags;     /* Boolean properties.  See COLFLAG_ defines below */
+ };
+ 
+@@ -11380,6 +15472,7 @@
+ */
+ #define COLFLAG_PRIMKEY  0x0001    /* Column is part of the primary key */
+ #define COLFLAG_HIDDEN   0x0002    /* A hidden column in a virtual table */
++#define COLFLAG_HASTYPE  0x0004    /* Type name follows column name */
+ 
+ /*
+ ** A "Collating Sequence" is defined by an instance of the following
+@@ -11403,22 +15496,23 @@
+ */
+ #define SQLITE_SO_ASC       0  /* Sort in ascending order */
+ #define SQLITE_SO_DESC      1  /* Sort in ascending order */
++#define SQLITE_SO_UNDEFINED -1 /* No sort order specified */
+ 
+ /*
+ ** Column affinity types.
+ **
+ ** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and
+ ** 't' for SQLITE_AFF_TEXT.  But we can save a little space and improve
+-** the speed a little by numbering the values consecutively.  
++** the speed a little by numbering the values consecutively.
+ **
+ ** But rather than start with 0 or 1, we begin with 'A'.  That way,
+ ** when multiple affinity types are concatenated into a string and
+ ** used as the P4 operand, they will be more readable.
+ **
+ ** Note also that the numeric types are grouped together so that testing
+-** for a numeric type is a single comparison.  And the NONE type is first.
++** for a numeric type is a single comparison.  And the BLOB type is first.
+ */
+-#define SQLITE_AFF_NONE     'A'
++#define SQLITE_AFF_BLOB     'A'
+ #define SQLITE_AFF_TEXT     'B'
+ #define SQLITE_AFF_NUMERIC  'C'
+ #define SQLITE_AFF_INTEGER  'D'
+@@ -11428,7 +15522,7 @@
+ 
+ /*
+ ** The SQLITE_AFF_MASK values masks off the significant bits of an
+-** affinity value. 
++** affinity value.
+ */
+ #define SQLITE_AFF_MASK     0x47
+ 
+@@ -11441,6 +15535,7 @@
+ ** operator is NULL.  It is added to certain comparison operators to
+ ** prove that the operands are always NOT NULL.
+ */
++#define SQLITE_KEEPNULL     0x08  /* Used by vector == or <> */
+ #define SQLITE_JUMPIFNULL   0x10  /* jumps if either operand is NULL */
+ #define SQLITE_STOREP2      0x20  /* Store result in reg[P2] rather than jump */
+ #define SQLITE_NULLEQ       0x80  /* NULL=NULL */
+@@ -11448,20 +15543,20 @@
+ 
+ /*
+ ** An object of this type is created for each virtual table present in
+-** the database schema. 
++** the database schema.
+ **
+ ** If the database schema is shared, then there is one instance of this
+ ** structure for each database connection (sqlite3*) that uses the shared
+ ** schema. This is because each database connection requires its own unique
+-** instance of the sqlite3_vtab* handle used to access the virtual table 
+-** implementation. sqlite3_vtab* handles can not be shared between 
+-** database connections, even when the rest of the in-memory database 
++** instance of the sqlite3_vtab* handle used to access the virtual table
++** implementation. sqlite3_vtab* handles can not be shared between
++** database connections, even when the rest of the in-memory database
+ ** schema is shared, as the implementation often stores the database
+ ** connection handle passed to it via the xConnect() or xCreate() method
+ ** during initialization internally. This database connection handle may
+-** then be used by the virtual table implementation to access real tables 
+-** within the database. So that they appear as part of the callers 
+-** transaction, these accesses need to be made via the same database 
++** then be used by the virtual table implementation to access real tables
++** within the database. So that they appear as part of the callers
++** transaction, these accesses need to be made via the same database
+ ** connection as that used to execute SQL operations on the virtual table.
+ **
+ ** All VTable objects that correspond to a single table in a shared
+@@ -11473,19 +15568,19 @@
+ ** sqlite3_vtab* handle in the compiled query.
+ **
+ ** When an in-memory Table object is deleted (for example when the
+-** schema is being reloaded for some reason), the VTable objects are not 
+-** deleted and the sqlite3_vtab* handles are not xDisconnect()ed 
++** schema is being reloaded for some reason), the VTable objects are not
++** deleted and the sqlite3_vtab* handles are not xDisconnect()ed
+ ** immediately. Instead, they are moved from the Table.pVTable list to
+ ** another linked list headed by the sqlite3.pDisconnect member of the
+-** corresponding sqlite3 structure. They are then deleted/xDisconnected 
++** corresponding sqlite3 structure. They are then deleted/xDisconnected
+ ** next time a statement is prepared using said sqlite3*. This is done
+ ** to avoid deadlock issues involving multiple sqlite3.mutex mutexes.
+ ** Refer to comments above function sqlite3VtabUnlockList() for an
+ ** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect
+ ** list without holding the corresponding sqlite3.mutex mutex.
+ **
+-** The memory for objects of this type is always allocated by 
+-** sqlite3DbMalloc(), using the connection handle stored in VTable.db as 
++** The memory for objects of this type is always allocated by
++** sqlite3DbMalloc(), using the connection handle stored in VTable.db as
+ ** the first argument.
+ */
+ struct VTable {
+@@ -11509,26 +15604,25 @@
+   Select *pSelect;     /* NULL for tables.  Points to definition if a view. */
+   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
++                       /*   ... also used as column name list in a VIEW */
+   int tnum;            /* Root BTree page for this table */
++  u32 nTabRef;         /* Number of pointers to this Table */
++  u32 tabFlags;        /* Mask of TF_* values */
+   i16 iPKey;           /* If not negative, use aCol[iPKey] as the rowid */
+   i16 nCol;            /* Number of columns in this table */
+-  u16 nRef;            /* Number of pointers to this Table */
+   LogEst nRowLogEst;   /* Estimated rows in table - from sqlite_stat1 table */
+   LogEst szTabRow;     /* Estimated size of each table row in bytes */
+ #ifdef SQLITE_ENABLE_COSTMULT
+   LogEst costMult;     /* Cost multiplier for using this table */
+ #endif
+-  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
+   int nModuleArg;      /* Number of arguments to the module */
+-  char **azModuleArg;  /* Text of all module args. [0] is module name */
++  char **azModuleArg;  /* 0: module 1: schema 2: vtab name 3...: args */
+   VTable *pVTable;     /* List of VTable objects. */
+ #endif
+   Trigger *pTrigger;   /* List of triggers stored in pSchema */
+@@ -11539,20 +15633,23 @@
+ /*
+ ** Allowed values for Table.tabFlags.
+ **
+-** TF_OOOHidden applies to virtual tables that have hidden columns that are
++** TF_OOOHidden applies to tables or view that have hidden columns that are
+ ** followed by non-hidden columns.  Example:  "CREATE VIRTUAL TABLE x USING
+ ** vtab1(a HIDDEN, b);".  Since "b" is a non-hidden column but "a" is hidden,
+ ** the TF_OOOHidden attribute would apply in this case.  Such tables require
+ ** special handling during INSERT processing.
+ */
+-#define TF_Readonly        0x01    /* Read-only system table */
+-#define TF_Ephemeral       0x02    /* An ephemeral table */
+-#define TF_HasPrimaryKey   0x04    /* Table has a primary key */
+-#define TF_Autoincrement   0x08    /* Integer primary key is autoincrement */
+-#define TF_Virtual         0x10    /* Is a virtual table */
+-#define TF_WithoutRowid    0x20    /* No rowid used. PRIMARY KEY is the key */
+-#define TF_OOOHidden       0x40    /* Out-of-Order hidden columns */
+-
++#define TF_Readonly        0x0001    /* Read-only system table */
++#define TF_Ephemeral       0x0002    /* An ephemeral table */
++#define TF_HasPrimaryKey   0x0004    /* Table has a primary key */
++#define TF_Autoincrement   0x0008    /* Integer primary key is autoincrement */
++#define TF_HasStat1        0x0010    /* nRowLogEst set from sqlite_stat1 */
++#define TF_WithoutRowid    0x0020    /* No rowid.  PRIMARY KEY is the key */
++#define TF_NoVisibleRowid  0x0040    /* No user-visible "rowid" column */
++#define TF_OOOHidden       0x0080    /* Out-of-Order hidden columns */
++#define TF_StatsUsed       0x0100    /* Query planner decisions affected by
++                                     ** Index.aiRowLogEst[] values */
++#define TF_HasNotNull      0x0200    /* Contains NOT NULL constraints */
+ 
+ /*
+ ** Test to see whether or not a table is a virtual table.  This is
+@@ -11560,15 +15657,32 @@
+ ** table support is omitted from the build.
+ */
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-#  define IsVirtual(X)      (((X)->tabFlags & TF_Virtual)!=0)
+-#  define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
++#  define IsVirtual(X)      ((X)->nModuleArg)
+ #else
+ #  define IsVirtual(X)      0
+-#  define IsHiddenColumn(X) 0
+ #endif
+ 
++/*
++** Macros to determine if a column is hidden.  IsOrdinaryHiddenColumn()
++** only works for non-virtual tables (ordinary tables and views) and is
++** always false unless SQLITE_ENABLE_HIDDEN_COLUMNS is defined.  The
++** IsHiddenColumn() macro is general purpose.
++*/
++#if defined(SQLITE_ENABLE_HIDDEN_COLUMNS)
++#  define IsHiddenColumn(X)         (((X)->colFlags & COLFLAG_HIDDEN)!=0)
++#  define IsOrdinaryHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
++#elif !defined(SQLITE_OMIT_VIRTUALTABLE)
++#  define IsHiddenColumn(X)         (((X)->colFlags & COLFLAG_HIDDEN)!=0)
++#  define IsOrdinaryHiddenColumn(X) 0
++#else
++#  define IsHiddenColumn(X)         0
++#  define IsOrdinaryHiddenColumn(X) 0
++#endif
++
++
+ /* Does the table have a rowid */
+ #define HasRowid(X)     (((X)->tabFlags & TF_WithoutRowid)==0)
++#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0)
+ 
+ /*
+ ** Each foreign key constraint is an instance of the following structure.
+@@ -11636,7 +15750,7 @@
+ ** key is set to NULL.  CASCADE means that a DELETE or UPDATE of the
+ ** referenced table row is propagated into the row that holds the
+ ** foreign key.
+-** 
++**
+ ** The following symbolic values are used to record which type
+ ** of action to take.
+ */
+@@ -11657,7 +15771,7 @@
+ 
+ /*
+ ** An instance of the following structure is passed as the first
+-** argument to sqlite3VdbeKeyCompare and is used to control the 
++** argument to sqlite3VdbeKeyCompare and is used to control the
+ ** comparison of the two index keys.
+ **
+ ** Note that aSortOrder[] and aColl[] have nField+1 slots.  There
+@@ -11675,9 +15789,8 @@
+ };
+ 
+ /*
+-** An instance of the following structure holds information about a
+-** single index record that has already been parsed out into individual
+-** values.
++** This object holds a record which has been parsed out into individual
++** fields, for the purposes of doing a comparison.
+ **
+ ** A record is an object that contains one or more fields of data.
+ ** Records are used to store the content of a table row and to store
+@@ -11685,20 +15798,40 @@
+ ** the OP_MakeRecord opcode of the VDBE and is disassembled by the
+ ** OP_Column opcode.
+ **
+-** This structure holds a record that has already been disassembled
+-** into its constituent fields.
+-**
+-** The r1 and r2 member variables are only used by the optimized comparison
+-** functions vdbeRecordCompareInt() and vdbeRecordCompareString().
++** An instance of this object serves as a "key" for doing a search on
++** an index b+tree. The goal of the search is to find the entry that
++** is closed to the key described by this object.  This object might hold
++** just a prefix of the key.  The number of fields is given by
++** pKeyInfo->nField.
++**
++** The r1 and r2 fields are the values to return if this key is less than
++** or greater than a key in the btree, respectively.  These are normally
++** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree
++** is in DESC order.
++**
++** The key comparison functions actually return default_rc when they find
++** an equals comparison.  default_rc can be -1, 0, or +1.  If there are
++** multiple entries in the b-tree with the same key (when only looking
++** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to
++** cause the search to find the last match, or +1 to cause the search to
++** find the first match.
++**
++** The key comparison functions will set eqSeen to true if they ever
++** get and equal results when comparing this structure to a b-tree record.
++** When default_rc!=0, the search might end up on the record immediately
++** before the first match or immediately after the last match.  The
++** eqSeen field will indicate whether or not an exact match exists in the
++** b-tree.
+ */
+ struct UnpackedRecord {
+   KeyInfo *pKeyInfo;  /* Collation and sort-order information */
++  Mem *aMem;          /* Values */
+   u16 nField;         /* Number of entries in apMem[] */
+   i8 default_rc;      /* Comparison result if keys are equal */
+   u8 errCode;         /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
+-  Mem *aMem;          /* Values */
+-  int r1;             /* Value to return if (lhs > rhs) */
+-  int r2;             /* Value to return if (rhs < lhs) */
++  i8 r1;              /* Value to return if (lhs > rhs) */
++  i8 r2;              /* Value to return if (rhs < lhs) */
++  u8 eqSeen;          /* True if an equality comparison has been seen */
+ };
+ 
+ 
+@@ -11716,7 +15849,7 @@
+ ** In the Table structure describing Ex1, nCol==3 because there are
+ ** three columns in the table.  In the Index structure describing
+ ** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
+-** The value of aiColumn is {2, 0}.  aiColumn[0]==2 because the 
++** The value of aiColumn is {2, 0}.  aiColumn[0]==2 because the
+ ** first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
+ ** The second column to be indexed (c1) has an index of 0 in
+ ** Ex1.aCol[], hence Ex2.aiColumn[1]==0.
+@@ -11724,9 +15857,17 @@
+ ** The Index.onError field determines whether or not the indexed columns
+ ** must be unique and what to do if they are not.  When Index.onError=OE_None,
+ ** it means this is not a unique index.  Otherwise it is a unique index
+-** and the value of Index.onError indicate the which conflict resolution 
++** and the value of Index.onError indicate the which conflict resolution
+ ** algorithm to employ whenever an attempt is made to insert a non-unique
+ ** element.
++**
++** While parsing a CREATE TABLE or CREATE INDEX statement in order to
++** generate VDBE code (as opposed to parsing one read from an sqlite_master
++** table as part of parsing an existing database schema), transient instances
++** of this structure may be created. In this case the Index.tnum variable is
++** used to store the address of a VDBE instruction, not a database page
++** number (it cannot - the database page is not allocated until the VDBE
++** program is executed). See convertToWithoutRowidTable() for details.
+ */
+ struct Index {
+   char *zName;             /* Name of this index */
+@@ -11737,8 +15878,9 @@
+   Index *pNext;            /* The next index associated with the same table */
+   Schema *pSchema;         /* Schema containing this index */
+   u8 *aSortOrder;          /* for each column: True==DESC, False==ASC */
+-  char **azColl;           /* Array of collation sequence names for index */
++  const char **azColl;     /* Array of collation sequence names for index */
+   Expr *pPartIdxWhere;     /* WHERE clause for partial indices */
++  ExprList *aColExpr;      /* Column expressions */
+   int tnum;                /* DB Page containing root of this index */
+   LogEst szIdxRow;         /* Estimated average row size in bytes */
+   u16 nKeyCol;             /* Number of columns forming the key */
+@@ -11750,6 +15892,7 @@
+   unsigned isResized:1;    /* True if resizeIndexObject() has been called */
+   unsigned isCovering:1;   /* True if this is a covering index */
+   unsigned noSkipScan:1;   /* Do not try to use skip-scan if true */
++  unsigned hasStat1:1;     /* aiRowLogEst values come from sqlite_stat1 */
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+   int nSample;             /* Number of elements in aSample[] */
+   int nSampleCol;          /* Size of IndexSample.anEq[] and so on */
+@@ -11773,8 +15916,14 @@
+ /* Return true if index X is a UNIQUE index */
+ #define IsUniqueIndex(X)      ((X)->onError!=OE_None)
+ 
++/* The Index.aiColumn[] values are normally positive integer.  But
++** there are some negative values that have special meaning:
++*/
++#define XN_ROWID     (-1)     /* Indexed column is the rowid */
++#define XN_EXPR      (-2)     /* Indexed column is an expression */
++
+ /*
+-** Each sample stored in the sqlite_stat3 table is represented in memory 
++** Each sample stored in the sqlite_stat3 table is represented in memory
+ ** using a structure of this type.  See documentation at the top of the
+ ** analyze.c source file for additional information.
+ */
+@@ -11869,9 +16018,9 @@
+ ** to represent the greater-than-or-equal-to operator in the expression
+ ** tree.
+ **
+-** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB, 
++** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
+ ** or TK_STRING), then Expr.token contains the text of the SQL literal. If
+-** the expression is a variable (TK_VARIABLE), then Expr.token contains the 
++** the expression is a variable (TK_VARIABLE), then Expr.token contains the
+ ** variable name. Finally, if the expression is an SQL function (TK_FUNCTION),
+ ** then Expr.token contains the name of the function.
+ **
+@@ -11882,7 +16031,7 @@
+ ** a CASE expression or an IN expression of the form "<lhs> IN (<y>, <z>...)".
+ ** Expr.x.pSelect is used if the expression is a sub-select or an expression of
+ ** the form "<lhs> IN (SELECT ...)". If the EP_xIsSelect bit is set in the
+-** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is 
++** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is
+ ** valid.
+ **
+ ** An expression of the form ID or ID.ID refers to a column in a table.
+@@ -11893,8 +16042,8 @@
+ ** value is also stored in the Expr.iAgg column in the aggregate so that
+ ** it can be accessed after all aggregates are computed.
+ **
+-** If the expression is an unbound variable marker (a question mark 
+-** character '?' in the original SQL) then the Expr.iTable holds the index 
++** If the expression is an unbound variable marker (a question mark
++** character '?' in the original SQL) then the Expr.iTable holds the index
+ ** number for that variable.
+ **
+ ** If the expression is a subquery then Expr.iColumn holds an integer
+@@ -11933,7 +16082,7 @@
+ 
+   /* If the EP_TokenOnly 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. 
++  ** access them will result in a segfault or malfunction.
+   *********************************************************************/
+ 
+   Expr *pLeft;           /* Left subnode */
+@@ -11954,9 +16103,11 @@
+   int iTable;            /* TK_COLUMN: cursor number of table holding column
+                          ** TK_REGISTER: register number
+                          ** TK_TRIGGER: 1 -> new, 0 -> old
+-                         ** EP_Unlikely:  134217728 times likelihood */
++                         ** EP_Unlikely:  134217728 times likelihood
++                         ** TK_SELECT: 1st register of result vector */
+   ynVar iColumn;         /* TK_COLUMN: column index.  -1 for rowid.
+-                         ** TK_VARIABLE: variable number (always >= 1). */
++                         ** TK_VARIABLE: variable number (always >= 1).
++                         ** TK_SELECT_COLUMN: column of the result vector */
+   i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
+   i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
+   u8 op2;                /* TK_REGISTER: original value of Expr.op
+@@ -11971,8 +16122,8 @@
+ */
+ #define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
+ #define EP_Agg       0x000002 /* Contains one or more aggregate functions */
+-#define EP_Resolved  0x000004 /* IDs have been resolved to COLUMNs */
+-#define EP_Error     0x000008 /* Expression contains one or more errors */
++                  /* 0x000004 // available for use */
++                  /* 0x000008 // available for use */
+ #define EP_Distinct  0x000010 /* Aggregate function with DISTINCT keyword */
+ #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
+ #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
+@@ -11988,9 +16139,11 @@
+ #define EP_MemToken  0x010000 /* Need to sqlite3DbFree() Expr.zToken */
+ #define EP_NoReduce  0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
+ #define EP_Unlikely  0x040000 /* unlikely() or likelihood() function */
+-#define EP_ConstFunc 0x080000 /* Node is a SQLITE_FUNC_CONSTANT function */
++#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
+ #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
+ #define EP_Subquery  0x200000 /* Tree contains a TK_SELECT operator */
++#define EP_Alias     0x400000 /* Is an alias for a result set column */
++#define EP_Leaf      0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
+ 
+ /*
+ ** Combinations of two or more EP_* flags
+@@ -11998,7 +16151,7 @@
+ #define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
+ 
+ /*
+-** These macros can be used to test, set, or clear bits in the 
++** These macros can be used to test, set, or clear bits in the
+ ** Expr.flags field.
+ */
+ #define ExprHasProperty(E,P)     (((E)->flags&(P))!=0)
+@@ -12017,8 +16170,8 @@
+ #endif
+ 
+ /*
+-** Macros to determine the number of bytes required by a normal Expr 
+-** struct, an Expr struct with the EP_Reduced flag set in Expr.flags 
++** Macros to determine the number of bytes required by a normal Expr
++** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
+ ** and an Expr struct with the EP_TokenOnly flag set.
+ */
+ #define EXPR_FULLSIZE           sizeof(Expr)           /* Full size */
+@@ -12026,7 +16179,7 @@
+ #define EXPR_TOKENONLYSIZE      offsetof(Expr,pLeft)   /* Fewer features */
+ 
+ /*
+-** Flags passed to the sqlite3ExprDup() function. See the header comment 
++** Flags passed to the sqlite3ExprDup() function. See the header comment
+ ** above sqlite3ExprDup() for details.
+ */
+ #define EXPRDUP_REDUCE         0x0001  /* Used reduced-size Expr nodes */
+@@ -12049,8 +16202,9 @@
+ */
+ struct ExprList {
+   int nExpr;             /* Number of expressions on the list */
++  int nAlloc;            /* Number of a[] slots allocated */
+   struct ExprList_item { /* For each expression in the list */
+-    Expr *pExpr;            /* The list of expressions */
++    Expr *pExpr;            /* The parse tree for this expression */
+     char *zName;            /* Token associated with this expression */
+     char *zSpan;            /* Original text of the expression */
+     u8 sortOrder;           /* 1 for DESC or 0 for ASC */
+@@ -12064,7 +16218,7 @@
+       } x;
+       int iConstExprReg;      /* Register in which Expr value is cached */
+     } u;
+-  } *a;                  /* Alloc a power of two greater or equal to nExpr */
++  } a[1];                  /* One slot for each expression in the list */
+ };
+ 
+ /*
+@@ -12108,7 +16262,11 @@
+ ** tables in a join to 32 instead of 64.  But it also reduces the size
+ ** of the library by 738 bytes on ix86.
+ */
+-typedef u64 Bitmask;
++#ifdef SQLITE_BITMASK_TYPE
++  typedef SQLITE_BITMASK_TYPE Bitmask;
++#else
++  typedef u64 Bitmask;
++#endif
+ 
+ /*
+ ** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
+@@ -12120,6 +16278,7 @@
+ */
+ #define MASKBIT(n)   (((Bitmask)1)<<(n))
+ #define MASKBIT32(n) (((unsigned int)1)<<(n))
++#define ALLBITS      ((Bitmask)-1)
+ 
+ /*
+ ** The following structure describes the FROM clause of a SELECT statement.
+@@ -12153,11 +16312,15 @@
+     int addrFillSub;  /* Address of subroutine to manifest a subquery */
+     int regReturn;    /* Register holding return address of addrFillSub */
+     int regResult;    /* Registers holding results of a co-routine */
+-    u8 jointype;      /* Type of join between this able and the previous */
+-    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 */
+-    unsigned isRecursive :1;   /* True for recursive reference in WITH */
++    struct {
++      u8 jointype;      /* Type of join between this table and the previous */
++      unsigned notIndexed :1;    /* True if there is a NOT INDEXED clause */
++      unsigned isIndexedBy :1;   /* True if there is an INDEXED BY clause */
++      unsigned isTabFunc :1;     /* True if table-valued-function syntax */
++      unsigned isCorrelated :1;  /* True if sub-query is correlated */
++      unsigned viaCoroutine :1;  /* Implemented as a co-routine */
++      unsigned isRecursive :1;   /* True for recursive reference in WITH */
++    } fg;
+ #ifndef SQLITE_OMIT_EXPLAIN
+     u8 iSelectId;     /* If pSelect!=0, the id of the sub-select in EQP */
+ #endif
+@@ -12165,8 +16328,11 @@
+     Expr *pOn;        /* The ON clause of a join */
+     IdList *pUsing;   /* The USING clause of a join */
+     Bitmask colUsed;  /* Bit N (1<<N) set if column N of pTab is used */
+-    char *zIndex;     /* Identifier from "INDEXED BY <zIndex>" clause */
+-    Index *pIndex;    /* Index structure corresponding to zIndex, if any */
++    union {
++      char *zIndexedBy;    /* Identifier from "INDEXED BY <zIndex>" clause */
++      ExprList *pFuncArg;  /* Arguments to table-valued-function */
++    } u1;
++    Index *pIBIndex;  /* Index structure corresponding to u1.zIndexedBy */
+   } a[1];             /* One entry for each identifier on the list */
+ };
+ 
+@@ -12185,21 +16351,28 @@
+ /*
+ ** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
+ ** and the WhereInfo.wctrlFlags member.
++**
++** Value constraints (enforced via assert()):
++**     WHERE_USE_LIMIT  == SF_FixedLimit
+ */
+ #define WHERE_ORDERBY_NORMAL   0x0000 /* No-op */
+ #define WHERE_ORDERBY_MIN      0x0001 /* ORDER BY processing for min() func */
+ #define WHERE_ORDERBY_MAX      0x0002 /* ORDER BY processing for max() func */
+ #define WHERE_ONEPASS_DESIRED  0x0004 /* Want to do one-pass UPDATE/DELETE */
+-#define WHERE_DUPLICATES_OK    0x0008 /* Ok to return a row more than once */
+-#define WHERE_OMIT_OPEN_CLOSE  0x0010 /* Table cursors are already open */
+-#define WHERE_FORCE_TABLE      0x0020 /* Do not use an index-only search */
+-#define WHERE_ONETABLE_ONLY    0x0040 /* Only code the 1st table in pTabList */
+-#define WHERE_NO_AUTOINDEX     0x0080 /* Disallow automatic indexes */
+-#define WHERE_GROUPBY          0x0100 /* pOrderBy is really a GROUP BY */
+-#define WHERE_DISTINCTBY       0x0200 /* pOrderby is really a DISTINCT clause */
+-#define WHERE_WANT_DISTINCT    0x0400 /* All output needs to be distinct */
+-#define WHERE_SORTBYGROUP      0x0800 /* Support sqlite3WhereIsSorted() */
+-#define WHERE_REOPEN_IDX       0x1000 /* Try to use OP_ReopenIdx */
++#define WHERE_ONEPASS_MULTIROW 0x0008 /* ONEPASS is ok with multiple rows */
++#define WHERE_DUPLICATES_OK    0x0010 /* Ok to return a row more than once */
++#define WHERE_OR_SUBCLAUSE     0x0020 /* Processing a sub-WHERE as part of
++                                      ** the OR optimization  */
++#define WHERE_GROUPBY          0x0040 /* pOrderBy is really a GROUP BY */
++#define WHERE_DISTINCTBY       0x0080 /* pOrderby is really a DISTINCT clause */
++#define WHERE_WANT_DISTINCT    0x0100 /* All output needs to be distinct */
++#define WHERE_SORTBYGROUP      0x0200 /* Support sqlite3WhereIsSorted() */
++#define WHERE_SEEK_TABLE       0x0400 /* Do not defer seeks on main table */
++#define WHERE_ORDERBY_LIMIT    0x0800 /* ORDERBY+LIMIT on the inner loop */
++#define WHERE_SEEK_UNIQ_TABLE  0x1000 /* Do not defer seeks if unique */
++                        /*     0x2000    not currently used */
++#define WHERE_USE_LIMIT        0x4000 /* Use the LIMIT in cost estimates */
++                        /*     0x8000    not currently used */
+ 
+ /* Allowed return values from sqlite3WhereIsDistinct()
+ */
+@@ -12217,12 +16390,12 @@
+ ** pEList corresponds to the result set of a SELECT and is NULL for
+ ** other statements.
+ **
+-** NameContexts can be nested.  When resolving names, the inner-most 
++** NameContexts can be nested.  When resolving names, the inner-most
+ ** context is searched first.  If no match is found, the next outer
+ ** context is checked.  If there is still no match, the next context
+ ** is checked.  This process continues until either a match is found
+ ** or all contexts are check.  When a match is found, the nRef member of
+-** the context containing the match is incremented. 
++** the context containing the match is incremented.
+ **
+ ** Each subquery gets a new NameContext.  The pNext field points to the
+ ** NameContext in the parent query.  Thus the process of scanning the
+@@ -12243,15 +16416,18 @@
+ /*
+ ** Allowed values for the NameContext, ncFlags field.
+ **
+-** Note:  NC_MinMaxAgg must have the same value as SF_MinMaxAgg and
+-** SQLITE_FUNC_MINMAX.
+-** 
++** Value constraints (all checked via assert()):
++**    NC_HasAgg    == SF_HasAgg
++**    NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX
++**
+ */
+ #define NC_AllowAgg  0x0001  /* Aggregate functions are allowed here */
+-#define NC_HasAgg    0x0002  /* One or more aggregate functions seen */
++#define NC_PartIdx   0x0002  /* True if resolving a partial index WHERE */
+ #define NC_IsCheck   0x0004  /* True if resolving names in a CHECK constraint */
+ #define NC_InAggFunc 0x0008  /* True if analyzing arguments to an agg func */
+-#define NC_PartIdx   0x0010  /* True if resolving a partial index WHERE */
++#define NC_HasAgg    0x0010  /* One or more aggregate functions seen */
++#define NC_IdxExpr   0x0020  /* True if resolving columns of CREATE INDEX */
++#define NC_VarSelect 0x0040  /* A correlated subquery has been seen */
+ #define NC_MinMaxAgg 0x1000  /* min/max aggregates seen.  See note above */
+ 
+ /*
+@@ -12277,13 +16453,13 @@
+ struct Select {
+   ExprList *pEList;      /* The fields of the result */
+   u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
+-  u16 selFlags;          /* Various SF_* values */
++  LogEst nSelectRow;     /* Estimated number of result rows */
++  u32 selFlags;          /* Various SF_* values */
+   int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
+ #if SELECTTRACE_ENABLED
+   char zSelName[12];     /* Symbolic name of this SELECT use for debugging */
+ #endif
+   int addrOpenEphm[2];   /* OP_OpenEphem opcodes related to this select */
+-  u64 nSelectRow;        /* Estimated number of result rows */
+   SrcList *pSrc;         /* The FROM clause */
+   Expr *pWhere;          /* The WHERE clause */
+   ExprList *pGroupBy;    /* The GROUP BY clause */
+@@ -12299,21 +16475,30 @@
+ /*
+ ** Allowed values for Select.selFlags.  The "SF" prefix stands for
+ ** "Select Flag".
+-*/
+-#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_Compound        0x0040  /* Part of a compound query */
+-#define SF_Values          0x0080  /* Synthesized from VALUES clause */
+-#define SF_MultiValue      0x0100  /* Single VALUES term with multiple rows */
+-#define SF_NestedFrom      0x0200  /* Part of a parenthesized FROM clause */
+-#define SF_MaybeConvert    0x0400  /* Need convertCompoundSelectToSubquery() */
+-#define SF_Recursive       0x0800  /* The recursive part of a recursive CTE */
+-#define SF_MinMaxAgg       0x1000  /* Aggregate containing min() or max() */
+-#define SF_Converted       0x2000  /* By convertCompoundSelectToSubquery() */
++**
++** Value constraints (all checked via assert())
++**     SF_HasAgg     == NC_HasAgg
++**     SF_MinMaxAgg  == NC_MinMaxAgg     == SQLITE_FUNC_MINMAX
++**     SF_FixedLimit == WHERE_USE_LIMIT
++*/
++#define SF_Distinct       0x00001  /* Output should be DISTINCT */
++#define SF_All            0x00002  /* Includes the ALL keyword */
++#define SF_Resolved       0x00004  /* Identifiers have been resolved */
++#define SF_Aggregate      0x00008  /* Contains agg functions or a GROUP BY */
++#define SF_HasAgg         0x00010  /* Contains aggregate functions */
++#define SF_UsesEphemeral  0x00020  /* Uses the OpenEphemeral opcode */
++#define SF_Expanded       0x00040  /* sqlite3SelectExpand() called on this */
++#define SF_HasTypeInfo    0x00080  /* FROM subqueries have Table metadata */
++#define SF_Compound       0x00100  /* Part of a compound query */
++#define SF_Values         0x00200  /* Synthesized from VALUES clause */
++#define SF_MultiValue     0x00400  /* Single VALUES term with multiple rows */
++#define SF_NestedFrom     0x00800  /* Part of a parenthesized FROM clause */
++#define SF_MinMaxAgg      0x01000  /* Aggregate containing min() or max() */
++#define SF_Recursive      0x02000  /* The recursive part of a recursive CTE */
++#define SF_FixedLimit     0x04000  /* nSelectRow set by a constant LIMIT */
++#define SF_MaybeConvert   0x08000  /* Need convertCompoundSelectToSubquery() */
++#define SF_Converted      0x10000  /* By convertCompoundSelectToSubquery() */
++#define SF_IncludeHidden  0x20000  /* Include hidden columns in output */
+ 
+ 
+ /*
+@@ -12321,7 +16506,7 @@
+ ** by one of the following macros.  The "SRT" prefix means "SELECT Result
+ ** Type".
+ **
+-**     SRT_Union       Store results as a key in a temporary index 
++**     SRT_Union       Store results as a key in a temporary index
+ **                     identified by pDest->iSDParm.
+ **
+ **     SRT_Except      Remove results from the temporary index pDest->iSDParm.
+@@ -12345,7 +16530,7 @@
+ **                     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->iSDParm. 
++**                     row of result as the key in table pDest->iSDParm.
+ **                     Apply the affinity pDest->affSdst before storing
+ **                     results.  Used to implement "IN (SELECT ...)".
+ **
+@@ -12405,19 +16590,19 @@
+ */
+ struct SelectDest {
+   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 */
++  char *zAffSdst;      /* Affinity used when eDest==SRT_Set */
+   ExprList *pOrderBy;  /* Key columns for SRT_Queue and SRT_DistQueue */
+ };
+ 
+ /*
+-** During code generation of statements that do inserts into AUTOINCREMENT 
++** During code generation of statements that do inserts into AUTOINCREMENT
+ ** tables, the following information is attached to the Table.u.autoInc.p
+ ** pointer of each autoincrement table to record some side information that
+ ** the code generator needs.  We have to keep per-table autoincrement
+-** information in case inserts are down within triggers.  Triggers do not
++** information in case inserts are done within triggers.  Triggers do not
+ ** normally coordinate their activities, but we do need to coordinate the
+ ** loading and saving of autoincrement information.
+ */
+@@ -12436,7 +16621,7 @@
+ #endif
+ 
+ /*
+-** At least one instance of the following structure is created for each 
++** At least one instance of the following structure is created for each
+ ** trigger that may be fired while parsing an INSERT, UPDATE or DELETE
+ ** statement. All such objects are stored in the linked list headed at
+ ** Parse.pTriggerPrg and deleted once statement compilation has been
+@@ -12449,7 +16634,7 @@
+ ** values for both pTrigger and orconf.
+ **
+ ** The TriggerPrg.aColmask[0] variable is set to a mask of old.* columns
+-** accessed (or set to 0 for triggers fired as a result of INSERT 
++** accessed (or set to 0 for triggers fired as a result of INSERT
+ ** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to
+ ** a mask of new.* columns used by the program.
+ */
+@@ -12490,7 +16675,7 @@
+ ** is constant but the second part is reset at the beginning and end of
+ ** each recursion.
+ **
+-** The nTableLock and aTableLock variables are only used if the shared-cache 
++** The nTableLock and aTableLock variables are only used if the shared-cache
+ ** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are
+ ** used to store the set of table-locks required by the statement being
+ ** compiled. Function sqlite3TableLock() is used to add entries to the
+@@ -12509,35 +16694,25 @@
+   u8 mayAbort;         /* True if statement may throw an ABORT exception */
+   u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
+   u8 okConstFactor;    /* OK to factor out constants */
+-  int aTempReg[8];     /* Holding area for temporary registers */
++  u8 disableLookaside; /* Number of times lookaside has been disabled */
++  u8 nColCache;        /* Number of entries in aColCache[] */
+   int nRangeReg;       /* Size of the temporary register block */
+   int iRangeReg;       /* First register in temporary register block */
+   int nErr;            /* Number of errors seen */
+   int nTab;            /* Number of previously allocated VDBE cursors */
+   int nMem;            /* Number of memory cells used so far */
+-  int nSet;            /* Number of sets used so far */
+-  int nOnce;           /* Number of OP_Once instructions so far */
+   int nOpAlloc;        /* Number of slots allocated for Vdbe.aOp[] */
+-  int iFixedOp;        /* Never back out opcodes iFixedOp-1 or earlier */
+-  int ckBase;          /* Base register of data during check constraints */
+-  int iPartIdxTab;     /* Table corresponding to a partial index */
++  int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
++  int iSelfTab;        /* Table for associated with an index on expr, or negative
++                       ** of the base register during check-constraint eval */
+   int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
+   int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
+   int nLabel;          /* Number of labels used */
+   int *aLabel;         /* Space to hold the labels */
+-  struct yColCache {
+-    int iTable;           /* Table cursor number */
+-    i16 iColumn;          /* Table column number */
+-    u8 tempReg;           /* iReg is a temp register that needs to be freed */
+-    int iLevel;           /* Nesting level */
+-    int iReg;             /* Reg with value of this column. 0 means none. */
+-    int lru;              /* Least recently used entry has the smallest value */
+-  } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
+   ExprList *pConstExpr;/* Constant expressions */
+   Token constraintName;/* Name of the constraint currently being parsed */
+   yDbMask writeMask;   /* Start a write transaction on these databases */
+   yDbMask cookieMask;  /* Bitmask of schema verified databases */
+-  int cookieValue[SQLITE_MAX_ATTACHED+2];  /* Values of cookies to verify */
+   int regRowid;        /* Register holding rowid of CREATE TABLE entry */
+   int regRoot;         /* Register holding root page number for new objects */
+   int nMaxArg;         /* Max args passed to user function by sub-program */
+@@ -12550,12 +16725,9 @@
+   TableLock *aTableLock; /* Required table locks for shared-cache mode */
+ #endif
+   AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */
+-
+-  /* Information used while coding trigger programs. */
+   Parse *pToplevel;    /* Parse structure for main program (or NULL) */
+   Table *pTriggerTab;  /* Table triggers are being coded for */
+   int addrCrTab;       /* Address of OP_CreateTable opcode on CREATE TABLE */
+-  int addrSkipPK;      /* Address of instruction to skip PRIMARY KEY index */
+   u32 nQueryLoop;      /* Est number of iterations of a query (10*log2(N)) */
+   u32 oldmask;         /* Mask of old.* columns referenced */
+   u32 newmask;         /* Mask of new.* columns referenced */
+@@ -12563,36 +16735,50 @@
+   u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
+   u8 disableTriggers;  /* True to disable triggers */
+ 
++  /**************************************************************************
++  ** Fields above must be initialized to zero.  The fields that follow,
++  ** down to the beginning of the recursive section, do not need to be
++  ** initialized as they will be set before being used.  The boundary is
++  ** determined by offsetof(Parse,aColCache).
++  **************************************************************************/
++
++  struct yColCache {
++    int iTable;           /* Table cursor number */
++    i16 iColumn;          /* Table column number */
++    u8 tempReg;           /* iReg is a temp register that needs to be freed */
++    int iLevel;           /* Nesting level */
++    int iReg;             /* Reg with value of this column. 0 means none. */
++    int lru;              /* Least recently used entry has the smallest value */
++  } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
++  int aTempReg[8];        /* Holding area for temporary registers */
++  Token sNameToken;       /* Token with unqualified schema object name */
++
+   /************************************************************************
+   ** Above is constant between recursions.  Below is reset before and after
+   ** each recursion.  The boundary between these two regions is determined
+-  ** using offsetof(Parse,nVar) so the nVar field must be the first field
+-  ** in the recursive region.
++  ** using offsetof(Parse,sLastToken) so the sLastToken field must be the
++  ** first field in the recursive region.
+   ************************************************************************/
+ 
+-  int nVar;                 /* Number of '?' variables seen in the SQL so far */
+-  int nzVar;                /* Number of available slots in azVar[] */
++  Token sLastToken;       /* The last token parsed */
++  ynVar nVar;               /* Number of '?' variables seen in the SQL so far */
+   u8 iPkSortOrder;          /* ASC or DESC for INTEGER PRIMARY KEY */
+-  u8 bFreeWith;             /* True if pWith should be freed with parser */
+   u8 explain;               /* True if the EXPLAIN flag is found on the query */
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+   u8 declareVtab;           /* True if inside sqlite3_declare_vtab() */
+   int nVtabLock;            /* Number of virtual tables to lock */
+ #endif
+-  int nAlias;               /* Number of aliased result set columns */
+   int nHeight;              /* Expression tree height of current sub-select */
+ #ifndef SQLITE_OMIT_EXPLAIN
+   int iSelectId;            /* ID of current select for EXPLAIN output */
+   int iNextSelectId;        /* Next available select ID for EXPLAIN output */
+ #endif
+-  char **azVar;             /* Pointers to names of parameters */
++  VList *pVList;            /* Mapping between variable names and numbers */
+   Vdbe *pReprepare;         /* VM being reprepared (sqlite3Reprepare()) */
+   const char *zTail;        /* All SQL text past the last semicolon parsed */
+   Table *pNewTable;         /* A table being constructed by CREATE TABLE */
+   Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
+   const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
+-  Token sNameToken;         /* Token with unqualified schema object name */
+-  Token sLastToken;         /* The last token parsed */
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+   Token sArg;               /* Complete text of a module argument */
+   Table **apVtabLock;       /* Pointer to virtual tables needing locking */
+@@ -12600,9 +16786,18 @@
+   Table *pZombieTab;        /* List of Table objects to delete after code gen */
+   TriggerPrg *pTriggerPrg;  /* Linked list of coded triggers */
+   With *pWith;              /* Current WITH clause, or NULL */
++  With *pWithToFree;        /* Free this WITH object at the end of the parse */
+ };
+ 
+ /*
++** Sizes and pointers of various parts of the Parse object.
++*/
++#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/
++#define PARSE_RECURSE_SZ offsetof(Parse,sLastToken)    /* Recursive part */
++#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
++#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ)  /* Pointer to tail */
++
++/*
+ ** Return true if currently inside an sqlite3_declare_vtab() call.
+ */
+ #ifdef SQLITE_OMIT_VIRTUALTABLE
+@@ -12622,26 +16817,40 @@
+ 
+ /*
+ ** Bitfield flags for P5 value in various opcodes.
++**
++** Value constraints (enforced via assert()):
++**    OPFLAG_LENGTHARG    == SQLITE_FUNC_LENGTH
++**    OPFLAG_TYPEOFARG    == SQLITE_FUNC_TYPEOF
++**    OPFLAG_BULKCSR      == BTREE_BULKLOAD
++**    OPFLAG_SEEKEQ       == BTREE_SEEK_EQ
++**    OPFLAG_FORDELETE    == BTREE_FORDELETE
++**    OPFLAG_SAVEPOSITION == BTREE_SAVEPOSITION
++**    OPFLAG_AUXDELETE    == BTREE_AUXDELETE
+ */
+-#define OPFLAG_NCHANGE       0x01    /* Set to update db->nChange */
++#define OPFLAG_NCHANGE       0x01    /* OP_Insert: Set to update db->nChange */
++                                     /* Also used in P2 (not P5) of OP_Delete */
+ #define OPFLAG_EPHEM         0x01    /* OP_Column: Ephemeral output is ok */
+-#define OPFLAG_LASTROWID     0x02    /* Set to update db->lastRowid */
++#define OPFLAG_LASTROWID     0x20    /* Set to update db->lastRowid */
+ #define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
+ #define OPFLAG_APPEND        0x08    /* This is likely to be an append */
+ #define OPFLAG_USESEEKRESULT 0x10    /* Try to avoid a seek in BtreeInsert() */
++#define OPFLAG_ISNOOP        0x40    /* OP_Delete does pre-update-hook only */
+ #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_SEEKEQ        0x02    /* OP_Open** cursor uses EQ seek only */
+-#define OPFLAG_P2ISREG       0x04    /* P2 to OP_Open** is a register number */
++#define OPFLAG_FORDELETE     0x08    /* OP_Open should use BTREE_FORDELETE */
++#define OPFLAG_P2ISREG       0x10    /* P2 to OP_Open** is a register number */
+ #define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */
++#define OPFLAG_SAVEPOSITION  0x02    /* OP_Delete/Insert: save cursor pos */
++#define OPFLAG_AUXDELETE     0x04    /* OP_Delete: index in a DELETE op */
+ 
+ /*
+  * Each trigger present in the database schema is stored as an instance of
+- * struct Trigger. 
++ * struct Trigger.
+  *
+  * Pointers to instances of struct Trigger are stored in two ways.
+- * 1. In the "trigHash" hash table (part of the sqlite3* that represents the 
++ * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
+  *    database). This allows Trigger structures to be retrieved by name.
+  * 2. All triggers associated with a single table form a linked list, using the
+  *    pNext member of struct Trigger. A pointer to the first element of the
+@@ -12667,7 +16876,7 @@
+ 
+ /*
+ ** A trigger is either a BEFORE or an AFTER trigger.  The following constants
+-** determine which. 
++** determine which.
+ **
+ ** If there are multiple triggers, you might of some BEFORE and some AFTER.
+ ** In that cases, the constants below can be ORed together.
+@@ -12677,15 +16886,15 @@
+ 
+ /*
+  * An instance of struct TriggerStep is used to store a single SQL statement
+- * that is a part of a trigger-program. 
++ * that is a part of a trigger-program.
+  *
+  * Instances of struct TriggerStep are stored in a singly linked list (linked
+- * using the "pNext" member) referenced by the "step_list" member of the 
++ * using the "pNext" member) referenced by the "step_list" member of the
+  * associated struct Trigger instance. The first element of the linked list is
+  * the first step of the trigger-program.
+- * 
++ *
+  * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
+- * "SELECT" statement. The meanings of the other members is determined by the 
++ * "SELECT" statement. The meanings of the other members is determined by the
+  * value of "op" as follows:
+  *
+  * (op == TK_INSERT)
+@@ -12695,7 +16904,7 @@
+  * zTarget   -> Dequoted name of the table to insert into.
+  * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
+  *              this stores values to be inserted. Otherwise NULL.
+- * pIdList   -> If this is an INSERT INTO ... (<column-names>) VALUES ... 
++ * pIdList   -> If this is an INSERT INTO ... (<column-names>) VALUES ...
+  *              statement, then this stores the column-names to be
+  *              inserted into.
+  *
+@@ -12703,7 +16912,7 @@
+  * zTarget   -> Dequoted name of the table to delete from.
+  * pWhere    -> The WHERE clause of the DELETE statement if one is specified.
+  *              Otherwise NULL.
+- * 
++ *
+  * (op == TK_UPDATE)
+  * zTarget   -> Dequoted name of the table to update.
+  * pWhere    -> The WHERE clause of the UPDATE statement if one is specified.
+@@ -12711,7 +16920,7 @@
+  * pExprList -> A list of the columns to update and the expressions to update
+  *              them to. See sqlite3Update() documentation of "pChanges"
+  *              argument.
+- * 
++ *
+  */
+ struct TriggerStep {
+   u8 op;               /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
+@@ -12729,7 +16938,7 @@
+ /*
+ ** The following structure contains information used by the sqliteFix...
+ ** routines as they walk the parse tree to make database references
+-** explicit.  
++** explicit.
+ */
+ typedef struct DbFixer DbFixer;
+ struct DbFixer {
+@@ -12749,13 +16958,20 @@
+   sqlite3 *db;         /* Optional database for lookaside.  Can be NULL */
+   char *zBase;         /* A base allocation.  Not from malloc. */
+   char *zText;         /* The string collected so far */
+-  int  nChar;          /* Length of the string so far */
+-  int  nAlloc;         /* Amount of space allocated in zText */
+-  int  mxAlloc;        /* Maximum allowed allocation.  0 for no malloc usage */
++  u32  nChar;          /* Length of the string so far */
++  u32  nAlloc;         /* Amount of space allocated in zText */
++  u32  mxAlloc;        /* Maximum allowed allocation.  0 for no malloc usage */
+   u8   accError;       /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
++  u8   printfFlags;    /* SQLITE_PRINTF flags below */
+ };
+ #define STRACCUM_NOMEM   1
+ #define STRACCUM_TOOBIG  2
++#define SQLITE_PRINTF_INTERNAL 0x01  /* Internal-use-only converters allowed */
++#define SQLITE_PRINTF_SQLFUNC  0x02  /* SQL function arguments to VXPrintf */
++#define SQLITE_PRINTF_MALLOCED 0x04  /* True if xText is allocated space */
++
++#define isMalloced(X)  (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
++
+ 
+ /*
+ ** A pointer to this structure is used to communicate information
+@@ -12783,6 +16999,7 @@
+   int neverCorrupt;                 /* Database is always well-formed */
+   int szLookaside;                  /* Default lookaside buffer size */
+   int nLookaside;                   /* Default lookaside buffer count */
++  int nStmtSpill;                   /* Stmt-journal spill-to-disk threshold */
+   sqlite3_mem_methods m;            /* Low-level memory allocation interface */
+   sqlite3_mutex_methods mutex;      /* Low-level mutex interface */
+   sqlite3_pcache_methods2 pcache2;  /* Low-level page-cache interface */
+@@ -12822,10 +17039,11 @@
+   void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx);  /* Callback */
+   void *pVdbeBranchArg;                                     /* 1st argument */
+ #endif
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
++#ifndef SQLITE_UNTESTABLE
+   int (*xTestCallback)(int);        /* Invoked by sqlite3FaultSim() */
+ #endif
+   int bLocaltimeFault;              /* True to fail localtime() calls */
++  int iOnceResetThreshold;          /* When to reset OP_Once counters */
+ };
+ 
+ /*
+@@ -12850,18 +17068,24 @@
+ ** Context pointer passed down through the tree-walk.
+ */
+ struct Walker {
++  Parse *pParse;                            /* Parser context.  */
+   int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
+   int (*xSelectCallback)(Walker*,Select*);  /* Callback for SELECTs */
+   void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
+-  Parse *pParse;                            /* Parser context.  */
+   int walkerDepth;                          /* Number of subqueries */
+   u8 eCode;                                 /* A small processing code */
+   union {                                   /* Extra data for callback */
+-    NameContext *pNC;                          /* Naming context */
+-    int n;                                     /* A counter */
+-    int iCur;                                  /* A cursor number */
+-    SrcList *pSrcList;                         /* FROM clause */
+-    struct SrcCount *pSrcCount;                /* Counting column references */
++    NameContext *pNC;                         /* Naming context */
++    int n;                                    /* A counter */
++    int iCur;                                 /* A cursor number */
++    SrcList *pSrcList;                        /* FROM clause */
++    struct SrcCount *pSrcCount;               /* Counting column references */
++    struct CCurHint *pCCurHint;               /* Used by codeCursorHint() */
++    int *aiCol;                               /* array of column indexes */
++    struct IdxCover *pIdxCover;               /* Check for index coverage */
++    struct IdxExprTrans *pIdxTrans;           /* Convert indexed expr to column */
++    ExprList *pGroupBy;                       /* GROUP BY clause */
++    struct HavingToWhereCtx *pHavingCtx;      /* HAVING to WHERE clause ctx */
+   } u;
+ };
+ 
+@@ -12871,6 +17095,11 @@
+ SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*);
+ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*);
+ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
++SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*);
++SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*);
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*);
++#endif
+ 
+ /*
+ ** Return code from the parse-tree walking primitives and their
+@@ -12891,7 +17120,7 @@
+     char *zName;                    /* Name of this CTE */
+     ExprList *pCols;                /* List of explicit column names, or NULL */
+     Select *pSelect;                /* The definition of this CTE */
+-    const char *zErr;               /* Error message for circular references */
++    const char *zCteErr;            /* Error message for circular references */
+   } a[1];
+ };
+ 
+@@ -12929,7 +17158,26 @@
+ #define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__)
+ #define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__)
+ #define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__)
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE   int sqlite3NomemError(int);
++SQLITE_PRIVATE   int sqlite3IoerrnomemError(int);
++SQLITE_PRIVATE   int sqlite3CorruptPgnoError(int,Pgno);
++# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__)
++# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__)
++# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptPgnoError(__LINE__,(P))
++#else
++# define SQLITE_NOMEM_BKPT SQLITE_NOMEM
++# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM
++# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptError(__LINE__)
++#endif
+ 
++/*
++** FTS3 and FTS4 both require virtual table support
++*/
++#if defined(SQLITE_OMIT_VIRTUALTABLE)
++# undef SQLITE_ENABLE_FTS3
++# undef SQLITE_ENABLE_FTS4
++#endif
+ 
+ /*
+ ** FTS4 is really an extension for FTS3.  It is enabled using the
+@@ -12962,6 +17210,7 @@
+ # define sqlite3Isdigit(x)   (sqlite3CtypeMap[(unsigned char)(x)]&0x04)
+ # define sqlite3Isxdigit(x)  (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
+ # define sqlite3Tolower(x)   (sqlite3UpperToLower[(unsigned char)(x)])
++# define sqlite3Isquote(x)   (sqlite3CtypeMap[(unsigned char)(x)]&0x80)
+ #else
+ # define sqlite3Toupper(x)   toupper((unsigned char)(x))
+ # define sqlite3Isspace(x)   isspace((unsigned char)(x))
+@@ -12970,14 +17219,18 @@
+ # define sqlite3Isdigit(x)   isdigit((unsigned char)(x))
+ # define sqlite3Isxdigit(x)  isxdigit((unsigned char)(x))
+ # define sqlite3Tolower(x)   tolower((unsigned char)(x))
++# define sqlite3Isquote(x)   ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`')
+ #endif
++#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+ SQLITE_PRIVATE int sqlite3IsIdChar(u8);
++#endif
+ 
+ /*
+ ** Internal function prototypes
+ */
+-#define sqlite3StrICmp sqlite3_stricmp
++SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*);
+ SQLITE_PRIVATE int sqlite3Strlen30(const char*);
++SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*);
+ #define sqlite3StrNICmp sqlite3_strnicmp
+ 
+ SQLITE_PRIVATE int sqlite3MallocInit(void);
+@@ -12986,12 +17239,14 @@
+ SQLITE_PRIVATE void *sqlite3MallocZero(u64);
+ SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, u64);
+ SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, u64);
++SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3*, u64);
+ SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*);
+ SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64);
+ SQLITE_PRIVATE void *sqlite3Realloc(void*, u64);
+ SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
+ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64);
+ SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*);
++SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*);
+ SQLITE_PRIVATE int sqlite3MallocSize(void*);
+ SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*);
+ SQLITE_PRIVATE void *sqlite3ScratchMalloc(int);
+@@ -12999,7 +17254,9 @@
+ SQLITE_PRIVATE void *sqlite3PageMalloc(int);
+ SQLITE_PRIVATE void sqlite3PageFree(void*);
+ SQLITE_PRIVATE void sqlite3MemSetDefault(void);
++#ifndef SQLITE_UNTESTABLE
+ SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
++#endif
+ SQLITE_PRIVATE int sqlite3HeapNearlyFull(void);
+ 
+ /*
+@@ -13013,18 +17270,22 @@
+ #ifdef SQLITE_USE_ALLOCA
+ # define sqlite3StackAllocRaw(D,N)   alloca(N)
+ # define sqlite3StackAllocZero(D,N)  memset(alloca(N), 0, N)
+-# define sqlite3StackFree(D,P)       
++# define sqlite3StackFree(D,P)
+ #else
+ # define sqlite3StackAllocRaw(D,N)   sqlite3DbMallocRaw(D,N)
+ # define sqlite3StackAllocZero(D,N)  sqlite3DbMallocZero(D,N)
+ # define sqlite3StackFree(D,P)       sqlite3DbFree(D,P)
+ #endif
+ 
+-#ifdef SQLITE_ENABLE_MEMSYS3
+-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
+-#endif
++/* Do not allow both MEMSYS5 and MEMSYS3 to be defined together.  If they
++** are, disable MEMSYS3
++*/
+ #ifdef SQLITE_ENABLE_MEMSYS5
+ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
++#undef SQLITE_ENABLE_MEMSYS3
++#endif
++#ifdef SQLITE_ENABLE_MEMSYS3
++SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
+ #endif
+ 
+ 
+@@ -13035,11 +17296,16 @@
+ SQLITE_PRIVATE   int sqlite3MutexInit(void);
+ SQLITE_PRIVATE   int sqlite3MutexEnd(void);
+ #endif
++#if !defined(SQLITE_MUTEX_OMIT) && !defined(SQLITE_MUTEX_NOOP)
++SQLITE_PRIVATE   void sqlite3MemoryBarrier(void);
++#else
++# define sqlite3MemoryBarrier()
++#endif
+ 
+ SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int);
+ SQLITE_PRIVATE void sqlite3StatusUp(int, int);
+ SQLITE_PRIVATE void sqlite3StatusDown(int, int);
+-SQLITE_PRIVATE void sqlite3StatusSet(int, int);
++SQLITE_PRIVATE void sqlite3StatusHighwater(int, int);
+ 
+ /* Access to mutexes used by sqlite3_status() */
+ SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void);
+@@ -13061,13 +17327,10 @@
+   sqlite3_value **apArg;   /* The argument values */
+ };
+ 
+-#define SQLITE_PRINTF_INTERNAL 0x01
+-#define SQLITE_PRINTF_SQLFUNC  0x02
+-SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list);
+-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
++SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, const char*, va_list);
++SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, const char*, ...);
+ SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
+ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
+-SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
+ #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
+ SQLITE_PRIVATE   void sqlite3DebugPrintf(const char*, ...);
+ #endif
+@@ -13076,19 +17339,18 @@
+ #endif
+ 
+ #if defined(SQLITE_DEBUG)
+-SQLITE_PRIVATE   TreeView *sqlite3TreeViewPush(TreeView*,u8);
+-SQLITE_PRIVATE   void sqlite3TreeViewPop(TreeView*);
+-SQLITE_PRIVATE   void sqlite3TreeViewLine(TreeView*, const char*, ...);
+-SQLITE_PRIVATE   void sqlite3TreeViewItem(TreeView*, const char*, u8);
+ SQLITE_PRIVATE   void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
++SQLITE_PRIVATE   void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
+ SQLITE_PRIVATE   void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
+ SQLITE_PRIVATE   void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
++SQLITE_PRIVATE   void sqlite3TreeViewWith(TreeView*, const With*, u8);
+ #endif
+ 
+ 
+-SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
++SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
+ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
+-SQLITE_PRIVATE int sqlite3Dequote(char*);
++SQLITE_PRIVATE void sqlite3Dequote(char*);
++SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*);
+ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
+ SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
+ SQLITE_PRIVATE void sqlite3FinishCoding(Parse*);
+@@ -13097,15 +17359,21 @@
+ SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int);
+ SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int);
+ SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*);
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int);
++#endif
+ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
+ SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
+ SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
+-SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
++SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
++SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
+ SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
+ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
+-SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
++SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
+ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
+ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
++SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
++SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
+ SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
+ SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
+ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
+@@ -13113,30 +17381,38 @@
+ SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
+ SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
+ SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName);
++#endif
+ SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*);
+ SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int);
+ SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*);
+-SQLITE_PRIVATE void sqlite3BeginParse(Parse*,int);
+ SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*);
++SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*);
++SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
++SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*);
+ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*);
+ SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int);
+ SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*);
+ SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index*, i16);
+ SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
+-SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*);
++#if SQLITE_ENABLE_HIDDEN_COLUMNS
++SQLITE_PRIVATE   void sqlite3ColumnPropertiesFromName(Table*, Column*);
++#else
++# define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
++#endif
++SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*,Token*);
+ SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int);
+ SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
+ SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
+-SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*);
+ SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*);
+ SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
+ SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
+ SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
+                     sqlite3_vfs**,char**,char **);
+ SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
+-SQLITE_PRIVATE int sqlite3CodeOnce(Parse *);
+ 
+-#ifdef SQLITE_OMIT_BUILTIN_TEST
++#ifdef SQLITE_UNTESTABLE
+ # define sqlite3FaultSim(X) SQLITE_OK
+ #else
+ SQLITE_PRIVATE   int sqlite3FaultSim(int);
+@@ -13144,11 +17420,14 @@
+ 
+ SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32);
+ SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32);
++SQLITE_PRIVATE int sqlite3BitvecTestNotNull(Bitvec*, u32);
+ SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32);
+ SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*);
+ SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*);
+ SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*);
++#ifndef SQLITE_UNTESTABLE
+ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
++#endif
+ 
+ SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
+ SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*);
+@@ -13156,7 +17435,7 @@
+ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64);
+ SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*);
+ 
+-SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
++SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int);
+ 
+ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
+ SQLITE_PRIVATE   int sqlite3ViewGetColumnNames(Parse*,Table*);
+@@ -13186,18 +17465,19 @@
+ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
+                                       Token*, Select*, Expr*, IdList*);
+ SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
++SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
+ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
+ SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
+ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
+ SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
+ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
+ SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
+-SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
+-                          Expr*, int, int);
++SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
++                          Expr*, int, int, u8);
+ SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
+ SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
+ SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
+-                         Expr*,ExprList*,u16,Expr*,Expr*);
++                         Expr*,ExprList*,u32,Expr*,Expr*);
+ SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
+ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
+ SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
+@@ -13209,14 +17489,20 @@
+ SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
+ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
+ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
+-SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo*);
++SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
++SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*);
++#define ONEPASS_OFF      0        /* Use of ONEPASS not allowed */
++#define ONEPASS_SINGLE   1        /* ONEPASS valid for a single row update */
++#define ONEPASS_MULTI    2        /* ONEPASS is valid for multiple rows */
++SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
+ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
++SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int);
+ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
+ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
+ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int);
+@@ -13226,59 +17512,78 @@
+ SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*);
+ SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
+ SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int);
++SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int);
+ SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
+-SQLITE_PRIVATE void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
++SQLITE_PRIVATE int sqlite3ExprCodeAtInit(Parse*, Expr*, int);
+ SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
+ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int);
+ SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse*, Expr*, int);
+-SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, u8);
++SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8);
+ #define SQLITE_ECEL_DUP      0x01  /* Deep, not shallow copies */
+ #define SQLITE_ECEL_FACTOR   0x02  /* Factor out constant terms */
++#define SQLITE_ECEL_REF      0x04  /* Use ExprList.u.x.iOrderByCol */
++#define SQLITE_ECEL_OMITREF  0x08  /* Omit if ExprList.u.x.iOrderByCol */
+ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
+ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
++SQLITE_PRIVATE void sqlite3ExprIfFalseDup(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 *);
++#define LOCATE_VIEW    0x01
++#define LOCATE_NOERR   0x02
++SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
++SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,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*);
+-SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
+-SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
++SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*);
++SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int);
+ SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
+-SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int);
++SQLITE_PRIVATE int sqlite3ExprCompare(Parse*,Expr*, Expr*, int);
++SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*, Expr*, int);
+ SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int);
+-SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
++SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int);
+ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
+ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
++SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
+ SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
+ SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
++#ifndef SQLITE_UNTESTABLE
+ SQLITE_PRIVATE void sqlite3PrngSaveState(void);
+ SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
++#endif
+ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*,int);
+ SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int);
+ SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
+ SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int);
+-SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*);
+-SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
++SQLITE_PRIVATE void sqlite3EndTransaction(Parse*,int);
+ 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*, u8);
++SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
+ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int);
++#ifdef SQLITE_ENABLE_CURSOR_HINTS
++SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*);
++#endif
+ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
+ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
+ SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
+ SQLITE_PRIVATE int sqlite3IsRowid(const char*);
+-SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
+-SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
++SQLITE_PRIVATE void sqlite3GenerateRowDelete(
++    Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
++SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
+ SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
+ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int);
+ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
+-                                     u8,u8,int,int*);
++                                     u8,u8,int,int*,int*);
++#ifdef SQLITE_ENABLE_NULL_TRIM
++SQLITE_PRIVATE   void sqlite3SetMakeRecordP5(Vdbe*,Table*);
++#else
++# define sqlite3SetMakeRecordP5(A,B)
++#endif
+ SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
+-SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*);
++SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*);
+ SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
+ SQLITE_PRIVATE void sqlite3MultiWrite(Parse*);
+ SQLITE_PRIVATE void sqlite3MayAbort(Parse*);
+@@ -13295,11 +17600,11 @@
+ #else
+ # define sqlite3SelectSetName(A,B)
+ #endif
+-SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
+-SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
+-SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
++SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
++SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
++SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
+ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
+-SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void);
++SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
+ SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*);
+ SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
+ SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
+@@ -13330,6 +17635,7 @@
+ SQLITE_PRIVATE   void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
+ SQLITE_PRIVATE   u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int);
+ # define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p))
++# define sqlite3IsToplevel(p) ((p)->pToplevel==0)
+ #else
+ # define sqlite3TriggersExist(B,C,D,E,F) 0
+ # define sqlite3DeleteTrigger(A,B)
+@@ -13339,6 +17645,7 @@
+ # define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F)
+ # define sqlite3TriggerList(X, Y) 0
+ # define sqlite3ParseToplevel(p) p
++# define sqlite3IsToplevel(p) 1
+ # define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0
+ #endif
+ 
+@@ -13368,7 +17675,9 @@
+ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8);
+ SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*);
+ SQLITE_PRIVATE int sqlite3Atoi(const char*);
++#ifndef SQLITE_OMIT_UTF16
+ SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar);
++#endif
+ SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
+ SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
+ SQLITE_PRIVATE LogEst sqlite3LogEst(u64);
+@@ -13376,7 +17685,14 @@
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+ SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double);
+ #endif
++#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
++    defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
++    defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
+ SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
++#endif
++SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
++SQLITE_PRIVATE const char *sqlite3VListNumToName(VList*,int);
++SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int);
+ 
+ /*
+ ** Routines to read and write variable-length integers.  These used to
+@@ -13402,15 +17718,17 @@
+ #define putVarint    sqlite3PutVarint
+ 
+ 
+-SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
++SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
+ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int);
+ SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2);
+ SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
++SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table*,int);
+ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr);
+ SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8);
+ SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*);
+ SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
+ SQLITE_PRIVATE void sqlite3Error(sqlite3*,int);
++SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int);
+ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
+ SQLITE_PRIVATE u8 sqlite3HexToInt(int h);
+ SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
+@@ -13443,21 +17761,24 @@
+ 
+ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
+ SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
+-SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, 
++SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
+                         void(*)(void*));
+ SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
+ SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
+ SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
++#ifndef SQLITE_OMIT_UTF16
+ SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
++#endif
+ SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
+ SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
+ #ifndef SQLITE_AMALGAMATION
+ SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[];
++SQLITE_PRIVATE const char sqlite3StrBINARY[];
+ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[];
+ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[];
+ SQLITE_PRIVATE const Token sqlite3IntTokens[];
+ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config;
+-SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
++SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions;
+ #ifndef SQLITE_OMIT_WSD
+ SQLITE_PRIVATE int sqlite3PendingByte;
+ #endif
+@@ -13469,10 +17790,12 @@
+ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
+ SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
+ SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
+-SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
++SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int);
+ SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
++SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
+ SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
+ SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
++SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*);
+ SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
+ SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
+ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
+@@ -13490,7 +17813,6 @@
+ SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*);
+ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int);
+ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
+-SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
+ SQLITE_PRIVATE void sqlite3SchemaClear(void *);
+ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
+ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
+@@ -13501,11 +17823,13 @@
+ #ifdef SQLITE_DEBUG
+ SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*);
+ #endif
+-SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, 
++SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
+   void (*)(sqlite3_context*,int,sqlite3_value **),
+   void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
+   FuncDestructor *pDestructor
+ );
++SQLITE_PRIVATE void sqlite3OomFault(sqlite3*);
++SQLITE_PRIVATE void sqlite3OomClear(sqlite3*);
+ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
+ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
+ 
+@@ -13521,19 +17845,29 @@
+ SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
+ SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
+ 
++#ifndef SQLITE_OMIT_SUBQUERY
++SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse*, Expr*);
++#else
++# define sqlite3ExprCheckIN(x,y) SQLITE_OK
++#endif
++
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void);
+-SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*);
++SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(
++    Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*);
+ SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**);
+ SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*);
+ SQLITE_PRIVATE int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**);
++SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3*, Index*, int);
+ #endif
+ 
+ /*
+ ** The interface to the LEMON-generated parser
+ */
+-SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64));
+-SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
++#ifndef SQLITE_AMALGAMATION
++SQLITE_PRIVATE   void *sqlite3ParserAlloc(void*(*)(u64));
++SQLITE_PRIVATE   void sqlite3ParserFree(void*, void(*)(void*));
++#endif
+ SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);
+ #ifdef YYTRACKMAXSTACKDEPTH
+ SQLITE_PRIVATE   int sqlite3ParserStackPeak(void*);
+@@ -13562,7 +17896,7 @@
+ #  define sqlite3VtabRollback(X)
+ #  define sqlite3VtabCommit(X)
+ #  define sqlite3VtabInSync(db) 0
+-#  define sqlite3VtabLock(X) 
++#  define sqlite3VtabLock(X)
+ #  define sqlite3VtabUnlock(X)
+ #  define sqlite3VtabUnlockList(X)
+ #  define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
+@@ -13579,8 +17913,17 @@
+ SQLITE_PRIVATE    int sqlite3VtabSavepoint(sqlite3 *, int, int);
+ SQLITE_PRIVATE    void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
+ SQLITE_PRIVATE    VTable *sqlite3GetVTable(sqlite3*, Table*);
++SQLITE_PRIVATE    Module *sqlite3VtabCreateModule(
++     sqlite3*,
++     const char*,
++     const sqlite3_module*,
++     void*,
++     void(*)(void*)
++   );
+ #  define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
+ #endif
++SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
++SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
+ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
+ SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
+ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
+@@ -13618,7 +17961,7 @@
+ ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
+ ** key functionality is available. If OMIT_TRIGGER is defined but
+ ** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In
+-** this case foreign keys are parsed, but no other functionality is 
++** this case foreign keys are parsed, but no other functionality is
+ ** provided (enforcement of FK constraints requires the triggers sub-system).
+ */
+ #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+@@ -13634,6 +17977,7 @@
+   #define sqlite3FkDropTable(a,b,c)
+   #define sqlite3FkOldmask(a,b)         0
+   #define sqlite3FkRequired(a,b,c,d)    0
++  #define sqlite3FkReferences(a)        0
+ #endif
+ #ifndef SQLITE_OMIT_FOREIGN_KEY
+ SQLITE_PRIVATE   void sqlite3FkDelete(sqlite3 *, Table*);
+@@ -13652,10 +17996,10 @@
+ 
+ /*
+ ** The interface to the code in fault.c used for identifying "benign"
+-** malloc failures. This is only present if SQLITE_OMIT_BUILTIN_TEST
++** malloc failures. This is only present if SQLITE_UNTESTABLE
+ ** is not defined.
+ */
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
++#ifndef SQLITE_UNTESTABLE
+ SQLITE_PRIVATE   void sqlite3BeginBenignMalloc(void);
+ SQLITE_PRIVATE   void sqlite3EndBenignMalloc(void);
+ #else
+@@ -13677,21 +18021,16 @@
+ #define IN_INDEX_NOOP_OK     0x0001  /* OK to return IN_INDEX_NOOP */
+ #define IN_INDEX_MEMBERSHIP  0x0002  /* IN operator used for membership test */
+ #define IN_INDEX_LOOP        0x0004  /* IN operator used as a loop */
+-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*);
++SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*);
+ 
++SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
++SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
+ #ifdef SQLITE_ENABLE_ATOMIC_WRITE
+-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 int sqlite3JournalIsInMemory(sqlite3_file *p);
+ SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *);
+-SQLITE_PRIVATE int sqlite3MemJournalSize(void);
+-SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *);
+ 
+ SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
+ #if SQLITE_MAX_EXPR_DEPTH>0
+@@ -13722,7 +18061,7 @@
+ /*
+ ** If the SQLITE_ENABLE IOTRACE exists then the global variable
+ ** sqlite3IoTrace is a pointer to a printf-like routine used to
+-** print I/O tracing messages. 
++** print I/O tracing messages.
+ */
+ #ifdef SQLITE_ENABLE_IOTRACE
+ # define IOTRACE(A)  if( sqlite3IoTrace ){ sqlite3IoTrace A; }
+@@ -13756,7 +18095,7 @@
+ ** that allocations that might have been satisfied by lookaside are not
+ ** passed back to non-lookaside free() routines.  Asserts such as the
+ ** example above are placed on the non-lookaside free() routines to verify
+-** this constraint. 
++** this constraint.
+ **
+ ** All of this is no-op for a production build.  It only comes into
+ ** play when the SQLITE_MEMDEBUG compile-time option is used.
+@@ -13783,9 +18122,3971 @@
+ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);
+ #endif
+ 
+-#endif /* _SQLITEINT_H_ */
++#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
++SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*);
++#endif
++
++SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr);
++SQLITE_PRIVATE int sqlite3ExprIsVector(Expr *pExpr);
++SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr*, int);
++SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(Parse*,Expr*,int);
++SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse*, Expr*);
++
++#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
++SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt);
++#endif
++
++#endif /* SQLITEINT_H */
+ 
+ /************** End of sqliteInt.h *******************************************/
++/************** Begin file crypto.c ******************************************/
++/* 
++** SQLCipher
++** http://sqlcipher.net
++** 
++** Copyright (c) 2008 - 2013, ZETETIC LLC
++** All rights reserved.
++** 
++** Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are met:
++**     * Redistributions of source code must retain the above copyright
++**       notice, this list of conditions and the following disclaimer.
++**     * Redistributions in binary form must reproduce the above copyright
++**       notice, this list of conditions and the following disclaimer in the
++**       documentation and/or other materials provided with the distribution.
++**     * Neither the name of the ZETETIC LLC nor the
++**       names of its contributors may be used to endorse or promote products
++**       derived from this software without specific prior written permission.
++** 
++** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
++** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
++** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++**  
++*/
++/* BEGIN SQLCIPHER */
++#ifdef SQLITE_HAS_CODEC
++
++/* #include <assert.h> */
++/* #include "sqliteInt.h" */
++/************** Include btreeInt.h in the middle of crypto.c *****************/
++/************** Begin file btreeInt.h ****************************************/
++/*
++** 2004 April 6
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This file implements an external (disk-based) database using BTrees.
++** For a detailed discussion of BTrees, refer to
++**
++**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
++**     "Sorting And Searching", pages 473-480. Addison-Wesley
++**     Publishing Company, Reading, Massachusetts.
++**
++** The basic idea is that each page of the file contains N database
++** entries and N+1 pointers to subpages.
++**
++**   ----------------------------------------------------------------
++**   |  Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) |
++**   ----------------------------------------------------------------
++**
++** All of the keys on the page that Ptr(0) points to have values less
++** than Key(0).  All of the keys on page Ptr(1) and its subpages have
++** values greater than Key(0) and less than Key(1).  All of the keys
++** on Ptr(N) and its subpages have values greater than Key(N-1).  And
++** so forth.
++**
++** Finding a particular key requires reading O(log(M)) pages from the 
++** disk where M is the number of entries in the tree.
++**
++** In this implementation, a single file can hold one or more separate 
++** BTrees.  Each BTree is identified by the index of its root page.  The
++** key and data for any entry are combined to form the "payload".  A
++** fixed amount of payload can be carried directly on the database
++** page.  If the payload is larger than the preset amount then surplus
++** bytes are stored on overflow pages.  The payload for an entry
++** and the preceding pointer are combined to form a "Cell".  Each 
++** page has a small header which contains the Ptr(N) pointer and other
++** information such as the size of key and data.
++**
++** FORMAT DETAILS
++**
++** The file is divided into pages.  The first page is called page 1,
++** the second is page 2, and so forth.  A page number of zero indicates
++** "no such page".  The page size can be any power of 2 between 512 and 65536.
++** Each page can be either a btree page, a freelist page, an overflow
++** page, or a pointer-map page.
++**
++** The first page is always a btree page.  The first 100 bytes of the first
++** page contain a special header (the "file header") that describes the file.
++** The format of the file header is as follows:
++**
++**   OFFSET   SIZE    DESCRIPTION
++**      0      16     Header string: "SQLite format 3\000"
++**     16       2     Page size in bytes.  (1 means 65536)
++**     18       1     File format write version
++**     19       1     File format read version
++**     20       1     Bytes of unused space at the end of each page
++**     21       1     Max embedded payload fraction (must be 64)
++**     22       1     Min embedded payload fraction (must be 32)
++**     23       1     Min leaf payload fraction (must be 32)
++**     24       4     File change counter
++**     28       4     Reserved for future use
++**     32       4     First freelist page
++**     36       4     Number of freelist pages in the file
++**     40      60     15 4-byte meta values passed to higher layers
++**
++**     40       4     Schema cookie
++**     44       4     File format of schema layer
++**     48       4     Size of page cache
++**     52       4     Largest root-page (auto/incr_vacuum)
++**     56       4     1=UTF-8 2=UTF16le 3=UTF16be
++**     60       4     User version
++**     64       4     Incremental vacuum mode
++**     68       4     Application-ID
++**     72      20     unused
++**     92       4     The version-valid-for number
++**     96       4     SQLITE_VERSION_NUMBER
++**
++** All of the integer values are big-endian (most significant byte first).
++**
++** The file change counter is incremented when the database is changed
++** This counter allows other processes to know when the file has changed
++** and thus when they need to flush their cache.
++**
++** The max embedded payload fraction is the amount of the total usable
++** space in a page that can be consumed by a single cell for standard
++** B-tree (non-LEAFDATA) tables.  A value of 255 means 100%.  The default
++** is to limit the maximum cell size so that at least 4 cells will fit
++** on one page.  Thus the default max embedded payload fraction is 64.
++**
++** If the payload for a cell is larger than the max payload, then extra
++** payload is spilled to overflow pages.  Once an overflow page is allocated,
++** as many bytes as possible are moved into the overflow pages without letting
++** the cell size drop below the min embedded payload fraction.
++**
++** The min leaf payload fraction is like the min embedded payload fraction
++** except that it applies to leaf nodes in a LEAFDATA tree.  The maximum
++** payload fraction for a LEAFDATA tree is always 100% (or 255) and it
++** not specified in the header.
++**
++** Each btree pages is divided into three sections:  The header, the
++** cell pointer array, and the cell content area.  Page 1 also has a 100-byte
++** file header that occurs before the page header.
++**
++**      |----------------|
++**      | file header    |   100 bytes.  Page 1 only.
++**      |----------------|
++**      | page header    |   8 bytes for leaves.  12 bytes for interior nodes
++**      |----------------|
++**      | cell pointer   |   |  2 bytes per cell.  Sorted order.
++**      | array          |   |  Grows downward
++**      |                |   v
++**      |----------------|
++**      | unallocated    |
++**      | space          |
++**      |----------------|   ^  Grows upwards
++**      | cell content   |   |  Arbitrary order interspersed with freeblocks.
++**      | area           |   |  and free space fragments.
++**      |----------------|
++**
++** The page headers looks like this:
++**
++**   OFFSET   SIZE     DESCRIPTION
++**      0       1      Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf
++**      1       2      byte offset to the first freeblock
++**      3       2      number of cells on this page
++**      5       2      first byte of the cell content area
++**      7       1      number of fragmented free bytes
++**      8       4      Right child (the Ptr(N) value).  Omitted on leaves.
++**
++** The flags define the format of this btree page.  The leaf flag means that
++** this page has no children.  The zerodata flag means that this page carries
++** only keys and no data.  The intkey flag means that the key is an integer
++** which is stored in the key size entry of the cell header rather than in
++** the payload area.
++**
++** The cell pointer array begins on the first byte after the page header.
++** The cell pointer array contains zero or more 2-byte numbers which are
++** offsets from the beginning of the page to the cell content in the cell
++** content area.  The cell pointers occur in sorted order.  The system strives
++** to keep free space after the last cell pointer so that new cells can
++** be easily added without having to defragment the page.
++**
++** Cell content is stored at the very end of the page and grows toward the
++** beginning of the page.
++**
++** Unused space within the cell content area is collected into a linked list of
++** freeblocks.  Each freeblock is at least 4 bytes in size.  The byte offset
++** to the first freeblock is given in the header.  Freeblocks occur in
++** increasing order.  Because a freeblock must be at least 4 bytes in size,
++** any group of 3 or fewer unused bytes in the cell content area cannot
++** exist on the freeblock chain.  A group of 3 or fewer free bytes is called
++** a fragment.  The total number of bytes in all fragments is recorded.
++** in the page header at offset 7.
++**
++**    SIZE    DESCRIPTION
++**      2     Byte offset of the next freeblock
++**      2     Bytes in this freeblock
++**
++** Cells are of variable length.  Cells are stored in the cell content area at
++** the end of the page.  Pointers to the cells are in the cell pointer array
++** that immediately follows the page header.  Cells is not necessarily
++** contiguous or in order, but cell pointers are contiguous and in order.
++**
++** Cell content makes use of variable length integers.  A variable
++** length integer is 1 to 9 bytes where the lower 7 bits of each 
++** byte are used.  The integer consists of all bytes that have bit 8 set and
++** the first byte with bit 8 clear.  The most significant byte of the integer
++** appears first.  A variable-length integer may not be more than 9 bytes long.
++** As a special case, all 8 bytes of the 9th byte are used as data.  This
++** allows a 64-bit integer to be encoded in 9 bytes.
++**
++**    0x00                      becomes  0x00000000
++**    0x7f                      becomes  0x0000007f
++**    0x81 0x00                 becomes  0x00000080
++**    0x82 0x00                 becomes  0x00000100
++**    0x80 0x7f                 becomes  0x0000007f
++**    0x8a 0x91 0xd1 0xac 0x78  becomes  0x12345678
++**    0x81 0x81 0x81 0x81 0x01  becomes  0x10204081
++**
++** Variable length integers are used for rowids and to hold the number of
++** bytes of key and data in a btree cell.
++**
++** The content of a cell looks like this:
++**
++**    SIZE    DESCRIPTION
++**      4     Page number of the left child. Omitted if leaf flag is set.
++**     var    Number of bytes of data. Omitted if the zerodata flag is set.
++**     var    Number of bytes of key. Or the key itself if intkey flag is set.
++**      *     Payload
++**      4     First page of the overflow chain.  Omitted if no overflow
++**
++** Overflow pages form a linked list.  Each page except the last is completely
++** filled with data (pagesize - 4 bytes).  The last page can have as little
++** as 1 byte of data.
++**
++**    SIZE    DESCRIPTION
++**      4     Page number of next overflow page
++**      *     Data
++**
++** Freelist pages come in two subtypes: trunk pages and leaf pages.  The
++** file header points to the first in a linked list of trunk page.  Each trunk
++** page points to multiple leaf pages.  The content of a leaf page is
++** unspecified.  A trunk page looks like this:
++**
++**    SIZE    DESCRIPTION
++**      4     Page number of next trunk page
++**      4     Number of leaf pointers on this page
++**      *     zero or more pages numbers of leaves
++*/
++/* #include "sqliteInt.h" */
++
++
++/* The following value is the maximum cell size assuming a maximum page
++** size give above.
++*/
++#define MX_CELL_SIZE(pBt)  ((int)(pBt->pageSize-8))
++
++/* The maximum number of cells on a single page of the database.  This
++** assumes a minimum cell size of 6 bytes  (4 bytes for the cell itself
++** plus 2 bytes for the index to the cell in the page header).  Such
++** small cells will be rare, but they are possible.
++*/
++#define MX_CELL(pBt) ((pBt->pageSize-8)/6)
++
++/* Forward declarations */
++typedef struct MemPage MemPage;
++typedef struct BtLock BtLock;
++typedef struct CellInfo CellInfo;
++
++/*
++** This is a magic string that appears at the beginning of every
++** SQLite database in order to identify the file as a real database.
++**
++** You can change this value at compile-time by specifying a
++** -DSQLITE_FILE_HEADER="..." on the compiler command-line.  The
++** header must be exactly 16 bytes including the zero-terminator so
++** the string itself should be 15 characters long.  If you change
++** the header, then your custom library will not be able to read 
++** databases generated by the standard tools and the standard tools
++** will not be able to read databases created by your custom library.
++*/
++#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */
++#  define SQLITE_FILE_HEADER "SQLite format 3"
++#endif
++
++/*
++** Page type flags.  An ORed combination of these flags appear as the
++** first byte of on-disk image of every BTree page.
++*/
++#define PTF_INTKEY    0x01
++#define PTF_ZERODATA  0x02
++#define PTF_LEAFDATA  0x04
++#define PTF_LEAF      0x08
++
++/*
++** An instance of this object stores information about each a single database
++** page that has been loaded into memory.  The information in this object
++** is derived from the raw on-disk page content.
++**
++** As each database page is loaded into memory, the pager allocats an
++** instance of this object and zeros the first 8 bytes.  (This is the
++** "extra" information associated with each page of the pager.)
++**
++** Access to all fields of this structure is controlled by the mutex
++** stored in MemPage.pBt->mutex.
++*/
++struct MemPage {
++  u8 isInit;           /* True if previously initialized. MUST BE FIRST! */
++  u8 bBusy;            /* Prevent endless loops on corrupt database files */
++  u8 intKey;           /* True if table b-trees.  False for index b-trees */
++  u8 intKeyLeaf;       /* True if the leaf of an intKey table */
++  Pgno pgno;           /* Page number for this page */
++  /* Only the first 8 bytes (above) are zeroed by pager.c when a new page
++  ** is allocated. All fields that follow must be initialized before use */
++  u8 leaf;             /* True if a leaf page */
++  u8 hdrOffset;        /* 100 for page 1.  0 otherwise */
++  u8 childPtrSize;     /* 0 if leaf==1.  4 if leaf==0 */
++  u8 max1bytePayload;  /* min(maxLocal,127) */
++  u8 nOverflow;        /* Number of overflow cell bodies in aCell[] */
++  u16 maxLocal;        /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
++  u16 minLocal;        /* Copy of BtShared.minLocal or BtShared.minLeaf */
++  u16 cellOffset;      /* Index in aData of first cell pointer */
++  u16 nFree;           /* Number of free bytes on the page */
++  u16 nCell;           /* Number of cells on this page, local and ovfl */
++  u16 maskPage;        /* Mask for page offset */
++  u16 aiOvfl[4];       /* Insert the i-th overflow cell before the aiOvfl-th
++                       ** non-overflow cell */
++  u8 *apOvfl[4];       /* Pointers to the body of overflow cells */
++  BtShared *pBt;       /* Pointer to BtShared that this page is part of */
++  u8 *aData;           /* Pointer to disk image of the page data */
++  u8 *aDataEnd;        /* One byte past the end of usable data */
++  u8 *aCellIdx;        /* The cell index area */
++  u8 *aDataOfst;       /* Same as aData for leaves.  aData+4 for interior */
++  DbPage *pDbPage;     /* Pager page handle */
++  u16 (*xCellSize)(MemPage*,u8*);             /* cellSizePtr method */
++  void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */
++};
++
++/*
++** A linked list of the following structures is stored at BtShared.pLock.
++** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor 
++** is opened on the table with root page BtShared.iTable. Locks are removed
++** from this list when a transaction is committed or rolled back, or when
++** a btree handle is closed.
++*/
++struct BtLock {
++  Btree *pBtree;        /* Btree handle holding this lock */
++  Pgno iTable;          /* Root page of table */
++  u8 eLock;             /* READ_LOCK or WRITE_LOCK */
++  BtLock *pNext;        /* Next in BtShared.pLock list */
++};
++
++/* Candidate values for BtLock.eLock */
++#define READ_LOCK     1
++#define WRITE_LOCK    2
++
++/* A Btree handle
++**
++** A database connection contains a pointer to an instance of
++** this object for every database file that it has open.  This structure
++** is opaque to the database connection.  The database connection cannot
++** see the internals of this structure and only deals with pointers to
++** this structure.
++**
++** For some database files, the same underlying database cache might be 
++** shared between multiple connections.  In that case, each connection
++** has it own instance of this object.  But each instance of this object
++** points to the same BtShared object.  The database cache and the
++** schema associated with the database file are all contained within
++** the BtShared object.
++**
++** All fields in this structure are accessed under sqlite3.mutex.
++** The pBt pointer itself may not be changed while there exists cursors 
++** in the referenced BtShared that point back to this Btree since those
++** cursors have to go through this Btree to find their BtShared and
++** they often do so without holding sqlite3.mutex.
++*/
++struct Btree {
++  sqlite3 *db;       /* The database connection holding this btree */
++  BtShared *pBt;     /* Sharable content of this btree */
++  u8 inTrans;        /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
++  u8 sharable;       /* True if we can share pBt with another db */
++  u8 locked;         /* True if db currently has pBt locked */
++  u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */
++  int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
++  int nBackup;       /* Number of backup operations reading this btree */
++  u32 iDataVersion;  /* Combines with pBt->pPager->iDataVersion */
++  Btree *pNext;      /* List of other sharable Btrees from the same db */
++  Btree *pPrev;      /* Back pointer of the same list */
++#ifndef SQLITE_OMIT_SHARED_CACHE
++  BtLock lock;       /* Object used to lock page 1 */
++#endif
++};
++
++/*
++** Btree.inTrans may take one of the following values.
++**
++** If the shared-data extension is enabled, there may be multiple users
++** of the Btree structure. At most one of these may open a write transaction,
++** but any number may have active read transactions.
++*/
++#define TRANS_NONE  0
++#define TRANS_READ  1
++#define TRANS_WRITE 2
++
++/*
++** An instance of this object represents a single database file.
++** 
++** A single database file can be in use at the same time by two
++** or more database connections.  When two or more connections are
++** sharing the same database file, each connection has it own
++** private Btree object for the file and each of those Btrees points
++** to this one BtShared object.  BtShared.nRef is the number of
++** connections currently sharing this database file.
++**
++** Fields in this structure are accessed under the BtShared.mutex
++** mutex, except for nRef and pNext which are accessed under the
++** global SQLITE_MUTEX_STATIC_MASTER mutex.  The pPager field
++** may not be modified once it is initially set as long as nRef>0.
++** The pSchema field may be set once under BtShared.mutex and
++** thereafter is unchanged as long as nRef>0.
++**
++** isPending:
++**
++**   If a BtShared client fails to obtain a write-lock on a database
++**   table (because there exists one or more read-locks on the table),
++**   the shared-cache enters 'pending-lock' state and isPending is
++**   set to true.
++**
++**   The shared-cache leaves the 'pending lock' state when either of
++**   the following occur:
++**
++**     1) The current writer (BtShared.pWriter) concludes its transaction, OR
++**     2) The number of locks held by other connections drops to zero.
++**
++**   while in the 'pending-lock' state, no connection may start a new
++**   transaction.
++**
++**   This feature is included to help prevent writer-starvation.
++*/
++struct BtShared {
++  Pager *pPager;        /* The page cache */
++  sqlite3 *db;          /* Database connection currently using this Btree */
++  BtCursor *pCursor;    /* A list of all open cursors */
++  MemPage *pPage1;      /* First page of the database */
++  u8 openFlags;         /* Flags to sqlite3BtreeOpen() */
++#ifndef SQLITE_OMIT_AUTOVACUUM
++  u8 autoVacuum;        /* True if auto-vacuum is enabled */
++  u8 incrVacuum;        /* True if incr-vacuum is enabled */
++  u8 bDoTruncate;       /* True to truncate db on commit */
++#endif
++  u8 inTransaction;     /* Transaction state */
++  u8 max1bytePayload;   /* Maximum first byte of cell for a 1-byte payload */
++#ifdef SQLITE_HAS_CODEC
++  u8 optimalReserve;    /* Desired amount of reserved space per page */
++#endif
++  u16 btsFlags;         /* Boolean parameters.  See BTS_* macros below */
++  u16 maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
++  u16 minLocal;         /* Minimum local payload in non-LEAFDATA tables */
++  u16 maxLeaf;          /* Maximum local payload in a LEAFDATA table */
++  u16 minLeaf;          /* Minimum local payload in a LEAFDATA table */
++  u32 pageSize;         /* Total number of bytes on a page */
++  u32 usableSize;       /* Number of usable bytes on each page */
++  int nTransaction;     /* Number of open transactions (read + write) */
++  u32 nPage;            /* Number of pages in the database */
++  void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
++  void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
++  sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */
++  Bitvec *pHasContent;  /* Set of pages moved to free-list this transaction */
++#ifndef SQLITE_OMIT_SHARED_CACHE
++  int nRef;             /* Number of references to this structure */
++  BtShared *pNext;      /* Next on a list of sharable BtShared structs */
++  BtLock *pLock;        /* List of locks held on this shared-btree struct */
++  Btree *pWriter;       /* Btree with currently open write transaction */
++#endif
++  u8 *pTmpSpace;        /* Temp space sufficient to hold a single cell */
++};
++
++/*
++** Allowed values for BtShared.btsFlags
++*/
++#define BTS_READ_ONLY        0x0001   /* Underlying file is readonly */
++#define BTS_PAGESIZE_FIXED   0x0002   /* Page size can no longer be changed */
++#define BTS_SECURE_DELETE    0x0004   /* PRAGMA secure_delete is enabled */
++#define BTS_OVERWRITE        0x0008   /* Overwrite deleted content with zeros */
++#define BTS_FAST_SECURE      0x000c   /* Combination of the previous two */
++#define BTS_INITIALLY_EMPTY  0x0010   /* Database was empty at trans start */
++#define BTS_NO_WAL           0x0020   /* Do not open write-ahead-log files */
++#define BTS_EXCLUSIVE        0x0040   /* pWriter has an exclusive lock */
++#define BTS_PENDING          0x0080   /* Waiting for read-locks to clear */
++
++/*
++** An instance of the following structure is used to hold information
++** about a cell.  The parseCellPtr() function fills in this structure
++** based on information extract from the raw disk page.
++*/
++struct CellInfo {
++  i64 nKey;      /* The key for INTKEY tables, or nPayload otherwise */
++  u8 *pPayload;  /* Pointer to the start of payload */
++  u32 nPayload;  /* Bytes of payload */
++  u16 nLocal;    /* Amount of payload held locally, not on overflow */
++  u16 nSize;     /* Size of the cell content on the main b-tree page */
++};
++
++/*
++** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than
++** this will be declared corrupt. This value is calculated based on a
++** maximum database size of 2^31 pages a minimum fanout of 2 for a
++** root-node and 3 for all other internal nodes.
++**
++** If a tree that appears to be taller than this is encountered, it is
++** assumed that the database is corrupt.
++*/
++#define BTCURSOR_MAX_DEPTH 20
++
++/*
++** A cursor is a pointer to a particular entry within a particular
++** b-tree within a database file.
++**
++** The entry is identified by its MemPage and the index in
++** MemPage.aCell[] of the entry.
++**
++** A single database file can be shared by two more database connections,
++** but cursors cannot be shared.  Each cursor is associated with a
++** particular database connection identified BtCursor.pBtree.db.
++**
++** Fields in this structure are accessed under the BtShared.mutex
++** found at self->pBt->mutex. 
++**
++** skipNext meaning:
++**    eState==SKIPNEXT && skipNext>0:  Next sqlite3BtreeNext() is no-op.
++**    eState==SKIPNEXT && skipNext<0:  Next sqlite3BtreePrevious() is no-op.
++**    eState==FAULT:                   Cursor fault with skipNext as error code.
++*/
++struct BtCursor {
++  Btree *pBtree;            /* The Btree to which this cursor belongs */
++  BtShared *pBt;            /* The BtShared this cursor points to */
++  BtCursor *pNext;          /* Forms a linked list of all cursors */
++  Pgno *aOverflow;          /* Cache of overflow page locations */
++  CellInfo info;            /* A parse of the cell we are pointing at */
++  i64 nKey;                 /* Size of pKey, or last integer key */
++  void *pKey;               /* Saved key that was cursor last known position */
++  Pgno pgnoRoot;            /* The root page of this tree */
++  int nOvflAlloc;           /* Allocated size of aOverflow[] array */
++  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive.
++                   ** Error code if eState==CURSOR_FAULT */
++  u8 curFlags;              /* zero or more BTCF_* flags defined below */
++  u8 curPagerFlags;         /* Flags to send to sqlite3PagerGet() */
++  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
++  u8 hints;                 /* As configured by CursorSetHints() */
++  /* All fields above are zeroed when the cursor is allocated.  See
++  ** sqlite3BtreeCursorZero().  Fields that follow must be manually
++  ** initialized. */
++  i8 iPage;                 /* Index of current page in apPage */
++  u8 curIntKey;             /* Value of apPage[0]->intKey */
++  u16 ix;                   /* Current index for apPage[iPage] */
++  u16 aiIdx[BTCURSOR_MAX_DEPTH-1];     /* Current index in apPage[i] */
++  struct KeyInfo *pKeyInfo;            /* Arg passed to comparison function */
++  MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
++};
++
++/*
++** Legal values for BtCursor.curFlags
++*/
++#define BTCF_WriteFlag    0x01   /* True if a write cursor */
++#define BTCF_ValidNKey    0x02   /* True if info.nKey is valid */
++#define BTCF_ValidOvfl    0x04   /* True if aOverflow is valid */
++#define BTCF_AtLast       0x08   /* Cursor is pointing ot the last entry */
++#define BTCF_Incrblob     0x10   /* True if an incremental I/O handle */
++#define BTCF_Multiple     0x20   /* Maybe another cursor on the same btree */
++
++/*
++** Potential values for BtCursor.eState.
++**
++** CURSOR_INVALID:
++**   Cursor does not point to a valid entry. This can happen (for example) 
++**   because the table is empty or because BtreeCursorFirst() has not been
++**   called.
++**
++** CURSOR_VALID:
++**   Cursor points to a valid entry. getPayload() etc. may be called.
++**
++** CURSOR_SKIPNEXT:
++**   Cursor is valid except that the Cursor.skipNext field is non-zero
++**   indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
++**   operation should be a no-op.
++**
++** CURSOR_REQUIRESEEK:
++**   The table that this cursor was opened on still exists, but has been 
++**   modified since the cursor was last used. The cursor position is saved
++**   in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in 
++**   this state, restoreCursorPosition() can be called to attempt to
++**   seek the cursor to the saved position.
++**
++** CURSOR_FAULT:
++**   An unrecoverable error (an I/O error or a malloc failure) has occurred
++**   on a different connection that shares the BtShared cache with this
++**   cursor.  The error has left the cache in an inconsistent state.
++**   Do nothing else with this cursor.  Any attempt to use the cursor
++**   should return the error code stored in BtCursor.skipNext
++*/
++#define CURSOR_INVALID           0
++#define CURSOR_VALID             1
++#define CURSOR_SKIPNEXT          2
++#define CURSOR_REQUIRESEEK       3
++#define CURSOR_FAULT             4
++
++/* 
++** The database page the PENDING_BYTE occupies. This page is never used.
++*/
++# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
++
++/*
++** These macros define the location of the pointer-map entry for a 
++** database page. The first argument to each is the number of usable
++** bytes on each page of the database (often 1024). The second is the
++** page number to look up in the pointer map.
++**
++** PTRMAP_PAGENO returns the database page number of the pointer-map
++** page that stores the required pointer. PTRMAP_PTROFFSET returns
++** the offset of the requested map entry.
++**
++** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page,
++** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be
++** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
++** this test.
++*/
++#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)
++#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1))
++#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
++
++/*
++** The pointer map is a lookup table that identifies the parent page for
++** each child page in the database file.  The parent page is the page that
++** contains a pointer to the child.  Every page in the database contains
++** 0 or 1 parent pages.  (In this context 'database page' refers
++** to any page that is not part of the pointer map itself.)  Each pointer map
++** entry consists of a single byte 'type' and a 4 byte parent page number.
++** The PTRMAP_XXX identifiers below are the valid types.
++**
++** The purpose of the pointer map is to facility moving pages from one
++** position in the file to another as part of autovacuum.  When a page
++** is moved, the pointer in its parent must be updated to point to the
++** new location.  The pointer map is used to locate the parent page quickly.
++**
++** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not
++**                  used in this case.
++**
++** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number 
++**                  is not used in this case.
++**
++** PTRMAP_OVERFLOW1: The database page is the first page in a list of 
++**                   overflow pages. The page number identifies the page that
++**                   contains the cell with a pointer to this overflow page.
++**
++** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of
++**                   overflow pages. The page-number identifies the previous
++**                   page in the overflow page list.
++**
++** PTRMAP_BTREE: The database page is a non-root btree page. The page number
++**               identifies the parent page in the btree.
++*/
++#define PTRMAP_ROOTPAGE 1
++#define PTRMAP_FREEPAGE 2
++#define PTRMAP_OVERFLOW1 3
++#define PTRMAP_OVERFLOW2 4
++#define PTRMAP_BTREE 5
++
++/* A bunch of assert() statements to check the transaction state variables
++** of handle p (type Btree*) are internally consistent.
++*/
++#define btreeIntegrity(p) \
++  assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \
++  assert( p->pBt->inTransaction>=p->inTrans ); 
++
++
++/*
++** The ISAUTOVACUUM macro is used within balance_nonroot() to determine
++** if the database supports auto-vacuum or not. Because it is used
++** within an expression that is an argument to another macro 
++** (sqliteMallocRaw), it is not possible to use conditional compilation.
++** So, this macro is defined instead.
++*/
++#ifndef SQLITE_OMIT_AUTOVACUUM
++#define ISAUTOVACUUM (pBt->autoVacuum)
++#else
++#define ISAUTOVACUUM 0
++#endif
++
++
++/*
++** This structure is passed around through all the sanity checking routines
++** in order to keep track of some global state information.
++**
++** The aRef[] array is allocated so that there is 1 bit for each page in
++** the database. As the integrity-check proceeds, for each page used in
++** the database the corresponding bit is set. This allows integrity-check to 
++** detect pages that are used twice and orphaned pages (both of which 
++** indicate corruption).
++*/
++typedef struct IntegrityCk IntegrityCk;
++struct IntegrityCk {
++  BtShared *pBt;    /* The tree being checked out */
++  Pager *pPager;    /* The associated pager.  Also accessible by pBt->pPager */
++  u8 *aPgRef;       /* 1 bit per page in the db (see above) */
++  Pgno nPage;       /* Number of pages in the database */
++  int mxErr;        /* Stop accumulating errors when this reaches zero */
++  int nErr;         /* Number of messages written to zErrMsg so far */
++  int mallocFailed; /* A memory allocation error has occurred */
++  const char *zPfx; /* Error message prefix */
++  int v1, v2;       /* Values for up to two %d fields in zPfx */
++  StrAccum errMsg;  /* Accumulate the error message text here */
++  u32 *heap;        /* Min-heap used for analyzing cell coverage */
++};
++
++/*
++** Routines to read or write a two- and four-byte big-endian integer values.
++*/
++#define get2byte(x)   ((x)[0]<<8 | (x)[1])
++#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v))
++#define get4byte sqlite3Get4byte
++#define put4byte sqlite3Put4byte
++
++/*
++** get2byteAligned(), unlike get2byte(), requires that its argument point to a
++** two-byte aligned address.  get2bytea() is only used for accessing the
++** cell addresses in a btree header.
++*/
++#if SQLITE_BYTEORDER==4321
++# define get2byteAligned(x)  (*(u16*)(x))
++#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4008000
++# define get2byteAligned(x)  __builtin_bswap16(*(u16*)(x))
++#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
++# define get2byteAligned(x)  _byteswap_ushort(*(u16*)(x))
++#else
++# define get2byteAligned(x)  ((x)[0]<<8 | (x)[1])
++#endif
++
++/************** End of btreeInt.h ********************************************/
++/************** Continuing where we left off in crypto.c *********************/
++/************** Include crypto.h in the middle of crypto.c *******************/
++/************** Begin file crypto.h ******************************************/
++/* 
++** SQLCipher
++** crypto.h developed by Stephen Lombardo (Zetetic LLC) 
++** sjlombardo at zetetic dot net
++** http://zetetic.net
++** 
++** Copyright (c) 2008, ZETETIC LLC
++** All rights reserved.
++** 
++** Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are met:
++**     * Redistributions of source code must retain the above copyright
++**       notice, this list of conditions and the following disclaimer.
++**     * Redistributions in binary form must reproduce the above copyright
++**       notice, this list of conditions and the following disclaimer in the
++**       documentation and/or other materials provided with the distribution.
++**     * Neither the name of the ZETETIC LLC nor the
++**       names of its contributors may be used to endorse or promote products
++**       derived from this software without specific prior written permission.
++** 
++** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
++** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
++** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++**  
++*/
++/* BEGIN SQLCIPHER */
++#ifdef SQLITE_HAS_CODEC
++#ifndef CRYPTO_H
++#define CRYPTO_H
++
++#if !defined (SQLCIPHER_CRYPTO_CC) \
++   && !defined (SQLCIPHER_CRYPTO_LIBTOMCRYPT) \
++   && !defined (SQLCIPHER_CRYPTO_OPENSSL)
++#define SQLCIPHER_CRYPTO_OPENSSL
++#endif
++
++#define FILE_HEADER_SZ 16
++
++#ifndef CIPHER_VERSION
++#ifdef SQLCIPHER_FIPS
++#define CIPHER_VERSION "3.4.2 FIPS"
++#else
++#define CIPHER_VERSION "3.4.2"
++#endif
++#endif
++
++#ifndef CIPHER
++#define CIPHER "aes-256-cbc"
++#endif
++
++#define CIPHER_DECRYPT 0
++#define CIPHER_ENCRYPT 1
++
++#define CIPHER_READ_CTX 0
++#define CIPHER_WRITE_CTX 1
++#define CIPHER_READWRITE_CTX 2
++
++#ifndef PBKDF2_ITER
++#define PBKDF2_ITER 64000
++#endif
++
++/* possible flags for cipher_ctx->flags */
++#define CIPHER_FLAG_HMAC          0x01
++#define CIPHER_FLAG_LE_PGNO       0x02
++#define CIPHER_FLAG_BE_PGNO       0x04
++
++#ifndef DEFAULT_CIPHER_FLAGS
++#define DEFAULT_CIPHER_FLAGS CIPHER_FLAG_HMAC | CIPHER_FLAG_LE_PGNO
++#endif
++
++
++/* by default, sqlcipher will use a reduced number of iterations to generate
++   the HMAC key / or transform a raw cipher key 
++   */
++#ifndef FAST_PBKDF2_ITER
++#define FAST_PBKDF2_ITER 2
++#endif
++
++/* this if a fixed random array that will be xor'd with the database salt to ensure that the
++   salt passed to the HMAC key derivation function is not the same as that used to derive
++   the encryption key. This can be overridden at compile time but it will make the resulting
++   binary incompatible with the default builds when using HMAC. A future version of SQLcipher
++   will likely allow this to be defined at runtime via pragma */ 
++#ifndef HMAC_SALT_MASK
++#define HMAC_SALT_MASK 0x3a
++#endif
++
++#ifndef CIPHER_MAX_IV_SZ
++#define CIPHER_MAX_IV_SZ 16
++#endif
++
++#ifndef CIPHER_MAX_KEY_SZ
++#define CIPHER_MAX_KEY_SZ 64
++#endif
++
++#ifdef __ANDROID__
++#include <android/log.h>
++#endif
++
++#ifdef CODEC_DEBUG_MUTEX
++#ifdef __ANDROID__
++#define CODEC_TRACE_MUTEX(...) {__android_log_print(ANDROID_LOG_DEBUG, "sqlcipher", __VA_ARGS__);}
++#else
++#define CODEC_TRACE_MUTEX(...)  {fprintf(stderr, __VA_ARGS__);fflush(stderr);}
++#endif
++#else
++#define CODEC_TRACE_MUTEX(...)
++#endif
++
++#ifdef CODEC_DEBUG
++#ifdef __ANDROID__
++#define CODEC_TRACE(...) {__android_log_print(ANDROID_LOG_DEBUG, "sqlcipher", __VA_ARGS__);}
++#else
++#define CODEC_TRACE(...)  {fprintf(stderr, __VA_ARGS__);fflush(stderr);}
++#endif
++#else
++#define CODEC_TRACE(...)
++#endif
++
++#ifdef CODEC_DEBUG_PAGEDATA
++#define CODEC_HEXDUMP(DESC,BUFFER,LEN)  \
++  { \
++    int __pctr; \
++    printf(DESC); \
++    for(__pctr=0; __pctr < LEN; __pctr++) { \
++      if(__pctr % 16 == 0) printf("\n%05x: ",__pctr); \
++      printf("%02x ",((unsigned char*) BUFFER)[__pctr]); \
++    } \
++    printf("\n"); \
++    fflush(stdout); \
++  }
++#else
++#define CODEC_HEXDUMP(DESC,BUFFER,LEN)
++#endif
++
++/* extensions defined in pager.c */ 
++SQLITE_API void sqlite3pager_get_codec(Pager *pPager, void **ctx);
++SQLITE_API int sqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno);
++SQLITE_PRIVATE sqlite3_file *sqlite3Pager_get_fd(Pager *pPager);
++SQLITE_API void sqlite3pager_sqlite3PagerSetCodec(
++  Pager *pPager,
++  void *(*xCodec)(void*,void*,Pgno,int),
++  void (*xCodecSizeChng)(void*,int,int),
++  void (*xCodecFree)(void*),
++  void *pCodec
++);
++SQLITE_API void sqlite3pager_sqlite3PagerSetError(Pager *pPager, int error);
++/* end extensions defined in pager.c */
++ 
++/*
++**  Simple shared routines for converting hex char strings to binary data
++ */
++static int cipher_hex2int(char c) {
++  return (c>='0' && c<='9') ? (c)-'0' :
++         (c>='A' && c<='F') ? (c)-'A'+10 :
++         (c>='a' && c<='f') ? (c)-'a'+10 : 0;
++}
++
++static void cipher_hex2bin(const unsigned char *hex, int sz, unsigned char *out){
++  int i;
++  for(i = 0; i < sz; i += 2){
++    out[i/2] = (cipher_hex2int(hex[i])<<4) | cipher_hex2int(hex[i+1]);
++  }
++}
++
++static void cipher_bin2hex(const unsigned char* in, int sz, char *out) {
++    int i;
++    for(i=0; i < sz; i++) {
++      sqlite3_snprintf(3, out + (i*2), "%02x ", in[i]);
++    } 
++}
++
++static int cipher_isHex(const unsigned char *hex, int sz){
++  int i;
++  for(i = 0; i < sz; i++) {
++    unsigned char c = hex[i];
++    if ((c < '0' || c > '9') &&
++        (c < 'A' || c > 'F') &&
++        (c < 'a' || c > 'f')) {
++      return 0;
++    }
++  }
++  return 1;
++}
++
++/* extensions defined in crypto_impl.c */
++typedef struct codec_ctx codec_ctx;
++
++/* activation and initialization */
++void sqlcipher_activate();
++void sqlcipher_deactivate();
++int sqlcipher_codec_ctx_init(codec_ctx **, Db *, Pager *, sqlite3_file *, const void *, int);
++void sqlcipher_codec_ctx_free(codec_ctx **);
++int sqlcipher_codec_key_derive(codec_ctx *);
++int sqlcipher_codec_key_copy(codec_ctx *, int);
++
++/* page cipher implementation */
++int sqlcipher_page_cipher(codec_ctx *, int, Pgno, int, int, unsigned char *, unsigned char *);
++
++/* context setters & getters */
++void sqlcipher_codec_ctx_set_error(codec_ctx *, int);
++
++int sqlcipher_codec_ctx_set_pass(codec_ctx *, const void *, int, int);
++void sqlcipher_codec_get_keyspec(codec_ctx *, void **zKey, int *nKey);
++
++int sqlcipher_codec_ctx_set_pagesize(codec_ctx *, int);
++int sqlcipher_codec_ctx_get_pagesize(codec_ctx *);
++int sqlcipher_codec_ctx_get_reservesize(codec_ctx *);
++
++void sqlcipher_set_default_pagesize(int page_size);
++int sqlcipher_get_default_pagesize();
++
++void sqlcipher_set_default_kdf_iter(int iter);
++int sqlcipher_get_default_kdf_iter();
++
++int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *, int, int);
++int sqlcipher_codec_ctx_get_kdf_iter(codec_ctx *ctx, int);
++
++void* sqlcipher_codec_ctx_get_kdf_salt(codec_ctx *ctx);
++
++int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *, int, int);
++int sqlcipher_codec_ctx_get_fast_kdf_iter(codec_ctx *, int);
++
++int sqlcipher_codec_ctx_set_cipher(codec_ctx *, const char *, int);
++const char* sqlcipher_codec_ctx_get_cipher(codec_ctx *ctx, int for_ctx);
++
++void* sqlcipher_codec_ctx_get_data(codec_ctx *);
++
++void sqlcipher_exportFunc(sqlite3_context *, int, sqlite3_value **);
++
++void sqlcipher_set_default_use_hmac(int use);
++int sqlcipher_get_default_use_hmac();
++
++void sqlcipher_set_hmac_salt_mask(unsigned char mask);
++unsigned char sqlcipher_get_hmac_salt_mask();
++
++int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use);
++int sqlcipher_codec_ctx_get_use_hmac(codec_ctx *ctx, int for_ctx);
++
++int sqlcipher_codec_ctx_set_flag(codec_ctx *ctx, unsigned int flag);
++int sqlcipher_codec_ctx_unset_flag(codec_ctx *ctx, unsigned int flag);
++int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag, int for_ctx);
++
++const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx);
++int sqlcipher_codec_ctx_migrate(codec_ctx *ctx);
++int sqlcipher_codec_add_random(codec_ctx *ctx, const char *data, int random_sz);
++int sqlcipher_cipher_profile(sqlite3 *db, const char *destination);
++int sqlcipher_codec_get_store_pass(codec_ctx *ctx);
++void sqlcipher_codec_get_pass(codec_ctx *ctx, void **zKey, int *nKey);
++void sqlcipher_codec_set_store_pass(codec_ctx *ctx, int value);
++int sqlcipher_codec_fips_status(codec_ctx *ctx);
++const char* sqlcipher_codec_get_provider_version(codec_ctx *ctx);
++int sqlcipher_codec_hmac(const codec_ctx *ctx, const unsigned char *hmac_key, int key_sz,
++                         unsigned char* in, int in_sz, unsigned char *in2, int in2_sz,
++                         unsigned char *out);
++#endif
++#endif
++/* END SQLCIPHER */
++
++/************** End of crypto.h **********************************************/
++/************** Continuing where we left off in crypto.c *********************/
++
++static const char* codec_get_cipher_version() {
++  return CIPHER_VERSION;
++}
++
++/* Generate code to return a string value */
++static void codec_vdbe_return_static_string(Parse *pParse, const char *zLabel, const char *value){
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  sqlite3VdbeSetNumCols(v, 1);
++  sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
++  sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, value, 0);
++  sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
++}
++
++static int codec_set_btree_to_codec_pagesize(sqlite3 *db, Db *pDb, codec_ctx *ctx) {
++  int rc, page_sz, reserve_sz; 
++
++  page_sz = sqlcipher_codec_ctx_get_pagesize(ctx);
++  reserve_sz = sqlcipher_codec_ctx_get_reservesize(ctx);
++
++  CODEC_TRACE("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d\n", page_sz, 
reserve_sz);
++
++  CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: entering database mutex %p\n", db->mutex);
++  sqlite3_mutex_enter(db->mutex);
++  CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: entered database mutex %p\n", db->mutex);
++  db->nextPagesize = page_sz; 
++
++  /* before forcing the page size we need to unset the BTS_PAGESIZE_FIXED flag, else  
++     sqliteBtreeSetPageSize will block the change  */
++  pDb->pBt->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
++  rc = sqlite3BtreeSetPageSize(pDb->pBt, page_sz, reserve_sz, 0);
++
++  CODEC_TRACE("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize returned %d\n", rc);
++
++  CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: leaving database mutex %p\n", db->mutex);
++  sqlite3_mutex_leave(db->mutex);
++  CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: left database mutex %p\n", db->mutex);
++
++  return rc;
++}
++
++static int codec_set_pass_key(sqlite3* db, int nDb, const void *zKey, int nKey, int for_ctx) {
++  struct Db *pDb = &db->aDb[nDb];
++  CODEC_TRACE("codec_set_pass_key: entered db=%p nDb=%d zKey=%s nKey=%d for_ctx=%d\n", db, nDb, (char 
*)zKey, nKey, for_ctx);
++  if(pDb->pBt) {
++    codec_ctx *ctx;
++    sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
++    if(ctx) return sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, for_ctx);
++  }
++  return SQLITE_ERROR;
++} 
++
++int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const char *zRight) {
++  char *pragma_cipher_deprecated_msg = "PRAGMA cipher command is deprecated, please remove from usage.";
++  struct Db *pDb = &db->aDb[iDb];
++  codec_ctx *ctx = NULL;
++  int rc;
++
++  if(pDb->pBt) {
++    sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
++  }
++
++  CODEC_TRACE("sqlcipher_codec_pragma: entered db=%p iDb=%d pParse=%p zLeft=%s zRight=%s ctx=%p\n", db, 
iDb, pParse, zLeft, zRight, ctx);
++  
++  if( sqlite3StrICmp(zLeft, "cipher_fips_status")== 0 && !zRight ){
++    if(ctx) {
++      char *fips_mode_status = sqlite3_mprintf("%d", sqlcipher_codec_fips_status(ctx));
++      codec_vdbe_return_static_string(pParse, "cipher_fips_status", fips_mode_status);
++      sqlite3_free(fips_mode_status);
++    }
++  } else
++  if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && zRight ) {
++    if(ctx) {
++      sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1));
++    }
++  } else
++  if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && !zRight ) {
++    if(ctx){
++      char *store_pass_value = sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx));
++      codec_vdbe_return_static_string(pParse, "cipher_store_pass", store_pass_value);
++      sqlite3_free(store_pass_value);
++    }
++  }
++  if( sqlite3StrICmp(zLeft, "cipher_profile")== 0 && zRight ){
++      char *profile_status = sqlite3_mprintf("%d", sqlcipher_cipher_profile(db, zRight));
++      codec_vdbe_return_static_string(pParse, "cipher_profile", profile_status);
++      sqlite3_free(profile_status);
++  } else
++  if( sqlite3StrICmp(zLeft, "cipher_add_random")==0 && zRight ){
++    if(ctx) {
++      char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, 
sqlite3Strlen30(zRight)));
++      codec_vdbe_return_static_string(pParse, "cipher_add_random", add_random_status);
++      sqlite3_free(add_random_status);
++    }
++  } else
++  if( sqlite3StrICmp(zLeft, "cipher_migrate")==0 && !zRight ){
++    if(ctx){
++      char *migrate_status = sqlite3_mprintf("%d", sqlcipher_codec_ctx_migrate(ctx));
++      codec_vdbe_return_static_string(pParse, "cipher_migrate", migrate_status);
++      sqlite3_free(migrate_status);
++    }
++  } else
++  if( sqlite3StrICmp(zLeft, "cipher_provider")==0 && !zRight ){
++    if(ctx) { codec_vdbe_return_static_string(pParse, "cipher_provider",
++                                              sqlcipher_codec_get_cipher_provider(ctx));
++    }
++  } else
++  if( sqlite3StrICmp(zLeft, "cipher_provider_version")==0 && !zRight){
++    if(ctx) { codec_vdbe_return_static_string(pParse, "cipher_provider_version",
++                                              sqlcipher_codec_get_provider_version(ctx));
++    }
++  } else
++  if( sqlite3StrICmp(zLeft, "cipher_version")==0 && !zRight ){
++    codec_vdbe_return_static_string(pParse, "cipher_version", codec_get_cipher_version());
++  }else
++  if( sqlite3StrICmp(zLeft, "cipher")==0 ){
++    if(ctx) {
++      if( zRight ) {
++        rc = sqlcipher_codec_ctx_set_cipher(ctx, zRight, 2); // change cipher for both
++        codec_vdbe_return_static_string(pParse, "cipher", pragma_cipher_deprecated_msg);
++        sqlite3_log(SQLITE_WARNING, pragma_cipher_deprecated_msg);
++        return rc;
++      }else {
++        codec_vdbe_return_static_string(pParse, "cipher",
++          sqlcipher_codec_ctx_get_cipher(ctx, 2));
++      }
++    }
++  }else
++  if( sqlite3StrICmp(zLeft, "rekey_cipher")==0 && zRight ){
++    if(ctx) sqlcipher_codec_ctx_set_cipher(ctx, zRight, 1); // change write cipher only 
++  }else
++  if( sqlite3StrICmp(zLeft,"cipher_default_kdf_iter")==0 ){
++    if( zRight ) {
++      sqlcipher_set_default_kdf_iter(atoi(zRight)); // change default KDF iterations
++    } else {
++      char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter());
++      codec_vdbe_return_static_string(pParse, "cipher_default_kdf_iter", kdf_iter);
++      sqlite3_free(kdf_iter);
++    }
++  }else
++  if( sqlite3StrICmp(zLeft, "kdf_iter")==0 ){
++    if(ctx) {
++      if( zRight ) {
++        sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight), 2); // change of RW PBKDF2 iteration 
++      } else {
++        char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_kdf_iter(ctx, 2));
++        codec_vdbe_return_static_string(pParse, "kdf_iter", kdf_iter);
++        sqlite3_free(kdf_iter);
++      }
++    }
++  }else
++  if( sqlite3StrICmp(zLeft, "fast_kdf_iter")==0){
++    if(ctx) {
++      if( zRight ) {
++        sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, atoi(zRight), 2); // change of RW PBKDF2 iteration 
++      } else {
++        char *fast_kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_fast_kdf_iter(ctx, 2));
++        codec_vdbe_return_static_string(pParse, "fast_kdf_iter", fast_kdf_iter);
++        sqlite3_free(fast_kdf_iter);
++      }
++    }
++  }else
++  if( sqlite3StrICmp(zLeft, "rekey_kdf_iter")==0 && zRight ){
++    if(ctx) sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight), 1); // write iterations only
++  }else
++  if( sqlite3StrICmp(zLeft,"cipher_page_size")==0 ){
++    if(ctx) {
++      if( zRight ) {
++        int size = atoi(zRight);
++        rc = sqlcipher_codec_ctx_set_pagesize(ctx, size);
++        if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
++        rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
++        if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
++      } else {
++        char * page_size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_pagesize(ctx));
++        codec_vdbe_return_static_string(pParse, "cipher_page_size", page_size);
++        sqlite3_free(page_size);
++      }
++    }
++  }else
++  if( sqlite3StrICmp(zLeft,"cipher_default_page_size")==0 ){
++    if( zRight ) {
++      sqlcipher_set_default_pagesize(atoi(zRight));
++    } else {
++      char *default_page_size = sqlite3_mprintf("%d", sqlcipher_get_default_pagesize());
++      codec_vdbe_return_static_string(pParse, "cipher_default_page_size", default_page_size);
++      sqlite3_free(default_page_size);
++    }
++  }else
++  if( sqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){
++    if( zRight ) {
++      sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight,1));
++    } else {
++      char *default_use_hmac = sqlite3_mprintf("%d", sqlcipher_get_default_use_hmac());
++      codec_vdbe_return_static_string(pParse, "cipher_default_use_hmac", default_use_hmac);
++      sqlite3_free(default_use_hmac);
++    }
++  }else
++  if( sqlite3StrICmp(zLeft,"cipher_use_hmac")==0 ){
++    if(ctx) {
++      if( zRight ) {
++        rc = sqlcipher_codec_ctx_set_use_hmac(ctx, sqlite3GetBoolean(zRight,1));
++        if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
++        /* since the use of hmac has changed, the page size may also change */
++        rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
++        if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
++      } else {
++        char *hmac_flag = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_use_hmac(ctx, 2));
++        codec_vdbe_return_static_string(pParse, "cipher_use_hmac", hmac_flag);
++        sqlite3_free(hmac_flag);
++      }
++    }
++  }else
++  if( sqlite3StrICmp(zLeft,"cipher_hmac_pgno")==0 ){
++    if(ctx) {
++      if(zRight) {
++        // clear both pgno endian flags
++        if(sqlite3StrICmp(zRight, "le") == 0) {
++          sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
++          sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_LE_PGNO);
++        } else if(sqlite3StrICmp(zRight, "be") == 0) {
++          sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
++          sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_BE_PGNO);
++        } else if(sqlite3StrICmp(zRight, "native") == 0) {
++          sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
++          sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
++        }
++      } else {
++        if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_LE_PGNO, 2)) {
++          codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "le");
++        } else if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_BE_PGNO, 2)) {
++          codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "be");
++        } else {
++          codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "native");
++        }
++      }
++    }
++  }else
++  if( sqlite3StrICmp(zLeft,"cipher_hmac_salt_mask")==0 ){
++    if(ctx) {
++      if(zRight) {
++        if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == 5) {
++          unsigned char mask = 0;
++          const unsigned char *hex = (const unsigned char *)zRight+2;
++          cipher_hex2bin(hex,2,&mask);
++          sqlcipher_set_hmac_salt_mask(mask);
++        }
++      } else {
++          char *hmac_salt_mask = sqlite3_mprintf("%02x", sqlcipher_get_hmac_salt_mask());
++          codec_vdbe_return_static_string(pParse, "cipher_hmac_salt_mask", hmac_salt_mask);
++          sqlite3_free(hmac_salt_mask);
++      }
++    }
++  }else {
++    return 0;
++  }
++  return 1;
++}
++
++
++/*
++ * sqlite3Codec can be called in multiple modes.
++ * encrypt mode - expected to return a pointer to the 
++ *   encrypted data without altering pData.
++ * decrypt mode - expected to return a pointer to pData, with
++ *   the data decrypted in the input buffer
++ */
++void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) {
++  codec_ctx *ctx = (codec_ctx *) iCtx;
++  int offset = 0, rc = 0;
++  int page_sz = sqlcipher_codec_ctx_get_pagesize(ctx); 
++  unsigned char *pData = (unsigned char *) data;
++  void *buffer = sqlcipher_codec_ctx_get_data(ctx);
++  void *kdf_salt = sqlcipher_codec_ctx_get_kdf_salt(ctx);
++  CODEC_TRACE("sqlite3Codec: entered pgno=%d, mode=%d, page_sz=%d\n", pgno, mode, page_sz);
++
++  /* call to derive keys if not present yet */
++  if((rc = sqlcipher_codec_key_derive(ctx)) != SQLITE_OK) {
++   sqlcipher_codec_ctx_set_error(ctx, rc); 
++   return NULL;
++  }
++
++  if(pgno == 1) offset = FILE_HEADER_SZ; /* adjust starting pointers in data page for header offset on 
first page*/
++
++  CODEC_TRACE("sqlite3Codec: switch mode=%d offset=%d\n",  mode, offset);
++  switch(mode) {
++    case 0: /* decrypt */
++    case 2:
++    case 3:
++      if(pgno == 1) memcpy(buffer, SQLITE_FILE_HEADER, FILE_HEADER_SZ); /* copy file header to the first 16 
bytes of the page */ 
++      rc = sqlcipher_page_cipher(ctx, CIPHER_READ_CTX, pgno, CIPHER_DECRYPT, page_sz - offset, pData + 
offset, (unsigned char*)buffer + offset);
++      if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
++      memcpy(pData, buffer, page_sz); /* copy buffer data back to pData and return */
++      return pData;
++      break;
++    case 6: /* encrypt */
++      if(pgno == 1) memcpy(buffer, kdf_salt, FILE_HEADER_SZ); /* copy salt to output buffer */ 
++      rc = sqlcipher_page_cipher(ctx, CIPHER_WRITE_CTX, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + 
offset, (unsigned char*)buffer + offset);
++      if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
++      return buffer; /* return persistent buffer data, pData remains intact */
++      break;
++    case 7:
++      if(pgno == 1) memcpy(buffer, kdf_salt, FILE_HEADER_SZ); /* copy salt to output buffer */ 
++      rc = sqlcipher_page_cipher(ctx, CIPHER_READ_CTX, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + 
offset, (unsigned char*)buffer + offset);
++      if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
++      return buffer; /* return persistent buffer data, pData remains intact */
++      break;
++    default:
++      return pData;
++      break;
++  }
++}
++
++SQLITE_PRIVATE void sqlite3FreeCodecArg(void *pCodecArg) {
++  codec_ctx *ctx = (codec_ctx *) pCodecArg;
++  if(pCodecArg == NULL) return;
++  sqlcipher_codec_ctx_free(&ctx); // wipe and free allocated memory for the context 
++  sqlcipher_deactivate(); /* cleanup related structures, OpenSSL etc, when codec is detatched */
++}
++
++SQLITE_PRIVATE int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
++  struct Db *pDb = &db->aDb[nDb];
++
++  CODEC_TRACE("sqlite3CodecAttach: entered db=%p, nDb=%d zKey=%s, nKey=%d\n", db, nDb, (char *)zKey, nKey);
++
++
++  if(nKey && zKey && pDb->pBt) {
++    int rc;
++    Pager *pPager = pDb->pBt->pBt->pPager;
++    sqlite3_file *fd = sqlite3Pager_get_fd(pPager);
++    codec_ctx *ctx;
++
++    CODEC_TRACE("sqlite3CodecAttach: calling sqlcipher_activate()\n");
++    sqlcipher_activate(); /* perform internal initialization for sqlcipher */
++
++    CODEC_TRACE_MUTEX("sqlite3CodecAttach: entering database mutex %p\n", db->mutex);
++    sqlite3_mutex_enter(db->mutex);
++    CODEC_TRACE_MUTEX("sqlite3CodecAttach: entered database mutex %p\n", db->mutex);
++
++    /* point the internal codec argument against the contet to be prepared */
++    CODEC_TRACE("sqlite3CodecAttach: calling sqlcipher_codec_ctx_init()\n");
++    rc = sqlcipher_codec_ctx_init(&ctx, pDb, pDb->pBt->pBt->pPager, fd, zKey, nKey); 
++
++    if(rc != SQLITE_OK) {
++      /* initialization failed, do not attach potentially corrupted context */
++      CODEC_TRACE("sqlite3CodecAttach: context initialization failed with rc=%d\n", rc);
++      CODEC_TRACE_MUTEX("sqlite3CodecAttach: leaving database mutex %p (early return on rc=%d)\n", 
db->mutex, rc);
++      sqlite3_mutex_leave(db->mutex);
++      CODEC_TRACE_MUTEX("sqlite3CodecAttach: left database mutex %p (early return on rc=%d)\n", db->mutex, 
rc);
++      return rc;
++    }
++
++    CODEC_TRACE("sqlite3CodecAttach: calling sqlite3pager_sqlite3PagerSetCodec()\n");
++    sqlite3pager_sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, 
(void *) ctx);
++
++    CODEC_TRACE("sqlite3CodecAttach: calling codec_set_btree_to_codec_pagesize()\n");
++    codec_set_btree_to_codec_pagesize(db, pDb, ctx);
++
++    /* force secure delete. This has the benefit of wiping internal data when deleted
++       and also ensures that all pages are written to disk (i.e. not skipped by
++       sqlite3PagerDontWrite optimizations) */ 
++    CODEC_TRACE("sqlite3CodecAttach: calling sqlite3BtreeSecureDelete()\n");
++    sqlite3BtreeSecureDelete(pDb->pBt, 1); 
++
++    /* if fd is null, then this is an in-memory database and
++       we dont' want to overwrite the AutoVacuum settings
++       if not null, then set to the default */
++    if(fd != NULL) { 
++      CODEC_TRACE("sqlite3CodecAttach: calling sqlite3BtreeSetAutoVacuum()\n");
++      sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM);
++    }
++    CODEC_TRACE_MUTEX("sqlite3CodecAttach: leaving database mutex %p\n", db->mutex);
++    sqlite3_mutex_leave(db->mutex);
++    CODEC_TRACE_MUTEX("sqlite3CodecAttach: left database mutex %p\n", db->mutex);
++  }
++  return SQLITE_OK;
++}
++
++SQLITE_API void sqlite3_activate_see(const char* in) {
++  /* do nothing, security enhancements are always active */
++}
++
++static int sqlcipher_find_db_index(sqlite3 *db, const char *zDb) {
++  int db_index;
++  if(zDb == NULL){
++    return 0;
++  }
++  for(db_index = 0; db_index < db->nDb; db_index++) {
++    struct Db *pDb = &db->aDb[db_index];
++    if(strcmp(pDb->zDbSName, zDb) == 0) {
++      return db_index;
++    }
++  }
++  return 0;
++}
++
++SQLITE_API int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
++  CODEC_TRACE("sqlite3_key entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey);
++  return sqlite3_key_v2(db, "main", pKey, nKey);
++}
++
++SQLITE_API int sqlite3_key_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
++  CODEC_TRACE("sqlite3_key_v2: entered db=%p zDb=%s pKey=%s nKey=%d\n", db, zDb, (char *)pKey, nKey);
++  /* attach key if db and pKey are not null and nKey is > 0 */
++  if(db && pKey && nKey) {
++    int db_index = sqlcipher_find_db_index(db, zDb);
++    return sqlite3CodecAttach(db, db_index, pKey, nKey); 
++  }
++  return SQLITE_ERROR;
++}
++
++SQLITE_API int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
++  CODEC_TRACE("sqlite3_rekey entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey);
++  return sqlite3_rekey_v2(db, "main", pKey, nKey);
++}
++
++/* sqlite3_rekey_v2
++** Given a database, this will reencrypt the database using a new key.
++** There is only one possible modes of operation - to encrypt a database
++** that is already encrpyted. If the database is not already encrypted
++** this should do nothing
++** The proposed logic for this function follows:
++** 1. Determine if the database is already encryptped
++** 2. If there is NOT already a key present do nothing
++** 3. If there is a key present, re-encrypt the database with the new key
++*/
++SQLITE_API int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
++  CODEC_TRACE("sqlite3_rekey_v2: entered db=%p zDb=%s pKey=%s, nKey=%d\n", db, zDb, (char *)pKey, nKey);
++  if(db && pKey && nKey) {
++    int db_index = sqlcipher_find_db_index(db, zDb);
++    struct Db *pDb = &db->aDb[db_index];
++    CODEC_TRACE("sqlite3_rekey_v2: database pDb=%p db_index:%d\n", pDb, db_index);
++    if(pDb->pBt) {
++      codec_ctx *ctx;
++      int rc, page_count;
++      Pgno pgno;
++      PgHdr *page;
++      Pager *pPager = pDb->pBt->pBt->pPager;
++
++      sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
++     
++      if(ctx == NULL) { 
++        /* there was no codec attached to this database, so this should do nothing! */ 
++        CODEC_TRACE("sqlite3_rekey_v2: no codec attached to db, exiting\n");
++        return SQLITE_OK;
++      }
++
++      CODEC_TRACE_MUTEX("sqlite3_rekey_v2: entering database mutex %p\n", db->mutex);
++      sqlite3_mutex_enter(db->mutex);
++      CODEC_TRACE_MUTEX("sqlite3_rekey_v2: entered database mutex %p\n", db->mutex);
++
++      codec_set_pass_key(db, db_index, pKey, nKey, CIPHER_WRITE_CTX);
++    
++      /* do stuff here to rewrite the database 
++      ** 1. Create a transaction on the database
++      ** 2. Iterate through each page, reading it and then writing it.
++      ** 3. If that goes ok then commit and put ctx->rekey into ctx->key
++      **    note: don't deallocate rekey since it may be used in a subsequent iteration 
++      */
++      rc = sqlite3BtreeBeginTrans(pDb->pBt, 1); /* begin write transaction */
++      sqlite3PagerPagecount(pPager, &page_count);
++      for(pgno = 1; rc == SQLITE_OK && pgno <= (unsigned int)page_count; pgno++) { /* pgno's start at 1 see 
pager.c:pagerAcquire */
++        if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for 
reasoning) */
++          rc = sqlite3PagerGet(pPager, pgno, &page, 0);
++          if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */
++            rc = sqlite3PagerWrite(page);
++            if(rc == SQLITE_OK) {
++              sqlite3PagerUnref(page);
++            } else {
++             CODEC_TRACE("sqlite3_rekey_v2: error %d occurred writing page %d\n", rc, pgno);  
++            }
++          } else {
++             CODEC_TRACE("sqlite3_rekey_v2: error %d occurred getting page %d\n", rc, pgno);  
++          }
++        } 
++      }
++
++      /* if commit was successful commit and copy the rekey data to current key, else rollback to release 
locks */
++      if(rc == SQLITE_OK) { 
++        CODEC_TRACE("sqlite3_rekey_v2: committing\n");
++        rc = sqlite3BtreeCommit(pDb->pBt); 
++        sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX);
++      } else {
++        CODEC_TRACE("sqlite3_rekey_v2: rollback\n");
++        sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK, 0);
++      }
++
++      CODEC_TRACE_MUTEX("sqlite3_rekey_v2: leaving database mutex %p\n", db->mutex);
++      sqlite3_mutex_leave(db->mutex);
++      CODEC_TRACE_MUTEX("sqlite3_rekey_v2: left database mutex %p\n", db->mutex);
++    }
++    return SQLITE_OK;
++  }
++  return SQLITE_ERROR;
++}
++
++SQLITE_PRIVATE void sqlite3CodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) {
++  struct Db *pDb = &db->aDb[nDb];
++  CODEC_TRACE("sqlite3CodecGetKey: entered db=%p, nDb=%d\n", db, nDb);
++  if( pDb->pBt ) {
++    codec_ctx *ctx;
++    sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
++    if(ctx) {
++      if(sqlcipher_codec_get_store_pass(ctx) == 1) {
++        sqlcipher_codec_get_pass(ctx, zKey, nKey);
++      } else {
++        sqlcipher_codec_get_keyspec(ctx, zKey, nKey);
++      }
++    } else {
++      *zKey = NULL;
++      *nKey = 0;
++    }
++  }
++}
++
++#ifndef OMIT_EXPORT
++
++/*
++ * Implementation of an "export" function that allows a caller
++ * to duplicate the main database to an attached database. This is intended
++ * as a conveneince for users who need to:
++ * 
++ *   1. migrate from an non-encrypted database to an encrypted database
++ *   2. move from an encrypted database to a non-encrypted database
++ *   3. convert beween the various flavors of encrypted databases.  
++ *
++ * This implementation is based heavily on the procedure and code used
++ * in vacuum.c, but is exposed as a function that allows export to any
++ * named attached database.
++ */
++
++/*
++** Finalize a prepared statement.  If there was an error, store the
++** text of the error message in *pzErrMsg.  Return the result code.
++** 
++** Based on vacuumFinalize from vacuum.c
++*/
++static int sqlcipher_finalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
++  int rc;
++  rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
++  if( rc ){
++    sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
++  }
++  return rc;
++}
++
++/*
++** Execute zSql on database db. Return an error code.
++** 
++** Based on execSql from vacuum.c
++*/
++static int sqlcipher_execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
++  sqlite3_stmt *pStmt;
++  VVA_ONLY( int rc; )
++  if( !zSql ){
++    return SQLITE_NOMEM;
++  }
++  if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
++    sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
++    return sqlite3_errcode(db);
++  }
++  VVA_ONLY( rc = ) sqlite3_step(pStmt);
++  assert( rc!=SQLITE_ROW );
++  return sqlcipher_finalize(db, pStmt, pzErrMsg);
++}
++
++/*
++** Execute zSql on database db. The statement returns exactly
++** one column. Execute this as SQL on the same database.
++** 
++** Based on execExecSql from vacuum.c
++*/
++static int sqlcipher_execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
++  sqlite3_stmt *pStmt;
++  int rc;
++
++  rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
++  if( rc!=SQLITE_OK ) return rc;
++
++  while( SQLITE_ROW==sqlite3_step(pStmt) ){
++    rc = sqlcipher_execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
++    if( rc!=SQLITE_OK ){
++      sqlcipher_finalize(db, pStmt, pzErrMsg);
++      return rc;
++    }
++  }
++
++  return sqlcipher_finalize(db, pStmt, pzErrMsg);
++}
++
++/*
++ * copy database and schema from the main database to an attached database
++ * 
++ * Based on sqlite3RunVacuum from vacuum.c
++*/
++void sqlcipher_exportFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
++  sqlite3 *db = sqlite3_context_db_handle(context);
++  const char* attachedDb = (const char*) sqlite3_value_text(argv[0]);
++  int saved_flags;        /* Saved value of the db->flags */
++  int saved_nChange;      /* Saved value of db->nChange */
++  int saved_nTotalChange; /* Saved value of db->nTotalChange */
++  u8 saved_mTrace;        /* Saved value of db->mTrace */
++  int (*saved_xTrace)(u32,void*,void*,void*); /* Saved db->xTrace */
++  int rc = SQLITE_OK;     /* Return code from service routines */
++  char *zSql = NULL;         /* SQL statements */
++  char *pzErrMsg = NULL;
++  
++  saved_flags = db->flags;
++  saved_nChange = db->nChange;
++  saved_nTotalChange = db->nTotalChange;
++  saved_xTrace = db->xTrace;
++  saved_mTrace = db->mTrace;
++  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
++  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
++  db->xTrace = 0;
++  db->mTrace = 0;
++
++  /* Query the schema of the main database. Create a mirror schema
++  ** in the temporary database.
++  */
++  zSql = sqlite3_mprintf(
++    "SELECT 'CREATE TABLE %s.' || substr(sql,14) "
++    "  FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
++    "   AND rootpage>0"
++  , attachedDb);
++  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); 
++  if( rc!=SQLITE_OK ) goto end_of_export;
++  sqlite3_free(zSql);
++
++  zSql = sqlite3_mprintf(
++    "SELECT 'CREATE INDEX %s.' || substr(sql,14)"
++    "  FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %%' "
++  , attachedDb);
++  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); 
++  if( rc!=SQLITE_OK ) goto end_of_export;
++  sqlite3_free(zSql);
++
++  zSql = sqlite3_mprintf(
++    "SELECT 'CREATE UNIQUE INDEX %s.' || substr(sql,21) "
++    "  FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %%'"
++  , attachedDb);
++  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); 
++  if( rc!=SQLITE_OK ) goto end_of_export;
++  sqlite3_free(zSql);
++
++  /* Loop through the tables in the main database. For each, do
++  ** an "INSERT INTO rekey_db.xxx SELECT * FROM main.xxx;" to copy
++  ** the contents to the temporary database.
++  */
++  zSql = sqlite3_mprintf(
++    "SELECT 'INSERT INTO %s.' || quote(name) "
++    "|| ' SELECT * FROM main.' || quote(name) || ';'"
++    "FROM main.sqlite_master "
++    "WHERE type = 'table' AND name!='sqlite_sequence' "
++    "  AND rootpage>0"
++  , attachedDb);
++  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); 
++  if( rc!=SQLITE_OK ) goto end_of_export;
++  sqlite3_free(zSql);
++
++  /* Copy over the sequence table
++  */
++  zSql = sqlite3_mprintf(
++    "SELECT 'DELETE FROM %s.' || quote(name) || ';' "
++    "FROM %s.sqlite_master WHERE name='sqlite_sequence' "
++  , attachedDb, attachedDb);
++  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); 
++  if( rc!=SQLITE_OK ) goto end_of_export;
++  sqlite3_free(zSql);
++
++  zSql = sqlite3_mprintf(
++    "SELECT 'INSERT INTO %s.' || quote(name) "
++    "|| ' SELECT * FROM main.' || quote(name) || ';' "
++    "FROM %s.sqlite_master WHERE name=='sqlite_sequence';"
++  , attachedDb, attachedDb);
++  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); 
++  if( rc!=SQLITE_OK ) goto end_of_export;
++  sqlite3_free(zSql);
++
++  /* Copy the triggers, views, and virtual tables from the main database
++  ** over to the temporary database.  None of these objects has any
++  ** associated storage, so all we have to do is copy their entries
++  ** from the SQLITE_MASTER table.
++  */
++  zSql = sqlite3_mprintf(
++    "INSERT INTO %s.sqlite_master "
++    "  SELECT type, name, tbl_name, rootpage, sql"
++    "    FROM main.sqlite_master"
++    "   WHERE type='view' OR type='trigger'"
++    "      OR (type='table' AND rootpage=0)"
++  , attachedDb);
++  rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execSql(db, &pzErrMsg, zSql); 
++  if( rc!=SQLITE_OK ) goto end_of_export;
++  sqlite3_free(zSql);
++
++  zSql = NULL;
++end_of_export:
++  db->flags = saved_flags;
++  db->nChange = saved_nChange;
++  db->nTotalChange = saved_nTotalChange;
++  db->xTrace = saved_xTrace;
++  db->mTrace = saved_mTrace;
++
++  sqlite3_free(zSql);
++
++  if(rc) {
++    if(pzErrMsg != NULL) {
++      sqlite3_result_error(context, pzErrMsg, -1);
++      sqlite3DbFree(db, pzErrMsg);
++    } else {
++      sqlite3_result_error(context, sqlite3ErrStr(rc), -1);
++    }
++  }
++}
++
++#endif
++
++/* END SQLCIPHER */
++#endif
++
++/************** End of crypto.c **********************************************/
++/************** Begin file crypto_impl.c *************************************/
++/* 
++** SQLCipher
++** http://sqlcipher.net
++** 
++** Copyright (c) 2008 - 2013, ZETETIC LLC
++** All rights reserved.
++** 
++** Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are met:
++**     * Redistributions of source code must retain the above copyright
++**       notice, this list of conditions and the following disclaimer.
++**     * Redistributions in binary form must reproduce the above copyright
++**       notice, this list of conditions and the following disclaimer in the
++**       documentation and/or other materials provided with the distribution.
++**     * Neither the name of the ZETETIC LLC nor the
++**       names of its contributors may be used to endorse or promote products
++**       derived from this software without specific prior written permission.
++** 
++** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
++** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
++** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++**  
++*/
++/* BEGIN SQLCIPHER */
++#ifdef SQLITE_HAS_CODEC
++
++/* #include "sqliteInt.h" */
++/* #include "btreeInt.h" */
++/************** Include sqlcipher.h in the middle of crypto_impl.c ***********/
++/************** Begin file sqlcipher.h ***************************************/
++/* 
++** SQLCipher
++** sqlcipher.h developed by Stephen Lombardo (Zetetic LLC) 
++** sjlombardo at zetetic dot net
++** http://zetetic.net
++** 
++** Copyright (c) 2008, ZETETIC LLC
++** All rights reserved.
++** 
++** Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are met:
++**     * Redistributions of source code must retain the above copyright
++**       notice, this list of conditions and the following disclaimer.
++**     * Redistributions in binary form must reproduce the above copyright
++**       notice, this list of conditions and the following disclaimer in the
++**       documentation and/or other materials provided with the distribution.
++**     * Neither the name of the ZETETIC LLC nor the
++**       names of its contributors may be used to endorse or promote products
++**       derived from this software without specific prior written permission.
++** 
++** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
++** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
++** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++**  
++*/
++/* BEGIN SQLCIPHER */
++#ifdef SQLITE_HAS_CODEC
++#ifndef SQLCIPHER_H
++#define SQLCIPHER_H
++
++
++typedef struct {
++  int (*activate)(void *ctx);
++  int (*deactivate)(void *ctx);
++  const char* (*get_provider_name)(void *ctx);
++  int (*add_random)(void *ctx, void *buffer, int length);
++  int (*random)(void *ctx, void *buffer, int length);
++  int (*hmac)(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char 
*in2, int in2_sz, unsigned char *out);
++  int (*kdf)(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int 
workfactor, int key_sz, unsigned char *key);
++  int (*cipher)(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, 
int in_sz, unsigned char *out);
++  int (*set_cipher)(void *ctx, const char *cipher_name);
++  const char* (*get_cipher)(void *ctx);
++  int (*get_key_sz)(void *ctx);
++  int (*get_iv_sz)(void *ctx);
++  int (*get_block_sz)(void *ctx);
++  int (*get_hmac_sz)(void *ctx);
++  int (*ctx_copy)(void *target_ctx, void *source_ctx);
++  int (*ctx_cmp)(void *c1, void *c2);
++  int (*ctx_init)(void **ctx);
++  int (*ctx_free)(void **ctx);
++  int (*fips_status)(void *ctx);
++  const char* (*get_provider_version)(void *ctx);
++} sqlcipher_provider;
++
++/* utility functions */
++void sqlcipher_free(void *ptr, int sz);
++void* sqlcipher_malloc(int sz);
++void* sqlcipher_memset(void *v, unsigned char value, int len);
++int sqlcipher_ismemset(const void *v, unsigned char value, int len);
++int sqlcipher_memcmp(const void *v0, const void *v1, int len);
++void sqlcipher_free(void *, int);
++
++/* provider interfaces */
++int sqlcipher_register_provider(sqlcipher_provider *p);
++sqlcipher_provider* sqlcipher_get_provider();
++
++#endif
++#endif
++/* END SQLCIPHER */
++
++
++/************** End of sqlcipher.h *******************************************/
++/************** Continuing where we left off in crypto_impl.c ****************/
++/* #include "crypto.h" */
++#ifndef OMIT_MEMLOCK
++#if defined(__unix__) || defined(__APPLE__) || defined(_AIX)
++#include <errno.h>
++#include <unistd.h>
++#include <sys/resource.h>
++#include <sys/mman.h>
++#elif defined(_WIN32)
++#include <windows.h>
++#endif
++#endif
++
++/* the default implementation of SQLCipher uses a cipher_ctx
++   to keep track of read / write state separately. The following
++   struct and associated functions are defined here */
++typedef struct {
++  int store_pass;
++  int derive_key;
++  int kdf_iter;
++  int fast_kdf_iter;
++  int key_sz;
++  int iv_sz;
++  int block_sz;
++  int pass_sz;
++  int reserve_sz;
++  int hmac_sz;
++  int keyspec_sz;
++  unsigned int flags;
++  unsigned char *key;
++  unsigned char *hmac_key;
++  unsigned char *pass;
++  char *keyspec;
++  sqlcipher_provider *provider;
++  void *provider_ctx;
++} cipher_ctx;
++
++static unsigned int default_flags = DEFAULT_CIPHER_FLAGS;
++static unsigned char hmac_salt_mask = HMAC_SALT_MASK;
++static int default_kdf_iter = PBKDF2_ITER;
++static int default_page_size = 1024;
++static unsigned int sqlcipher_activate_count = 0;
++static sqlite3_mutex* sqlcipher_provider_mutex = NULL;
++static sqlcipher_provider *default_provider = NULL;
++
++struct codec_ctx {
++  int kdf_salt_sz;
++  int page_sz;
++  unsigned char *kdf_salt;
++  unsigned char *hmac_kdf_salt;
++  unsigned char *buffer;
++  Btree *pBt;
++  cipher_ctx *read_ctx;
++  cipher_ctx *write_ctx;
++  unsigned int skip_read_hmac;
++  unsigned int need_kdf_salt;
++};
++
++int sqlcipher_register_provider(sqlcipher_provider *p) {
++  CODEC_TRACE_MUTEX("sqlcipher_register_provider: entering sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++  sqlite3_mutex_enter(sqlcipher_provider_mutex);
++  CODEC_TRACE_MUTEX("sqlcipher_register_provider: entered sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++
++  if(default_provider != NULL && default_provider != p) {
++    /* only free the current registerd provider if it has been initialized
++       and it isn't a pointer to the same provider passed to the function
++       (i.e. protect against a caller calling register twice for the same provider) */
++    sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
++  }
++  default_provider = p;   
++  CODEC_TRACE_MUTEX("sqlcipher_register_provider: leaving sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++  sqlite3_mutex_leave(sqlcipher_provider_mutex);
++  CODEC_TRACE_MUTEX("sqlcipher_register_provider: left sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++
++  return SQLITE_OK;
++}
++
++/* return a pointer to the currently registered provider. This will
++   allow an application to fetch the current registered provider and
++   make minor changes to it */
++sqlcipher_provider* sqlcipher_get_provider() {
++  return default_provider;
++}
++
++void sqlcipher_activate() {
++  CODEC_TRACE_MUTEX("sqlcipher_activate: entering static master mutex\n");
++  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
++  CODEC_TRACE_MUTEX("sqlcipher_activate: entered static master mutex\n");
++
++  if(sqlcipher_provider_mutex == NULL) {
++    /* allocate a new mutex to guard access to the provider */
++    CODEC_TRACE_MUTEX("sqlcipher_activate: allocating sqlcipher provider mutex\n");
++    sqlcipher_provider_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
++    CODEC_TRACE_MUTEX("sqlcipher_activate: allocated sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++  }
++
++  /* check to see if there is a provider registered at this point
++     if there no provider registered at this point, register the 
++     default provider */
++  if(sqlcipher_get_provider() == NULL) {
++    sqlcipher_provider *p = sqlcipher_malloc(sizeof(sqlcipher_provider)); 
++#if defined (SQLCIPHER_CRYPTO_CC)
++    extern int sqlcipher_cc_setup(sqlcipher_provider *p);
++    sqlcipher_cc_setup(p);
++#elif defined (SQLCIPHER_CRYPTO_LIBTOMCRYPT)
++    extern int sqlcipher_ltc_setup(sqlcipher_provider *p);
++    sqlcipher_ltc_setup(p);
++#elif defined (SQLCIPHER_CRYPTO_OPENSSL)
++    extern int sqlcipher_openssl_setup(sqlcipher_provider *p);
++    sqlcipher_openssl_setup(p);
++#else
++#error "NO DEFAULT SQLCIPHER CRYPTO PROVIDER DEFINED"
++#endif
++    CODEC_TRACE("sqlcipher_activate: calling sqlcipher_register_provider(%p)\n", p);
++    sqlcipher_register_provider(p);
++    CODEC_TRACE("sqlcipher_activate: called sqlcipher_register_provider(%p)\n",p);
++  }
++
++  sqlcipher_activate_count++; /* increment activation count */
++
++  CODEC_TRACE_MUTEX("sqlcipher_activate: leaving static master mutex\n");
++  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
++  CODEC_TRACE_MUTEX("sqlcipher_activate: left static master mutex\n");
++}
++
++void sqlcipher_deactivate() {
++  CODEC_TRACE_MUTEX("sqlcipher_deactivate: entering static master mutex\n");
++  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
++  CODEC_TRACE_MUTEX("sqlcipher_deactivate: entered static master mutex\n");
++
++  sqlcipher_activate_count--;
++  /* if no connections are using sqlcipher, cleanup globals */
++  if(sqlcipher_activate_count < 1) {
++    int rc;
++    CODEC_TRACE_MUTEX("sqlcipher_deactivate: entering sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++    sqlite3_mutex_enter(sqlcipher_provider_mutex);
++    CODEC_TRACE_MUTEX("sqlcipher_deactivate: entered sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++
++    if(default_provider != NULL) {
++      sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
++      default_provider = NULL;
++    }
++
++    CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++    sqlite3_mutex_leave(sqlcipher_provider_mutex);
++    CODEC_TRACE_MUTEX("sqlcipher_deactivate: left sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
++    
++    /* last connection closed, free provider mutex*/
++    CODEC_TRACE_MUTEX("sqlcipher_deactivate: freeing sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++    sqlite3_mutex_free(sqlcipher_provider_mutex); 
++    CODEC_TRACE_MUTEX("sqlcipher_deactivate: freed sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++
++    sqlcipher_provider_mutex = NULL;
++
++    sqlcipher_activate_count = 0; /* reset activation count */
++  }
++
++  CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving static master mutex\n");
++  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
++  CODEC_TRACE_MUTEX("sqlcipher_deactivate: left static master mutex\n");
++}
++
++/* constant time memset using volitile to avoid having the memset
++   optimized out by the compiler. 
++   Note: As suggested by Joachim Schipper (joachim schipper fox-it com)
++*/
++void* sqlcipher_memset(void *v, unsigned char value, int len) {
++  int i = 0;
++  volatile unsigned char *a = v;
++
++  if (v == NULL) return v;
++
++  CODEC_TRACE("sqlcipher_memset: setting %p[0-%d]=%d)\n", a, len, value);
++  for(i = 0; i < len; i++) {
++    a[i] = value;
++  }
++
++  return v;
++}
++
++/* constant time memory check tests every position of a memory segement
++   matches a single value (i.e. the memory is all zeros)
++   returns 0 if match, 1 of no match */
++int sqlcipher_ismemset(const void *v, unsigned char value, int len) {
++  const unsigned char *a = v;
++  int i = 0, result = 0;
++
++  for(i = 0; i < len; i++) {
++    result |= a[i] ^ value;
++  }
++
++  return (result != 0);
++}
++
++/* constant time memory comparison routine. 
++   returns 0 if match, 1 if no match */
++int sqlcipher_memcmp(const void *v0, const void *v1, int len) {
++  const unsigned char *a0 = v0, *a1 = v1;
++  int i = 0, result = 0;
++
++  for(i = 0; i < len; i++) {
++    result |= a0[i] ^ a1[i];
++  }
++  
++  return (result != 0);
++}
++
++/**
++  * Free and wipe memory. Uses SQLites internal sqlite3_free so that memory
++  * can be countend and memory leak detection works in the test suite. 
++  * If ptr is not null memory will be freed. 
++  * If sz is greater than zero, the memory will be overwritten with zero before it is freed
++  * If sz is > 0, and not compiled with OMIT_MEMLOCK, system will attempt to unlock the
++  * memory segment so it can be paged
++  */
++void sqlcipher_free(void *ptr, int sz) {
++  if(ptr) {
++    if(sz > 0) {
++#ifndef OMIT_MEMLOCK
++      int rc;
++#if defined(__unix__) || defined(__APPLE__) 
++      unsigned long pagesize = sysconf(_SC_PAGESIZE);
++      unsigned long offset = (unsigned long) ptr % pagesize;
++#endif
++#endif
++      CODEC_TRACE("sqlcipher_free: calling sqlcipher_memset(%p,0,%d)\n", ptr, sz);
++      sqlcipher_memset(ptr, 0, sz);
++#ifndef OMIT_MEMLOCK
++#if defined(__unix__) || defined(__APPLE__) 
++      CODEC_TRACE("sqlcipher_free: calling munlock(%p,%lu)\n", ptr - offset, sz + offset);
++      rc = munlock(ptr - offset, sz + offset);
++      if(rc!=0) {
++        CODEC_TRACE("sqlcipher_free: munlock(%p,%lu) returned %d errno=%d\n", ptr - offset, sz + offset, 
rc, errno);
++      }
++#elif defined(_WIN32)
++#if !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == 
WINAPI_FAMILY_APP))
++      rc = VirtualUnlock(ptr, sz);
++      if(!rc) {
++        CODEC_TRACE("sqlcipher_free: VirtualUnlock(%p,%d) returned %d LastError=%d\n", ptr, sz, rc, 
GetLastError());
++      }
++#endif
++#endif
++#endif
++    }
++    sqlite3_free(ptr);
++  }
++}
++
++/**
++  * allocate memory. Uses sqlite's internall malloc wrapper so memory can be 
++  * reference counted and leak detection works. Unless compiled with OMIT_MEMLOCK
++  * attempts to lock the memory pages so sensitive information won't be swapped
++  */
++void* sqlcipher_malloc(int sz) {
++  void *ptr;
++  CODEC_TRACE("sqlcipher_malloc: calling sqlite3Malloc(%d)\n", sz);
++  ptr = sqlite3Malloc(sz);
++  CODEC_TRACE("sqlcipher_malloc: calling sqlcipher_memset(%p,0,%d)\n", ptr, sz);
++  sqlcipher_memset(ptr, 0, sz);
++#ifndef OMIT_MEMLOCK
++  if(ptr) {
++    int rc;
++#if defined(__unix__) || defined(__APPLE__) 
++    unsigned long pagesize = sysconf(_SC_PAGESIZE);
++    unsigned long offset = (unsigned long) ptr % pagesize;
++    CODEC_TRACE("sqlcipher_malloc: calling mlock(%p,%lu); _SC_PAGESIZE=%lu\n", ptr - offset, sz + offset, 
pagesize);
++    rc = mlock(ptr - offset, sz + offset);
++    if(rc!=0) {
++      CODEC_TRACE("sqlcipher_malloc: mlock(%p,%lu) returned %d errno=%d\n", ptr - offset, sz + offset, rc, 
errno);
++    }
++#elif defined(_WIN32)
++#if !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == 
WINAPI_FAMILY_APP))
++    rc = VirtualLock(ptr, sz);
++    if(rc==0) {
++      CODEC_TRACE("sqlcipher_malloc: VirtualLock(%p,%d) returned %d LastError=%d\n", ptr, sz, rc, 
GetLastError());
++    }
++#endif
++#endif
++  }
++#endif
++  return ptr;
++}
++
++
++/**
++  * Initialize new cipher_ctx struct. This function will allocate memory
++  * for the cipher context and for the key
++  * 
++  * returns SQLITE_OK if initialization was successful
++  * returns SQLITE_NOMEM if an error occured allocating memory
++  */
++static int sqlcipher_cipher_ctx_init(cipher_ctx **iCtx) {
++  int rc;
++  cipher_ctx *ctx;
++  CODEC_TRACE("sqlcipher_cipher_ctx_init: allocating context\n");
++  *iCtx = (cipher_ctx *) sqlcipher_malloc(sizeof(cipher_ctx));
++  ctx = *iCtx;
++  if(ctx == NULL) return SQLITE_NOMEM;
++
++  CODEC_TRACE("sqlcipher_cipher_ctx_init: allocating provider\n");
++  ctx->provider = (sqlcipher_provider *) sqlcipher_malloc(sizeof(sqlcipher_provider));
++  if(ctx->provider == NULL) return SQLITE_NOMEM;
++
++  /* make a copy of the provider to be used for the duration of the context */
++  CODEC_TRACE_MUTEX("sqlcipher_cipher_ctx_init: entering sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++  sqlite3_mutex_enter(sqlcipher_provider_mutex);
++  CODEC_TRACE_MUTEX("sqlcipher_cipher_ctx_init: entered sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++
++  memcpy(ctx->provider, default_provider, sizeof(sqlcipher_provider));
++
++  CODEC_TRACE_MUTEX("sqlcipher_cipher_ctx_init: leaving sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++  sqlite3_mutex_leave(sqlcipher_provider_mutex);
++  CODEC_TRACE_MUTEX("sqlcipher_cipher_ctx_init: left sqlcipher provider mutex %p\n", 
sqlcipher_provider_mutex);
++
++  CODEC_TRACE("sqlcipher_cipher_ctx_init: calling provider ctx_init\n");
++  if((rc = ctx->provider->ctx_init(&ctx->provider_ctx)) != SQLITE_OK) return rc;
++
++  CODEC_TRACE("sqlcipher_cipher_ctx_init: allocating key\n");
 +  ctx->key = (unsigned char *) sqlcipher_malloc(CIPHER_MAX_KEY_SZ);
++
++  CODEC_TRACE("sqlcipher_cipher_ctx_init: allocating hmac_key\n");
 +  ctx->hmac_key = (unsigned char *) sqlcipher_malloc(CIPHER_MAX_KEY_SZ);
++
 +  if(ctx->key == NULL) return SQLITE_NOMEM;
 +  if(ctx->hmac_key == NULL) return SQLITE_NOMEM;
++
++  /* setup default flags */
++  ctx->flags = default_flags;
++
++  return SQLITE_OK;
++}
++
++/**
++  * Free and wipe memory associated with a cipher_ctx
++  */
++static void sqlcipher_cipher_ctx_free(cipher_ctx **iCtx) {
++  cipher_ctx *ctx = *iCtx;
++  CODEC_TRACE("cipher_ctx_free: entered iCtx=%p\n", iCtx);
++  ctx->provider->ctx_free(&ctx->provider_ctx);
++  sqlcipher_free(ctx->provider, sizeof(sqlcipher_provider)); 
++  sqlcipher_free(ctx->key, ctx->key_sz);
++  sqlcipher_free(ctx->hmac_key, ctx->key_sz);
++  sqlcipher_free(ctx->pass, ctx->pass_sz);
++  sqlcipher_free(ctx->keyspec, ctx->keyspec_sz);
++  sqlcipher_free(ctx, sizeof(cipher_ctx)); 
++}
++
++/**
++  * Compare one cipher_ctx to another.
++  *
++  * returns 0 if all the parameters (except the derived key data) are the same
++  * returns 1 otherwise
++  */
++static int sqlcipher_cipher_ctx_cmp(cipher_ctx *c1, cipher_ctx *c2) {
++  int are_equal = (
++    c1->iv_sz == c2->iv_sz
++    && c1->kdf_iter == c2->kdf_iter
++    && c1->fast_kdf_iter == c2->fast_kdf_iter
++    && c1->key_sz == c2->key_sz
++    && c1->pass_sz == c2->pass_sz
++    && c1->flags == c2->flags
++    && c1->hmac_sz == c2->hmac_sz
++    && c1->provider->ctx_cmp(c1->provider_ctx, c2->provider_ctx) 
++    && (
++      c1->pass == c2->pass
++      || !sqlcipher_memcmp((const unsigned char*)c1->pass,
++                           (const unsigned char*)c2->pass,
++                           c1->pass_sz)
++    ));
++
++  CODEC_TRACE("sqlcipher_cipher_ctx_cmp: entered \
++                  c1=%p c2=%p \
++                  c1->iv_sz=%d c2->iv_sz=%d \
++                  c1->kdf_iter=%d c2->kdf_iter=%d \
++                  c1->fast_kdf_iter=%d c2->fast_kdf_iter=%d \
++                  c1->key_sz=%d c2->key_sz=%d \
++                  c1->pass_sz=%d c2->pass_sz=%d \
++                  c1->flags=%d c2->flags=%d \
++                  c1->hmac_sz=%d c2->hmac_sz=%d \
++                  c1->provider_ctx=%p c2->provider_ctx=%p \
++                  c1->pass=%p c2->pass=%p \
++                  c1->pass=%s c2->pass=%s \
++                  provider->ctx_cmp=%d \
++                  sqlcipher_memcmp=%d \
++                  are_equal=%d \
++                   \n", 
++                  c1, c2,
++                  c1->iv_sz, c2->iv_sz,
++                  c1->kdf_iter, c2->kdf_iter,
++                  c1->fast_kdf_iter, c2->fast_kdf_iter,
++                  c1->key_sz, c2->key_sz,
++                  c1->pass_sz, c2->pass_sz,
++                  c1->flags, c2->flags,
++                  c1->hmac_sz, c2->hmac_sz,
++                  c1->provider_ctx, c2->provider_ctx,
++                  c1->pass, c2->pass,
++                  c1->pass, c2->pass,
++                  c1->provider->ctx_cmp(c1->provider_ctx, c2->provider_ctx),
++                  (c1->pass == NULL || c2->pass == NULL) 
++                    ? -1 : sqlcipher_memcmp(
++                      (const unsigned char*)c1->pass,
++                      (const unsigned char*)c2->pass,
++                      c1->pass_sz),
++                  are_equal
++                  );
++
++  return !are_equal; /* return 0 if they are the same, 1 otherwise */
++}
++
++/**
++  * Copy one cipher_ctx to another. For instance, assuming that read_ctx is a 
++  * fully initialized context, you could copy it to write_ctx and all yet data
++  * and pass information across
++  *
++  * returns SQLITE_OK if initialization was successful
++  * returns SQLITE_NOMEM if an error occured allocating memory
++  */
++static int sqlcipher_cipher_ctx_copy(cipher_ctx *target, cipher_ctx *source) {
++  void *key = target->key; 
++  void *hmac_key = target->hmac_key; 
++  void *provider = target->provider;
++  void *provider_ctx = target->provider_ctx;
++
++  CODEC_TRACE("sqlcipher_cipher_ctx_copy: entered target=%p, source=%p\n", target, source);
++  sqlcipher_free(target->pass, target->pass_sz); 
++  sqlcipher_free(target->keyspec, target->keyspec_sz); 
++  memcpy(target, source, sizeof(cipher_ctx));
++
++  target->key = key; //restore pointer to previously allocated key data
++  memcpy(target->key, source->key, CIPHER_MAX_KEY_SZ);
++
++  target->hmac_key = hmac_key; //restore pointer to previously allocated hmac key data
++  memcpy(target->hmac_key, source->hmac_key, CIPHER_MAX_KEY_SZ);
++
++  target->provider = provider; // restore pointer to previouly allocated provider;
++  memcpy(target->provider, source->provider, sizeof(sqlcipher_provider));
++
++  target->provider_ctx = provider_ctx; // restore pointer to previouly allocated provider context;
++  target->provider->ctx_copy(target->provider_ctx, source->provider_ctx);
++
++  if(source->pass && source->pass_sz) {
++    target->pass = sqlcipher_malloc(source->pass_sz);
++    if(target->pass == NULL) return SQLITE_NOMEM;
++    memcpy(target->pass, source->pass, source->pass_sz);
++  }
++  if(source->keyspec && source->keyspec_sz) {
++    target->keyspec = sqlcipher_malloc(source->keyspec_sz);
++    if(target->keyspec == NULL) return SQLITE_NOMEM;
++    memcpy(target->keyspec, source->keyspec, source->keyspec_sz);
++  }
++  return SQLITE_OK;
++}
++
++/**
++  * Set the keyspec for the cipher_ctx
++  * 
++  * returns SQLITE_OK if assignment was successfull
++  * returns SQLITE_NOMEM if an error occured allocating memory
++  */
++static int sqlcipher_cipher_ctx_set_keyspec(cipher_ctx *ctx, const unsigned char *key, int key_sz, const 
unsigned char *salt, int salt_sz) {
++
++    /* free, zero existing pointers and size */
++  sqlcipher_free(ctx->keyspec, ctx->keyspec_sz);
++  ctx->keyspec = NULL;
++  ctx->keyspec_sz = 0;
++
++  /* establic a hex-formated key specification, containing the raw encryption key and
++     the salt used to generate it */
++  ctx->keyspec_sz = ((key_sz + salt_sz) * 2) + 3;
++  ctx->keyspec = sqlcipher_malloc(ctx->keyspec_sz);
++  if(ctx->keyspec == NULL) return SQLITE_NOMEM;
++
++  ctx->keyspec[0] = 'x';
++  ctx->keyspec[1] = '\'';
++  cipher_bin2hex(key, key_sz, ctx->keyspec + 2);
++  cipher_bin2hex(salt, salt_sz, ctx->keyspec + (key_sz * 2) + 2);
++  ctx->keyspec[ctx->keyspec_sz - 1] = '\'';
++  return SQLITE_OK;
++}
++
++int sqlcipher_codec_get_store_pass(codec_ctx *ctx) {
++  return ctx->read_ctx->store_pass;
++}
++
++void sqlcipher_codec_set_store_pass(codec_ctx *ctx, int value) {
++  ctx->read_ctx->store_pass = value;
++}
++
++void sqlcipher_codec_get_pass(codec_ctx *ctx, void **zKey, int *nKey) {
++  *zKey = ctx->read_ctx->pass;
++  *nKey = ctx->read_ctx->pass_sz;
++}
++
++/**
++  * Set the passphrase for the cipher_ctx
++  * 
++  * returns SQLITE_OK if assignment was successfull
++  * returns SQLITE_NOMEM if an error occured allocating memory
++  */
++static int sqlcipher_cipher_ctx_set_pass(cipher_ctx *ctx, const void *zKey, int nKey) {
++
++  /* free, zero existing pointers and size */
++  sqlcipher_free(ctx->pass, ctx->pass_sz);
++  ctx->pass = NULL;
++  ctx->pass_sz = 0;
++
++  if(zKey && nKey) { /* if new password is provided, copy it */
++    ctx->pass_sz = nKey;
++    ctx->pass = sqlcipher_malloc(nKey);
++    if(ctx->pass == NULL) return SQLITE_NOMEM;
++    memcpy(ctx->pass, zKey, nKey);
++  } 
++  return SQLITE_OK;
++}
++
++int sqlcipher_codec_ctx_set_pass(codec_ctx *ctx, const void *zKey, int nKey, int for_ctx) {
++  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
++  int rc;
++
++  if((rc = sqlcipher_cipher_ctx_set_pass(c_ctx, zKey, nKey)) != SQLITE_OK) return rc; 
++  c_ctx->derive_key = 1;
++
++  if(for_ctx == 2)
++    if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK) 
++      return rc; 
++
++  return SQLITE_OK;
++} 
++
++int sqlcipher_codec_ctx_set_cipher(codec_ctx *ctx, const char *cipher_name, int for_ctx) {
++  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
++  int rc;
++
++  rc = c_ctx->provider->set_cipher(c_ctx->provider_ctx, cipher_name);
++  if(rc != SQLITE_OK){
++    sqlcipher_codec_ctx_set_error(ctx, rc);
++    return rc;
++  }
++  c_ctx->key_sz = c_ctx->provider->get_key_sz(c_ctx->provider_ctx);
++  c_ctx->iv_sz = c_ctx->provider->get_iv_sz(c_ctx->provider_ctx);
++  c_ctx->block_sz = c_ctx->provider->get_block_sz(c_ctx->provider_ctx);
++  c_ctx->hmac_sz = c_ctx->provider->get_hmac_sz(c_ctx->provider_ctx);
++  c_ctx->derive_key = 1;
++
++  if(for_ctx == 2)
++    if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK)
++      return rc; 
++
++  return SQLITE_OK;
++}
++
++const char* sqlcipher_codec_ctx_get_cipher(codec_ctx *ctx, int for_ctx) {
++  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
++  return c_ctx->provider->get_cipher(c_ctx->provider_ctx);
++}
++
++/* set the global default KDF iteration */
++void sqlcipher_set_default_kdf_iter(int iter) {
++  default_kdf_iter = iter; 
++}
++
++int sqlcipher_get_default_kdf_iter() {
++  return default_kdf_iter;
++}
++
++int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *ctx, int kdf_iter, int for_ctx) {
++  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
++  int rc;
++
++  c_ctx->kdf_iter = kdf_iter;
++  c_ctx->derive_key = 1;
++
++  if(for_ctx == 2)
++    if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK)
++      return rc; 
++
++  return SQLITE_OK;
++}
++
++int sqlcipher_codec_ctx_get_kdf_iter(codec_ctx *ctx, int for_ctx) {
++  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
++  return c_ctx->kdf_iter;
++}
++
++int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *ctx, int fast_kdf_iter, int for_ctx) {
++  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
++  int rc;
++
++  c_ctx->fast_kdf_iter = fast_kdf_iter;
++  c_ctx->derive_key = 1;
++
++  if(for_ctx == 2)
++    if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK)
++      return rc; 
++
++  return SQLITE_OK;
++}
++
++int sqlcipher_codec_ctx_get_fast_kdf_iter(codec_ctx *ctx, int for_ctx) {
++  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
++  return c_ctx->fast_kdf_iter;
++}
++
++/* set the global default flag for HMAC */
++void sqlcipher_set_default_use_hmac(int use) {
++  if(use) default_flags |= CIPHER_FLAG_HMAC; 
++  else default_flags &= ~CIPHER_FLAG_HMAC; 
++}
++
++int sqlcipher_get_default_use_hmac() {
++  return (default_flags & CIPHER_FLAG_HMAC) != 0;
++}
++
++void sqlcipher_set_hmac_salt_mask(unsigned char mask) {
++  hmac_salt_mask = mask;
++}
++
++unsigned char sqlcipher_get_hmac_salt_mask() {
++  return hmac_salt_mask;
++}
++
++/* set the codec flag for whether this individual database should be using hmac */
++int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use) {
++  int reserve = CIPHER_MAX_IV_SZ; /* base reserve size will be IV only */ 
++
++  if(use) reserve += ctx->read_ctx->hmac_sz; /* if reserve will include hmac, update that size */
++
++  /* calculate the amount of reserve needed in even increments of the cipher block size */
++
++  reserve = ((reserve % ctx->read_ctx->block_sz) == 0) ? reserve :
++               ((reserve / ctx->read_ctx->block_sz) + 1) * ctx->read_ctx->block_sz;  
++
++  CODEC_TRACE("sqlcipher_codec_ctx_set_use_hmac: use=%d block_sz=%d md_size=%d reserve=%d\n", 
++                use, ctx->read_ctx->block_sz, ctx->read_ctx->hmac_sz, reserve); 
++
++  
++  if(use) {
++    sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_HMAC);
++  } else {
++    sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_HMAC);
++  } 
++  
++  ctx->write_ctx->reserve_sz = ctx->read_ctx->reserve_sz = reserve;
++
++  return SQLITE_OK;
++}
++
++int sqlcipher_codec_ctx_get_use_hmac(codec_ctx *ctx, int for_ctx) {
++  cipher_ctx * c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
++  return (c_ctx->flags & CIPHER_FLAG_HMAC) != 0;
++}
++
++int sqlcipher_codec_ctx_set_flag(codec_ctx *ctx, unsigned int flag) {
++  ctx->write_ctx->flags |= flag;
++  ctx->read_ctx->flags |= flag;
++  return SQLITE_OK;
++}
++
++int sqlcipher_codec_ctx_unset_flag(codec_ctx *ctx, unsigned int flag) {
++  ctx->write_ctx->flags &= ~flag;
++  ctx->read_ctx->flags &= ~flag;
++  return SQLITE_OK;
++}
++
++int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag, int for_ctx) {
++  cipher_ctx * c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
++  return (c_ctx->flags & flag) != 0;
++}
++
++void sqlcipher_codec_ctx_set_error(codec_ctx *ctx, int error) {
++  CODEC_TRACE("sqlcipher_codec_ctx_set_error: ctx=%p, error=%d\n", ctx, error);
++  sqlite3pager_sqlite3PagerSetError(ctx->pBt->pBt->pPager, error);
++  ctx->pBt->pBt->db->errCode = error;
++}
++
++int sqlcipher_codec_ctx_get_reservesize(codec_ctx *ctx) {
++  return ctx->read_ctx->reserve_sz;
++}
++
++void* sqlcipher_codec_ctx_get_data(codec_ctx *ctx) {
++  return ctx->buffer;
++}
++
++void* sqlcipher_codec_ctx_get_kdf_salt(codec_ctx *ctx) {
++  return ctx->kdf_salt;
++}
++
++void sqlcipher_codec_get_keyspec(codec_ctx *ctx, void **zKey, int *nKey) {
++  *zKey = ctx->read_ctx->keyspec;
++  *nKey = ctx->read_ctx->keyspec_sz;
++}
++
++int sqlcipher_codec_ctx_set_pagesize(codec_ctx *ctx, int size) {
++  if(!((size != 0) && ((size & (size - 1)) == 0)) || size < 512 || size > 65536) {
++    CODEC_TRACE(("cipher_page_size not a power of 2 and between 512 and 65536 inclusive\n"));
++    return SQLITE_ERROR;
++  }
++  /* attempt to free the existing page buffer */
++  sqlcipher_free(ctx->buffer,ctx->page_sz);
++  ctx->page_sz = size;
++
++  /* pre-allocate a page buffer of PageSize bytes. This will
++     be used as a persistent buffer for encryption and decryption 
++     operations to avoid overhead of multiple memory allocations*/
++  ctx->buffer = sqlcipher_malloc(size);
++  if(ctx->buffer == NULL) return SQLITE_NOMEM;
++
++  return SQLITE_OK;
++}
++
++int sqlcipher_codec_ctx_get_pagesize(codec_ctx *ctx) {
++  return ctx->page_sz;
++}
++
++void sqlcipher_set_default_pagesize(int page_size) {
++  default_page_size = page_size;
++}
++
++int sqlcipher_get_default_pagesize() {
++  return default_page_size;
++}
++
++int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_file *fd, const void *zKey, 
int nKey) {
++  int rc;
++  codec_ctx *ctx;
++
++  CODEC_TRACE("sqlcipher_codec_ctx_init: allocating context\n");
++
++  *iCtx = sqlcipher_malloc(sizeof(codec_ctx));
++  ctx = *iCtx;
++
++  if(ctx == NULL) return SQLITE_NOMEM;
++
++  ctx->pBt = pDb->pBt; /* assign pointer to database btree structure */
++
++  /* allocate space for salt data. Then read the first 16 bytes 
++       directly off the database file. This is the salt for the
++       key derivation function. If we get a short read allocate
++       a new random salt value */
++  CODEC_TRACE("sqlcipher_codec_ctx_init: allocating kdf_salt\n");
++  ctx->kdf_salt_sz = FILE_HEADER_SZ;
++  ctx->kdf_salt = sqlcipher_malloc(ctx->kdf_salt_sz);
++  if(ctx->kdf_salt == NULL) return SQLITE_NOMEM;
++
++  /* allocate space for separate hmac salt data. We want the
++     HMAC derivation salt to be different than the encryption
++     key derivation salt */
++  CODEC_TRACE("sqlcipher_codec_ctx_init: allocating hmac_kdf_salt\n");
++  ctx->hmac_kdf_salt = sqlcipher_malloc(ctx->kdf_salt_sz);
++  if(ctx->hmac_kdf_salt == NULL) return SQLITE_NOMEM;
++
++
++  /*
++     Always overwrite page size and set to the default because the first page of the database
++     in encrypted and thus sqlite can't effectively determine the pagesize. this causes an issue in 
++     cases where bytes 16 & 17 of the page header are a power of 2 as reported by John Lehman
++  */
++  CODEC_TRACE("sqlcipher_codec_ctx_init: calling sqlcipher_codec_ctx_set_pagesize with %d\n", 
default_page_size);
++  if((rc = sqlcipher_codec_ctx_set_pagesize(ctx, default_page_size)) != SQLITE_OK) return rc;
++
++  CODEC_TRACE("sqlcipher_codec_ctx_init: initializing read_ctx\n");
++  if((rc = sqlcipher_cipher_ctx_init(&ctx->read_ctx)) != SQLITE_OK) return rc; 
++
++  CODEC_TRACE("sqlcipher_codec_ctx_init: initializing write_ctx\n");
++  if((rc = sqlcipher_cipher_ctx_init(&ctx->write_ctx)) != SQLITE_OK) return rc; 
++
++  CODEC_TRACE("sqlcipher_codec_ctx_init: reading file header\n");
++  if(fd == NULL || sqlite3OsRead(fd, ctx->kdf_salt, FILE_HEADER_SZ, 0) != SQLITE_OK) {
++    ctx->need_kdf_salt = 1;
++  }
++
++  CODEC_TRACE("sqlcipher_codec_ctx_init: setting cipher\n");
++  if((rc = sqlcipher_codec_ctx_set_cipher(ctx, CIPHER, 0)) != SQLITE_OK) return rc;
++
++  CODEC_TRACE("sqlcipher_codec_ctx_init: setting default_kdf_iter\n");
++  if((rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, default_kdf_iter, 0)) != SQLITE_OK) return rc;
++
++  CODEC_TRACE("sqlcipher_codec_ctx_init: setting fast_kdf_iter\n");
++  if((rc = sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, FAST_PBKDF2_ITER, 0)) != SQLITE_OK) return rc;
++
++  CODEC_TRACE("sqlcipher_codec_ctx_init: setting pass key\n");
++  if((rc = sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, 0)) != SQLITE_OK) return rc;
++
++  /* Note that use_hmac is a special case that requires recalculation of page size
++     so we call set_use_hmac to perform setup */
++  CODEC_TRACE("sqlcipher_codec_ctx_init: setting use_hmac\n");
++  if((rc = sqlcipher_codec_ctx_set_use_hmac(ctx, default_flags & CIPHER_FLAG_HMAC)) != SQLITE_OK) return rc;
++
++  CODEC_TRACE("sqlcipher_codec_ctx_init: copying write_ctx to read_ctx\n");
++  if((rc = sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx)) != SQLITE_OK) return rc;
++
++  return SQLITE_OK;
++}
++
++/**
++  * Free and wipe memory associated with a cipher_ctx, including the allocated
++  * read_ctx and write_ctx.
++  */
++void sqlcipher_codec_ctx_free(codec_ctx **iCtx) {
++  codec_ctx *ctx = *iCtx;
++  CODEC_TRACE("codec_ctx_free: entered iCtx=%p\n", iCtx);
++  sqlcipher_free(ctx->kdf_salt, ctx->kdf_salt_sz);
++  sqlcipher_free(ctx->hmac_kdf_salt, ctx->kdf_salt_sz);
++  sqlcipher_free(ctx->buffer, 0);
++  sqlcipher_cipher_ctx_free(&ctx->read_ctx);
++  sqlcipher_cipher_ctx_free(&ctx->write_ctx);
++  sqlcipher_free(ctx, sizeof(codec_ctx)); 
++}
++
++/** convert a 32bit unsigned integer to little endian byte ordering */
++static void sqlcipher_put4byte_le(unsigned char *p, u32 v) { 
++  p[0] = (u8)v;
++  p[1] = (u8)(v>>8);
++  p[2] = (u8)(v>>16);
++  p[3] = (u8)(v>>24);
++}
++
++static int sqlcipher_page_hmac(cipher_ctx *ctx, Pgno pgno, unsigned char *in, int in_sz, unsigned char 
*out) {
++  unsigned char pgno_raw[sizeof(pgno)];
++  /* we may convert page number to consistent representation before calculating MAC for
++     compatibility across big-endian and little-endian platforms. 
++
++     Note: The public release of sqlcipher 2.0.0 to 2.0.6 had a bug where the bytes of pgno 
++     were used directly in the MAC. SQLCipher convert's to little endian by default to preserve
++     backwards compatibility on the most popular platforms, but can optionally be configured
++     to use either big endian or native byte ordering via pragma. */
++
++  if(ctx->flags & CIPHER_FLAG_LE_PGNO) { /* compute hmac using little endian pgno*/
++    sqlcipher_put4byte_le(pgno_raw, pgno);
++  } else if(ctx->flags & CIPHER_FLAG_BE_PGNO) { /* compute hmac using big endian pgno */
++    sqlite3Put4byte(pgno_raw, pgno); /* sqlite3Put4byte converts 32bit uint to big endian  */
++  } else { /* use native byte ordering */
++    memcpy(pgno_raw, &pgno, sizeof(pgno));
++  }
++
++  /* include the encrypted page data,  initialization vector, and page number in HMAC. This will 
++     prevent both tampering with the ciphertext, manipulation of the IV, or resequencing otherwise
++     valid pages out of order in a database */ 
++  ctx->provider->hmac(
++    ctx->provider_ctx, ctx->hmac_key,
++    ctx->key_sz, in,
++    in_sz, (unsigned char*) &pgno_raw,
++    sizeof(pgno), out);
++  return SQLITE_OK; 
++}
++
++/*
++ * ctx - codec context
++ * pgno - page number in database
++ * size - size in bytes of input and output buffers
++ * mode - 1 to encrypt, 0 to decrypt
++ * in - pointer to input bytes
++ * out - pouter to output bytes
++ */
++int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int page_sz, unsigned char *in, 
unsigned char *out) {
++  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
++  unsigned char *iv_in, *iv_out, *hmac_in, *hmac_out, *out_start;
++  int size;
++
++  /* calculate some required positions into various buffers */
++  size = page_sz - c_ctx->reserve_sz; /* adjust size to useable size and memset reserve at end of page */
++  iv_out = out + size;
++  iv_in = in + size;
++
++  /* hmac will be written immediately after the initialization vector. the remainder of the page reserve 
will contain
++     random bytes. note, these pointers are only valid when using hmac */
++  hmac_in = in + size + c_ctx->iv_sz; 
++  hmac_out = out + size + c_ctx->iv_sz;
++  out_start = out; /* note the original position of the output buffer pointer, as out will be rewritten 
during encryption */
++
++  CODEC_TRACE("codec_cipher:entered pgno=%d, mode=%d, size=%d\n", pgno, mode, size);
++  CODEC_HEXDUMP("codec_cipher: input page data", in, page_sz);
++
++  /* the key size should never be zero. If it is, error out. */
++  if(c_ctx->key_sz == 0) {
++    CODEC_TRACE("codec_cipher: error possible context corruption, key_sz is zero for pgno=%d\n", pgno);
++    sqlcipher_memset(out, 0, page_sz); 
++    return SQLITE_ERROR;
++  } 
++
++  if(mode == CIPHER_ENCRYPT) {
++    /* start at front of the reserve block, write random data to the end */
++    if(c_ctx->provider->random(c_ctx->provider_ctx, iv_out, c_ctx->reserve_sz) != SQLITE_OK) return 
SQLITE_ERROR; 
++  } else { /* CIPHER_DECRYPT */
++    memcpy(iv_out, iv_in, c_ctx->iv_sz); /* copy the iv from the input to output buffer */
++  } 
++
++  if((c_ctx->flags & CIPHER_FLAG_HMAC) && (mode == CIPHER_DECRYPT) && !ctx->skip_read_hmac) {
++    if(sqlcipher_page_hmac(c_ctx, pgno, in, size + c_ctx->iv_sz, hmac_out) != SQLITE_OK) {
++      sqlcipher_memset(out, 0, page_sz); 
++      CODEC_TRACE("codec_cipher: hmac operations failed for pgno=%d\n", pgno);
++      return SQLITE_ERROR;
++    }
++
++    CODEC_TRACE("codec_cipher: comparing hmac on in=%p out=%p hmac_sz=%d\n", hmac_in, hmac_out, 
c_ctx->hmac_sz);
++    if(sqlcipher_memcmp(hmac_in, hmac_out, c_ctx->hmac_sz) != 0) { /* the hmac check failed */ 
++      if(sqlcipher_ismemset(in, 0, page_sz) == 0) {
++        /* first check if the entire contents of the page is zeros. If so, this page 
++           resulted from a short read (i.e. sqlite attempted to pull a page after the end of the file. 
these 
++           short read failures must be ignored for autovaccum mode to work so wipe the output buffer 
++           and return SQLITE_OK to skip the decryption step. */
++        CODEC_TRACE("codec_cipher: zeroed page (short read) for pgno %d, encryption but returning 
SQLITE_OK\n", pgno);
++        sqlcipher_memset(out, 0, page_sz); 
++      return SQLITE_OK;
++      } else {
++      /* if the page memory is not all zeros, it means the there was data and a hmac on the page. 
++           since the check failed, the page was either tampered with or corrupted. wipe the output buffer,
++           and return SQLITE_ERROR to the caller */
++              CODEC_TRACE("codec_cipher: hmac check failed for pgno=%d returning SQLITE_ERROR\n", pgno);
++        sqlcipher_memset(out, 0, page_sz); 
++              return SQLITE_ERROR;
++      }
++    }
++  } 
++  
++  c_ctx->provider->cipher(c_ctx->provider_ctx, mode, c_ctx->key, c_ctx->key_sz, iv_out, in, size, out);
++
++  if((c_ctx->flags & CIPHER_FLAG_HMAC) && (mode == CIPHER_ENCRYPT)) {
++    sqlcipher_page_hmac(c_ctx, pgno, out_start, size + c_ctx->iv_sz, hmac_out); 
++  }
++
++  CODEC_HEXDUMP("codec_cipher: output page data", out_start, page_sz);
++
++  return SQLITE_OK;
++}
++
++/**
++  * Derive an encryption key for a cipher contex key based on the raw password.
++  *
++  * If the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
++  * the key (i.e 64 hex chars for a 256 bit key) then the key data will be used directly. 
++
++  * Else, if the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
++  * the key and the salt (i.e 92 hex chars for a 256 bit key and 16 byte salt) then it will be unpacked
++  * as the key followed by the salt.
++  * 
++  * Otherwise, a key data will be derived using PBKDF2
++  * 
++  * returns SQLITE_OK if initialization was successful
++  * returns SQLITE_ERROR if the key could't be derived (for instance if pass is NULL or pass_sz is 0)
++  */
++static int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
++  int rc;
++  CODEC_TRACE("cipher_ctx_key_derive: entered c_ctx->pass=%s, c_ctx->pass_sz=%d \
++                ctx->kdf_salt=%p ctx->kdf_salt_sz=%d c_ctx->kdf_iter=%d \
++                ctx->hmac_kdf_salt=%p, c_ctx->fast_kdf_iter=%d c_ctx->key_sz=%d\n", 
++                c_ctx->pass, c_ctx->pass_sz, ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter, 
++                ctx->hmac_kdf_salt, c_ctx->fast_kdf_iter, c_ctx->key_sz); 
++                
++  
++  if(c_ctx->pass && c_ctx->pass_sz) { // if pass is not null
++
++    if(ctx->need_kdf_salt) {
++      if(ctx->read_ctx->provider->random(ctx->read_ctx->provider_ctx, ctx->kdf_salt, FILE_HEADER_SZ) != 
SQLITE_OK) return SQLITE_ERROR;
++      ctx->need_kdf_salt = 0;
++    }
++    if (c_ctx->pass_sz == ((c_ctx->key_sz * 2) + 3) && sqlite3StrNICmp((const char *)c_ctx->pass ,"x'", 2) 
== 0 && cipher_isHex(c_ctx->pass + 2, c_ctx->key_sz * 2)) { 
++      int n = c_ctx->pass_sz - 3; /* adjust for leading x' and tailing ' */
++      const unsigned char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
++      CODEC_TRACE("cipher_ctx_key_derive: using raw key from hex\n");
++      cipher_hex2bin(z, n, c_ctx->key);
++    } else if (c_ctx->pass_sz == (((c_ctx->key_sz + ctx->kdf_salt_sz) * 2) + 3) && sqlite3StrNICmp((const 
char *)c_ctx->pass ,"x'", 2) == 0 && cipher_isHex(c_ctx->pass + 2, (c_ctx->key_sz + ctx->kdf_salt_sz) * 2)) { 
++      const unsigned char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
++      CODEC_TRACE("cipher_ctx_key_derive: using raw key from hex\n"); 
++      cipher_hex2bin(z, (c_ctx->key_sz * 2), c_ctx->key);
++      cipher_hex2bin(z + (c_ctx->key_sz * 2), (ctx->kdf_salt_sz * 2), ctx->kdf_salt);
++    } else { 
++      CODEC_TRACE("cipher_ctx_key_derive: deriving key using full PBKDF2 with %d iterations\n", 
c_ctx->kdf_iter); 
++      c_ctx->provider->kdf(c_ctx->provider_ctx, c_ctx->pass, c_ctx->pass_sz, 
++                    ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter,
++                    c_ctx->key_sz, c_ctx->key);
++    }
++
++    /* set the context "keyspec" containing the hex-formatted key and salt to be used when attaching 
databases */
++    if((rc = sqlcipher_cipher_ctx_set_keyspec(c_ctx, c_ctx->key, c_ctx->key_sz, ctx->kdf_salt, 
ctx->kdf_salt_sz)) != SQLITE_OK) return rc;
++
++    /* if this context is setup to use hmac checks, generate a seperate and different 
++       key for HMAC. In this case, we use the output of the previous KDF as the input to 
++       this KDF run. This ensures a distinct but predictable HMAC key. */
++    if(c_ctx->flags & CIPHER_FLAG_HMAC) {
++      int i;
++
++      /* start by copying the kdf key into the hmac salt slot
++         then XOR it with the fixed hmac salt defined at compile time
++         this ensures that the salt passed in to derive the hmac key, while 
++         easy to derive and publically known, is not the same as the salt used 
++         to generate the encryption key */ 
++      memcpy(ctx->hmac_kdf_salt, ctx->kdf_salt, ctx->kdf_salt_sz);
++      for(i = 0; i < ctx->kdf_salt_sz; i++) {
++        ctx->hmac_kdf_salt[i] ^= hmac_salt_mask;
++      } 
++
++      CODEC_TRACE("cipher_ctx_key_derive: deriving hmac key from encryption key using PBKDF2 with %d 
iterations\n", 
++        c_ctx->fast_kdf_iter); 
++
++      
++      c_ctx->provider->kdf(c_ctx->provider_ctx, c_ctx->key, c_ctx->key_sz, 
++                    ctx->hmac_kdf_salt, ctx->kdf_salt_sz, c_ctx->fast_kdf_iter,
++                    c_ctx->key_sz, c_ctx->hmac_key); 
++    }
++
++    c_ctx->derive_key = 0;
++    return SQLITE_OK;
++  };
++  return SQLITE_ERROR;
++}
++
++int sqlcipher_codec_key_derive(codec_ctx *ctx) {
++  /* derive key on first use if necessary */
++  if(ctx->read_ctx->derive_key) {
++    if(sqlcipher_cipher_ctx_key_derive(ctx, ctx->read_ctx) != SQLITE_OK) return SQLITE_ERROR;
++  }
++
++  if(ctx->write_ctx->derive_key) {
++    if(sqlcipher_cipher_ctx_cmp(ctx->write_ctx, ctx->read_ctx) == 0) {
++      /* the relevant parameters are the same, just copy read key */
++      if(sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx) != SQLITE_OK) return SQLITE_ERROR;
++    } else {
++      if(sqlcipher_cipher_ctx_key_derive(ctx, ctx->write_ctx) != SQLITE_OK) return SQLITE_ERROR;
++    }
++  }
++
++  /* TODO: wipe and free passphrase after key derivation */
++  if(ctx->read_ctx->store_pass  != 1) {
++    sqlcipher_cipher_ctx_set_pass(ctx->read_ctx, NULL, 0);
++    sqlcipher_cipher_ctx_set_pass(ctx->write_ctx, NULL, 0);
++  }
++
++  return SQLITE_OK; 
++}
++
++int sqlcipher_codec_key_copy(codec_ctx *ctx, int source) {
++  if(source == CIPHER_READ_CTX) { 
++      return sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx); 
++  } else {
++      return sqlcipher_cipher_ctx_copy(ctx->read_ctx, ctx->write_ctx); 
++  }
++}
++
++const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx) {
++  return ctx->read_ctx->provider->get_provider_name(ctx->read_ctx);
++}
++
++
++static int sqlcipher_check_connection(const char *filename, char *key, int key_sz, char *sql, int 
*user_version) {
++  int rc;
++  sqlite3 *db = NULL;
++  sqlite3_stmt *statement = NULL;
++  char *query_user_version = "PRAGMA user_version;";
++  
++  rc = sqlite3_open(filename, &db);
++  if(rc != SQLITE_OK){
++    goto cleanup;
++  }
++  rc = sqlite3_key(db, key, key_sz);
++  if(rc != SQLITE_OK){
++    goto cleanup;
++  }
++  rc = sqlite3_exec(db, sql, NULL, NULL, NULL);
++  if(rc != SQLITE_OK){
++    goto cleanup;
++  }
++  rc = sqlite3_prepare(db, query_user_version, -1, &statement, NULL);
++  if(rc != SQLITE_OK){
++    goto cleanup;
++  }
++  rc = sqlite3_step(statement);
++  if(rc == SQLITE_ROW){
++    *user_version = sqlite3_column_int(statement, 0);
++    rc = SQLITE_OK;
++  }
++  
++cleanup:
++  if(statement){
++    sqlite3_finalize(statement);
++  }
++  if(db){
++    sqlite3_close(db);
++  }
++  return rc;
++}
++
++int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
++  u32 meta;
++  int rc = 0;
++  int command_idx = 0;
++  int password_sz;
++  int saved_flags;
++  int saved_nChange;
++  int saved_nTotalChange;
++  u8 saved_mTrace;
++  int (*saved_xTrace)(u32,void*,void*,void*); /* Saved db->xTrace */
++  Db *pDb = 0;
++  sqlite3 *db = ctx->pBt->db;
++  const char *db_filename = sqlite3_db_filename(db, "main");
++  char *migrated_db_filename = sqlite3_mprintf("%s-migrated", db_filename);
++  char *pragma_hmac_off = "PRAGMA cipher_use_hmac = OFF;";
++  char *pragma_4k_kdf_iter = "PRAGMA kdf_iter = 4000;";
++  char *pragma_1x_and_4k;
++  char *set_user_version;
++  char *key;
++  int key_sz;
++  int user_version = 0;
++  int upgrade_1x_format = 0;
++  int upgrade_4k_format = 0;
++  static const unsigned char aCopy[] = {
++    BTREE_SCHEMA_VERSION,     1,  /* Add one to the old schema cookie */
++    BTREE_DEFAULT_CACHE_SIZE, 0,  /* Preserve the default page cache size */
++    BTREE_TEXT_ENCODING,      0,  /* Preserve the text encoding */
++    BTREE_USER_VERSION,       0,  /* Preserve the user version */
++    BTREE_APPLICATION_ID,     0,  /* Preserve the application id */
++  };
++
++
++  key_sz = ctx->read_ctx->pass_sz + 1;
++  key = sqlcipher_malloc(key_sz);
++  memset(key, 0, key_sz);
++  memcpy(key, ctx->read_ctx->pass, ctx->read_ctx->pass_sz);
++
++  if(db_filename){
++    const char* commands[5];
++    char *attach_command = sqlite3_mprintf("ATTACH DATABASE '%s-migrated' as migrate KEY '%q';",
++                                            db_filename, key);
++
++    int rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, "", &user_version);
++    if(rc == SQLITE_OK){
++      CODEC_TRACE("No upgrade required - exiting\n");
++      goto exit;
++    }
++    
++    // Version 2 - check for 4k with hmac format 
++    rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, pragma_4k_kdf_iter, 
&user_version);
++    if(rc == SQLITE_OK) {
++      CODEC_TRACE("Version 2 format found\n");
++      upgrade_4k_format = 1;
++    }
++
++    // Version 1 - check both no hmac and 4k together
++    pragma_1x_and_4k = sqlite3_mprintf("%s%s", pragma_hmac_off,
++                                             pragma_4k_kdf_iter);
++    rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, pragma_1x_and_4k, 
&user_version);
++    sqlite3_free(pragma_1x_and_4k);
++    if(rc == SQLITE_OK) {
++      CODEC_TRACE("Version 1 format found\n");
++      upgrade_1x_format = 1;
++      upgrade_4k_format = 1;
++    }
++
++    if(upgrade_1x_format == 0 && upgrade_4k_format == 0) {
++      CODEC_TRACE("Upgrade format not determined\n");
++      goto handle_error;
++    }
++
++    set_user_version = sqlite3_mprintf("PRAGMA migrate.user_version = %d;", user_version);
++    commands[0] = upgrade_4k_format == 1 ? pragma_4k_kdf_iter : "";
++    commands[1] = upgrade_1x_format == 1 ? pragma_hmac_off : "";
++    commands[2] = attach_command;
++    commands[3] = "SELECT sqlcipher_export('migrate');";
++    commands[4] = set_user_version;
++      
++    for(command_idx = 0; command_idx < ArraySize(commands); command_idx++){
++      const char *command = commands[command_idx];
++      if(strcmp(command, "") == 0){
++        continue;
++      }
++      rc = sqlite3_exec(db, command, NULL, NULL, NULL);
++      if(rc != SQLITE_OK){
++        break;
++      }
++    }
++    sqlite3_free(attach_command);
++    sqlite3_free(set_user_version);
++    sqlcipher_free(key, key_sz);
++    
++    if(rc == SQLITE_OK){
++      Btree *pDest;
++      Btree *pSrc;
++      int i = 0;
++
++      if( !db->autoCommit ){
++        CODEC_TRACE("cannot migrate from within a transaction");
++        goto handle_error;
++      }
++      if( db->nVdbeActive>1 ){
++        CODEC_TRACE("cannot migrate - SQL statements in progress");
++        goto handle_error;
++      }
++
++      /* Save the current value of the database flags so that it can be
++      ** restored before returning. Then set the writable-schema flag, and
++      ** disable CHECK and foreign key constraints.  */
++      saved_flags = db->flags;
++      saved_nChange = db->nChange;
++      saved_nTotalChange = db->nTotalChange;
++      saved_xTrace = db->xTrace;
++      saved_mTrace = db->mTrace;
++      db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
++      db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
++      db->xTrace = 0;
++      db->mTrace = 0;
++      
++      pDest = db->aDb[0].pBt;
++      pDb = &(db->aDb[db->nDb-1]);
++      pSrc = pDb->pBt;
++      
++      rc = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
++      rc = sqlite3BtreeBeginTrans(pSrc, 2);
++      rc = sqlite3BtreeBeginTrans(pDest, 2);
++      
++      assert( 1==sqlite3BtreeIsInTrans(pDest) );
++      assert( 1==sqlite3BtreeIsInTrans(pSrc) );
++
++      sqlite3CodecGetKey(db, db->nDb - 1, (void**)&key, &password_sz);
++      sqlite3CodecAttach(db, 0, key, password_sz);
++      sqlite3pager_get_codec(pDest->pBt->pPager, (void**)&ctx);
++      
++      ctx->skip_read_hmac = 1;      
++      for(i=0; i<ArraySize(aCopy); i+=2){
++        sqlite3BtreeGetMeta(pSrc, aCopy[i], &meta);
++        rc = sqlite3BtreeUpdateMeta(pDest, aCopy[i], meta+aCopy[i+1]);
++        if( NEVER(rc!=SQLITE_OK) ) goto handle_error; 
++      }
++      rc = sqlite3BtreeCopyFile(pDest, pSrc);
++      ctx->skip_read_hmac = 0;
++      if( rc!=SQLITE_OK ) goto handle_error;
++      rc = sqlite3BtreeCommit(pDest);
++
++      db->flags = saved_flags;
++      db->nChange = saved_nChange;
++      db->nTotalChange = saved_nTotalChange;
++      db->xTrace = saved_xTrace;
++      db->mTrace = saved_mTrace;
++      db->autoCommit = 1;
++      sqlite3BtreeClose(pDb->pBt);
++      pDb->pBt = 0;
++      pDb->pSchema = 0;
++      sqlite3ResetAllSchemasOfConnection(db);
++      remove(migrated_db_filename);
++      sqlite3_free(migrated_db_filename);
++    } else {
++      CODEC_TRACE("*** migration failure** \n\n");
++    }
++    
++  }
++  goto exit;
++
++ handle_error:
++  CODEC_TRACE("An error occurred attempting to migrate the database\n");
++  rc = SQLITE_ERROR;
++
++ exit:
++  return rc;
++}
++
++int sqlcipher_codec_add_random(codec_ctx *ctx, const char *zRight, int random_sz){
++  const char *suffix = &zRight[random_sz-1];
++  int n = random_sz - 3; /* adjust for leading x' and tailing ' */
++  if (n > 0 &&
++      sqlite3StrNICmp((const char *)zRight ,"x'", 2) == 0 &&
++      sqlite3StrNICmp(suffix, "'", 1) == 0 &&
++      n % 2 == 0) {
++    int rc = 0;
++    int buffer_sz = n / 2;
++    unsigned char *random;
++    const unsigned char *z = (const unsigned char *)zRight + 2; /* adjust lead offset of x' */
++    CODEC_TRACE("sqlcipher_codec_add_random: using raw random blob from hex\n");
++    random = sqlcipher_malloc(buffer_sz);
++    memset(random, 0, buffer_sz);
++    cipher_hex2bin(z, n, random);
++    rc = ctx->read_ctx->provider->add_random(ctx->read_ctx->provider_ctx, random, buffer_sz);
++    sqlcipher_free(random, buffer_sz);
++    return rc;
++  }
++  return SQLITE_ERROR;
++}
++
++static void sqlcipher_profile_callback(void *file, const char *sql, sqlite3_uint64 run_time){
++  FILE *f = (FILE*)file;
++  double elapsed = run_time/1000000.0;
++  if(f) fprintf(f, "Elapsed time:%.3f ms - %s\n", elapsed, sql);
++}
++
++int sqlcipher_cipher_profile(sqlite3 *db, const char *destination){
++#if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED)
++  return SQLITE_ERROR;
++#else
++  FILE *f;
++  if(sqlite3StrICmp(destination, "stdout") == 0){
++    f = stdout;
++  }else if(sqlite3StrICmp(destination, "stderr") == 0){
++    f = stderr;
++  }else if(sqlite3StrICmp(destination, "off") == 0){
++    f = 0;
++  }else{
++#if defined(_WIN32) && (__STDC_VERSION__ > 199901L) || defined(SQLITE_OS_WINRT)
++    if(fopen_s(&f, destination, "a") != 0){
++#else
++    f = fopen(destination, "a");
++    if(f == 0){
++#endif    
++    return SQLITE_ERROR;
++  }   
++
++  }
++  sqlite3_profile(db, sqlcipher_profile_callback, f);
++  return SQLITE_OK;
++#endif
++}
++
++int sqlcipher_codec_fips_status(codec_ctx *ctx) {
++  return ctx->read_ctx->provider->fips_status(ctx->read_ctx);
++}
++
++const char* sqlcipher_codec_get_provider_version(codec_ctx *ctx) {
++  return ctx->read_ctx->provider->get_provider_version(ctx->read_ctx);
++}
++
++int sqlcipher_codec_hmac(const codec_ctx *ctx, const unsigned char *hmac_key, int key_sz,
++                         unsigned char* in, int in_sz, unsigned char *in2, int in2_sz,
++                         unsigned char *out) {
++  ctx->read_ctx->provider->hmac(ctx->read_ctx, (unsigned char *)hmac_key, key_sz, in, in_sz, in2, in2_sz, 
out);
++  return SQLITE_OK;
++}
++
++
++#endif
++/* END SQLCIPHER */
++
++/************** End of crypto_impl.c *****************************************/
++/************** Begin file crypto_libtomcrypt.c ******************************/
++/*
++** SQLCipher
++** http://sqlcipher.net
++**
++** Copyright (c) 2008 - 2013, ZETETIC LLC
++** All rights reserved.
++**
++** Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are met:
++**     * Redistributions of source code must retain the above copyright
++**       notice, this list of conditions and the following disclaimer.
++**     * Redistributions in binary form must reproduce the above copyright
++**       notice, this list of conditions and the following disclaimer in the
++**       documentation and/or other materials provided with the distribution.
++**     * Neither the name of the ZETETIC LLC nor the
++**       names of its contributors may be used to endorse or promote products
++**       derived from this software without specific prior written permission.
++**
++** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
++** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
++** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++**
++*/
++/* BEGIN SQLCIPHER */
++#ifdef SQLITE_HAS_CODEC
++#ifdef SQLCIPHER_CRYPTO_LIBTOMCRYPT
++/* #include "sqliteInt.h" */
++/* #include "sqlcipher.h" */
++#include <tomcrypt.h>
++
++#define FORTUNA_MAX_SZ 32
++static prng_state prng;
++static unsigned int ltc_init = 0;
++static unsigned int ltc_ref_count = 0;
++static sqlite3_mutex* ltc_rand_mutex = NULL;
++
++static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
++  int rc = 0;
++  int data_to_read = length;
++  int block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
++  const unsigned char * data = (const unsigned char *)buffer;
++#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
++  sqlite3_mutex_enter(ltc_rand_mutex);
++#endif
++    while(data_to_read > 0){
++      rc = fortuna_add_entropy(data, block_sz, &prng);
++      rc = rc != CRYPT_OK ? SQLITE_ERROR : SQLITE_OK;
++      if(rc != SQLITE_OK){
++        break;
++      }
++      data_to_read -= block_sz;
++      data += block_sz;
++      block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
++    }
++    fortuna_ready(&prng);
++#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
++  sqlite3_mutex_leave(ltc_rand_mutex);
++#endif
++  return rc;
++}
++
++static int sqlcipher_ltc_activate(void *ctx) {
++  unsigned char random_buffer[FORTUNA_MAX_SZ];
++#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
++  if(ltc_rand_mutex == NULL){
++    ltc_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
++  }
++  sqlite3_mutex_enter(ltc_rand_mutex);
++#endif
++  sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
++  if(ltc_init == 0) {
++    if(register_prng(&fortuna_desc) != CRYPT_OK) return SQLITE_ERROR;
++    if(register_cipher(&rijndael_desc) != CRYPT_OK) return SQLITE_ERROR;
++    if(register_hash(&sha1_desc) != CRYPT_OK) return SQLITE_ERROR;
++    if(fortuna_start(&prng) != CRYPT_OK) {
++      return SQLITE_ERROR;
++    }
++    ltc_init = 1;
++  }
++  ltc_ref_count++;
++#ifndef SQLCIPHER_TEST
++  sqlite3_randomness(FORTUNA_MAX_SZ, random_buffer);
++#endif
++#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
++  sqlite3_mutex_leave(ltc_rand_mutex);
++#endif
++  if(sqlcipher_ltc_add_random(ctx, random_buffer, FORTUNA_MAX_SZ) != SQLITE_OK) {
++    return SQLITE_ERROR;
++  }
++  sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
++  return SQLITE_OK;
++}
++
++static int sqlcipher_ltc_deactivate(void *ctx) {
++#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
++  sqlite3_mutex_enter(ltc_rand_mutex);
++#endif
++  ltc_ref_count--;
++  if(ltc_ref_count == 0){
++    fortuna_done(&prng);
++    sqlcipher_memset((void *)&prng, 0, sizeof(prng));
++#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
++    sqlite3_mutex_leave(ltc_rand_mutex);
++    sqlite3_mutex_free(ltc_rand_mutex);
++    ltc_rand_mutex = NULL;
++#endif
++  }
++#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
++  else {
++    sqlite3_mutex_leave(ltc_rand_mutex);
++  }
++#endif    
++  return SQLITE_OK;
++}
++
++static const char* sqlcipher_ltc_get_provider_name(void *ctx) {
++  return "libtomcrypt";
++}
++
++static const char* sqlcipher_ltc_get_provider_version(void *ctx) {
++  return SCRYPT;
++}
++
++static int sqlcipher_ltc_random(void *ctx, void *buffer, int length) {
++#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
++  sqlite3_mutex_enter(ltc_rand_mutex);
++#endif
++  fortuna_read(buffer, length, &prng);
++#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
++  sqlite3_mutex_leave(ltc_rand_mutex);
++#endif
++  return SQLITE_OK;
++}
++
++static int sqlcipher_ltc_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, 
unsigned char *in2, int in2_sz, unsigned char *out) {
++  int rc, hash_idx;
++  hmac_state hmac;
++  unsigned long outlen = key_sz;
++
++  hash_idx = find_hash("sha1");
++  if(in == NULL) return SQLITE_ERROR;
++  if((rc = hmac_init(&hmac, hash_idx, hmac_key, key_sz)) != CRYPT_OK) return SQLITE_ERROR;
++  if((rc = hmac_process(&hmac, in, in_sz)) != CRYPT_OK) return SQLITE_ERROR;
++  if(in2 != NULL && (rc = hmac_process(&hmac, in2, in2_sz)) != CRYPT_OK) return SQLITE_ERROR;
++  if((rc = hmac_done(&hmac, out, &outlen)) != CRYPT_OK) return SQLITE_ERROR;
++  return SQLITE_OK;
++}
++
++static int sqlcipher_ltc_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int 
salt_sz, int workfactor, int key_sz, unsigned char *key) {
++  int rc, hash_idx;
++  unsigned long outlen = key_sz;
++  unsigned long random_buffer_sz = sizeof(char) * 256;
++  unsigned char *random_buffer = sqlcipher_malloc(random_buffer_sz);
++  sqlcipher_memset(random_buffer, 0, random_buffer_sz);
++
++  hash_idx = find_hash("sha1");
++  if((rc = pkcs_5_alg2(pass, pass_sz, salt, salt_sz,
++                       workfactor, hash_idx, key, &outlen)) != CRYPT_OK) {
++    return SQLITE_ERROR;
++  }
++  if((rc = pkcs_5_alg2(key, key_sz, salt, salt_sz,
++                       1, hash_idx, random_buffer, &random_buffer_sz)) != CRYPT_OK) {
++    return SQLITE_ERROR;
++  }
++  sqlcipher_ltc_add_random(ctx, random_buffer, random_buffer_sz);
++  sqlcipher_free(random_buffer, random_buffer_sz);
++  return SQLITE_OK;
++}
++
++static const char* sqlcipher_ltc_get_cipher(void *ctx) {
++  return "rijndael";
++}
++
++static int sqlcipher_ltc_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, 
unsigned char *in, int in_sz, unsigned char *out) {
++  int rc, cipher_idx;
++  symmetric_CBC cbc;
++
++  if((cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx))) == -1) return SQLITE_ERROR;
++  if((rc = cbc_start(cipher_idx, iv, key, key_sz, 0, &cbc)) != CRYPT_OK) return SQLITE_ERROR;
++  rc = mode == 1 ? cbc_encrypt(in, out, in_sz, &cbc) : cbc_decrypt(in, out, in_sz, &cbc);
++  if(rc != CRYPT_OK) return SQLITE_ERROR;
++  cbc_done(&cbc);
++  return SQLITE_OK;
++}
++
++static int sqlcipher_ltc_set_cipher(void *ctx, const char *cipher_name) {
++  return SQLITE_OK;
++}
++
++static int sqlcipher_ltc_get_key_sz(void *ctx) {
++  int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
++  return cipher_descriptor[cipher_idx].max_key_length;
++}
++
++static int sqlcipher_ltc_get_iv_sz(void *ctx) {
++  int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
++  return cipher_descriptor[cipher_idx].block_length;
++}
++
++static int sqlcipher_ltc_get_block_sz(void *ctx) {
++  int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
++  return cipher_descriptor[cipher_idx].block_length;
++}
++
++static int sqlcipher_ltc_get_hmac_sz(void *ctx) {
++  int hash_idx = find_hash("sha1");
++  return hash_descriptor[hash_idx].hashsize;
++}
++
++static int sqlcipher_ltc_ctx_copy(void *target_ctx, void *source_ctx) {
++  return SQLITE_OK;
++}
++
++static int sqlcipher_ltc_ctx_cmp(void *c1, void *c2) {
++  return 1;
++}
++
++static int sqlcipher_ltc_ctx_init(void **ctx) {
++  sqlcipher_ltc_activate(NULL);
++  return SQLITE_OK;
++}
++
++static int sqlcipher_ltc_ctx_free(void **ctx) {
++  sqlcipher_ltc_deactivate(&ctx);
++  return SQLITE_OK;
++}
++
++static int sqlcipher_ltc_fips_status(void *ctx) {
++  return 0;
++}
++
++int sqlcipher_ltc_setup(sqlcipher_provider *p) {
++  p->activate = sqlcipher_ltc_activate;
++  p->deactivate = sqlcipher_ltc_deactivate;
++  p->get_provider_name = sqlcipher_ltc_get_provider_name;
++  p->random = sqlcipher_ltc_random;
++  p->hmac = sqlcipher_ltc_hmac;
++  p->kdf = sqlcipher_ltc_kdf;
++  p->cipher = sqlcipher_ltc_cipher;
++  p->set_cipher = sqlcipher_ltc_set_cipher;
++  p->get_cipher = sqlcipher_ltc_get_cipher;
++  p->get_key_sz = sqlcipher_ltc_get_key_sz;
++  p->get_iv_sz = sqlcipher_ltc_get_iv_sz;
++  p->get_block_sz = sqlcipher_ltc_get_block_sz;
++  p->get_hmac_sz = sqlcipher_ltc_get_hmac_sz;
++  p->ctx_copy = sqlcipher_ltc_ctx_copy;
++  p->ctx_cmp = sqlcipher_ltc_ctx_cmp;
++  p->ctx_init = sqlcipher_ltc_ctx_init;
++  p->ctx_free = sqlcipher_ltc_ctx_free;
++  p->add_random = sqlcipher_ltc_add_random;
++  p->fips_status = sqlcipher_ltc_fips_status;
++  p->get_provider_version = sqlcipher_ltc_get_provider_version;
++  return SQLITE_OK;
++}
++
++#endif
++#endif
++/* END SQLCIPHER */
++
++/************** End of crypto_libtomcrypt.c **********************************/
++/************** Begin file crypto_openssl.c **********************************/
++/*
++** SQLCipher
++** http://sqlcipher.net
++**
++** Copyright (c) 2008 - 2013, ZETETIC LLC
++** All rights reserved.
++**
++** Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are met:
++**     * Redistributions of source code must retain the above copyright
++**       notice, this list of conditions and the following disclaimer.
++**     * Redistributions in binary form must reproduce the above copyright
++**       notice, this list of conditions and the following disclaimer in the
++**       documentation and/or other materials provided with the distribution.
++**     * Neither the name of the ZETETIC LLC nor the
++**       names of its contributors may be used to endorse or promote products
++**       derived from this software without specific prior written permission.
++**
++** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
++** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
++** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++**
++*/
++/* BEGIN SQLCIPHER */
++#ifdef SQLITE_HAS_CODEC
++#ifdef SQLCIPHER_CRYPTO_OPENSSL
++/* #include "sqliteInt.h" */
++/* #include "crypto.h" */
++/* #include "sqlcipher.h" */
++#include <openssl/rand.h>
++#include <openssl/evp.h>
++#include <openssl/hmac.h>
++#include <openssl/err.h>
++
++typedef struct {
++  EVP_CIPHER *evp_cipher;
++} openssl_ctx;
++
++static unsigned int openssl_external_init = 0;
++static unsigned int openssl_init_count = 0;
++static sqlite3_mutex* openssl_rand_mutex = NULL;
++
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++static HMAC_CTX *HMAC_CTX_new(void)
++{
++  HMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
++  if (ctx != NULL) {
++    HMAC_CTX_init(ctx);
++  }
++  return ctx;
++}
++
++// Per 1.1.0 (https://wiki.openssl.org/index.php/1.1_API_Changes)
++// HMAC_CTX_free should call HMAC_CTX_cleanup, then EVP_MD_CTX_Cleanup.
++// HMAC_CTX_cleanup internally calls EVP_MD_CTX_cleanup so these
++// calls are not needed.
++static void HMAC_CTX_free(HMAC_CTX *ctx)
++{
++  if (ctx != NULL) {
++    HMAC_CTX_cleanup(ctx);
++    OPENSSL_free(ctx);
++  }
++}
++#endif
++
++static int sqlcipher_openssl_add_random(void *ctx, void *buffer, int length) {
++#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: entering openssl_rand_mutex %p\n", openssl_rand_mutex);
++  sqlite3_mutex_enter(openssl_rand_mutex);
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: entered openssl_rand_mutex %p\n", openssl_rand_mutex);
++#endif
++  RAND_add(buffer, length, 0);
++#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: leaving openssl_rand_mutex %p\n", openssl_rand_mutex);
++  sqlite3_mutex_leave(openssl_rand_mutex);
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: left openssl_rand_mutex %p\n", openssl_rand_mutex);
++#endif
++  return SQLITE_OK;
++}
++
++/* activate and initialize sqlcipher. Most importantly, this will automatically
++   intialize OpenSSL's EVP system if it hasn't already be externally. Note that 
++   this function may be called multiple times as new codecs are intiialized. 
++   Thus it performs some basic counting to ensure that only the last and final
++   sqlcipher_openssl_deactivate() will free the EVP structures. 
++*/
++static int sqlcipher_openssl_activate(void *ctx) {
++  /* initialize openssl and increment the internal init counter
++     but only if it hasn't been initalized outside of SQLCipher by this program 
++     e.g. on startup */
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entering static master mutex");
++  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered static master mutex");
++
++  if(openssl_init_count == 0 && EVP_get_cipherbyname(CIPHER) != NULL) {
++    /* if openssl has not yet been initialized by this library, but 
++       a call to get_cipherbyname works, then the openssl library
++       has been initialized externally already. */
++    openssl_external_init = 1;
++  }
++
++#ifdef SQLCIPHER_FIPS
++  if(!FIPS_mode()){
++    if(!FIPS_mode_set(1)){
++      ERR_load_crypto_strings();
++      ERR_print_errors_fp(stderr);
++    }
++  }
++#endif
++
++  if(openssl_init_count == 0 && openssl_external_init == 0)  {
++    /* if the library was not externally initialized, then should be now */
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++    OpenSSL_add_all_algorithms();
++#endif
++  } 
++
++#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
++  if(openssl_rand_mutex == NULL) {
++    /* allocate a mutex to guard against concurrent calls to RAND_bytes() */
++    CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: allocating openssl_rand_mutex");
++    openssl_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
++    CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: allocated openssl_rand_mutex %p", openssl_rand_mutex);
++  }
++#endif
++
++  openssl_init_count++; 
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving static master mutex");
++  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left static master mutex");
++  return SQLITE_OK;
++}
++
++/* deactivate SQLCipher, most imporantly decremeting the activation count and
++   freeing the EVP structures on the final deactivation to ensure that 
++   OpenSSL memory is cleaned up */
++static int sqlcipher_openssl_deactivate(void *ctx) {
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: entering static master mutex");
++  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: entered static master mutex");
++  openssl_init_count--;
++
++  if(openssl_init_count == 0) {
++    if(openssl_external_init == 0) {
++    /* if OpenSSL hasn't be initialized externally, and the counter reaches zero 
++       after it's decremented, release EVP memory
++       Note: this code will only be reached if OpensSSL_add_all_algorithms()
++       is called by SQLCipher internally. This should prevent SQLCipher from 
++       "cleaning up" openssl when it was initialized externally by the program */
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++      EVP_cleanup();
++#endif
++    } else {
++      openssl_external_init = 0;
++    }
++#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
++    CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: freeing openssl_rand_mutex %p", openssl_rand_mutex);
++    sqlite3_mutex_free(openssl_rand_mutex);
++    CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: freed openssl_rand_mutex %p", openssl_rand_mutex);
++    openssl_rand_mutex = NULL;
++#endif
++  }
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: leaving static master mutex");
++  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: left static master mutex");
++  return SQLITE_OK;
++}
++
++static const char* sqlcipher_openssl_get_provider_name(void *ctx) {
++  return "openssl";
++}
++
++static const char* sqlcipher_openssl_get_provider_version(void *ctx) {
++  return OPENSSL_VERSION_TEXT;
++}
++
++/* generate a defined number of random bytes */
++static int sqlcipher_openssl_random (void *ctx, void *buffer, int length) {
++  int rc = 0;
++  /* concurrent calls to RAND_bytes can cause a crash under some openssl versions when a 
++     naive application doesn't use CRYPTO_set_locking_callback and
++     CRYPTO_THREADID_set_callback to ensure openssl thread safety. 
++     This is simple workaround to prevent this common crash
++     but a more proper solution is that applications setup platform-appropriate
++     thread saftey in openssl externally */
++#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_random: entering openssl_rand_mutex %p", openssl_rand_mutex);
++  sqlite3_mutex_enter(openssl_rand_mutex);
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_random: entered openssl_rand_mutex %p", openssl_rand_mutex);
++#endif
++  rc = RAND_bytes((unsigned char *)buffer, length);
++#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_random: leaving openssl_rand_mutex %p", openssl_rand_mutex);
++  sqlite3_mutex_leave(openssl_rand_mutex);
++  CODEC_TRACE_MUTEX("sqlcipher_openssl_random: left openssl_rand_mutex %p", openssl_rand_mutex);
++#endif
++  return (rc == 1) ? SQLITE_OK : SQLITE_ERROR;
++}
++
++static int sqlcipher_openssl_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int 
in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
++  unsigned int outlen;
++  HMAC_CTX* hctx = HMAC_CTX_new();
++  if(hctx == NULL || in == NULL) return SQLITE_ERROR;
++  HMAC_Init_ex(hctx, hmac_key, key_sz, EVP_sha1(), NULL);
++  HMAC_Update(hctx, in, in_sz);
++  if(in2 != NULL) HMAC_Update(hctx, in2, in2_sz);
++  HMAC_Final(hctx, out, &outlen);
++  HMAC_CTX_free(hctx);
++  return SQLITE_OK; 
++}
++
++static int sqlcipher_openssl_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, 
int salt_sz, int workfactor, int key_sz, unsigned char *key) {
++  PKCS5_PBKDF2_HMAC_SHA1((const char *)pass, pass_sz, salt, salt_sz, workfactor, key_sz, key);
++  return SQLITE_OK; 
++}
++
++static int sqlcipher_openssl_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, 
unsigned char *in, int in_sz, unsigned char *out) {
++  int tmp_csz, csz;
++  EVP_CIPHER_CTX* ectx = EVP_CIPHER_CTX_new();
++  if(ectx == NULL) return SQLITE_ERROR;
++  EVP_CipherInit_ex(ectx, ((openssl_ctx *)ctx)->evp_cipher, NULL, NULL, NULL, mode);
++  EVP_CIPHER_CTX_set_padding(ectx, 0); // no padding
++  EVP_CipherInit_ex(ectx, NULL, NULL, key, iv, mode);
++  EVP_CipherUpdate(ectx, out, &tmp_csz, in, in_sz);
++  csz = tmp_csz;  
++  out += tmp_csz;
++  EVP_CipherFinal_ex(ectx, out, &tmp_csz);
++  csz += tmp_csz;
++  EVP_CIPHER_CTX_free(ectx);
++  assert(in_sz == csz);
++  return SQLITE_OK; 
++}
++
++static int sqlcipher_openssl_set_cipher(void *ctx, const char *cipher_name) {
++  openssl_ctx *o_ctx = (openssl_ctx *)ctx;
++  EVP_CIPHER* cipher = (EVP_CIPHER *) EVP_get_cipherbyname(cipher_name);
++  if(cipher != NULL) {
++    o_ctx->evp_cipher = cipher;
++  }
++  return cipher != NULL ? SQLITE_OK : SQLITE_ERROR;
++}
++
++static const char* sqlcipher_openssl_get_cipher(void *ctx) {
++  return EVP_CIPHER_name(((openssl_ctx *)ctx)->evp_cipher);
++}
++
++static int sqlcipher_openssl_get_key_sz(void *ctx) {
++  return EVP_CIPHER_key_length(((openssl_ctx *)ctx)->evp_cipher);
++}
++
++static int sqlcipher_openssl_get_iv_sz(void *ctx) {
++  return EVP_CIPHER_iv_length(((openssl_ctx *)ctx)->evp_cipher);
++}
++
++static int sqlcipher_openssl_get_block_sz(void *ctx) {
++  return EVP_CIPHER_block_size(((openssl_ctx *)ctx)->evp_cipher);
++}
++
++static int sqlcipher_openssl_get_hmac_sz(void *ctx) {
++  return EVP_MD_size(EVP_sha1());
++}
++
++static int sqlcipher_openssl_ctx_copy(void *target_ctx, void *source_ctx) {
++  memcpy(target_ctx, source_ctx, sizeof(openssl_ctx));
++  return SQLITE_OK;
++}
++
++static int sqlcipher_openssl_ctx_cmp(void *c1, void *c2) {
++  return ((openssl_ctx *)c1)->evp_cipher == ((openssl_ctx *)c2)->evp_cipher;
++}
++
++static int sqlcipher_openssl_ctx_init(void **ctx) {
++  *ctx = sqlcipher_malloc(sizeof(openssl_ctx));
++  if(*ctx == NULL) return SQLITE_NOMEM;
++  sqlcipher_openssl_activate(*ctx);
++  return SQLITE_OK;
++}
++
++static int sqlcipher_openssl_ctx_free(void **ctx) {
++  sqlcipher_openssl_deactivate(*ctx);
++  sqlcipher_free(*ctx, sizeof(openssl_ctx));
++  return SQLITE_OK;
++}
++
++static int sqlcipher_openssl_fips_status(void *ctx) {
++#ifdef SQLCIPHER_FIPS  
++  return FIPS_mode();
++#else
++  return 0;
++#endif
++}
++
++int sqlcipher_openssl_setup(sqlcipher_provider *p) {
++  p->activate = sqlcipher_openssl_activate;  
++  p->deactivate = sqlcipher_openssl_deactivate;
++  p->get_provider_name = sqlcipher_openssl_get_provider_name;
++  p->random = sqlcipher_openssl_random;
++  p->hmac = sqlcipher_openssl_hmac;
++  p->kdf = sqlcipher_openssl_kdf;
++  p->cipher = sqlcipher_openssl_cipher;
++  p->set_cipher = sqlcipher_openssl_set_cipher;
++  p->get_cipher = sqlcipher_openssl_get_cipher;
++  p->get_key_sz = sqlcipher_openssl_get_key_sz;
++  p->get_iv_sz = sqlcipher_openssl_get_iv_sz;
++  p->get_block_sz = sqlcipher_openssl_get_block_sz;
++  p->get_hmac_sz = sqlcipher_openssl_get_hmac_sz;
++  p->ctx_copy = sqlcipher_openssl_ctx_copy;
++  p->ctx_cmp = sqlcipher_openssl_ctx_cmp;
++  p->ctx_init = sqlcipher_openssl_ctx_init;
++  p->ctx_free = sqlcipher_openssl_ctx_free;
++  p->add_random = sqlcipher_openssl_add_random;
++  p->fips_status = sqlcipher_openssl_fips_status;
++  p->get_provider_version = sqlcipher_openssl_get_provider_version;
++  return SQLITE_OK;
++}
++
++#endif
++#endif
++/* END SQLCIPHER */
++
++/************** End of crypto_openssl.c **************************************/
++/************** Begin file crypto_cc.c ***************************************/
++/*
++** SQLCipher
++** http://sqlcipher.net
++**
++** Copyright (c) 2008 - 2013, ZETETIC LLC
++** All rights reserved.
++**
++** Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are met:
++**     * Redistributions of source code must retain the above copyright
++**       notice, this list of conditions and the following disclaimer.
++**     * Redistributions in binary form must reproduce the above copyright
++**       notice, this list of conditions and the following disclaimer in the
++**       documentation and/or other materials provided with the distribution.
++**     * Neither the name of the ZETETIC LLC nor the
++**       names of its contributors may be used to endorse or promote products
++**       derived from this software without specific prior written permission.
++**
++** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
++** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
++** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++**
++*/
++/* BEGIN SQLCIPHER */
++#ifdef SQLITE_HAS_CODEC
++#ifdef SQLCIPHER_CRYPTO_CC
++/* #include "crypto.h" */
++/* #include "sqlcipher.h" */
++#include <CommonCrypto/CommonCrypto.h>
++#include <Security/SecRandom.h>
++#include <CoreFoundation/CoreFoundation.h>
++
++static int sqlcipher_cc_add_random(void *ctx, void *buffer, int length) {
++  return SQLITE_OK;
++}
++
++/* generate a defined number of random bytes */
++static int sqlcipher_cc_random (void *ctx, void *buffer, int length) {
++  return (SecRandomCopyBytes(kSecRandomDefault, length, (uint8_t *)buffer) == 0) ? SQLITE_OK : SQLITE_ERROR;
++}
++
++static const char* sqlcipher_cc_get_provider_name(void *ctx) {
++  return "commoncrypto";
++}
++
++static const char* sqlcipher_cc_get_provider_version(void *ctx) {
++#if TARGET_OS_MAC
++  CFTypeRef version;
++  CFBundleRef bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security"));
++  if(bundle == NULL) {
++    return "unknown";
++  }
++  version = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString"));
++  return CFStringGetCStringPtr(version, kCFStringEncodingUTF8);
++#else
++  return "unknown";
++#endif
++}
++
++static int sqlcipher_cc_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, 
unsigned char *in2, int in2_sz, unsigned char *out) {
++  CCHmacContext hmac_context;
++  if(in == NULL) return SQLITE_ERROR;
++  CCHmacInit(&hmac_context, kCCHmacAlgSHA1, hmac_key, key_sz);
++  CCHmacUpdate(&hmac_context, in, in_sz);
++  if(in2 != NULL) CCHmacUpdate(&hmac_context, in2, in2_sz);
++  CCHmacFinal(&hmac_context, out);
++  return SQLITE_OK; 
++}
++
++static int sqlcipher_cc_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int 
salt_sz, int workfactor, int key_sz, unsigned char *key) {
++  CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pass, pass_sz, salt, salt_sz, kCCPRFHmacAlgSHA1, 
workfactor, key, key_sz);
++  return SQLITE_OK; 
++}
++
++static int sqlcipher_cc_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, 
unsigned char *in, int in_sz, unsigned char *out) {
++  CCCryptorRef cryptor;
++  size_t tmp_csz, csz;
++  CCOperation op = mode == CIPHER_ENCRYPT ? kCCEncrypt : kCCDecrypt;
++
++  CCCryptorCreate(op, kCCAlgorithmAES128, 0, key, kCCKeySizeAES256, iv, &cryptor);
++  CCCryptorUpdate(cryptor, in, in_sz, out, in_sz, &tmp_csz);
++  csz = tmp_csz;
++  out += tmp_csz;
++  CCCryptorFinal(cryptor, out, in_sz - csz, &tmp_csz);
++  csz += tmp_csz;
++  CCCryptorRelease(cryptor);
++  assert(in_sz == csz);
++
++  return SQLITE_OK; 
++}
++
++static int sqlcipher_cc_set_cipher(void *ctx, const char *cipher_name) {
++  return SQLITE_OK;
++}
++
++static const char* sqlcipher_cc_get_cipher(void *ctx) {
++  return "aes-256-cbc";
++}
++
++static int sqlcipher_cc_get_key_sz(void *ctx) {
++  return kCCKeySizeAES256;
++}
++
++static int sqlcipher_cc_get_iv_sz(void *ctx) {
++  return kCCBlockSizeAES128;
++}
++
++static int sqlcipher_cc_get_block_sz(void *ctx) {
++  return kCCBlockSizeAES128;
++}
++
++static int sqlcipher_cc_get_hmac_sz(void *ctx) {
++  return CC_SHA1_DIGEST_LENGTH;
++}
++
++static int sqlcipher_cc_ctx_copy(void *target_ctx, void *source_ctx) {
++  return SQLITE_OK;
++}
++
++static int sqlcipher_cc_ctx_cmp(void *c1, void *c2) {
++  return 1; /* always indicate contexts are the same */
++}
++
++static int sqlcipher_cc_ctx_init(void **ctx) {
++  return SQLITE_OK;
++}
++
++static int sqlcipher_cc_ctx_free(void **ctx) {
++  return SQLITE_OK;
++}
++
++static int sqlcipher_cc_fips_status(void *ctx) {
++  return 0;
++}
++
++int sqlcipher_cc_setup(sqlcipher_provider *p) {
++  p->random = sqlcipher_cc_random;
++  p->get_provider_name = sqlcipher_cc_get_provider_name;
++  p->hmac = sqlcipher_cc_hmac;
++  p->kdf = sqlcipher_cc_kdf;
++  p->cipher = sqlcipher_cc_cipher;
++  p->set_cipher = sqlcipher_cc_set_cipher;
++  p->get_cipher = sqlcipher_cc_get_cipher;
++  p->get_key_sz = sqlcipher_cc_get_key_sz;
++  p->get_iv_sz = sqlcipher_cc_get_iv_sz;
++  p->get_block_sz = sqlcipher_cc_get_block_sz;
++  p->get_hmac_sz = sqlcipher_cc_get_hmac_sz;
++  p->ctx_copy = sqlcipher_cc_ctx_copy;
++  p->ctx_cmp = sqlcipher_cc_ctx_cmp;
++  p->ctx_init = sqlcipher_cc_ctx_init;
++  p->ctx_free = sqlcipher_cc_ctx_free;
++  p->add_random = sqlcipher_cc_add_random;
++  p->fips_status = sqlcipher_cc_fips_status;
++  p->get_provider_version = sqlcipher_cc_get_provider_version;
++  return SQLITE_OK;
++}
++
++#endif
++#endif
++/* END SQLCIPHER */
++
++/************** End of crypto_cc.c *******************************************/
+ /************** Begin file global.c ******************************************/
+ /*
+ ** 2008 June 13
+@@ -13801,6 +22102,7 @@
+ **
+ ** This file contains definitions of global variables and constants.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /* An array to map all upper-case characters into their corresponding
+ ** lower-case character. 
+@@ -13858,6 +22160,7 @@
+ **   isxdigit()                       0x08
+ **   toupper()                        0x20
+ **   SQLite identifier character      0x40
++**   Quote character                  0x80
+ **
+ ** Bit 0x20 is set if the mapped character requires translation to upper
+ ** case. i.e. if the character is a lower-case ASCII character.
+@@ -13866,16 +22169,13 @@
+ **
+ **   (x & ~(map[x]&0x20))
+ **
+-** Standard function tolower() is implemented using the sqlite3UpperToLower[]
++** The equivalent of tolower() is implemented using the sqlite3UpperToLower[]
+ ** array. tolower() is used more often than toupper() by SQLite.
+ **
+-** Bit 0x40 is set if the character non-alphanumeric and can be used in an 
++** Bit 0x40 is set if the character is non-alphanumeric and can be used in an 
+ ** SQLite identifier.  Identifiers are alphanumerics, "_", "$", and any
+ ** non-ASCII UTF character. Hence the test for whether or not a character is
+ ** part of an identifier is 0x46.
+-**
+-** SQLite's versions are identical to the standard versions assuming a
+-** locale of "C". They are implemented as macros in sqliteInt.h.
+ */
+ #ifdef SQLITE_ASCII
+ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
+@@ -13883,7 +22183,7 @@
+   0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,  /* 08..0f    ........ */
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 10..17    ........ */
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 18..1f    ........ */
+-  0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,  /* 20..27     !"#$%&' */
++  0x01, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x80,  /* 20..27     !"#$%&' */
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 28..2f    ()*+,-./ */
+   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,  /* 30..37    01234567 */
+   0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 38..3f    89:;<=>? */
+@@ -13891,8 +22191,8 @@
+   0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02,  /* 40..47    @ABCDEFG */
+   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 48..4f    HIJKLMNO */
+   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 50..57    PQRSTUVW */
+-  0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40,  /* 58..5f    XYZ[\]^_ */
+-  0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22,  /* 60..67    `abcdefg */
++  0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x00, 0x40,  /* 58..5f    XYZ[\]^_ */
++  0x80, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22,  /* 60..67    `abcdefg */
+   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 68..6f    hijklmno */
+   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 70..77    pqrstuvw */
+   0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 78..7f    xyz{|}~. */
+@@ -13927,9 +22227,16 @@
+ ** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
+ ** disabled. The default value may be changed by compiling with the
+ ** SQLITE_USE_URI symbol defined.
++**
++** URI filenames are enabled by default if SQLITE_HAS_CODEC is
++** enabled.
+ */
+ #ifndef SQLITE_USE_URI
+-# define  SQLITE_USE_URI 0
++# ifdef SQLITE_HAS_CODEC
++#  define SQLITE_USE_URI 1
++# else
++#  define SQLITE_USE_URI 0
++# endif
+ #endif
+ 
+ /* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
+@@ -13947,6 +22254,31 @@
+ # define SQLITE_SORTER_PMASZ 250
+ #endif
+ 
++/* Statement journals spill to disk when their size exceeds the following
++** threshold (in bytes). 0 means that statement journals are created and
++** written to disk immediately (the default behavior for SQLite versions
++** before 3.12.0).  -1 means always keep the entire statement journal in
++** memory.  (The statement journal is also always held entirely in memory
++** if journal_mode=MEMORY or if temp_store=MEMORY, regardless of this
++** setting.)
++*/
++#ifndef SQLITE_STMTJRNL_SPILL 
++# define SQLITE_STMTJRNL_SPILL (64*1024)
++#endif
++
++/*
++** The default lookaside-configuration, the format "SZ,N".  SZ is the
++** number of bytes in each lookaside slot (should be a multiple of 8)
++** and N is the number of slots.  The lookaside-configuration can be
++** changed as start-time using sqlite3_config(SQLITE_CONFIG_LOOKASIDE)
++** or at run-time for an individual database connection using
++** sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE);
++*/
++#ifndef SQLITE_DEFAULT_LOOKASIDE
++# define SQLITE_DEFAULT_LOOKASIDE 1200,100
++#endif
++
++
+ /*
+ ** The following singleton contains the global configuration for
+ ** the SQLite library.
+@@ -13959,8 +22291,8 @@
+    SQLITE_ALLOW_COVERING_INDEX_SCAN,   /* bUseCis */
+    0x7ffffffe,                /* mxStrlen */
+    0,                         /* neverCorrupt */
+-   128,                       /* szLookaside */
+-   500,                       /* nLookaside */
++   SQLITE_DEFAULT_LOOKASIDE,  /* szLookaside, nLookaside */
++   SQLITE_STMTJRNL_SPILL,     /* nStmtSpill */
+    {0,0,0,0,0,0,0,0},         /* m */
+    {0,0,0,0,0,0,0,0,0},       /* mutex */
+    {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
+@@ -13974,7 +22306,7 @@
+    0,                         /* nScratch */
+    (void*)0,                  /* pPage */
+    0,                         /* szPage */
+-   0,                         /* nPage */
++   SQLITE_DEFAULT_PCACHE_INITSZ, /* nPage */
+    0,                         /* mxParserStack */
+    0,                         /* sharedCacheEnabled */
+    SQLITE_SORTER_PMASZ,       /* szPma */
+@@ -13996,10 +22328,11 @@
+    0,                         /* xVdbeBranch */
+    0,                         /* pVbeBranchArg */
+ #endif
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
++#ifndef SQLITE_UNTESTABLE
+    0,                         /* xTestCallback */
+ #endif
+-   0                          /* bLocaltimeFault */
++   0,                         /* bLocaltimeFault */
++   0x7ffffffe                 /* iOnceResetThreshold */
+ };
+ 
+ /*
+@@ -14007,7 +22340,7 @@
+ ** database connections.  After initialization, this table is
+ ** read-only.
+ */
+-SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
++SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions;
+ 
+ /*
+ ** Constant tokens for values 0 and 1.
+@@ -14022,7 +22355,7 @@
+ ** The value of the "pending" byte must be 0x40000000 (1 byte past the
+ ** 1-gibabyte boundary) in a compatible database.  SQLite never uses
+ ** the database page that contains the pending byte.  It never attempts
+-** to read or write that page.  The pending byte page is set assign
++** to read or write that page.  The pending byte page is set aside
+ ** for use by the VFS layers as space for managing file locks.
+ **
+ ** During testing, it is often desirable to move the pending byte to
+@@ -14040,6 +22373,7 @@
+ SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
+ #endif
+ 
++/* #include "opcodes.h" */
+ /*
+ ** Properties of opcodes.  The OPFLG_INITIALIZER macro is
+ ** created by mkopcodeh.awk during compilation.  Data is obtained
+@@ -14048,439 +22382,12 @@
+ */
+ SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
+ 
+-/************** End of global.c **********************************************/
+-/************** Begin file ctime.c *******************************************/
+-/*
+-** 2010 February 23
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
+-**
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-*************************************************************************
+-**
+-** This file implements routines used to report what compile-time options
+-** SQLite was built with.
+-*/
+-
+-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+-
+-
+-/*
+-** An array of names of all compile-time options.  This array should 
+-** be sorted A-Z.
+-**
+-** This array looks large, but in a typical installation actually uses
+-** only a handful of compile-time options, so most times this array is usually
+-** rather short and uses little memory space.
+-*/
+-static const char * const azCompileOpt[] = {
+-
+-/* These macros are provided to "stringify" the value of the define
+-** for those options in which the value is meaningful. */
+-#define CTIMEOPT_VAL_(opt) #opt
+-#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
+-
+-#if SQLITE_32BIT_ROWID
+-  "32BIT_ROWID",
+-#endif
+-#if SQLITE_4_BYTE_ALIGNED_MALLOC
+-  "4_BYTE_ALIGNED_MALLOC",
+-#endif
+-#if SQLITE_CASE_SENSITIVE_LIKE
+-  "CASE_SENSITIVE_LIKE",
+-#endif
+-#if SQLITE_CHECK_PAGES
+-  "CHECK_PAGES",
+-#endif
+-#if SQLITE_COVERAGE_TEST
+-  "COVERAGE_TEST",
+-#endif
+-#if SQLITE_DEBUG
+-  "DEBUG",
+-#endif
+-#if SQLITE_DEFAULT_LOCKING_MODE
+-  "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
+-#endif
+-#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
+-  "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
+-#endif
+-#if SQLITE_DISABLE_DIRSYNC
+-  "DISABLE_DIRSYNC",
+-#endif
+-#if SQLITE_DISABLE_LFS
+-  "DISABLE_LFS",
+-#endif
+-#if SQLITE_ENABLE_API_ARMOR
+-  "ENABLE_API_ARMOR",
+-#endif
+-#if SQLITE_ENABLE_ATOMIC_WRITE
+-  "ENABLE_ATOMIC_WRITE",
+-#endif
+-#if SQLITE_ENABLE_CEROD
+-  "ENABLE_CEROD",
+-#endif
+-#if SQLITE_ENABLE_COLUMN_METADATA
+-  "ENABLE_COLUMN_METADATA",
+-#endif
+-#if SQLITE_ENABLE_DBSTAT_VTAB
+-  "ENABLE_DBSTAT_VTAB",
+-#endif
+-#if SQLITE_ENABLE_EXPENSIVE_ASSERT
+-  "ENABLE_EXPENSIVE_ASSERT",
+-#endif
+-#if SQLITE_ENABLE_FTS1
+-  "ENABLE_FTS1",
+-#endif
+-#if SQLITE_ENABLE_FTS2
+-  "ENABLE_FTS2",
+-#endif
+-#if SQLITE_ENABLE_FTS3
+-  "ENABLE_FTS3",
+-#endif
+-#if SQLITE_ENABLE_FTS3_PARENTHESIS
+-  "ENABLE_FTS3_PARENTHESIS",
+-#endif
+-#if SQLITE_ENABLE_FTS4
+-  "ENABLE_FTS4",
+-#endif
+-#if SQLITE_ENABLE_ICU
+-  "ENABLE_ICU",
+-#endif
+-#if SQLITE_ENABLE_IOTRACE
+-  "ENABLE_IOTRACE",
+-#endif
+-#if SQLITE_ENABLE_LOAD_EXTENSION
+-  "ENABLE_LOAD_EXTENSION",
+-#endif
+-#if SQLITE_ENABLE_LOCKING_STYLE
+-  "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
+-#endif
+-#if SQLITE_ENABLE_MEMORY_MANAGEMENT
+-  "ENABLE_MEMORY_MANAGEMENT",
+-#endif
+-#if SQLITE_ENABLE_MEMSYS3
+-  "ENABLE_MEMSYS3",
+-#endif
+-#if SQLITE_ENABLE_MEMSYS5
+-  "ENABLE_MEMSYS5",
+-#endif
+-#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
+-  "ENABLE_OVERSIZE_CELL_CHECK",
+-#endif
+-#if SQLITE_ENABLE_RTREE
+-  "ENABLE_RTREE",
+-#endif
+-#if defined(SQLITE_ENABLE_STAT4)
+-  "ENABLE_STAT4",
+-#elif defined(SQLITE_ENABLE_STAT3)
+-  "ENABLE_STAT3",
+-#endif
+-#if SQLITE_ENABLE_UNLOCK_NOTIFY
+-  "ENABLE_UNLOCK_NOTIFY",
+-#endif
+-#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
+-  "ENABLE_UPDATE_DELETE_LIMIT",
+-#endif
+-#if SQLITE_HAS_CODEC
+-  "HAS_CODEC",
+-#endif
+-#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
+-  "HAVE_ISNAN",
+-#endif
+-#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
+-  "HOMEGROWN_RECURSIVE_MUTEX",
+-#endif
+-#if SQLITE_IGNORE_AFP_LOCK_ERRORS
+-  "IGNORE_AFP_LOCK_ERRORS",
+-#endif
+-#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS
+-  "IGNORE_FLOCK_LOCK_ERRORS",
+-#endif
+-#ifdef SQLITE_INT64_TYPE
+-  "INT64_TYPE",
+-#endif
+-#if SQLITE_LOCK_TRACE
+-  "LOCK_TRACE",
+-#endif
+-#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc)
+-  "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE),
+-#endif
+-#ifdef SQLITE_MAX_SCHEMA_RETRY
+-  "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
+-#endif
+-#if SQLITE_MEMDEBUG
+-  "MEMDEBUG",
+-#endif
+-#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
+-  "MIXED_ENDIAN_64BIT_FLOAT",
+-#endif
+-#if SQLITE_NO_SYNC
+-  "NO_SYNC",
+-#endif
+-#if SQLITE_OMIT_ALTERTABLE
+-  "OMIT_ALTERTABLE",
+-#endif
+-#if SQLITE_OMIT_ANALYZE
+-  "OMIT_ANALYZE",
+-#endif
+-#if SQLITE_OMIT_ATTACH
+-  "OMIT_ATTACH",
+-#endif
+-#if SQLITE_OMIT_AUTHORIZATION
+-  "OMIT_AUTHORIZATION",
+-#endif
+-#if SQLITE_OMIT_AUTOINCREMENT
+-  "OMIT_AUTOINCREMENT",
+-#endif
+-#if SQLITE_OMIT_AUTOINIT
+-  "OMIT_AUTOINIT",
+-#endif
+-#if SQLITE_OMIT_AUTOMATIC_INDEX
+-  "OMIT_AUTOMATIC_INDEX",
+-#endif
+-#if SQLITE_OMIT_AUTORESET
+-  "OMIT_AUTORESET",
+-#endif
+-#if SQLITE_OMIT_AUTOVACUUM
+-  "OMIT_AUTOVACUUM",
+-#endif
+-#if SQLITE_OMIT_BETWEEN_OPTIMIZATION
+-  "OMIT_BETWEEN_OPTIMIZATION",
+-#endif
+-#if SQLITE_OMIT_BLOB_LITERAL
+-  "OMIT_BLOB_LITERAL",
+-#endif
+-#if SQLITE_OMIT_BTREECOUNT
+-  "OMIT_BTREECOUNT",
+-#endif
+-#if SQLITE_OMIT_BUILTIN_TEST
+-  "OMIT_BUILTIN_TEST",
+-#endif
+-#if SQLITE_OMIT_CAST
+-  "OMIT_CAST",
+-#endif
+-#if SQLITE_OMIT_CHECK
+-  "OMIT_CHECK",
+-#endif
+-#if SQLITE_OMIT_COMPLETE
+-  "OMIT_COMPLETE",
+-#endif
+-#if SQLITE_OMIT_COMPOUND_SELECT
+-  "OMIT_COMPOUND_SELECT",
+-#endif
+-#if SQLITE_OMIT_CTE
+-  "OMIT_CTE",
+-#endif
+-#if SQLITE_OMIT_DATETIME_FUNCS
+-  "OMIT_DATETIME_FUNCS",
+-#endif
+-#if SQLITE_OMIT_DECLTYPE
+-  "OMIT_DECLTYPE",
+-#endif
+-#if SQLITE_OMIT_DEPRECATED
+-  "OMIT_DEPRECATED",
+-#endif
+-#if SQLITE_OMIT_DISKIO
+-  "OMIT_DISKIO",
+-#endif
+-#if SQLITE_OMIT_EXPLAIN
+-  "OMIT_EXPLAIN",
+-#endif
+-#if SQLITE_OMIT_FLAG_PRAGMAS
+-  "OMIT_FLAG_PRAGMAS",
+-#endif
+-#if SQLITE_OMIT_FLOATING_POINT
+-  "OMIT_FLOATING_POINT",
+-#endif
+-#if SQLITE_OMIT_FOREIGN_KEY
+-  "OMIT_FOREIGN_KEY",
+-#endif
+-#if SQLITE_OMIT_GET_TABLE
+-  "OMIT_GET_TABLE",
+-#endif
+-#if SQLITE_OMIT_INCRBLOB
+-  "OMIT_INCRBLOB",
+-#endif
+-#if SQLITE_OMIT_INTEGRITY_CHECK
+-  "OMIT_INTEGRITY_CHECK",
+-#endif
+-#if SQLITE_OMIT_LIKE_OPTIMIZATION
+-  "OMIT_LIKE_OPTIMIZATION",
+-#endif
+-#if SQLITE_OMIT_LOAD_EXTENSION
+-  "OMIT_LOAD_EXTENSION",
+-#endif
+-#if SQLITE_OMIT_LOCALTIME
+-  "OMIT_LOCALTIME",
+-#endif
+-#if SQLITE_OMIT_LOOKASIDE
+-  "OMIT_LOOKASIDE",
+-#endif
+-#if SQLITE_OMIT_MEMORYDB
+-  "OMIT_MEMORYDB",
+-#endif
+-#if SQLITE_OMIT_OR_OPTIMIZATION
+-  "OMIT_OR_OPTIMIZATION",
+-#endif
+-#if SQLITE_OMIT_PAGER_PRAGMAS
+-  "OMIT_PAGER_PRAGMAS",
+-#endif
+-#if SQLITE_OMIT_PRAGMA
+-  "OMIT_PRAGMA",
+-#endif
+-#if SQLITE_OMIT_PROGRESS_CALLBACK
+-  "OMIT_PROGRESS_CALLBACK",
+-#endif
+-#if SQLITE_OMIT_QUICKBALANCE
+-  "OMIT_QUICKBALANCE",
+-#endif
+-#if SQLITE_OMIT_REINDEX
+-  "OMIT_REINDEX",
+-#endif
+-#if SQLITE_OMIT_SCHEMA_PRAGMAS
+-  "OMIT_SCHEMA_PRAGMAS",
+-#endif
+-#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
+-  "OMIT_SCHEMA_VERSION_PRAGMAS",
+-#endif
+-#if SQLITE_OMIT_SHARED_CACHE
+-  "OMIT_SHARED_CACHE",
+-#endif
+-#if SQLITE_OMIT_SUBQUERY
+-  "OMIT_SUBQUERY",
+-#endif
+-#if SQLITE_OMIT_TCL_VARIABLE
+-  "OMIT_TCL_VARIABLE",
+-#endif
+-#if SQLITE_OMIT_TEMPDB
+-  "OMIT_TEMPDB",
+-#endif
+-#if SQLITE_OMIT_TRACE
+-  "OMIT_TRACE",
+-#endif
+-#if SQLITE_OMIT_TRIGGER
+-  "OMIT_TRIGGER",
+-#endif
+-#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION
+-  "OMIT_TRUNCATE_OPTIMIZATION",
+-#endif
+-#if SQLITE_OMIT_UTF16
+-  "OMIT_UTF16",
+-#endif
+-#if SQLITE_OMIT_VACUUM
+-  "OMIT_VACUUM",
+-#endif
+-#if SQLITE_OMIT_VIEW
+-  "OMIT_VIEW",
+-#endif
+-#if SQLITE_OMIT_VIRTUALTABLE
+-  "OMIT_VIRTUALTABLE",
+-#endif
+-#if SQLITE_OMIT_WAL
+-  "OMIT_WAL",
+-#endif
+-#if SQLITE_OMIT_WSD
+-  "OMIT_WSD",
+-#endif
+-#if SQLITE_OMIT_XFER_OPT
+-  "OMIT_XFER_OPT",
+-#endif
+-#if SQLITE_PERFORMANCE_TRACE
+-  "PERFORMANCE_TRACE",
+-#endif
+-#if SQLITE_PROXY_DEBUG
+-  "PROXY_DEBUG",
+-#endif
+-#if SQLITE_RTREE_INT_ONLY
+-  "RTREE_INT_ONLY",
+-#endif
+-#if SQLITE_SECURE_DELETE
+-  "SECURE_DELETE",
+-#endif
+-#if SQLITE_SMALL_STACK
+-  "SMALL_STACK",
+-#endif
+-#if SQLITE_SOUNDEX
+-  "SOUNDEX",
+-#endif
+-#if SQLITE_SYSTEM_MALLOC
+-  "SYSTEM_MALLOC",
+-#endif
+-#if SQLITE_TCL
+-  "TCL",
+-#endif
+-#if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc)
+-  "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
+-#endif
+-#if SQLITE_TEST
+-  "TEST",
+-#endif
+-#if defined(SQLITE_THREADSAFE)
+-  "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
+-#endif
+-#if SQLITE_USE_ALLOCA
+-  "USE_ALLOCA",
+-#endif
+-#if SQLITE_USER_AUTHENTICATION
+-  "USER_AUTHENTICATION",
+-#endif
+-#if SQLITE_WIN32_MALLOC
+-  "WIN32_MALLOC",
+-#endif
+-#if SQLITE_ZERO_MALLOC
+-  "ZERO_MALLOC"
+-#endif
+-};
+-
+-/*
+-** Given the name of a compile-time option, return true if that option
+-** was used and false if not.
+-**
+-** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
+-** is not required for a match.
+-*/
+-SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){
+-  int i, n;
+-
+-#if SQLITE_ENABLE_API_ARMOR
+-  if( zOptName==0 ){
+-    (void)SQLITE_MISUSE_BKPT;
+-    return 0;
+-  }
+-#endif
+-  if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
+-  n = sqlite3Strlen30(zOptName);
+-
+-  /* Since ArraySize(azCompileOpt) is normally in single digits, a
+-  ** linear search is adequate.  No need for a binary search. */
+-  for(i=0; i<ArraySize(azCompileOpt); i++){
+-    if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
+-     && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
+-    ){
+-      return 1;
+-    }
+-  }
+-  return 0;
+-}
+-
+ /*
+-** Return the N-th compile-time option string.  If N is out of range,
+-** return a NULL pointer.
++** Name of the default collating sequence
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N){
+-  if( N>=0 && N<ArraySize(azCompileOpt) ){
+-    return azCompileOpt[N];
+-  }
+-  return 0;
+-}
+-
+-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
++SQLITE_PRIVATE const char sqlite3StrBINARY[] = "BINARY";
+ 
+-/************** End of ctime.c ***********************************************/
++/************** End of global.c **********************************************/
+ /************** Begin file status.c ******************************************/
+ /*
+ ** 2008 June 18
+@@ -14497,6 +22404,7 @@
+ ** This module implements the sqlite3_status() interface and related
+ ** functionality.
+ */
++/* #include "sqliteInt.h" */
+ /************** Include vdbeInt.h in the middle of status.c ******************/
+ /************** Begin file vdbeInt.h *****************************************/
+ /*
+@@ -14516,8 +22424,8 @@
+ ** 6000 lines long) it was split up into several smaller files and
+ ** this header information was factored out.
+ */
+-#ifndef _VDBEINT_H_
+-#define _VDBEINT_H_
++#ifndef SQLITE_VDBEINT_H
++#define SQLITE_VDBEINT_H
+ 
+ /*
+ ** The maximum number of times that a statement will try to reparse
+@@ -14528,6 +22436,17 @@
+ #endif
+ 
+ /*
++** VDBE_DISPLAY_P4 is true or false depending on whether or not the
++** "explain" P4 display logic is enabled.
++*/
++#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
++     || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
++# define VDBE_DISPLAY_P4 1
++#else
++# define VDBE_DISPLAY_P4 0
++#endif
++
++/*
+ ** SQL is translated into a sequence of instructions to be
+ ** executed by a virtual machine.  Each instruction is an instance
+ ** of the following structure.
+@@ -14542,70 +22461,88 @@
+ /* Opaque type used by code in vdbesort.c */
+ typedef struct VdbeSorter VdbeSorter;
+ 
+-/* Opaque type used by the explainer */
+-typedef struct Explain Explain;
+-
+ /* Elements of the linked list at Vdbe.pAuxData */
+ typedef struct AuxData AuxData;
+ 
++/* Types of VDBE cursors */
++#define CURTYPE_BTREE       0
++#define CURTYPE_SORTER      1
++#define CURTYPE_VTAB        2
++#define CURTYPE_PSEUDO      3
++
+ /*
+-** A cursor is a pointer into a single BTree within a database file.
+-** The cursor can seek to a BTree entry with a particular key, or
+-** loop over all entries of the Btree.  You can also insert new BTree
+-** entries or retrieve the key or data from the entry that the cursor
+-** is currently pointing to.
+-**
+-** Cursors can also point to virtual tables, sorters, or "pseudo-tables".
+-** A pseudo-table is a single-row table implemented by registers.
+-** 
+-** Every cursor that the virtual machine has open is represented by an
+-** instance of the following structure.
++** A VdbeCursor is an superclass (a wrapper) for various cursor objects:
++**
++**      * A b-tree cursor
++**          -  In the main database or in an ephemeral database
++**          -  On either an index or a table
++**      * A sorter
++**      * A virtual table
++**      * A one-row "pseudotable" stored in a single register
+ */
++typedef struct VdbeCursor VdbeCursor;
+ struct VdbeCursor {
+-  BtCursor *pCursor;    /* The cursor structure of the backend */
+-  Btree *pBt;           /* Separate file holding temporary table */
+-  KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
+-  int seekResult;       /* Result of previous sqlite3BtreeMoveto() */
+-  int pseudoTableReg;   /* Register holding pseudotable content. */
+-  i16 nField;           /* Number of fields in the header */
+-  u16 nHdrParsed;       /* Number of header fields parsed so far */
++  u8 eCurType;            /* One of the CURTYPE_* values above */
++  i8 iDb;                 /* Index of cursor database in db->aDb[] (or -1) */
++  u8 nullRow;             /* True if pointing to a row with no data */
++  u8 deferredMoveto;      /* A call to sqlite3BtreeMoveto() is needed */
++  u8 isTable;             /* True for rowid tables.  False for indexes */
+ #ifdef SQLITE_DEBUG
+-  u8 seekOp;            /* Most recent seek operation on this cursor */
++  u8 seekOp;              /* Most recent seek operation on this cursor */
++  u8 wrFlag;              /* The wrFlag argument to sqlite3BtreeCursor() */
+ #endif
+-  i8 iDb;               /* Index of cursor database in db->aDb[] (or -1) */
+-  u8 nullRow;           /* True if pointing to a row with no data */
+-  u8 deferredMoveto;    /* A call to sqlite3BtreeMoveto() is needed */
+-  Bool isEphemeral:1;   /* True for an ephemeral table */
+-  Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
+-  Bool isTable:1;       /* True if a table requiring integer keys */
+-  Bool isOrdered:1;     /* True if the underlying table is BTREE_UNORDERED */
+-  Pgno pgnoRoot;        /* Root page of the open btree cursor */
+-  sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
+-  i64 seqCount;         /* Sequence counter */
+-  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
+-  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
++  Bool isEphemeral:1;     /* True for an ephemeral table */
++  Bool useRandomRowid:1;  /* Generate new record numbers semi-randomly */
++  Bool isOrdered:1;       /* True if the table is not BTREE_UNORDERED */
++  Btree *pBtx;            /* Separate file holding temporary table */
++  i64 seqCount;           /* Sequence counter */
++  int *aAltMap;           /* Mapping from table to index column numbers */
+ 
+-  /* Cached information about the header for the data record that the
+-  ** cursor is currently pointing to.  Only valid if cacheStatus matches
++  /* Cached OP_Column parse information is only valid if cacheStatus matches
+   ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
+-  ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
+-  ** the cache is out of date.
+-  **
+-  ** aRow might point to (ephemeral) data for the current row, or it might
+-  ** be NULL.
+-  */
+-  u32 cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
+-  u32 payloadSize;      /* Total number of bytes in the record */
+-  u32 szRow;            /* Byte available in aRow */
+-  u32 iHdrOffset;       /* Offset to next unparsed byte of the header */
+-  const u8 *aRow;       /* Data for the current row, if all on one page */
+-  u32 *aOffset;         /* Pointer to aType[nField] */
+-  u32 aType[1];         /* Type values for all entries in the record */
++  ** CACHE_STALE (0) and so setting cacheStatus=CACHE_STALE guarantees that
++  ** the cache is out of date. */
++  u32 cacheStatus;        /* Cache is valid if this matches Vdbe.cacheCtr */
++  int seekResult;         /* Result of previous sqlite3BtreeMoveto() or 0
++                          ** if there have been no prior seeks on the cursor. */
++  /* NB: seekResult does not distinguish between "no seeks have ever occurred
++  ** on this cursor" and "the most recent seek was an exact match". */
++
++  /* When a new VdbeCursor is allocated, only the fields above are zeroed.
++  ** The fields that follow are uninitialized, and must be individually
++  ** initialized prior to first use. */
++  VdbeCursor *pAltCursor; /* Associated index cursor from which to read */
++  union {
++    BtCursor *pCursor;          /* CURTYPE_BTREE.  Btree cursor */
++    sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB.   Vtab cursor */
++    int pseudoTableReg;         /* CURTYPE_PSEUDO. Reg holding content. */
++    VdbeSorter *pSorter;        /* CURTYPE_SORTER. Sorter object */
++  } uc;
++  KeyInfo *pKeyInfo;      /* Info about index keys needed by index cursors */
++  u32 iHdrOffset;         /* Offset to next unparsed byte of the header */
++  Pgno pgnoRoot;          /* Root page of the open btree cursor */
++  i16 nField;             /* Number of fields in the header */
++  u16 nHdrParsed;         /* Number of header fields parsed so far */
++  i64 movetoTarget;       /* Argument to the deferred sqlite3BtreeMoveto() */
++  u32 *aOffset;           /* Pointer to aType[nField] */
++  const u8 *aRow;         /* Data for the current row, if all on one page */
++  u32 payloadSize;        /* Total number of bytes in the record */
++  u32 szRow;              /* Byte available in aRow */
++#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
++  u64 maskUsed;           /* Mask of columns used by this cursor */
++#endif
++
+   /* 2*nField extra array elements allocated for aType[], beyond the one
+   ** static element declared in the structure.  nField total array slots for
+   ** aType[] and nField+1 array slots for aOffset[] */
++  u32 aType[1];           /* Type values record decode.  MUST BE LAST */
+ };
+-typedef struct VdbeCursor VdbeCursor;
++
++
++/*
++** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
++*/
++#define CACHE_STALE 0
+ 
+ /*
+ ** When a sub-program is executed (OP_Program), a structure of this type
+@@ -14635,15 +22572,15 @@
+   Op *aOp;                /* Program instructions for parent frame */
+   i64 *anExec;            /* Event counters from parent frame */
+   Mem *aMem;              /* Array of memory cells for parent frame */
+-  u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
+   VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
++  u8 *aOnce;              /* Bitmask used by OP_Once */
+   void *token;            /* Copy of SubProgram.token */
+   i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
++  AuxData *pAuxData;      /* Linked list of auxdata allocations */
+   int nCursor;            /* Number of entries in apCsr */
+   int pc;                 /* Program Counter in parent (calling) frame */
+   int nOp;                /* Size of aOp array */
+   int nMem;               /* Number of entries in aMem */
+-  int nOnceFlag;          /* Number of entries in aOnceFlag */
+   int nChildMem;          /* Number of memory cells for child frame */
+   int nChildCsr;          /* Number of cursors for child frame */
+   int nChange;            /* Statement changes (Vdbe.nChange)     */
+@@ -14653,26 +22590,23 @@
+ #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
+ 
+ /*
+-** A value for VdbeCursor.cacheValid that means the cache is always invalid.
+-*/
+-#define CACHE_STALE 0
+-
+-/*
+ ** Internally, the vdbe manipulates nearly all SQL values as Mem
+ ** structures. Each Mem struct may cache multiple representations (string,
+ ** integer etc.) of the same value.
+ */
+-struct Mem {
++struct sqlite3_value {
+   union MemValue {
+     double r;           /* Real value used when MEM_Real is set in flags */
+     i64 i;              /* Integer value used when MEM_Int is set in flags */
+-    int nZero;          /* Used when bit MEM_Zero is set in flags */
++    int nZero;          /* Extra zero bytes when MEM_Zero and MEM_Blob set */
++    const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
+     FuncDef *pDef;      /* Used only when flags==MEM_Agg */
+     RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
+     VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
+   } u;
+   u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
+   u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
++  u8  eSubtype;       /* Subtype for this value */
+   int n;              /* Number of characters in string value, excluding '\0' */
+   char *z;            /* String or BLOB value */
+   /* ShallowCopy only needs to copy the information above */
+@@ -14687,11 +22621,18 @@
+ #endif
+ };
+ 
++/*
++** Size of struct Mem not including the Mem.zMalloc member or anything that
++** follows.
++*/
++#define MEMCELLSIZE offsetof(Mem,zMalloc)
++
+ /* One or more of the following flags are set to indicate the validOK
+ ** representations of the value stored in the Mem struct.
+ **
+ ** If the MEM_Null flag is set, then the value is an SQL NULL value.
+-** No other flags may be set in this case.
++** For a pointer type created using sqlite3_bind_pointer() or
++** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
+ **
+ ** If the MEM_Str flag is set then Mem.z points at a string representation.
+ ** Usually this is encoded in the same unicode encoding as the main
+@@ -14699,7 +22640,7 @@
+ ** set, then the string is nul terminated. The MEM_Int and MEM_Real 
+ ** flags may coexist with the MEM_Str flag.
+ */
+-#define MEM_Null      0x0001   /* Value is NULL */
++#define MEM_Null      0x0001   /* Value is NULL (or a pointer) */
+ #define MEM_Str       0x0002   /* Value is a string */
+ #define MEM_Int       0x0004   /* Value is an integer */
+ #define MEM_Real      0x0008   /* Value is a real number */
+@@ -14709,7 +22650,7 @@
+ #define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
+ #define MEM_Undefined 0x0080   /* Value is undefined */
+ #define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
+-#define MEM_TypeMask  0x01ff   /* Mask of type bits */
++#define MEM_TypeMask  0xc1ff   /* Mask of type bits */
+ 
+ 
+ /* Whenever Mem contains a valid string or blob representation, one of
+@@ -14717,17 +22658,24 @@
+ ** policy for Mem.z.  The MEM_Term flag tells us whether or not the
+ ** string is \000 or \u0000 terminated
+ */
+-#define MEM_Term      0x0200   /* String rep is nul terminated */
++#define MEM_Term      0x0200   /* String in Mem.z is zero terminated */
+ #define MEM_Dyn       0x0400   /* Need to call Mem.xDel() on Mem.z */
+ #define MEM_Static    0x0800   /* Mem.z points to a static string */
+ #define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
+ #define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
+ #define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
++#define MEM_Subtype   0x8000   /* Mem.eSubtype is valid */
+ #ifdef SQLITE_OMIT_INCRBLOB
+   #undef MEM_Zero
+   #define MEM_Zero 0x0000
+ #endif
+ 
++/* Return TRUE if Mem X contains dynamically allocated content - anything
++** that needs to be deallocated to avoid a leak.
++*/
++#define VdbeMemDynamic(X)  \
++  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
++
+ /*
+ ** Clear any existing type flags from a Mem and replace them with f
+ */
+@@ -14750,11 +22698,11 @@
+ ** when the VM is halted (if not before).
+ */
+ struct AuxData {
+-  int iOp;                        /* Instruction number of OP_Function opcode */
+-  int iArg;                       /* Index of function argument. */
++  int iAuxOp;                     /* Instruction number of OP_Function opcode */
++  int iAuxArg;                    /* Index of function argument. */
+   void *pAux;                     /* Aux data pointer */
+-  void (*xDelete)(void *);        /* Destructor for the aux data */
+-  AuxData *pNext;                 /* Next element in list */
++  void (*xDeleteAux)(void*);      /* Destructor for the aux data */
++  AuxData *pNextAux;              /* Next element in list */
+ };
+ 
+ /*
+@@ -14771,26 +22719,16 @@
+ ** (Mem) which are only defined there.
+ */
+ struct sqlite3_context {
+-  Mem *pOut;            /* The return value is stored here */
+-  FuncDef *pFunc;       /* Pointer to function information */
+-  Mem *pMem;            /* Memory cell used to store aggregate context */
+-  Vdbe *pVdbe;          /* The VM that owns this context */
+-  int iOp;              /* Instruction number of OP_Function */
+-  int isError;          /* Error code returned by the function. */
+-  u8 skipFlag;          /* Skip accumulator loading if true */
+-  u8 fErrorOrAux;       /* isError!=0 or pVdbe->pAuxData modified */
+-};
+-
+-/*
+-** An Explain object accumulates indented output which is helpful
+-** in describing recursive data structures.
+-*/
+-struct Explain {
+-  Vdbe *pVdbe;       /* Attach the explanation to this Vdbe */
+-  StrAccum str;      /* The string being accumulated */
+-  int nIndent;       /* Number of elements in aIndent */
+-  u16 aIndent[100];  /* Levels of indentation */
+-  char zBase[100];   /* Initial space */
++  Mem *pOut;              /* The return value is stored here */
++  FuncDef *pFunc;         /* Pointer to function information */
++  Mem *pMem;              /* Memory cell used to store aggregate context */
++  Vdbe *pVdbe;            /* The VM that owns this context */
++  int iOp;                /* Instruction number of OP_Function */
++  int isError;            /* Error code returned by the function. */
++  u8 skipFlag;            /* Skip accumulator loading if true */
++  u8 fErrorOrAux;         /* isError!=0 or pVdbe->pAuxData modified */
++  u8 argc;                /* Number of arguments */
++  sqlite3_value *argv[1]; /* Argument set */
+ };
+ 
+ /* A bitfield type for use inside of structures.  Always follow with :N where
+@@ -14817,53 +22755,56 @@
+ */
+ struct Vdbe {
+   sqlite3 *db;            /* The database connection that owns this statement */
++  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
++  Parse *pParse;          /* Parsing context used to create this Vdbe */
++  ynVar nVar;             /* Number of entries in aVar[] */
++  u32 magic;              /* Magic number for sanity checking */
++  int nMem;               /* Number of memory locations currently allocated */
++  int nCursor;            /* Number of slots in apCsr[] */
++  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
++  int pc;                 /* The program counter */
++  int rc;                 /* Value to return */
++  int nChange;            /* Number of db changes made since last reset */
++  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
++  i64 iCurrentTime;       /* Value of julianday('now') for this statement */
++  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
++  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
++  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
++
++  /* When allocating a new Vdbe object, all of the fields below should be
++  ** initialized to zero or NULL */
++
+   Op *aOp;                /* Space to hold the virtual machine's program */
+   Mem *aMem;              /* The memory locations */
+   Mem **apArg;            /* Arguments to currently executing user function */
+   Mem *aColName;          /* Column names to return */
+   Mem *pResultSet;        /* Pointer to an array of results */
+-  Parse *pParse;          /* Parsing context used to create this Vdbe */
+-  int nMem;               /* Number of memory locations currently allocated */
+-  int nOp;                /* Number of instructions in the program */
+-  int nCursor;            /* Number of slots in apCsr[] */
+-  u32 magic;              /* Magic number for sanity checking */
+   char *zErrMsg;          /* Error message written here */
+-  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
+   VdbeCursor **apCsr;     /* One element of this array for each open cursor */
+   Mem *aVar;              /* Values for the OP_Variable opcode. */
+-  char **azVar;           /* Name of variables */
+-  ynVar nVar;             /* Number of entries in aVar[] */
+-  ynVar nzVar;            /* Number of entries in azVar[] */
+-  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
+-  int pc;                 /* The program counter */
+-  int rc;                 /* Value to return */
++  VList *pVList;          /* Name of variables */
++#ifndef SQLITE_OMIT_TRACE
++  i64 startTime;          /* Time when query started - used for profiling */
++#endif
++  int nOp;                /* Number of instructions in the program */
+ #ifdef SQLITE_DEBUG
+   int rcApp;              /* errcode set by sqlite3_result_error_code() */
+ #endif
+   u16 nResColumn;         /* Number of columns in one row of the result set */
+   u8 errorAction;         /* Recovery action to do in case of an error */
+   u8 minWriteFileFormat;  /* Minimum file format for writable database files */
++  u8 prepFlags;           /* SQLITE_PREPARE_* flags */
++  bft expired:1;          /* True if the VM needs to be recompiled */
++  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
+   bft explain:2;          /* True if EXPLAIN present on SQL command */
+   bft changeCntOn:1;      /* True to update the change-counter */
+-  bft expired:1;          /* True if the VM needs to be recompiled */
+   bft runOnlyOnce:1;      /* Automatically expire on reset */
+   bft usesStmtJournal:1;  /* True if uses a statement journal */
+   bft readOnly:1;         /* True for statements that do not write */
+   bft bIsReader:1;        /* True for statements that read */
+-  bft isPrepareV2:1;      /* True if prepared with prepare_v2() */
+-  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
+-  int nChange;            /* Number of db changes made since last reset */
+   yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
+   yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
+-  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
+-  u32 aCounter[5];        /* Counters used by sqlite3_stmt_status() */
+-#ifndef SQLITE_OMIT_TRACE
+-  i64 startTime;          /* Time when query started - used for profiling */
+-#endif
+-  i64 iCurrentTime;       /* Value of julianday('now') for this statement */
+-  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
+-  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
+-  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
++  u32 aCounter[7];        /* Counters used by sqlite3_stmt_status() */
+   char *zSql;             /* Text of the SQL statement that generated this */
+   void *pFree;            /* Free this when deleting the vdbe */
+   VdbeFrame *pFrame;      /* Parent frame */
+@@ -14871,8 +22812,6 @@
+   int nFrame;             /* Number of frames in pFrame list */
+   u32 expmask;            /* Binding to these vars invalidates VM */
+   SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
+-  int nOnceFlag;          /* Size of array aOnceFlag[] */
+-  u8 *aOnceFlag;          /* Flags for OP_Once */
+   AuxData *pAuxData;      /* Linked list of auxdata allocations */
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+   i64 *anExec;            /* Number of times each op has been executed */
+@@ -14884,26 +22823,49 @@
+ /*
+ ** The following are allowed values for Vdbe.magic
+ */
+-#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
+-#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
+-#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
+-#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */
++#define VDBE_MAGIC_INIT     0x16bceaa5    /* Building a VDBE program */
++#define VDBE_MAGIC_RUN      0x2df20da3    /* VDBE is ready to execute */
++#define VDBE_MAGIC_HALT     0x319c2973    /* VDBE has completed execution */
++#define VDBE_MAGIC_RESET    0x48fa9f76    /* Reset and ready to run again */
++#define VDBE_MAGIC_DEAD     0x5606c3c8    /* The VDBE has been deallocated */
++
++/*
++** Structure used to store the context required by the 
++** sqlite3_preupdate_*() API functions.
++*/
++struct PreUpdate {
++  Vdbe *v;
++  VdbeCursor *pCsr;               /* Cursor to read old values from */
++  int op;                         /* One of SQLITE_INSERT, UPDATE, DELETE */
++  u8 *aRecord;                    /* old.* database record */
++  KeyInfo keyinfo;
++  UnpackedRecord *pUnpacked;      /* Unpacked version of aRecord[] */
++  UnpackedRecord *pNewUnpacked;   /* Unpacked version of new.* record */
++  int iNewReg;                    /* Register for new.* values */
++  i64 iKey1;                      /* First key value passed to hook */
++  i64 iKey2;                      /* Second key value passed to hook */
++  Mem *aNew;                      /* Array of new.* values */
++  Table *pTab;                    /* Schema object being upated */          
++  Index *pPk;                     /* PK index if pTab is WITHOUT ROWID */
++};
+ 
+ /*
+ ** Function prototypes
+ */
++SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
+ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
+ void sqliteVdbePopStack(Vdbe*,int);
+-SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
++SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, int*);
+ SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
+ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
+ #endif
+ SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
+-SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
++SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
++SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int, u32*);
+ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
+ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
+-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
++SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
+ 
+ int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
+ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
+@@ -14924,6 +22886,7 @@
+ #else
+ SQLITE_PRIVATE   void sqlite3VdbeMemSetDouble(Mem*, double);
+ #endif
++SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
+ SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
+ SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
+ SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
+@@ -14937,10 +22900,8 @@
+ SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
+ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
+ SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8);
+-SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
++SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
+ SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
+-#define VdbeMemDynamic(X)  \
+-  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
+ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
+ SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
+ SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
+@@ -14948,22 +22909,29 @@
+ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
+ SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
+ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int);
++#endif
+ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
+ 
+ SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *);
+ SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *);
+ SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
+ SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
+-SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
++SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *);
+ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
+ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
+ SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
+ 
+-#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
++#if !defined(SQLITE_OMIT_SHARED_CACHE) 
+ SQLITE_PRIVATE   void sqlite3VdbeEnter(Vdbe*);
+-SQLITE_PRIVATE   void sqlite3VdbeLeave(Vdbe*);
+ #else
+ # define sqlite3VdbeEnter(X)
++#endif
++
++#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
++SQLITE_PRIVATE   void sqlite3VdbeLeave(Vdbe*);
++#else
+ # define sqlite3VdbeLeave(X)
+ #endif
+ 
+@@ -14978,12 +22946,14 @@
+ # define sqlite3VdbeCheckFk(p,i) 0
+ #endif
+ 
+-SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8);
+ #ifdef SQLITE_DEBUG
+ SQLITE_PRIVATE   void sqlite3VdbePrintSql(Vdbe*);
+ SQLITE_PRIVATE   void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
+ #endif
+-SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem);
++#ifndef SQLITE_OMIT_UTF16
++SQLITE_PRIVATE   int sqlite3VdbeMemTranslate(Mem*, u8);
++SQLITE_PRIVATE   int sqlite3VdbeMemHandleBom(Mem *pMem);
++#endif
+ 
+ #ifndef SQLITE_OMIT_INCRBLOB
+ SQLITE_PRIVATE   int sqlite3VdbeMemExpandBlob(Mem *);
+@@ -14993,7 +22963,7 @@
+   #define ExpandBlob(P) SQLITE_OK
+ #endif
+ 
+-#endif /* !defined(_VDBEINT_H_) */
++#endif /* !defined(SQLITE_VDBEINT_H) */
+ 
+ /************** End of vdbeInt.h *********************************************/
+ /************** Continuing where we left off in status.c *********************/
+@@ -15001,15 +22971,15 @@
+ /*
+ ** Variables in which to record status information.
+ */
+-typedef struct sqlite3StatType sqlite3StatType;
+-static SQLITE_WSD struct sqlite3StatType {
+ #if SQLITE_PTRSIZE>4
+-  sqlite3_int64 nowValue[10];         /* Current value */
+-  sqlite3_int64 mxValue[10];          /* Maximum value */
++typedef sqlite3_int64 sqlite3StatValueType;
+ #else
+-  u32 nowValue[10];                   /* Current value */
+-  u32 mxValue[10];                    /* Maximum value */
++typedef u32 sqlite3StatValueType;
+ #endif
++typedef struct sqlite3StatType sqlite3StatType;
++static SQLITE_WSD struct sqlite3StatType {
++  sqlite3StatValueType nowValue[10];  /* Current value */
++  sqlite3StatValueType mxValue[10];   /* Maximum value */
+ } sqlite3Stat = { {0,}, {0,} };
+ 
+ /*
+@@ -15090,25 +23060,31 @@
+ }
+ 
+ /*
+-** Set the value of a status to X.  The highwater mark is adjusted if
+-** necessary.  The caller must hold the appropriate mutex.
++** Adjust the highwater mark if necessary.
++** The caller must hold the appropriate mutex.
+ */
+-SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
++SQLITE_PRIVATE void sqlite3StatusHighwater(int op, int X){
++  sqlite3StatValueType newValue;
+   wsdStatInit;
++  assert( X>=0 );
++  newValue = (sqlite3StatValueType)X;
+   assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
+   assert( op>=0 && op<ArraySize(statMutex) );
+   assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+                                            : sqlite3MallocMutex()) );
+-  wsdStat.nowValue[op] = X;
+-  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
+-    wsdStat.mxValue[op] = wsdStat.nowValue[op];
++  assert( op==SQLITE_STATUS_MALLOC_SIZE
++          || op==SQLITE_STATUS_PAGECACHE_SIZE
++          || op==SQLITE_STATUS_SCRATCH_SIZE
++          || op==SQLITE_STATUS_PARSER_STACK );
++  if( newValue>wsdStat.mxValue[op] ){
++    wsdStat.mxValue[op] = newValue;
+   }
+ }
+ 
+ /*
+ ** Query status information.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_status64(
++SQLITE_API int sqlite3_status64(
+   int op,
+   sqlite3_int64 *pCurrent,
+   sqlite3_int64 *pHighwater,
+@@ -15133,8 +23109,8 @@
+   (void)pMutex;  /* Prevent warning when SQLITE_THREADSAFE=0 */
+   return SQLITE_OK;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
+-  sqlite3_int64 iCur, iHwtr;
++SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
++  sqlite3_int64 iCur = 0, iHwtr = 0;
+   int rc;
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
+@@ -15150,7 +23126,7 @@
+ /*
+ ** Query status information for a single database connection
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_db_status(
++SQLITE_API int sqlite3_db_status(
+   sqlite3 *db,          /* The database connection whose status is desired */
+   int op,               /* Status verb */
+   int *pCurrent,        /* Write current value here */
+@@ -15195,6 +23171,7 @@
+     ** by all pagers associated with the given database connection.  The
+     ** highwater mark is meaningless and is returned as zero.
+     */
++    case SQLITE_DBSTATUS_CACHE_USED_SHARED:
+     case SQLITE_DBSTATUS_CACHE_USED: {
+       int totalUsed = 0;
+       int i;
+@@ -15203,7 +23180,11 @@
+         Btree *pBt = db->aDb[i].pBt;
+         if( pBt ){
+           Pager *pPager = sqlite3BtreePager(pBt);
+-          totalUsed += sqlite3PagerMemUsed(pPager);
++          int nByte = sqlite3PagerMemUsed(pPager);
++          if( op==SQLITE_DBSTATUS_CACHE_USED_SHARED ){
++            nByte = nByte / sqlite3BtreeConnectionCount(pBt);
++          }
++          totalUsed += nByte;
+         }
+       }
+       sqlite3BtreeLeaveAll(db);
+@@ -15234,10 +23215,10 @@
+             + pSchema->idxHash.count
+             + pSchema->fkeyHash.count
+           );
+-          nByte += sqlite3MallocSize(pSchema->tblHash.ht);
+-          nByte += sqlite3MallocSize(pSchema->trigHash.ht);
+-          nByte += sqlite3MallocSize(pSchema->idxHash.ht);
+-          nByte += sqlite3MallocSize(pSchema->fkeyHash.ht);
++          nByte += sqlite3_msize(pSchema->tblHash.ht);
++          nByte += sqlite3_msize(pSchema->trigHash.ht);
++          nByte += sqlite3_msize(pSchema->idxHash.ht);
++          nByte += sqlite3_msize(pSchema->fkeyHash.ht);
+ 
+           for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
+             sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
+@@ -15368,59 +23349,87 @@
+ **      Willmann-Bell, Inc
+ **      Richmond, Virginia (USA)
+ */
++/* #include "sqliteInt.h" */
+ /* #include <stdlib.h> */
+ /* #include <assert.h> */
+ #include <time.h>
+ 
+ #ifndef SQLITE_OMIT_DATETIME_FUNCS
+ 
++/*
++** The MSVC CRT on Windows CE may not have a localtime() function.
++** So declare a substitute.  The substitute function itself is
++** defined in "os_win.c".
++*/
++#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
++    (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
++struct tm *__cdecl localtime(const time_t *);
++#endif
+ 
+ /*
+ ** A structure for holding a single date and time.
+ */
+ typedef struct DateTime DateTime;
+ struct DateTime {
+-  sqlite3_int64 iJD; /* The julian day number times 86400000 */
+-  int Y, M, D;       /* Year, month, and day */
+-  int h, m;          /* Hour and minutes */
+-  int tz;            /* Timezone offset in minutes */
+-  double s;          /* Seconds */
+-  char validYMD;     /* True (1) if Y,M,D are valid */
+-  char validHMS;     /* True (1) if h,m,s are valid */
+-  char validJD;      /* True (1) if iJD is valid */
+-  char validTZ;      /* True (1) if tz is valid */
++  sqlite3_int64 iJD;  /* The julian day number times 86400000 */
++  int Y, M, D;        /* Year, month, and day */
++  int h, m;           /* Hour and minutes */
++  int tz;             /* Timezone offset in minutes */
++  double s;           /* Seconds */
++  char validJD;       /* True (1) if iJD is valid */
++  char rawS;          /* Raw numeric value stored in s */
++  char validYMD;      /* True (1) if Y,M,D are valid */
++  char validHMS;      /* True (1) if h,m,s are valid */
++  char validTZ;       /* True (1) if tz is valid */
++  char tzSet;         /* Timezone was set explicitly */
++  char isError;       /* An overflow has occurred */
+ };
+ 
+ 
+ /*
+-** Convert zDate into one or more integers.  Additional arguments
+-** come in groups of 5 as follows:
++** Convert zDate into one or more integers according to the conversion
++** specifier zFormat.
++**
++** zFormat[] contains 4 characters for each integer converted, except for
++** the last integer which is specified by three characters.  The meaning
++** of a four-character format specifiers ABCD is:
++**
++**    A:   number of digits to convert.  Always "2" or "4".
++**    B:   minimum value.  Always "0" or "1".
++**    C:   maximum value, decoded as:
++**           a:  12
++**           b:  14
++**           c:  24
++**           d:  31
++**           e:  59
++**           f:  9999
++**    D:   the separator character, or \000 to indicate this is the
++**         last number to convert.
++**
++** Example:  To translate an ISO-8601 date YYYY-MM-DD, the format would
++** be "40f-21a-20c".  The "40f-" indicates the 4-digit year followed by "-".
++** The "21a-" indicates the 2-digit month followed by "-".  The "20c" indicates
++** the 2-digit day which is the last integer in the set.
+ **
+-**       N       number of digits in the integer
+-**       min     minimum allowed value of the integer
+-**       max     maximum allowed value of the integer
+-**       nextC   first character after the integer
+-**       pVal    where to write the integers value.
+-**
+-** Conversions continue until one with nextC==0 is encountered.
+ ** The function returns the number of successful conversions.
+ */
+-static int getDigits(const char *zDate, ...){
++static int getDigits(const char *zDate, const char *zFormat, ...){
++  /* The aMx[] array translates the 3rd character of each format
++  ** spec into a max size:    a   b   c   d   e     f */
++  static const u16 aMx[] = { 12, 14, 24, 31, 59, 9999 };
+   va_list ap;
+-  int val;
+-  int N;
+-  int min;
+-  int max;
+-  int nextC;
+-  int *pVal;
+   int cnt = 0;
+-  va_start(ap, zDate);
++  char nextC;
++  va_start(ap, zFormat);
+   do{
+-    N = va_arg(ap, int);
+-    min = va_arg(ap, int);
+-    max = va_arg(ap, int);
+-    nextC = va_arg(ap, int);
+-    pVal = va_arg(ap, int*);
++    char N = zFormat[0] - '0';
++    char min = zFormat[1] - '0';
++    int val = 0;
++    u16 max;
++
++    assert( zFormat[2]>='a' && zFormat[2]<='f' );
++    max = aMx[zFormat[2] - 'a'];
++    nextC = zFormat[3];
+     val = 0;
+     while( N-- ){
+       if( !sqlite3Isdigit(*zDate) ){
+@@ -15429,12 +23438,13 @@
+       val = val*10 + *zDate - '0';
+       zDate++;
+     }
+-    if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
++    if( val<(int)min || val>(int)max || (nextC!=0 && nextC!=*zDate) ){
+       goto end_getDigits;
+     }
+-    *pVal = val;
++    *va_arg(ap,int*) = val;
+     zDate++;
+     cnt++;
++    zFormat += 4;
+   }while( nextC );
+ end_getDigits:
+   va_end(ap);
+@@ -15475,13 +23485,14 @@
+     return c!=0;
+   }
+   zDate++;
+-  if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
++  if( getDigits(zDate, "20b:20e", &nHr, &nMn)!=2 ){
+     return 1;
+   }
+   zDate += 5;
+   p->tz = sgn*(nMn + nHr*60);
+ zulu_time:
+   while( sqlite3Isspace(*zDate) ){ zDate++; }
++  p->tzSet = 1;
+   return *zDate!=0;
+ }
+ 
+@@ -15495,13 +23506,13 @@
+ static int parseHhMmSs(const char *zDate, DateTime *p){
+   int h, m, s;
+   double ms = 0.0;
+-  if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
++  if( getDigits(zDate, "20c:20e", &h, &m)!=2 ){
+     return 1;
+   }
+   zDate += 5;
+   if( *zDate==':' ){
+     zDate++;
+-    if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
++    if( getDigits(zDate, "20e", &s)!=1 ){
+       return 1;
+     }
+     zDate += 2;
+@@ -15519,6 +23530,7 @@
+     s = 0;
+   }
+   p->validJD = 0;
++  p->rawS = 0;
+   p->validHMS = 1;
+   p->h = h;
+   p->m = m;
+@@ -15529,6 +23541,14 @@
+ }
+ 
+ /*
++** Put the DateTime object into its error state.
++*/
++static void datetimeError(DateTime *p){
++  memset(p, 0, sizeof(*p));
++  p->isError = 1;
++}
++
++/*
+ ** Convert from YYYY-MM-DD HH:MM:SS to julian day.  We always assume
+ ** that the YYYY-MM-DD is according to the Gregorian calendar.
+ **
+@@ -15547,6 +23567,10 @@
+     M = 1;
+     D = 1;
+   }
++  if( Y<-4713 || Y>9999 || p->rawS ){
++    datetimeError(p);
++    return;
++  }
+   if( M<=2 ){
+     Y--;
+     M += 12;
+@@ -15589,7 +23613,7 @@
+   }else{
+     neg = 0;
+   }
+-  if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
++  if( getDigits(zDate, "40f-21a-21d", &Y, &M, &D)!=3 ){
+     return 1;
+   }
+   zDate += 10;
+@@ -15628,6 +23652,21 @@
+ }
+ 
+ /*
++** Input "r" is a numeric quantity which might be a julian day number,
++** or the number of seconds since 1970.  If the value if r is within
++** range of a julian day number, install it as such and set validJD.
++** If the value is a valid unix timestamp, put it in p->s and set p->rawS.
++*/
++static void setRawDateNumber(DateTime *p, double r){
++  p->s = r;
++  p->rawS = 1;
++  if( r>=0.0 && r<5373484.5 ){
++    p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
++    p->validJD = 1;
++  }
++}
++
++/*
+ ** Attempt to parse the given string into a julian day number.  Return
+ ** the number of errors.
+ **
+@@ -15653,16 +23692,33 @@
+     return 0;
+   }else if( parseHhMmSs(zDate, p)==0 ){
+     return 0;
+-  }else if( sqlite3StrICmp(zDate,"now")==0){
++  }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){
+     return setDateTimeToCurrent(context, p);
+   }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
+-    p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
+-    p->validJD = 1;
++    setRawDateNumber(p, r);
+     return 0;
+   }
+   return 1;
+ }
+ 
++/* The julian day number for 9999-12-31 23:59:59.999 is 5373484.4999999.
++** Multiplying this by 86400000 gives 464269060799999 as the maximum value
++** for DateTime.iJD.
++**
++** But some older compilers (ex: gcc 4.2.1 on older Macs) cannot deal with 
++** such a large integer literal, so we have to encode it.
++*/
++#define INT_464269060799999  ((((i64)0x1a640)<<32)|0x1072fdff)
++
++/*
++** Return TRUE if the given julian day number is within range.
++**
++** The input is the JulianDay times 86400000.
++*/
++static int validJulianDay(sqlite3_int64 iJD){
++  return iJD>=0 && iJD<=INT_464269060799999;
++}
++
+ /*
+ ** Compute the Year, Month, and Day from the julian day number.
+ */
+@@ -15673,13 +23729,16 @@
+     p->Y = 2000;
+     p->M = 1;
+     p->D = 1;
++  }else if( !validJulianDay(p->iJD) ){
++    datetimeError(p);
++    return;
+   }else{
+     Z = (int)((p->iJD + 43200000)/86400000);
+     A = (int)((Z - 1867216.25)/36524.25);
+     A = Z + 1 + A - (A/4);
+     B = A + 1524;
+     C = (int)((B - 122.1)/365.25);
+-    D = (36525*C)/100;
++    D = (36525*(C&32767))/100;
+     E = (int)((B-D)/30.6001);
+     X1 = (int)(30.6001*E);
+     p->D = B - D - X1;
+@@ -15704,6 +23763,7 @@
+   s -= p->h*3600;
+   p->m = s/60;
+   p->s += s - p->m*60;
++  p->rawS = 0;
+   p->validHMS = 1;
+ }
+ 
+@@ -15724,6 +23784,7 @@
+   p->validTZ = 0;
+ }
+ 
++#ifndef SQLITE_OMIT_LOCALTIME
+ /*
+ ** On recent Windows platforms, the localtime_s() function is available
+ ** as part of the "Secure CRT". It is essentially equivalent to 
+@@ -15742,7 +23803,6 @@
+ #define HAVE_LOCALTIME_S 1
+ #endif
+ 
+-#ifndef SQLITE_OMIT_LOCALTIME
+ /*
+ ** The following routine implements the rough equivalent of localtime_r()
+ ** using whatever operating-system specific localtime facility that
+@@ -15765,14 +23825,14 @@
+ #endif
+   sqlite3_mutex_enter(mutex);
+   pX = localtime(t);
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
++#ifndef SQLITE_UNTESTABLE
+   if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
+ #endif
+   if( pX ) *pTm = *pX;
+   sqlite3_mutex_leave(mutex);
+   rc = pX==0;
+ #else
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
++#ifndef SQLITE_UNTESTABLE
+   if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
+ #endif
+ #if HAVE_LOCALTIME_R
+@@ -15843,7 +23903,9 @@
+   y.validYMD = 1;
+   y.validHMS = 1;
+   y.validJD = 0;
++  y.rawS = 0;
+   y.validTZ = 0;
++  y.isError = 0;
+   computeJD(&y);
+   *pRc = SQLITE_OK;
+   return y.iJD - x.iJD;
+@@ -15851,6 +23913,29 @@
+ #endif /* SQLITE_OMIT_LOCALTIME */
+ 
+ /*
++** The following table defines various date transformations of the form
++**
++**            'NNN days'
++**
++** Where NNN is an arbitrary floating-point number and "days" can be one
++** of several units of time.
++*/
++static const struct {
++  u8 eType;           /* Transformation type code */
++  u8 nName;           /* Length of th name */
++  char *zName;        /* Name of the transformation */
++  double rLimit;      /* Maximum NNN value for this transform */
++  double rXform;      /* Constant used for this transform */
++} aXformType[] = {
++  { 0, 6, "second", 464269060800.0, 86400000.0/(24.0*60.0*60.0) },
++  { 0, 6, "minute", 7737817680.0,   86400000.0/(24.0*60.0)      },
++  { 0, 4, "hour",   128963628.0,    86400000.0/24.0             },
++  { 0, 3, "day",    5373485.0,      86400000.0                  },
++  { 1, 5, "month",  176546.0,       30.0*86400000.0             },
++  { 2, 4, "year",   14713.0,        365.0*86400000.0            },
++};
++
++/*
+ ** Process a modifier to a date-time stamp.  The modifiers are
+ ** as follows:
+ **
+@@ -15874,17 +23959,15 @@
+ ** to context pCtx. If the error is an unrecognized modifier, no error is
+ ** written to pCtx.
+ */
+-static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
++static int parseModifier(
++  sqlite3_context *pCtx,      /* Function context */
++  const char *z,              /* The text of the modifier */
++  int n,                      /* Length of zMod in bytes */
++  DateTime *p                 /* The date/time value to be modified */
++){
+   int rc = 1;
+-  int n;
+   double r;
+-  char *z, zBuf[30];
+-  z = zBuf;
+-  for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){
+-    z[n] = (char)sqlite3UpperToLower[(u8)zMod[n]];
+-  }
+-  z[n] = 0;
+-  switch( z[0] ){
++  switch(sqlite3UpperToLower[(u8)z[0]] ){
+ #ifndef SQLITE_OMIT_LOCALTIME
+     case 'l': {
+       /*    localtime
+@@ -15892,7 +23975,7 @@
+       ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
+       ** show local time.
+       */
+-      if( strcmp(z, "localtime")==0 ){
++      if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
+         computeJD(p);
+         p->iJD += localtimeOffset(p, pCtx, &rc);
+         clearYMD_HMS_TZ(p);
+@@ -15904,23 +23987,33 @@
+       /*
+       **    unixepoch
+       **
+-      ** Treat the current value of p->iJD as the number of
++      ** Treat the current value of p->s as the number of
+       ** seconds since 1970.  Convert to a real julian day number.
+       */
+-      if( strcmp(z, "unixepoch")==0 && p->validJD ){
+-        p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000;
+-        clearYMD_HMS_TZ(p);
+-        rc = 0;
++      if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
++        r = p->s*1000.0 + 210866760000000.0;
++        if( r>=0.0 && r<464269060800000.0 ){
++          clearYMD_HMS_TZ(p);
++          p->iJD = (sqlite3_int64)r;
++          p->validJD = 1;
++          p->rawS = 0;
++          rc = 0;
++        }
+       }
+ #ifndef SQLITE_OMIT_LOCALTIME
+-      else if( strcmp(z, "utc")==0 ){
+-        sqlite3_int64 c1;
+-        computeJD(p);
+-        c1 = localtimeOffset(p, pCtx, &rc);
+-        if( rc==SQLITE_OK ){
+-          p->iJD -= c1;
+-          clearYMD_HMS_TZ(p);
+-          p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
++      else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
++        if( p->tzSet==0 ){
++          sqlite3_int64 c1;
++          computeJD(p);
++          c1 = localtimeOffset(p, pCtx, &rc);
++          if( rc==SQLITE_OK ){
++            p->iJD -= c1;
++            clearYMD_HMS_TZ(p);
++            p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
++          }
++          p->tzSet = 1;
++        }else{
++          rc = SQLITE_OK;
+         }
+       }
+ #endif
+@@ -15934,7 +24027,7 @@
+       ** weekday N where 0==Sunday, 1==Monday, and so forth.  If the
+       ** date is already on the appropriate weekday, this is a no-op.
+       */
+-      if( strncmp(z, "weekday ", 8)==0
++      if( sqlite3_strnicmp(z, "weekday ", 8)==0
+                && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
+                && (n=(int)r)==r && n>=0 && r<7 ){
+         sqlite3_int64 Z;
+@@ -15957,23 +24050,24 @@
+       ** Move the date backwards to the beginning of the current day,
+       ** or month or year.
+       */
+-      if( strncmp(z, "start of ", 9)!=0 ) break;
++      if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break;
++      if( !p->validJD && !p->validYMD && !p->validHMS ) break;
+       z += 9;
+       computeYMD(p);
+       p->validHMS = 1;
+       p->h = p->m = 0;
+       p->s = 0.0;
++      p->rawS = 0;
+       p->validTZ = 0;
+       p->validJD = 0;
+-      if( strcmp(z,"month")==0 ){
++      if( sqlite3_stricmp(z,"month")==0 ){
+         p->D = 1;
+         rc = 0;
+-      }else if( strcmp(z,"year")==0 ){
+-        computeYMD(p);
++      }else if( sqlite3_stricmp(z,"year")==0 ){
+         p->M = 1;
+         p->D = 1;
+         rc = 0;
+-      }else if( strcmp(z,"day")==0 ){
++      }else if( sqlite3_stricmp(z,"day")==0 ){
+         rc = 0;
+       }
+       break;
+@@ -15991,6 +24085,7 @@
+     case '8':
+     case '9': {
+       double rRounder;
++      int i;
+       for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
+       if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
+         rc = 1;
+@@ -16019,46 +24114,48 @@
+         rc = 0;
+         break;
+       }
++
++      /* If control reaches this point, it means the transformation is
++      ** one of the forms like "+NNN days".  */
+       z += n;
+       while( sqlite3Isspace(*z) ) z++;
+       n = sqlite3Strlen30(z);
+       if( n>10 || n<3 ) break;
+-      if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
++      if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--;
+       computeJD(p);
+-      rc = 0;
++      rc = 1;
+       rRounder = r<0 ? -0.5 : +0.5;
+-      if( n==3 && strcmp(z,"day")==0 ){
+-        p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder);
+-      }else if( n==4 && strcmp(z,"hour")==0 ){
+-        p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder);
+-      }else if( n==6 && strcmp(z,"minute")==0 ){
+-        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder);
+-      }else if( n==6 && strcmp(z,"second")==0 ){
+-        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder);
+-      }else if( n==5 && strcmp(z,"month")==0 ){
+-        int x, y;
+-        computeYMD_HMS(p);
+-        p->M += (int)r;
+-        x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
+-        p->Y += x;
+-        p->M -= x*12;
+-        p->validJD = 0;
+-        computeJD(p);
+-        y = (int)r;
+-        if( y!=r ){
+-          p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder);
+-        }
+-      }else if( n==4 && strcmp(z,"year")==0 ){
+-        int y = (int)r;
+-        computeYMD_HMS(p);
+-        p->Y += y;
+-        p->validJD = 0;
+-        computeJD(p);
+-        if( y!=r ){
+-          p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder);
++      for(i=0; i<ArraySize(aXformType); i++){
++        if( aXformType[i].nName==n
++         && sqlite3_strnicmp(aXformType[i].zName, z, n)==0
++         && r>-aXformType[i].rLimit && r<aXformType[i].rLimit
++        ){
++          switch( aXformType[i].eType ){
++            case 1: { /* Special processing to add months */
++              int x;
++              computeYMD_HMS(p);
++              p->M += (int)r;
++              x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
++              p->Y += x;
++              p->M -= x*12;
++              p->validJD = 0;
++              r -= (int)r;
++              break;
++            }
++            case 2: { /* Special processing to add years */
++              int y = (int)r;
++              computeYMD_HMS(p);
++              p->Y += y;
++              p->validJD = 0;
++              r -= (int)r;
++              break;
++            }
++          }
++          computeJD(p);
++          p->iJD += (sqlite3_int64)(r*aXformType[i].rXform + rRounder);
++          rc = 0;
++          break;
+         }
+-      }else{
+-        rc = 1;
+       }
+       clearYMD_HMS_TZ(p);
+       break;
+@@ -16085,7 +24182,7 @@
+   sqlite3_value **argv, 
+   DateTime *p
+ ){
+-  int i;
++  int i, n;
+   const unsigned char *z;
+   int eType;
+   memset(p, 0, sizeof(*p));
+@@ -16094,8 +24191,7 @@
+   }
+   if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
+                    || eType==SQLITE_INTEGER ){
+-    p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
+-    p->validJD = 1;
++    setRawDateNumber(p, sqlite3_value_double(argv[0]));
+   }else{
+     z = sqlite3_value_text(argv[0]);
+     if( !z || parseDateOrTime(context, (char*)z, p) ){
+@@ -16104,8 +24200,11 @@
+   }
+   for(i=1; i<argc; i++){
+     z = sqlite3_value_text(argv[i]);
+-    if( z==0 || parseModifier(context, (char*)z, p) ) return 1;
++    n = sqlite3_value_bytes(argv[i]);
++    if( z==0 || parseModifier(context, (char*)z, n, p) ) return 1;
+   }
++  computeJD(p);
++  if( p->isError || !validJulianDay(p->iJD) ) return 1;
+   return 0;
+ }
+ 
+@@ -16268,7 +24367,7 @@
+     sqlite3_result_error_toobig(context);
+     return;
+   }else{
+-    z = sqlite3DbMallocRaw(db, (int)n);
++    z = sqlite3DbMallocRawNN(db, (int)n);
+     if( z==0 ){
+       sqlite3_result_error_nomem(context);
+       return;
+@@ -16404,7 +24503,6 @@
+ ){
+   time_t t;
+   char *zFormat = (char *)sqlite3_user_data(context);
+-  sqlite3 *db;
+   sqlite3_int64 iT;
+   struct tm *pTm;
+   struct tm sNow;
+@@ -16437,29 +24535,23 @@
+ ** external linkage.
+ */
+ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
+-  static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
++  static FuncDef aDateTimeFuncs[] = {
+ #ifndef SQLITE_OMIT_DATETIME_FUNCS
+-    FUNCTION(julianday,        -1, 0, 0, juliandayFunc ),
+-    FUNCTION(date,             -1, 0, 0, dateFunc      ),
+-    FUNCTION(time,             -1, 0, 0, timeFunc      ),
+-    FUNCTION(datetime,         -1, 0, 0, datetimeFunc  ),
+-    FUNCTION(strftime,         -1, 0, 0, strftimeFunc  ),
+-    FUNCTION(current_time,      0, 0, 0, ctimeFunc     ),
+-    FUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
+-    FUNCTION(current_date,      0, 0, 0, cdateFunc     ),
++    PURE_DATE(julianday,        -1, 0, 0, juliandayFunc ),
++    PURE_DATE(date,             -1, 0, 0, dateFunc      ),
++    PURE_DATE(time,             -1, 0, 0, timeFunc      ),
++    PURE_DATE(datetime,         -1, 0, 0, datetimeFunc  ),
++    PURE_DATE(strftime,         -1, 0, 0, strftimeFunc  ),
++    DFUNCTION(current_time,      0, 0, 0, ctimeFunc     ),
++    DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
++    DFUNCTION(current_date,      0, 0, 0, cdateFunc     ),
+ #else
+     STR_FUNCTION(current_time,      0, "%H:%M:%S",          0, currentTimeFunc),
+     STR_FUNCTION(current_date,      0, "%Y-%m-%d",          0, currentTimeFunc),
+     STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
+ #endif
+   };
+-  int i;
+-  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
+-  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs);
+-
+-  for(i=0; i<ArraySize(aDateTimeFuncs); i++){
+-    sqlite3FuncDefInsert(pHash, &aFunc[i]);
+-  }
++  sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs));
+ }
+ 
+ /************** End of date.c ************************************************/
+@@ -16479,8 +24571,29 @@
+ ** This file contains OS interface code that is common to all
+ ** architectures.
+ */
+-#define _SQLITE_OS_C_ 1
+-#undef _SQLITE_OS_C_
++/* #include "sqliteInt.h" */
++
++/*
++** 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.
++*/
++#if defined(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;
++#endif /* defined(SQLITE_TEST) */
++
++/*
++** When testing, also keep a count of the number of open files.
++*/
++#if defined(SQLITE_TEST)
++SQLITE_API int sqlite3_open_file_count = 0;
++#endif /* defined(SQLITE_TEST) */
+ 
+ /*
+ ** The default SQLite sqlite3_vfs implementations do not allocate
+@@ -16489,7 +24602,7 @@
+ ** So we test the effects of a malloc() failing and the sqlite3OsXXX()
+ ** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
+ **
+-** The following functions are instrumented for malloc() failure 
++** The following functions are instrumented for malloc() failure
+ ** testing:
+ **
+ **     sqlite3OsRead()
+@@ -16509,9 +24622,9 @@
+ #if defined(SQLITE_TEST)
+ SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1;
+   #define DO_OS_MALLOC_TEST(x)                                       \
+-  if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) {  \
++  if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3JournalIsInMemory(x))) { \
+     void *pTstAlloc = sqlite3Malloc(10);                             \
+-    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
++    if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT;                  \
+     sqlite3_free(pTstAlloc);                                         \
+   }
+ #else
+@@ -16524,13 +24637,11 @@
+ ** of this would be completely automatic if SQLite were coded using
+ ** C++ instead of plain old C.
+ */
+-SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file *pId){
+-  int rc = SQLITE_OK;
++SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file *pId){
+   if( pId->pMethods ){
+-    rc = pId->pMethods->xClose(pId);
++    pId->pMethods->xClose(pId);
+     pId->pMethods = 0;
+   }
+-  return rc;
+ }
+ SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
+   DO_OS_MALLOC_TEST(id);
+@@ -16575,8 +24686,8 @@
+ #ifdef SQLITE_TEST
+   if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
+     /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
+-    ** is using a regular VFS, it is called after the corresponding 
+-    ** transaction has been committed. Injecting a fault at this point 
++    ** is using a regular VFS, it is called after the corresponding
++    ** transaction has been committed. Injecting a fault at this point
+     ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
+     ** but the transaction is committed anyway.
+     **
+@@ -16645,10 +24756,10 @@
+ ** VFS methods.
+ */
+ SQLITE_PRIVATE int sqlite3OsOpen(
+-  sqlite3_vfs *pVfs, 
+-  const char *zPath, 
+-  sqlite3_file *pFile, 
+-  int flags, 
++  sqlite3_vfs *pVfs,
++  const char *zPath,
++  sqlite3_file *pFile,
++  int flags,
+   int *pFlagsOut
+ ){
+   int rc;
+@@ -16667,18 +24778,18 @@
+   return pVfs->xDelete(pVfs, zPath, dirSync);
+ }
+ SQLITE_PRIVATE int sqlite3OsAccess(
+-  sqlite3_vfs *pVfs, 
+-  const char *zPath, 
+-  int flags, 
++  sqlite3_vfs *pVfs,
++  const char *zPath,
++  int flags,
+   int *pResOut
+ ){
+   DO_OS_MALLOC_TEST(0);
+   return pVfs->xAccess(pVfs, zPath, flags, pResOut);
+ }
+ SQLITE_PRIVATE int sqlite3OsFullPathname(
+-  sqlite3_vfs *pVfs, 
+-  const char *zPath, 
+-  int nPathOut, 
++  sqlite3_vfs *pVfs,
++  const char *zPath,
++  int nPathOut,
+   char *zPathOut
+ ){
+   DO_OS_MALLOC_TEST(0);
+@@ -16705,6 +24816,9 @@
+ SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
+   return pVfs->xSleep(pVfs, nMicro);
+ }
++SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs *pVfs){
++  return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0;
++}
+ SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
+   int rc;
+   /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
+@@ -16724,13 +24838,13 @@
+ }
+ 
+ SQLITE_PRIVATE int sqlite3OsOpenMalloc(
+-  sqlite3_vfs *pVfs, 
+-  const char *zFile, 
+-  sqlite3_file **ppFile, 
++  sqlite3_vfs *pVfs,
++  const char *zFile,
++  sqlite3_file **ppFile,
+   int flags,
+   int *pOutFlags
+ ){
+-  int rc = SQLITE_NOMEM;
++  int rc;
+   sqlite3_file *pFile;
+   pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
+   if( pFile ){
+@@ -16740,15 +24854,15 @@
+     }else{
+       *ppFile = pFile;
+     }
++  }else{
++    rc = SQLITE_NOMEM_BKPT;
+   }
+   return rc;
+ }
+-SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *pFile){
+-  int rc = SQLITE_OK;
++SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
+   assert( pFile );
+-  rc = sqlite3OsClose(pFile);
++  sqlite3OsClose(pFile);
+   sqlite3_free(pFile);
+-  return rc;
+ }
+ 
+ /*
+@@ -16759,7 +24873,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3OsInit(void){
+   void *p = sqlite3_malloc(10);
+-  if( p==0 ) return SQLITE_NOMEM;
++  if( p==0 ) return SQLITE_NOMEM_BKPT;
+   sqlite3_free(p);
+   return sqlite3_os_init();
+ }
+@@ -16774,7 +24888,7 @@
+ ** Locate a VFS by name.  If no name is given, simply return the
+ ** first VFS on the list.
+ */
+-SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfs){
++SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
+   sqlite3_vfs *pVfs = 0;
+ #if SQLITE_THREADSAFE
+   sqlite3_mutex *mutex;
+@@ -16820,7 +24934,7 @@
+ ** VFS multiple times.  The new VFS becomes the default if makeDflt is
+ ** true.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
++SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
+   MUTEX_LOGIC(sqlite3_mutex *mutex;)
+ #ifndef SQLITE_OMIT_AUTOINIT
+   int rc = sqlite3_initialize();
+@@ -16848,7 +24962,7 @@
+ /*
+ ** Unregister a VFS so that it is no longer accessible.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
++SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
+ #if SQLITE_THREADSAFE
+   sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+ #endif
+@@ -16886,8 +25000,9 @@
+ ** during a hash table resize is a benign fault.
+ */
+ 
++/* #include "sqliteInt.h" */
+ 
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
++#ifndef SQLITE_UNTESTABLE
+ 
+ /*
+ ** Global variables.
+@@ -16945,7 +25060,7 @@
+   }
+ }
+ 
+-#endif   /* #ifndef SQLITE_OMIT_BUILTIN_TEST */
++#endif   /* #ifndef SQLITE_UNTESTABLE */
+ 
+ /************** End of fault.c ***********************************************/
+ /************** Begin file mem0.c ********************************************/
+@@ -16967,6 +25082,7 @@
+ ** are merely placeholders.  Real drivers must be substituted using
+ ** sqlite3_config() before SQLite will operate.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** This version of the memory allocator is the default.  It is
+@@ -17053,6 +25169,7 @@
+ **                                be necessary when compiling for Delphi,
+ **                                for example.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** This version of the memory allocator is the default.  It is
+@@ -17068,7 +25185,9 @@
+ */
+ #include <sys/sysctl.h>
+ #include <malloc/malloc.h>
++#ifdef SQLITE_MIGHT_BE_SINGLE_CORE
+ #include <libkern/OSAtomic.h>
++#endif /* SQLITE_MIGHT_BE_SINGLE_CORE */
+ static malloc_zone_t* _sqliteZone_;
+ #define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
+ #define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
+@@ -17136,7 +25255,9 @@
+ */
+ static void *sqlite3MemMalloc(int nByte){
+ #ifdef SQLITE_MALLOCSIZE
+-  void *p = SQLITE_MALLOC( nByte );
++  void *p;
++  testcase( ROUND8(nByte)==nByte );
++  p = SQLITE_MALLOC( nByte );
+   if( p==0 ){
+     testcase( sqlite3GlobalConfig.xLog!=0 );
+     sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
+@@ -17145,7 +25266,7 @@
+ #else
+   sqlite3_int64 *p;
+   assert( nByte>0 );
+-  nByte = ROUND8(nByte);
++  testcase( ROUND8(nByte)!=nByte );
+   p = SQLITE_MALLOC( nByte+8 );
+   if( p ){
+     p[0] = nByte;
+@@ -17183,10 +25304,11 @@
+ */
+ static int sqlite3MemSize(void *pPrior){
+ #ifdef SQLITE_MALLOCSIZE
+-  return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0;
++  assert( pPrior!=0 );
++  return (int)SQLITE_MALLOCSIZE(pPrior);
+ #else
+   sqlite3_int64 *p;
+-  if( pPrior==0 ) return 0;
++  assert( pPrior!=0 );
+   p = (sqlite3_int64*)pPrior;
+   p--;
+   return (int)p[0];
+@@ -17258,19 +25380,10 @@
+   }else{
+     /* only 1 core, use our own zone to contention over global locks, 
+     ** e.g. we have our own dedicated locks */
+-    bool success;
+-    malloc_zone_t* newzone = malloc_create_zone(4096, 0);
+-    malloc_set_zone_name(newzone, "Sqlite_Heap");
+-    do{
+-      success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, 
+-                                 (void * volatile *)&_sqliteZone_);
+-    }while(!_sqliteZone_);
+-    if( !success ){
+-      /* somebody registered a zone first */
+-      malloc_destroy_zone(newzone);
+-    }
++    _sqliteZone_ = malloc_create_zone(4096, 0);
++    malloc_set_zone_name(_sqliteZone_, "Sqlite_Heap");
+   }
+-#endif
++#endif /*  defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) */
+   UNUSED_PARAMETER(NotUsed);
+   return SQLITE_OK;
+ }
+@@ -17328,6 +25441,7 @@
+ ** This file contains implementations of the low-level memory allocation
+ ** routines specified in the sqlite3_mem_methods object.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** This version of the memory allocator is used only if the
+@@ -17862,6 +25976,7 @@
+ ** This version of the memory allocation subsystem is included
+ ** in the build only if SQLITE_ENABLE_MEMSYS3 is defined.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** This version of the memory allocator is only built into the library
+@@ -18314,7 +26429,7 @@
+ */
+ static int memsys3Size(void *p){
+   Mem3Block *pBlock;
+-  if( p==0 ) return 0;
++  assert( p!=0 );
+   pBlock = (Mem3Block*)p;
+   assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
+   return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
+@@ -18553,7 +26668,7 @@
+ **
+ ** This memory allocator uses the following algorithm:
+ **
+-**   1.  All memory allocations sizes are rounded up to a power of 2.
++**   1.  All memory allocation sizes are rounded up to a power of 2.
+ **
+ **   2.  If two adjacent free blocks are the halves of a larger block,
+ **       then the two blocks are coalesced into the single larger block.
+@@ -18576,6 +26691,7 @@
+ ** The sqlite3_status() logic tracks the maximum values of n and M so
+ ** that an application can, at any time, verify this constraint.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** This version of the memory allocator is used only when 
+@@ -18629,6 +26745,7 @@
+   */
+   sqlite3_mutex *mutex;
+ 
++#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+   /*
+   ** Performance statistics
+   */
+@@ -18640,11 +26757,12 @@
+   u32 maxOut;         /* Maximum instantaneous currentOut */
+   u32 maxCount;       /* Maximum instantaneous currentCount */
+   u32 maxRequest;     /* Largest allocation (exclusive of internal frag) */
++#endif
+   
+   /*
+   ** Lists of free blocks.  aiFreelist[0] is a list of free blocks of
+   ** size mem5.szAtom.  aiFreelist[1] holds blocks of size szAtom*2.
+-  ** and so forth.
++  ** aiFreelist[2] holds free blocks of size szAtom*4.  And so forth.
+   */
+   int aiFreelist[LOGMAX+1];
+ 
+@@ -18710,9 +26828,7 @@
+ }
+ 
+ /*
+-** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
+-** will already be held (obtained by code in malloc.c) if
+-** sqlite3GlobalConfig.bMemStat is true.
++** Obtain or release the mutex needed to access global data structures.
+ */
+ static void memsys5Enter(void){
+   sqlite3_mutex_enter(mem5.mutex);
+@@ -18722,17 +26838,15 @@
+ }
+ 
+ /*
+-** Return the size of an outstanding allocation, in bytes.  The
+-** size returned omits the 8-byte header overhead.  This only
+-** works for chunks that are currently checked out.
++** Return the size of an outstanding allocation, in bytes.
++** This only works for chunks that are currently checked out.
+ */
+ static int memsys5Size(void *p){
+-  int iSize = 0;
+-  if( p ){
+-    int i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom);
+-    assert( i>=0 && i<mem5.nBlock );
+-    iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
+-  }
++  int iSize, i;
++  assert( p!=0 );
++  i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom);
++  assert( i>=0 && i<mem5.nBlock );
++  iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
+   return iSize;
+ }
+ 
+@@ -18755,21 +26869,20 @@
+   /* nByte must be a positive */
+   assert( nByte>0 );
+ 
++  /* No more than 1GiB per allocation */
++  if( nByte > 0x40000000 ) return 0;
++
++#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+   /* Keep track of the maximum allocation request.  Even unfulfilled
+   ** requests are counted */
+   if( (u32)nByte>mem5.maxRequest ){
+     mem5.maxRequest = nByte;
+   }
++#endif
+ 
+-  /* Abort if the requested allocation size is larger than the largest
+-  ** power of two that we can represent using 32-bit signed integers.
+-  */
+-  if( nByte > 0x40000000 ){
+-    return 0;
+-  }
+ 
+   /* Round nByte up to the next valid power of two */
+-  for(iFullSz=mem5.szAtom, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){}
++  for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte; iFullSz*=2,iLogsize++){}
+ 
+   /* Make sure mem5.aiFreelist[iLogsize] contains at least one free
+   ** block.  If not, then split a block of the next larger power of
+@@ -18793,6 +26906,7 @@
+   }
+   mem5.aCtrl[i] = iLogsize;
+ 
++#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+   /* Update allocator performance statistics. */
+   mem5.nAlloc++;
+   mem5.totalAlloc += iFullSz;
+@@ -18801,6 +26915,7 @@
+   mem5.currentOut += iFullSz;
+   if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
+   if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
++#endif
+ 
+ #ifdef SQLITE_DEBUG
+   /* Make sure the allocated memory does not assume that it is set to zero
+@@ -18835,23 +26950,26 @@
+ 
+   mem5.aCtrl[iBlock] |= CTRL_FREE;
+   mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
++
++#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+   assert( mem5.currentCount>0 );
+   assert( mem5.currentOut>=(size*mem5.szAtom) );
+   mem5.currentCount--;
+   mem5.currentOut -= size*mem5.szAtom;
+   assert( mem5.currentOut>0 || mem5.currentCount==0 );
+   assert( mem5.currentCount>0 || mem5.currentOut==0 );
++#endif
+ 
+   mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
+   while( ALWAYS(iLogsize<LOGMAX) ){
+     int iBuddy;
+     if( (iBlock>>iLogsize) & 1 ){
+       iBuddy = iBlock - size;
++      assert( iBuddy>=0 );
+     }else{
+       iBuddy = iBlock + size;
++      if( iBuddy>=mem5.nBlock ) break;
+     }
+-    assert( iBuddy>=0 );
+-    if( (iBuddy+(1<<iLogsize))>mem5.nBlock ) break;
+     if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
+     memsys5Unlink(iBuddy, iLogsize);
+     iLogsize++;
+@@ -18926,13 +27044,11 @@
+   if( nBytes<=nOld ){
+     return pPrior;
+   }
+-  memsys5Enter();
+-  p = memsys5MallocUnsafe(nBytes);
++  p = memsys5Malloc(nBytes);
+   if( p ){
+     memcpy(p, pPrior, nOld);
+-    memsys5FreeUnsafe(pPrior);
++    memsys5Free(pPrior);
+   }
+-  memsys5Leave();
+   return p;
+ }
+ 
+@@ -19119,6 +27235,7 @@
+ **
+ ** This file contains code that is common across all mutex implementations.
+ */
++/* #include "sqliteInt.h" */
+ 
+ #if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
+ /*
+@@ -19127,7 +27244,7 @@
+ ** allocate a mutex while the system is uninitialized.
+ */
+ static SQLITE_WSD int mutexIsInit = 0;
+-#endif /* SQLITE_DEBUG */
++#endif /* SQLITE_DEBUG && !defined(SQLITE_MUTEX_OMIT) */
+ 
+ 
+ #ifndef SQLITE_MUTEX_OMIT
+@@ -19150,11 +27267,18 @@
+     }else{
+       pFrom = sqlite3NoopMutex();
+     }
+-    memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
+-    memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
+-           sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
++    pTo->xMutexInit = pFrom->xMutexInit;
++    pTo->xMutexEnd = pFrom->xMutexEnd;
++    pTo->xMutexFree = pFrom->xMutexFree;
++    pTo->xMutexEnter = pFrom->xMutexEnter;
++    pTo->xMutexTry = pFrom->xMutexTry;
++    pTo->xMutexLeave = pFrom->xMutexLeave;
++    pTo->xMutexHeld = pFrom->xMutexHeld;
++    pTo->xMutexNotheld = pFrom->xMutexNotheld;
++    sqlite3MemoryBarrier();
+     pTo->xMutexAlloc = pFrom->xMutexAlloc;
+   }
++  assert( sqlite3GlobalConfig.mutex.xMutexInit );
+   rc = sqlite3GlobalConfig.mutex.xMutexInit();
+ 
+ #ifdef SQLITE_DEBUG
+@@ -19184,11 +27308,12 @@
+ /*
+ ** Retrieve a pointer to a static mutex or allocate a new dynamic one.
+ */
+-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int id){
++SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
+ #ifndef SQLITE_OMIT_AUTOINIT
+   if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
+   if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
+ #endif
++  assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
+   return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
+ }
+ 
+@@ -19197,14 +27322,16 @@
+     return 0;
+   }
+   assert( GLOBAL(int, mutexIsInit) );
++  assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
+   return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
+ }
+ 
+ /*
+ ** Free a dynamic mutex.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex *p){
++SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
+   if( p ){
++    assert( sqlite3GlobalConfig.mutex.xMutexFree );
+     sqlite3GlobalConfig.mutex.xMutexFree(p);
+   }
+ }
+@@ -19213,8 +27340,9 @@
+ ** Obtain the mutex p. If some other thread already has the mutex, block
+ ** until it can be obtained.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex *p){
++SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
+   if( p ){
++    assert( sqlite3GlobalConfig.mutex.xMutexEnter );
+     sqlite3GlobalConfig.mutex.xMutexEnter(p);
+   }
+ }
+@@ -19223,9 +27351,10 @@
+ ** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
+ ** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex *p){
++SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
+   int rc = SQLITE_OK;
+   if( p ){
++    assert( sqlite3GlobalConfig.mutex.xMutexTry );
+     return sqlite3GlobalConfig.mutex.xMutexTry(p);
+   }
+   return rc;
+@@ -19237,8 +27366,9 @@
+ ** is not currently entered. If a NULL pointer is passed as an argument
+ ** this function is a no-op.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex *p){
++SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
+   if( p ){
++    assert( sqlite3GlobalConfig.mutex.xMutexLeave );
+     sqlite3GlobalConfig.mutex.xMutexLeave(p);
+   }
+ }
+@@ -19248,10 +27378,12 @@
+ ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
+ ** intended for use inside assert() statements.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex *p){
++SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
++  assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
+   return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex *p){
++SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
++  assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
+   return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
+ }
+ #endif
+@@ -19287,6 +27419,7 @@
+ ** that does error checking on mutexes to make sure they are being
+ ** called correctly.
+ */
++/* #include "sqliteInt.h" */
+ 
+ #ifndef SQLITE_MUTEX_OMIT
+ 
+@@ -19368,7 +27501,7 @@
+ ** that means that a mutex could not be allocated. 
+ */
+ static sqlite3_mutex *debugMutexAlloc(int id){
+-  static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_APP3 - 1];
++  static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_VFS3 - 1];
+   sqlite3_debug_mutex *pNew = 0;
+   switch( id ){
+     case SQLITE_MUTEX_FAST:
+@@ -19490,6 +27623,7 @@
+ *************************************************************************
+ ** This file contains the C functions that implement mutexes for pthreads
+ */
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** The code in this file is only used if we are compiling threadsafe
+@@ -19528,7 +27662,9 @@
+ #endif
+ };
+ #if SQLITE_MUTEX_NREF
+-#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 }
++#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0}
++#elif defined(SQLITE_ENABLE_API_ARMOR)
++#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 }
+ #else
+ #define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
+ #endif
+@@ -19559,6 +27695,19 @@
+ #endif
+ 
+ /*
++** Try to provide a memory barrier operation, needed for initialization
++** and also for the implementation of xShmBarrier in the VFS in cases
++** where SQLite is compiled without mutexes.
++*/
++SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
++#if defined(SQLITE_MEMORY_BARRIER)
++  SQLITE_MEMORY_BARRIER;
++#elif defined(__GNUC__) && GCC_VERSION>=4001000
++  __sync_synchronize();
++#endif
++}
++
++/*
+ ** Initialize and deinitialize the mutex subsystem.
+ */
+ static int pthreadMutexInit(void){ return SQLITE_OK; }
+@@ -19583,6 +27732,9 @@
+ ** <li>  SQLITE_MUTEX_STATIC_APP1
+ ** <li>  SQLITE_MUTEX_STATIC_APP2
+ ** <li>  SQLITE_MUTEX_STATIC_APP3
++** <li>  SQLITE_MUTEX_STATIC_VFS1
++** <li>  SQLITE_MUTEX_STATIC_VFS2
++** <li>  SQLITE_MUTEX_STATIC_VFS3
+ ** </ul>
+ **
+ ** The first two constants cause sqlite3_mutex_alloc() to create
+@@ -19619,6 +27771,9 @@
+     SQLITE3_MUTEX_INITIALIZER,
+     SQLITE3_MUTEX_INITIALIZER,
+     SQLITE3_MUTEX_INITIALIZER,
++    SQLITE3_MUTEX_INITIALIZER,
++    SQLITE3_MUTEX_INITIALIZER,
++    SQLITE3_MUTEX_INITIALIZER,
+     SQLITE3_MUTEX_INITIALIZER
+   };
+   sqlite3_mutex *p;
+@@ -19858,6 +28013,7 @@
+ *************************************************************************
+ ** This file contains the C functions that implement mutexes for Win32.
+ */
++/* #include "sqliteInt.h" */
+ 
+ #if SQLITE_OS_WIN
+ /*
+@@ -19902,8 +28058,8 @@
+ */
+ #ifdef SQLITE_PERFORMANCE_TRACE
+ 
+-/* 
+-** hwtime.h contains inline assembler code for implementing 
++/*
++** hwtime.h contains inline assembler code for implementing
+ ** high-performance timing routines.
+ */
+ /************** Include hwtime.h in the middle of os_common.h ****************/
+@@ -19923,8 +28079,8 @@
+ ** This file contains inline asm code for retrieving "high-performance"
+ ** counters for x86 class CPUs.
+ */
+-#ifndef _HWTIME_H_
+-#define _HWTIME_H_
++#ifndef SQLITE_HWTIME_H
++#define SQLITE_HWTIME_H
+ 
+ /*
+ ** The following routine only works on pentium-class (or newer) processors.
+@@ -19992,7 +28148,7 @@
+ 
+ #endif
+ 
+-#endif /* !defined(_HWTIME_H_) */
++#endif /* !defined(SQLITE_HWTIME_H) */
+ 
+ /************** End of hwtime.h **********************************************/
+ /************** Continuing where we left off in os_common.h ******************/
+@@ -20013,14 +28169,14 @@
+ ** 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;
++#if defined(SQLITE_TEST)
++SQLITE_API extern int sqlite3_io_error_hit;
++SQLITE_API extern int sqlite3_io_error_hardhit;
++SQLITE_API extern int sqlite3_io_error_pending;
++SQLITE_API extern int sqlite3_io_error_persist;
++SQLITE_API extern int sqlite3_io_error_benign;
++SQLITE_API extern int sqlite3_diskfull_pending;
++SQLITE_API extern int sqlite3_diskfull;
+ #define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
+ #define SimulateIOError(CODE)  \
+   if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
+@@ -20046,17 +28202,17 @@
+ #define SimulateIOErrorBenign(X)
+ #define SimulateIOError(A)
+ #define SimulateDiskfullError(A)
+-#endif
++#endif /* defined(SQLITE_TEST) */
+ 
+ /*
+ ** When testing, keep a count of the number of open files.
+ */
+-#ifdef SQLITE_TEST
+-SQLITE_API int sqlite3_open_file_count = 0;
++#if defined(SQLITE_TEST)
++SQLITE_API extern int sqlite3_open_file_count;
+ #define OpenCounter(X)  sqlite3_open_file_count+=(X)
+ #else
+ #define OpenCounter(X)
+-#endif
++#endif /* defined(SQLITE_TEST) */
+ 
+ #endif /* !defined(_OS_COMMON_H_) */
+ 
+@@ -20082,17 +28238,17 @@
+ **
+ ** This file contains code that is specific to Windows.
+ */
+-#ifndef _OS_WIN_H_
+-#define _OS_WIN_H_
++#ifndef SQLITE_OS_WIN_H
++#define SQLITE_OS_WIN_H
+ 
+ /*
+ ** Include the primary Windows SDK header file.
+ */
+-#include "windows.h"
++/* #include "windows.h" */
+ 
+ #ifdef __CYGWIN__
+ # include <sys/cygwin.h>
+-# include <errno.h> /* amalgamator: dontcache */
++/* # include <errno.h> ** amalgamator: dontcache ** */
+ #endif
+ 
+ /*
+@@ -20155,7 +28311,7 @@
+ # define SQLITE_OS_WIN_THREADS 0
+ #endif
+ 
+-#endif /* _OS_WIN_H_ */
++#endif /* SQLITE_OS_WIN_H */
+ 
+ /************** End of os_win.h **********************************************/
+ /************** Continuing where we left off in mutex_w32.c ******************/
+@@ -20214,6 +28370,23 @@
+ #endif
+ 
+ /*
++** Try to provide a memory barrier operation, needed for initialization
++** and also for the xShmBarrier method of the VFS in cases when SQLite is
++** compiled without mutexes (SQLITE_THREADSAFE=0).
++*/
++SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
++#if defined(SQLITE_MEMORY_BARRIER)
++  SQLITE_MEMORY_BARRIER;
++#elif defined(__GNUC__)
++  __sync_synchronize();
++#elif MSVC_VERSION>=1300
++  _ReadWriteBarrier();
++#elif defined(MemoryBarrier)
++  MemoryBarrier();
++#endif
++}
++
++/*
+ ** Initialize and deinitialize the mutex subsystem.
+ */
+ static sqlite3_mutex winMutex_staticMutexes[] = {
+@@ -20225,6 +28398,9 @@
+   SQLITE3_MUTEX_INITIALIZER,
+   SQLITE3_MUTEX_INITIALIZER,
+   SQLITE3_MUTEX_INITIALIZER,
++  SQLITE3_MUTEX_INITIALIZER,
++  SQLITE3_MUTEX_INITIALIZER,
++  SQLITE3_MUTEX_INITIALIZER,
+   SQLITE3_MUTEX_INITIALIZER
+ };
+ 
+@@ -20237,8 +28413,8 @@
+ */
+ static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0;
+ 
+-SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void); /* os_win.c */
+-SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
++SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */
++SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
+ 
+ static int winMutexInit(void){
+   /* The first to increment to 1 does actual initialization */
+@@ -20296,6 +28472,9 @@
+ ** <li>  SQLITE_MUTEX_STATIC_APP1
+ ** <li>  SQLITE_MUTEX_STATIC_APP2
+ ** <li>  SQLITE_MUTEX_STATIC_APP3
++** <li>  SQLITE_MUTEX_STATIC_VFS1
++** <li>  SQLITE_MUTEX_STATIC_VFS2
++** <li>  SQLITE_MUTEX_STATIC_VFS3
+ ** </ul>
+ **
+ ** The first two constants cause sqlite3_mutex_alloc() to create
+@@ -20411,8 +28590,8 @@
+   p->owner = tid;
+   p->nRef++;
+   if( p->trace ){
+-    OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
+-             tid, p, p->trace, p->nRef));
++    OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
++             tid, p->id, p, p->trace, p->nRef));
+   }
+ #endif
+ }
+@@ -20454,8 +28633,8 @@
+ #endif
+ #ifdef SQLITE_DEBUG
+   if( p->trace ){
+-    OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
+-             tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
++    OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
++             tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
+   }
+ #endif
+   return rc;
+@@ -20483,8 +28662,8 @@
+   LeaveCriticalSection(&p->mutex);
+ #ifdef SQLITE_DEBUG
+   if( p->trace ){
+-    OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
+-             tid, p, p->trace, p->nRef));
++    OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
++             tid, p->id, p, p->trace, p->nRef));
+   }
+ #endif
+ }
+@@ -20527,6 +28706,7 @@
+ **
+ ** Memory allocation functions used throughout sqlite.
+ */
++/* #include "sqliteInt.h" */
+ /* #include <stdarg.h> */
+ 
+ /*
+@@ -20534,7 +28714,7 @@
+ ** held by SQLite. An example of non-essential memory is memory used to
+ ** cache database pages that are not currently in use.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int n){
++SQLITE_API int sqlite3_release_memory(int n){
+ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+   return sqlite3PcacheReleaseMemory(n);
+ #else
+@@ -20559,16 +28739,7 @@
+ */
+ static SQLITE_WSD struct Mem0Global {
+   sqlite3_mutex *mutex;         /* Mutex to serialize access */
+-
+-  /*
+-  ** The alarm callback and its arguments.  The mem0.mutex lock will
+-  ** be held while the callback is running.  Recursive calls into
+-  ** the memory subsystem are allowed, but no new callbacks will be
+-  ** issued.
+-  */
+-  sqlite3_int64 alarmThreshold;
+-  void (*alarmCallback)(void*, sqlite3_int64,int);
+-  void *alarmArg;
++  sqlite3_int64 alarmThreshold; /* The soft heap limit */
+ 
+   /*
+   ** Pointers to the end of sqlite3GlobalConfig.pScratch memory
+@@ -20585,7 +28756,7 @@
+   ** sqlite3_soft_heap_limit() setting.
+   */
+   int nearlyFull;
+-} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
++} mem0 = { 0, 0, 0, 0, 0, 0 };
+ 
+ #define mem0 GLOBAL(struct Mem0Global, mem0)
+ 
+@@ -20596,50 +28767,21 @@
+   return mem0.mutex;
+ }
+ 
+-/*
+-** This routine runs when the memory allocator sees that the
+-** total memory allocation is about to exceed the soft heap
+-** limit.
+-*/
+-static void softHeapLimitEnforcer(
+-  void *NotUsed, 
+-  sqlite3_int64 NotUsed2,
+-  int allocSize
+-){
+-  UNUSED_PARAMETER2(NotUsed, NotUsed2);
+-  sqlite3_release_memory(allocSize);
+-}
+-
+-/*
+-** Change the alarm callback
+-*/
+-static int sqlite3MemoryAlarm(
+-  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
+-  void *pArg,
+-  sqlite3_int64 iThreshold
+-){
+-  sqlite3_int64 nUsed;
+-  sqlite3_mutex_enter(mem0.mutex);
+-  mem0.alarmCallback = xCallback;
+-  mem0.alarmArg = pArg;
+-  mem0.alarmThreshold = iThreshold;
+-  nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
+-  mem0.nearlyFull = (iThreshold>0 && iThreshold<=nUsed);
+-  sqlite3_mutex_leave(mem0.mutex);
+-  return SQLITE_OK;
+-}
+-
+ #ifndef SQLITE_OMIT_DEPRECATED
+ /*
+-** Deprecated external interface.  Internal/core SQLite code
+-** should call sqlite3MemoryAlarm.
++** Deprecated external interface.  It used to set an alarm callback
++** that was invoked when memory usage grew too large.  Now it is a
++** no-op.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_memory_alarm(
++SQLITE_API int sqlite3_memory_alarm(
+   void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
+   void *pArg,
+   sqlite3_int64 iThreshold
+ ){
+-  return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
++  (void)xCallback;
++  (void)pArg;
++  (void)iThreshold;
++  return SQLITE_OK;
+ }
+ #endif
+ 
+@@ -20647,27 +28789,29 @@
+ ** Set the soft heap-size limit for the library. Passing a zero or 
+ ** negative value indicates no limit.
+ */
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 n){
++SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
+   sqlite3_int64 priorLimit;
+   sqlite3_int64 excess;
++  sqlite3_int64 nUsed;
+ #ifndef SQLITE_OMIT_AUTOINIT
+   int rc = sqlite3_initialize();
+   if( rc ) return -1;
+ #endif
+   sqlite3_mutex_enter(mem0.mutex);
+   priorLimit = mem0.alarmThreshold;
+-  sqlite3_mutex_leave(mem0.mutex);
+-  if( n<0 ) return priorLimit;
+-  if( n>0 ){
+-    sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n);
+-  }else{
+-    sqlite3MemoryAlarm(0, 0, 0);
++  if( n<0 ){
++    sqlite3_mutex_leave(mem0.mutex);
++    return priorLimit;
+   }
++  mem0.alarmThreshold = n;
++  nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
++  mem0.nearlyFull = (n>0 && n<=nUsed);
++  sqlite3_mutex_leave(mem0.mutex);
+   excess = sqlite3_memory_used() - n;
+   if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
+   return priorLimit;
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_soft_heap_limit(int n){
++SQLITE_API void sqlite3_soft_heap_limit(int n){
+   if( n<0 ) n = 0;
+   sqlite3_soft_heap_limit64(n);
+ }
+@@ -20681,9 +28825,7 @@
+     sqlite3MemSetDefault();
+   }
+   memset(&mem0, 0, sizeof(mem0));
+-  if( sqlite3GlobalConfig.bCoreMutex ){
+-    mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
+-  }
++  mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
+   if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
+       && sqlite3GlobalConfig.nScratch>0 ){
+     int i, n, sz;
+@@ -20707,10 +28849,9 @@
+     sqlite3GlobalConfig.nScratch = 0;
+   }
+   if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
+-      || sqlite3GlobalConfig.nPage<1 ){
++      || sqlite3GlobalConfig.nPage<=0 ){
+     sqlite3GlobalConfig.pPage = 0;
+     sqlite3GlobalConfig.szPage = 0;
+-    sqlite3GlobalConfig.nPage = 0;
+   }
+   rc = sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
+   if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0));
+@@ -20739,11 +28880,9 @@
+ /*
+ ** Return the amount of memory currently checked out.
+ */
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){
+-  int n, mx;
+-  sqlite3_int64 res;
+-  sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
+-  res = (sqlite3_int64)n;  /* Work around bug in Borland C. Ticket #3216 */
++SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
++  sqlite3_int64 res, mx;
++  sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, 0);
+   return res;
+ }
+ 
+@@ -20752,44 +28891,48 @@
+ ** checked out since either the beginning of this process
+ ** or since the most recent reset.
+ */
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag){
+-  int n, mx;
+-  sqlite3_int64 res;
+-  sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
+-  res = (sqlite3_int64)mx;  /* Work around bug in Borland C. Ticket #3216 */
+-  return res;
++SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
++  sqlite3_int64 res, mx;
++  sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag);
++  return mx;
+ }
+ 
+ /*
+ ** Trigger the alarm 
+ */
+ static void sqlite3MallocAlarm(int nByte){
+-  void (*xCallback)(void*,sqlite3_int64,int);
+-  sqlite3_int64 nowUsed;
+-  void *pArg;
+-  if( mem0.alarmCallback==0 ) return;
+-  xCallback = mem0.alarmCallback;
+-  nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
+-  pArg = mem0.alarmArg;
+-  mem0.alarmCallback = 0;
++  if( mem0.alarmThreshold<=0 ) return;
+   sqlite3_mutex_leave(mem0.mutex);
+-  xCallback(pArg, nowUsed, nByte);
++  sqlite3_release_memory(nByte);
+   sqlite3_mutex_enter(mem0.mutex);
+-  mem0.alarmCallback = xCallback;
+-  mem0.alarmArg = pArg;
+ }
+ 
+ /*
+ ** Do a memory allocation with statistics and alarms.  Assume the
+ ** lock is already held.
+ */
+-static int mallocWithAlarm(int n, void **pp){
+-  int nFull;
++static void mallocWithAlarm(int n, void **pp){
+   void *p;
++  int nFull;
+   assert( sqlite3_mutex_held(mem0.mutex) );
++  assert( n>0 );
++
++  /* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal
++  ** implementation of malloc_good_size(), which must be called in debug
++  ** mode and specifically when the DMD "Dark Matter Detector" is enabled
++  ** or else a crash results.  Hence, do not attempt to optimize out the
++  ** following xRoundup() call. */
+   nFull = sqlite3GlobalConfig.m.xRoundup(n);
+-  sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
+-  if( mem0.alarmCallback!=0 ){
++
++#ifdef SQLITE_MAX_MEMORY
++  if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nFull>SQLITE_MAX_MEMORY ){
++    *pp = 0;
++    return;
++  }
++#endif
++
++  sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
++  if( mem0.alarmThreshold>0 ){
+     sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
+     if( nUsed >= mem0.alarmThreshold - nFull ){
+       mem0.nearlyFull = 1;
+@@ -20800,7 +28943,7 @@
+   }
+   p = sqlite3GlobalConfig.m.xMalloc(nFull);
+ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+-  if( p==0 && mem0.alarmCallback ){
++  if( p==0 && mem0.alarmThreshold>0 ){
+     sqlite3MallocAlarm(nFull);
+     p = sqlite3GlobalConfig.m.xMalloc(nFull);
+   }
+@@ -20811,7 +28954,6 @@
+     sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1);
+   }
+   *pp = p;
+-  return nFull;
+ }
+ 
+ /*
+@@ -20843,13 +28985,13 @@
+ ** First make sure the memory subsystem is initialized, then do the
+ ** allocation.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int n){
++SQLITE_API void *sqlite3_malloc(int n){
+ #ifndef SQLITE_OMIT_AUTOINIT
+   if( sqlite3_initialize() ) return 0;
+ #endif
+   return n<=0 ? 0 : sqlite3Malloc(n);
+ }
+-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64 n){
++SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){
+ #ifndef SQLITE_OMIT_AUTOINIT
+   if( sqlite3_initialize() ) return 0;
+ #endif
+@@ -20880,7 +29022,7 @@
+   assert( n>0 );
+ 
+   sqlite3_mutex_enter(mem0.mutex);
+-  sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
++  sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n);
+   if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){
+     p = mem0.pScratchFree;
+     mem0.pScratchFree = mem0.pScratchFree->pNext;
+@@ -20924,7 +29066,7 @@
+     scratchAllocOut--;
+ #endif
+ 
+-    if( p>=sqlite3GlobalConfig.pScratch && p<mem0.pScratchEnd ){
++    if( SQLITE_WITHIN(p, sqlite3GlobalConfig.pScratch, mem0.pScratchEnd) ){
+       /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */
+       ScratchFreeslot *pSlot;
+       pSlot = (ScratchFreeslot*)p;
+@@ -20960,7 +29102,7 @@
+ */
+ #ifndef SQLITE_OMIT_LOOKASIDE
+ static int isLookaside(sqlite3 *db, void *p){
+-  return p>=db->lookaside.pStart && p<db->lookaside.pEnd;
++  return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd);
+ }
+ #else
+ #define isLookaside(A,B) 0
+@@ -20975,31 +29117,33 @@
+   return sqlite3GlobalConfig.m.xSize(p);
+ }
+ SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
+-  if( db==0 ){
+-    assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
+-    assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
+-    return sqlite3MallocSize(p);
+-  }else{
+-    assert( sqlite3_mutex_held(db->mutex) );
+-    if( isLookaside(db, p) ){
+-      return db->lookaside.sz;
++  assert( p!=0 );
++  if( db==0 || !isLookaside(db,p) ){
++#ifdef SQLITE_DEBUG
++    if( db==0 ){
++      assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
++      assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
+     }else{
+       assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+       assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+-      return sqlite3GlobalConfig.m.xSize(p);
+     }
++#endif
++    return sqlite3GlobalConfig.m.xSize(p);
++  }else{
++    assert( sqlite3_mutex_held(db->mutex) );
++    return db->lookaside.sz;
+   }
+ }
+-SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void *p){
++SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
+   assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
+   assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
+-  return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
++  return p ? sqlite3GlobalConfig.m.xSize(p) : 0;
+ }
+ 
+ /*
+ ** Free memory previously obtained from sqlite3Malloc().
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_free(void *p){
++SQLITE_API void sqlite3_free(void *p){
+   if( p==0 ) return;  /* IMP: R-49053-54554 */
+   assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
+   assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
+@@ -21024,11 +29168,12 @@
+ 
+ /*
+ ** Free memory that might be associated with a particular database
+-** connection.
++** connection.  Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op.
++** The sqlite3DbFreeNN(D,X) version requires that X be non-NULL.
+ */
+-SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
++SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){
+   assert( db==0 || sqlite3_mutex_held(db->mutex) );
+-  if( p==0 ) return;
++  assert( p!=0 );
+   if( db ){
+     if( db->pnBytesFreed ){
+       measureAllocationSize(db, p);
+@@ -21036,7 +29181,7 @@
+     }
+     if( isLookaside(db, p) ){
+       LookasideSlot *pBuf = (LookasideSlot*)p;
+-#if SQLITE_DEBUG
++#ifdef SQLITE_DEBUG
+       /* Trash all content in the buffer being freed */
+       memset(p, 0xaa, db->lookaside.sz);
+ #endif
+@@ -21052,6 +29197,10 @@
+   sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
+   sqlite3_free(p);
+ }
++SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
++  assert( db==0 || sqlite3_mutex_held(db->mutex) );
++  if( p ) sqlite3DbFreeNN(db, p);
++}
+ 
+ /*
+ ** Change the size of an existing memory allocation
+@@ -21081,14 +29230,14 @@
+     pNew = pOld;
+   }else if( sqlite3GlobalConfig.bMemstat ){
+     sqlite3_mutex_enter(mem0.mutex);
+-    sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
++    sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
+     nDiff = nNew - nOld;
+-    if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= 
++    if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= 
+           mem0.alarmThreshold-nDiff ){
+       sqlite3MallocAlarm(nDiff);
+     }
+     pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
+-    if( pNew==0 && mem0.alarmCallback ){
++    if( pNew==0 && mem0.alarmThreshold>0 ){
+       sqlite3MallocAlarm((int)nBytes);
+       pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
+     }
+@@ -21108,14 +29257,14 @@
+ ** The public interface to sqlite3Realloc.  Make sure that the memory
+ ** subsystem is initialized prior to invoking sqliteRealloc.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void *pOld, int n){
++SQLITE_API void *sqlite3_realloc(void *pOld, int n){
+ #ifndef SQLITE_OMIT_AUTOINIT
+   if( sqlite3_initialize() ) return 0;
+ #endif
+   if( n<0 ) n = 0;  /* IMP: R-26507-47431 */
+   return sqlite3Realloc(pOld, n);
+ }
+-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
++SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
+ #ifndef SQLITE_OMIT_AUTOINIT
+   if( sqlite3_initialize() ) return 0;
+ #endif
+@@ -21139,16 +29288,31 @@
+ ** the mallocFailed flag in the connection pointer.
+ */
+ SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, u64 n){
+-  void *p = sqlite3DbMallocRaw(db, n);
+-  if( p ){
+-    memset(p, 0, (size_t)n);
+-  }
++  void *p;
++  testcase( db==0 );
++  p = sqlite3DbMallocRaw(db, n);
++  if( p ) memset(p, 0, (size_t)n);
++  return p;
++}
++
++
++/* Finish the work of sqlite3DbMallocRawNN for the unusual and
++** slower case when the allocation cannot be fulfilled using lookaside.
++*/
++static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){
++  void *p;
++  assert( db!=0 );
++  p = sqlite3Malloc(n);
++  if( !p ) sqlite3OomFault(db);
++  sqlite3MemdebugSetType(p, 
++         (db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
+   return p;
+ }
+ 
+ /*
+-** Allocate and zero memory.  If the allocation fails, make
+-** the mallocFailed flag in the connection pointer.
++** Allocate memory, either lookaside (if possible) or heap.  
++** If the allocation fails, set the mallocFailed flag in
++** the connection pointer.
+ **
+ ** If db!=0 and db->mallocFailed is true (indicating a prior malloc
+ ** failure on the same database connection) then always return 0.
+@@ -21163,64 +29327,73 @@
+ **
+ ** In other words, if a subsequent malloc (ex: "b") worked, it is assumed
+ ** that all prior mallocs (ex: "a") worked too.
++**
++** The sqlite3MallocRawNN() variant guarantees that the "db" parameter is
++** not a NULL pointer.
+ */
+ SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){
+   void *p;
+-  assert( db==0 || sqlite3_mutex_held(db->mutex) );
+-  assert( db==0 || db->pnBytesFreed==0 );
++  if( db ) return sqlite3DbMallocRawNN(db, n);
++  p = sqlite3Malloc(n);
++  sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
++  return p;
++}
++SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){
+ #ifndef SQLITE_OMIT_LOOKASIDE
+-  if( db ){
+-    LookasideSlot *pBuf;
+-    if( db->mallocFailed ){
+-      return 0;
+-    }
+-    if( db->lookaside.bEnabled ){
+-      if( n>db->lookaside.sz ){
+-        db->lookaside.anStat[1]++;
+-      }else if( (pBuf = db->lookaside.pFree)==0 ){
+-        db->lookaside.anStat[2]++;
+-      }else{
+-        db->lookaside.pFree = pBuf->pNext;
+-        db->lookaside.nOut++;
+-        db->lookaside.anStat[0]++;
+-        if( db->lookaside.nOut>db->lookaside.mxOut ){
+-          db->lookaside.mxOut = db->lookaside.nOut;
+-        }
+-        return (void*)pBuf;
++  LookasideSlot *pBuf;
++  assert( db!=0 );
++  assert( sqlite3_mutex_held(db->mutex) );
++  assert( db->pnBytesFreed==0 );
++  if( db->lookaside.bDisable==0 ){
++    assert( db->mallocFailed==0 );
++    if( n>db->lookaside.sz ){
++      db->lookaside.anStat[1]++;
++    }else if( (pBuf = db->lookaside.pFree)==0 ){
++      db->lookaside.anStat[2]++;
++    }else{
++      db->lookaside.pFree = pBuf->pNext;
++      db->lookaside.nOut++;
++      db->lookaside.anStat[0]++;
++      if( db->lookaside.nOut>db->lookaside.mxOut ){
++        db->lookaside.mxOut = db->lookaside.nOut;
+       }
++      return (void*)pBuf;
+     }
++  }else if( db->mallocFailed ){
++    return 0;
+   }
+ #else
+-  if( db && db->mallocFailed ){
++  assert( db!=0 );
++  assert( sqlite3_mutex_held(db->mutex) );
++  assert( db->pnBytesFreed==0 );
++  if( db->mallocFailed ){
+     return 0;
+   }
+ #endif
+-  p = sqlite3Malloc(n);
+-  if( !p && db ){
+-    db->mallocFailed = 1;
+-  }
+-  sqlite3MemdebugSetType(p, 
+-         (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
+-  return p;
++  return dbMallocRawFinish(db, n);
+ }
+ 
++/* Forward declaration */
++static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n);
++
+ /*
+ ** Resize the block of memory pointed to by p to n bytes. If the
+ ** resize fails, set the mallocFailed flag in the connection object.
+ */
+ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){
+-  void *pNew = 0;
+   assert( db!=0 );
++  if( p==0 ) return sqlite3DbMallocRawNN(db, n);
+   assert( sqlite3_mutex_held(db->mutex) );
++  if( isLookaside(db,p) && n<=db->lookaside.sz ) return p;
++  return dbReallocFinish(db, p, n);
++}
++static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){
++  void *pNew = 0;
++  assert( db!=0 );
++  assert( p!=0 );
+   if( db->mallocFailed==0 ){
+-    if( p==0 ){
+-      return sqlite3DbMallocRaw(db, n);
+-    }
+     if( isLookaside(db, p) ){
+-      if( n<=db->lookaside.sz ){
+-        return p;
+-      }
+-      pNew = sqlite3DbMallocRaw(db, n);
++      pNew = sqlite3DbMallocRawNN(db, n);
+       if( pNew ){
+         memcpy(pNew, p, db->lookaside.sz);
+         sqlite3DbFree(db, p);
+@@ -21231,10 +29404,10 @@
+       sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
+       pNew = sqlite3_realloc64(p, n);
+       if( !pNew ){
+-        db->mallocFailed = 1;
++        sqlite3OomFault(db);
+       }
+       sqlite3MemdebugSetType(pNew,
+-            (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
++            (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
+     }
+   }
+   return pNew;
+@@ -21266,9 +29439,8 @@
+   if( z==0 ){
+     return 0;
+   }
+-  n = sqlite3Strlen30(z) + 1;
+-  assert( (n&0x7fffffff)==n );
+-  zNew = sqlite3DbMallocRaw(db, (int)n);
++  n = strlen(z) + 1;
++  zNew = sqlite3DbMallocRaw(db, n);
+   if( zNew ){
+     memcpy(zNew, z, n);
+   }
+@@ -21276,11 +29448,12 @@
+ }
+ SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){
+   char *zNew;
++  assert( db!=0 );
+   if( z==0 ){
+     return 0;
+   }
+   assert( (n&0x7fffffff)==n );
+-  zNew = sqlite3DbMallocRaw(db, n+1);
++  zNew = sqlite3DbMallocRawNN(db, n+1);
+   if( zNew ){
+     memcpy(zNew, z, (size_t)n);
+     zNew[n] = 0;
+@@ -21289,28 +29462,52 @@
+ }
+ 
+ /*
+-** Create a string from the zFromat argument and the va_list that follows.
+-** Store the string in memory obtained from sqliteMalloc() and make *pz
+-** point to that string.
++** Free any prior content in *pz and replace it with a copy of zNew.
+ */
+-SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){
+-  va_list ap;
+-  char *z;
+-
+-  va_start(ap, zFormat);
+-  z = sqlite3VMPrintf(db, zFormat, ap);
+-  va_end(ap);
++SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
+   sqlite3DbFree(db, *pz);
+-  *pz = z;
++  *pz = sqlite3DbStrDup(db, zNew);
++}
++
++/*
++** Call this routine to record the fact that an OOM (out-of-memory) error
++** has happened.  This routine will set db->mallocFailed, and also
++** temporarily disable the lookaside memory allocator and interrupt
++** any running VDBEs.
++*/
++SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){
++  if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
++    db->mallocFailed = 1;
++    if( db->nVdbeExec>0 ){
++      db->u1.isInterrupted = 1;
++    }
++    db->lookaside.bDisable++;
++  }
++}
++
++/*
++** This routine reactivates the memory allocator and clears the
++** db->mallocFailed flag as necessary.
++**
++** The memory allocator is not restarted if there are running
++** VDBEs.
++*/
++SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){
++  if( db->mallocFailed && db->nVdbeExec==0 ){
++    db->mallocFailed = 0;
++    db->u1.isInterrupted = 0;
++    assert( db->lookaside.bDisable>0 );
++    db->lookaside.bDisable--;
++  }
+ }
+ 
+ /*
+ ** Take actions at the end of an API call to indicate an OOM error
+ */
+ static SQLITE_NOINLINE int apiOomError(sqlite3 *db){
+-  db->mallocFailed = 0;
++  sqlite3OomClear(db);
+   sqlite3Error(db, SQLITE_NOMEM);
+-  return SQLITE_NOMEM;
++  return SQLITE_NOMEM_BKPT;
+ }
+ 
+ /*
+@@ -21322,17 +29519,16 @@
+ ** function. However, if a malloc() failure has occurred since the previous
+ ** invocation SQLITE_NOMEM is returned instead. 
+ **
+-** If the first argument, db, is not NULL and a malloc() error has occurred,
+-** then the connection error-code (the value returned by sqlite3_errcode())
+-** is set to SQLITE_NOMEM.
++** If an OOM as occurred, then the connection error-code (the value
++** returned by sqlite3_errcode()) is set to SQLITE_NOMEM.
+ */
+ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
+-  /* If the db handle is not NULL, then we must hold the connection handle
+-  ** mutex here. Otherwise the read (and possible write) of db->mallocFailed 
++  /* If the db handle must hold the connection handle mutex here.
++  ** Otherwise the read (and possible write) of db->mallocFailed 
+   ** is unsafe, as is the call to sqlite3Error().
+   */
+-  assert( !db || sqlite3_mutex_held(db->mutex) );
+-  if( db==0 ) return rc & 0xff;
++  assert( db!=0 );
++  assert( sqlite3_mutex_held(db->mutex) );
+   if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){
+     return apiOomError(db);
+   }
+@@ -21343,43 +29539,42 @@
+ /************** Begin file printf.c ******************************************/
+ /*
+ ** The "printf" code that follows dates from the 1980's.  It is in
+-** the public domain.  The original comments are included here for
+-** completeness.  They are very out-of-date but might be useful as
+-** an historical reference.  Most of the "enhancements" have been backed
+-** out so that the functionality is now the same as standard printf().
++** the public domain. 
+ **
+ **************************************************************************
+ **
+ ** This file contains code for a set of "printf"-like routines.  These
+ ** routines format strings much like the printf() from the standard C
+ ** library, though the implementation here has enhancements to support
+-** SQLlite.
++** SQLite.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** Conversion types fall into various categories as defined by the
+ ** following enumeration.
+ */
+-#define etRADIX       1 /* Integer types.  %d, %x, %o, and so forth */
+-#define etFLOAT       2 /* Floating point.  %f */
+-#define etEXP         3 /* Exponentional notation. %e and %E */
+-#define etGENERIC     4 /* Floating or exponential, depending on exponent. %g */
+-#define etSIZE        5 /* Return number of characters processed so far. %n */
+-#define etSTRING      6 /* Strings. %s */
+-#define etDYNSTRING   7 /* Dynamically allocated strings. %z */
+-#define etPERCENT     8 /* Percent symbol. %% */
+-#define etCHARX       9 /* Characters. %c */
++#define etRADIX       0 /* non-decimal integer types.  %x %o */
++#define etFLOAT       1 /* Floating point.  %f */
++#define etEXP         2 /* Exponentional notation. %e and %E */
++#define etGENERIC     3 /* Floating or exponential, depending on exponent. %g */
++#define etSIZE        4 /* Return number of characters processed so far. %n */
++#define etSTRING      5 /* Strings. %s */
++#define etDYNSTRING   6 /* Dynamically allocated strings. %z */
++#define etPERCENT     7 /* Percent symbol. %% */
++#define etCHARX       8 /* Characters. %c */
+ /* The rest are extensions, not normally found in printf() */
+-#define etSQLESCAPE  10 /* Strings with '\'' doubled.  %q */
+-#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '',
++#define etSQLESCAPE   9 /* Strings with '\'' doubled.  %q */
++#define etSQLESCAPE2 10 /* Strings with '\'' doubled and enclosed in '',
+                           NULL pointers replaced by SQL NULL.  %Q */
+-#define etTOKEN      12 /* a pointer to a Token structure */
+-#define etSRCLIST    13 /* a pointer to a SrcList */
+-#define etPOINTER    14 /* The %p conversion */
+-#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */
+-#define etORDINAL    16 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */
++#define etTOKEN      11 /* a pointer to a Token structure */
++#define etSRCLIST    12 /* a pointer to a SrcList */
++#define etPOINTER    13 /* The %p conversion */
++#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */
++#define etORDINAL    15 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */
++#define etDECIMAL    16 /* %d or %u, but not %x, %o */
+ 
+-#define etINVALID     0 /* Any unrecognized conversion type */
++#define etINVALID    17 /* Any unrecognized conversion type */
+ 
+ 
+ /*
+@@ -21403,9 +29598,8 @@
+ /*
+ ** Allowed values for et_info.flags
+ */
+-#define FLAG_SIGNED  1     /* True if the value to convert is signed */
+-#define FLAG_INTERN  2     /* True if for internal use only */
+-#define FLAG_STRING  4     /* Allow infinity precision */
++#define FLAG_SIGNED    1     /* True if the value to convert is signed */
++#define FLAG_STRING    4     /* Allow infinite precision */
+ 
+ 
+ /*
+@@ -21415,7 +29609,7 @@
+ static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
+ static const char aPrefix[] = "-x0\000X0";
+ static const et_info fmtinfo[] = {
+-  {  'd', 10, 1, etRADIX,      0,  0 },
++  {  'd', 10, 1, etDECIMAL,    0,  0 },
+   {  's',  0, 4, etSTRING,     0,  0 },
+   {  'g',  0, 1, etGENERIC,    30, 0 },
+   {  'z',  0, 4, etDYNSTRING,  0,  0 },
+@@ -21424,7 +29618,7 @@
+   {  'w',  0, 4, etSQLESCAPE3, 0,  0 },
+   {  'c',  0, 0, etCHARX,      0,  0 },
+   {  'o',  8, 0, etRADIX,      0,  2 },
+-  {  'u', 10, 0, etRADIX,      0,  0 },
++  {  'u', 10, 0, etDECIMAL,    0,  0 },
+   {  'x', 16, 0, etRADIX,      16, 1 },
+   {  'X', 16, 0, etRADIX,      0,  4 },
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+@@ -21433,16 +29627,15 @@
+   {  'E',  0, 1, etEXP,        14, 0 },
+   {  'G',  0, 1, etGENERIC,    14, 0 },
+ #endif
+-  {  'i', 10, 1, etRADIX,      0,  0 },
++  {  'i', 10, 1, etDECIMAL,    0,  0 },
+   {  'n',  0, 0, etSIZE,       0,  0 },
+   {  '%',  0, 0, etPERCENT,    0,  0 },
+   {  'p', 16, 0, etPOINTER,    0,  1 },
+ 
+-/* All the rest have the FLAG_INTERN bit set and are thus for internal
+-** use only */
+-  {  'T',  0, 2, etTOKEN,      0,  0 },
+-  {  'S',  0, 2, etSRCLIST,    0,  0 },
+-  {  'r', 10, 3, etORDINAL,    0,  0 },
++  /* All the rest are undocumented and are for internal use only */
++  {  'T',  0, 0, etTOKEN,      0,  0 },
++  {  'S',  0, 0, etSRCLIST,    0,  0 },
++  {  'r', 10, 1, etORDINAL,    0,  0 },
+ };
+ 
+ /*
+@@ -21516,7 +29709,6 @@
+ */
+ SQLITE_PRIVATE void sqlite3VXPrintf(
+   StrAccum *pAccum,          /* Accumulate results here */
+-  u32 bFlags,                /* SQLITE_PRINTF_* flags */
+   const char *fmt,           /* Format string */
+   va_list ap                 /* arguments */
+ ){
+@@ -21527,17 +29719,15 @@
+   int idx;                   /* A general purpose loop counter */
+   int width;                 /* Width of the current field */
+   etByte flag_leftjustify;   /* True if "-" flag is present */
+-  etByte flag_plussign;      /* True if "+" flag is present */
+-  etByte flag_blanksign;     /* True if " " flag is present */
++  etByte flag_prefix;        /* '+' or ' ' or 0 for prefix */
+   etByte flag_alternateform; /* True if "#" flag is present */
+   etByte flag_altform2;      /* True if "!" flag is present */
+   etByte flag_zeropad;       /* True if field width constant starts with zero */
+-  etByte flag_long;          /* True if "l" flag is present */
+-  etByte flag_longlong;      /* True if the "ll" flag is present */
++  etByte flag_long;          /* 1 for the "l" flag, 2 for "ll", 0 by default */
+   etByte done;               /* Loop termination flag */
+-  etByte xtype = 0;          /* Conversion paradigm */
++  etByte cThousand;          /* Thousands separator for %d and %u */
++  etByte xtype = etINVALID;  /* Conversion paradigm */
+   u8 bArgList;               /* True for SQLITE_PRINTF_SQLFUNC */
+-  u8 useIntern;              /* Ok to use internal conversions (ex: %T) */
+   char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
+   sqlite_uint64 longvalue;   /* Value for integer types */
+   LONGDOUBLE_TYPE realvalue; /* Value for real types */
+@@ -21556,13 +29746,11 @@
+   char buf[etBUFSIZE];       /* Conversion buffer */
+ 
+   bufpt = 0;
+-  if( bFlags ){
+-    if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
+-      pArgList = va_arg(ap, PrintfArguments*);
+-    }
+-    useIntern = bFlags & SQLITE_PRINTF_INTERNAL;
++  if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){
++    pArgList = va_arg(ap, PrintfArguments*);
++    bArgList = 1;
+   }else{
+-    bArgList = useIntern = 0;
++    bArgList = 0;
+   }
+   for(; (c=(*fmt))!=0; ++fmt){
+     if( c!='%' ){
+@@ -21580,17 +29768,18 @@
+       break;
+     }
+     /* Find out what flags are present */
+-    flag_leftjustify = flag_plussign = flag_blanksign = 
++    flag_leftjustify = flag_prefix = cThousand =
+      flag_alternateform = flag_altform2 = flag_zeropad = 0;
+     done = 0;
+     do{
+       switch( c ){
+         case '-':   flag_leftjustify = 1;     break;
+-        case '+':   flag_plussign = 1;        break;
+-        case ' ':   flag_blanksign = 1;       break;
++        case '+':   flag_prefix = '+';        break;
++        case ' ':   flag_prefix = ' ';        break;
+         case '#':   flag_alternateform = 1;   break;
+         case '!':   flag_altform2 = 1;        break;
+         case '0':   flag_zeropad = 1;         break;
++        case ',':   cThousand = ',';          break;
+         default:    done = 1;                 break;
+       }
+     }while( !done && (c=(*++fmt))!=0 );
+@@ -21615,6 +29804,12 @@
+       testcase( wx>0x7fffffff );
+       width = wx & 0x7fffffff;
+     }
++    assert( width>=0 );
++#ifdef SQLITE_PRINTF_PRECISION_LIMIT
++    if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
++      width = SQLITE_PRINTF_PRECISION_LIMIT;
++    }
++#endif
+ 
+     /* Get the precision */
+     if( c=='.' ){
+@@ -21641,18 +29836,24 @@
+     }else{
+       precision = -1;
+     }
++    assert( precision>=(-1) );
++#ifdef SQLITE_PRINTF_PRECISION_LIMIT
++    if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){
++      precision = SQLITE_PRINTF_PRECISION_LIMIT;
++    }
++#endif
++
++
+     /* Get the conversion type modifier */
+     if( c=='l' ){
+       flag_long = 1;
+       c = *++fmt;
+       if( c=='l' ){
+-        flag_longlong = 1;
++        flag_long = 2;
+         c = *++fmt;
+-      }else{
+-        flag_longlong = 0;
+       }
+     }else{
+-      flag_long = flag_longlong = 0;
++      flag_long = 0;
+     }
+     /* Fetch the info entry for the field */
+     infop = &fmtinfo[0];
+@@ -21660,11 +29861,7 @@
+     for(idx=0; idx<ArraySize(fmtinfo); idx++){
+       if( c==fmtinfo[idx].fmttype ){
+         infop = &fmtinfo[idx];
+-        if( useIntern || (infop->flags & FLAG_INTERN)==0 ){
+-          xtype = infop->type;
+-        }else{
+-          return;
+-        }
++        xtype = infop->type;
+         break;
+       }
+     }
+@@ -21674,15 +29871,11 @@
+     **
+     **   flag_alternateform          TRUE if a '#' is present.
+     **   flag_altform2               TRUE if a '!' is present.
+-    **   flag_plussign               TRUE if a '+' is present.
++    **   flag_prefix                 '+' or ' ' or zero
+     **   flag_leftjustify            TRUE if a '-' is present or if the
+     **                               field width was negative.
+     **   flag_zeropad                TRUE if the width began with 0.
+-    **   flag_long                   TRUE if the letter 'l' (ell) prefixed
+-    **                               the conversion character.
+-    **   flag_longlong               TRUE if the letter 'll' (ell ell) prefixed
+-    **                               the conversion character.
+-    **   flag_blanksign              TRUE if a ' ' is present.
++    **   flag_long                   1 for "l", 2 for "ll"
+     **   width                       The specified field width.  This is
+     **                               always non-negative.  Zero is the default.
+     **   precision                   The specified precision.  The default
+@@ -21692,19 +29885,24 @@
+     */
+     switch( xtype ){
+       case etPOINTER:
+-        flag_longlong = sizeof(char*)==sizeof(i64);
+-        flag_long = sizeof(char*)==sizeof(long int);
++        flag_long = sizeof(char*)==sizeof(i64) ? 2 :
++                     sizeof(char*)==sizeof(long int) ? 1 : 0;
+         /* Fall through into the next case */
+       case etORDINAL:
+-      case etRADIX:
++      case etRADIX:      
++        cThousand = 0;
++        /* Fall through into the next case */
++      case etDECIMAL:
+         if( infop->flags & FLAG_SIGNED ){
+           i64 v;
+           if( bArgList ){
+             v = getIntArg(pArgList);
+-          }else if( flag_longlong ){
+-            v = va_arg(ap,i64);
+           }else if( flag_long ){
+-            v = va_arg(ap,long int);
++            if( flag_long==2 ){
++              v = va_arg(ap,i64) ;
++            }else{
++              v = va_arg(ap,long int);
++            }
+           }else{
+             v = va_arg(ap,int);
+           }
+@@ -21717,17 +29915,17 @@
+             prefix = '-';
+           }else{
+             longvalue = v;
+-            if( flag_plussign )        prefix = '+';
+-            else if( flag_blanksign )  prefix = ' ';
+-            else                       prefix = 0;
++            prefix = flag_prefix;
+           }
+         }else{
+           if( bArgList ){
+             longvalue = (u64)getIntArg(pArgList);
+-          }else if( flag_longlong ){
+-            longvalue = va_arg(ap,u64);
+           }else if( flag_long ){
+-            longvalue = va_arg(ap,unsigned long int);
++            if( flag_long==2 ){
++              longvalue = va_arg(ap,u64);
++            }else{
++              longvalue = va_arg(ap,unsigned long int);
++            }
+           }else{
+             longvalue = va_arg(ap,unsigned int);
+           }
+@@ -21737,16 +29935,17 @@
+         if( flag_zeropad && precision<width-(prefix!=0) ){
+           precision = width-(prefix!=0);
+         }
+-        if( precision<etBUFSIZE-10 ){
++        if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
+           nOut = etBUFSIZE;
+           zOut = buf;
+         }else{
+-          nOut = precision + 10;
+-          zOut = zExtra = sqlite3Malloc( nOut );
++          u64 n = (u64)precision + 10 + precision/3;
++          zOut = zExtra = sqlite3Malloc( n );
+           if( zOut==0 ){
+             setStrAccumError(pAccum, STRACCUM_NOMEM);
+             return;
+           }
++          nOut = (int)n;
+         }
+         bufpt = &zOut[nOut-1];
+         if( xtype==etORDINAL ){
+@@ -21767,8 +29966,23 @@
+           }while( longvalue>0 );
+         }
+         length = (int)(&zOut[nOut-1]-bufpt);
+-        for(idx=precision-length; idx>0; idx--){
++        while( precision>length ){
+           *(--bufpt) = '0';                             /* Zero pad */
++          length++;
++        }
++        if( cThousand ){
++          int nn = (length - 1)/3;  /* Number of "," to insert */
++          int ix = (length - 1)%3 + 1;
++          bufpt -= nn;
++          for(idx=0; nn>0; idx++){
++            bufpt[idx] = bufpt[idx+nn];
++            ix--;
++            if( ix==0 ){
++              bufpt[++idx] = cThousand;
++              nn--;
++              ix = 3;
++            }
++          }
+         }
+         if( prefix ) *(--bufpt) = prefix;               /* Add sign */
+         if( flag_alternateform && infop->prefix ){      /* Add "0" or "0x" */
+@@ -21795,9 +30009,7 @@
+           realvalue = -realvalue;
+           prefix = '-';
+         }else{
+-          if( flag_plussign )          prefix = '+';
+-          else if( flag_blanksign )    prefix = ' ';
+-          else                         prefix = 0;
++          prefix = flag_prefix;
+         }
+         if( xtype==etGENERIC && precision>0 ) precision--;
+         testcase( precision>0xfff );
+@@ -21813,21 +30025,16 @@
+         if( realvalue>0.0 ){
+           LONGDOUBLE_TYPE scale = 1.0;
+           while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
+-          while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; }
+-          while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; }
++          while( realvalue>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; }
+           while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
+           realvalue /= scale;
+           while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
+           while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
+           if( exp>350 ){
+-            if( prefix=='-' ){
+-              bufpt = "-Inf";
+-            }else if( prefix=='+' ){
+-              bufpt = "+Inf";
+-            }else{
+-              bufpt = "Inf";
+-            }
+-            length = sqlite3Strlen30(bufpt);
++            bufpt = buf;
++            buf[0] = prefix;
++            memcpy(buf+(prefix!=0),"Inf",4);
++            length = 3+(prefix!=0);
+             break;
+           }
+         }
+@@ -21976,12 +30183,13 @@
+       case etDYNSTRING:
+         if( bArgList ){
+           bufpt = getTextArg(pArgList);
++          xtype = etSTRING;
+         }else{
+           bufpt = va_arg(ap,char*);
+         }
+         if( bufpt==0 ){
+           bufpt = "";
+-        }else if( xtype==etDYNSTRING && !bArgList ){
++        }else if( xtype==etDYNSTRING ){
+           zExtra = bufpt;
+         }
+         if( precision>=0 ){
+@@ -21990,9 +30198,9 @@
+           length = sqlite3Strlen30(bufpt);
+         }
+         break;
+-      case etSQLESCAPE:
+-      case etSQLESCAPE2:
+-      case etSQLESCAPE3: {
++      case etSQLESCAPE:           /* Escape ' characters */
++      case etSQLESCAPE2:          /* Escape ' and enclose in '...' */
++      case etSQLESCAPE3: {        /* Escape " characters */
+         int i, j, k, n, isnull;
+         int needQuote;
+         char ch;
+@@ -22011,7 +30219,7 @@
+           if( ch==q )  n++;
+         }
+         needQuote = !isnull && xtype==etSQLESCAPE2;
+-        n += i + 1 + needQuote*2;
++        n += i + 3;
+         if( n>etBUFSIZE ){
+           bufpt = zExtra = sqlite3Malloc( n );
+           if( bufpt==0 ){
+@@ -22037,7 +30245,9 @@
+         break;
+       }
+       case etTOKEN: {
+-        Token *pToken = va_arg(ap, Token*);
++        Token *pToken;
++        if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
++        pToken = va_arg(ap, Token*);
+         assert( bArgList==0 );
+         if( pToken && pToken->n ){
+           sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
+@@ -22046,9 +30256,13 @@
+         break;
+       }
+       case etSRCLIST: {
+-        SrcList *pSrc = va_arg(ap, SrcList*);
+-        int k = va_arg(ap, int);
+-        struct SrcList_item *pItem = &pSrc->a[k];
++        SrcList *pSrc;
++        int k;
++        struct SrcList_item *pItem;
++        if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
++        pSrc = va_arg(ap, SrcList*);
++        k = va_arg(ap, int);
++        pItem = &pSrc->a[k];
+         assert( bArgList==0 );
+         assert( k>=0 && k<pSrc->nSrc );
+         if( pItem->zDatabase ){
+@@ -22070,12 +30284,16 @@
+     ** the output.
+     */
+     width -= length;
+-    if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
+-    sqlite3StrAccumAppend(pAccum, bufpt, length);
+-    if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
++    if( width>0 ){
++      if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
++      sqlite3StrAccumAppend(pAccum, bufpt, length);
++      if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
++    }else{
++      sqlite3StrAccumAppend(pAccum, bufpt, length);
++    }
+ 
+     if( zExtra ){
+-      sqlite3_free(zExtra);
++      sqlite3DbFree(pAccum->db, zExtra);
+       zExtra = 0;
+     }
+   }/* End for loop over the format string */
+@@ -22101,8 +30319,9 @@
+     setStrAccumError(p, STRACCUM_TOOBIG);
+     return N;
+   }else{
+-    char *zOld = (p->zText==p->zBase ? 0 : p->zText);
++    char *zOld = isMalloced(p) ? p->zText : 0;
+     i64 szNew = p->nChar;
++    assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
+     szNew += N + 1;
+     if( szNew+p->nChar<=p->mxAlloc ){
+       /* Force exponential buffer size growth as long as it does not overflow,
+@@ -22123,9 +30342,10 @@
+     }
+     if( zNew ){
+       assert( p->zText!=0 || p->nChar==0 );
+-      if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
++      if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
+       p->zText = zNew;
+       p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
++      p->printfFlags |= SQLITE_PRINTF_MALLOCED;
+     }else{
+       sqlite3StrAccumReset(p);
+       setStrAccumError(p, STRACCUM_NOMEM);
+@@ -22143,6 +30363,7 @@
+   if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
+     return;
+   }
++  assert( (p->zText==p->zBase)==!isMalloced(p) );
+   while( (N--)>0 ) p->zText[p->nChar++] = c;
+ }
+ 
+@@ -22160,6 +30381,7 @@
+     memcpy(&p->zText[p->nChar], z, N);
+     p->nChar += N;
+   }
++  assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
+ }
+ 
+ /*
+@@ -22173,7 +30395,7 @@
+   assert( p->accError==0 || p->nAlloc==0 );
+   if( p->nChar+N >= p->nAlloc ){
+     enlargeAndAppend(p,z,N);
+-  }else{
++  }else if( N ){
+     assert( p->zText );
+     p->nChar += N;
+     memcpy(&p->zText[p->nChar-N], z, N);
+@@ -22193,16 +30415,23 @@
+ ** Return a pointer to the resulting string.  Return a NULL
+ ** pointer if any kind of error was encountered.
+ */
++static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){
++  assert( p->mxAlloc>0 && !isMalloced(p) );
++  p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
++  if( p->zText ){
++    memcpy(p->zText, p->zBase, p->nChar+1);
++    p->printfFlags |= SQLITE_PRINTF_MALLOCED;
++  }else{
++    setStrAccumError(p, STRACCUM_NOMEM);
++  }
++  return p->zText;
++}
+ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
+   if( p->zText ){
++    assert( (p->zText==p->zBase)==!isMalloced(p) );
+     p->zText[p->nChar] = 0;
+-    if( p->mxAlloc>0 && p->zText==p->zBase ){
+-      p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
+-      if( p->zText ){
+-        memcpy(p->zText, p->zBase, p->nChar+1);
+-      }else{
+-        setStrAccumError(p, STRACCUM_NOMEM);
+-      }
++    if( p->mxAlloc>0 && !isMalloced(p) ){
++      return strAccumFinishRealloc(p);
+     }
+   }
+   return p->zText;
+@@ -22212,8 +30441,10 @@
+ ** Reset an StrAccum string.  Reclaim all malloced memory.
+ */
+ SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
+-  if( p->zText!=p->zBase ){
++  assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
++  if( isMalloced(p) ){
+     sqlite3DbFree(p->db, p->zText);
++    p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
+   }
+   p->zText = 0;
+ }
+@@ -22239,6 +30470,7 @@
+   p->nAlloc = n;
+   p->mxAlloc = mx;
+   p->accError = 0;
++  p->printfFlags = 0;
+ }
+ 
+ /*
+@@ -22252,10 +30484,11 @@
+   assert( db!=0 );
+   sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
+                       db->aLimit[SQLITE_LIMIT_LENGTH]);
+-  sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
++  acc.printfFlags = SQLITE_PRINTF_INTERNAL;
++  sqlite3VXPrintf(&acc, zFormat, ap);
+   z = sqlite3StrAccumFinish(&acc);
+   if( acc.accError==STRACCUM_NOMEM ){
+-    db->mallocFailed = 1;
++    sqlite3OomFault(db);
+   }
+   return z;
+ }
+@@ -22274,28 +30507,10 @@
+ }
+ 
+ /*
+-** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
+-** the string and before returning.  This routine is intended to be used
+-** to modify an existing string.  For example:
+-**
+-**       x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
+-**
+-*/
+-SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){
+-  va_list ap;
+-  char *z;
+-  va_start(ap, zFormat);
+-  z = sqlite3VMPrintf(db, zFormat, ap);
+-  va_end(ap);
+-  sqlite3DbFree(db, zStr);
+-  return z;
+-}
+-
+-/*
+ ** Print into memory obtained from sqlite3_malloc().  Omit the internal
+ ** %-conversion extensions.
+ */
+-SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap){
++SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
+   char *z;
+   char zBase[SQLITE_PRINT_BUF_SIZE];
+   StrAccum acc;
+@@ -22310,7 +30525,7 @@
+   if( sqlite3_initialize() ) return 0;
+ #endif
+   sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
+-  sqlite3VXPrintf(&acc, 0, zFormat, ap);
++  sqlite3VXPrintf(&acc, zFormat, ap);
+   z = sqlite3StrAccumFinish(&acc);
+   return z;
+ }
+@@ -22319,7 +30534,7 @@
+ ** Print into memory obtained from sqlite3_malloc()().  Omit the internal
+ ** %-conversion extensions.
+ */
+-SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char *zFormat, ...){
++SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
+   va_list ap;
+   char *z;
+ #ifndef SQLITE_OMIT_AUTOINIT
+@@ -22344,7 +30559,7 @@
+ **
+ ** sqlite3_vsnprintf() is the varargs version.
+ */
+-SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
++SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
+   StrAccum acc;
+   if( n<=0 ) return zBuf;
+ #ifdef SQLITE_ENABLE_API_ARMOR
+@@ -22355,10 +30570,11 @@
+   }
+ #endif
+   sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
+-  sqlite3VXPrintf(&acc, 0, zFormat, ap);
+-  return sqlite3StrAccumFinish(&acc);
++  sqlite3VXPrintf(&acc, zFormat, ap);
++  zBuf[acc.nChar] = 0;
++  return zBuf;
+ }
+-SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
++SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
+   char *z;
+   va_list ap;
+   va_start(ap,zFormat);
+@@ -22375,13 +30591,18 @@
+ ** sqlite3_log() must render into a static buffer.  It cannot dynamically
+ ** allocate memory because it might be called while the memory allocator
+ ** mutex is held.
++**
++** sqlite3VXPrintf() might ask for *temporary* memory allocations for
++** certain format characters (%q) or for very large precisions or widths.
++** Care must be taken that any sqlite3_log() calls that occur while the
++** memory mutex is held do not use these mechanisms.
+ */
+ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
+   StrAccum acc;                          /* String accumulator */
+   char zMsg[SQLITE_PRINT_BUF_SIZE*3];    /* Complete log message */
+ 
+   sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
+-  sqlite3VXPrintf(&acc, 0, zFormat, ap);
++  sqlite3VXPrintf(&acc, zFormat, ap);
+   sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
+                            sqlite3StrAccumFinish(&acc));
+ }
+@@ -22389,7 +30610,7 @@
+ /*
+ ** Format and write a message to the log if logging is enabled.
+ */
+-SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...){
++SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
+   va_list ap;                             /* Vararg list */
+   if( sqlite3GlobalConfig.xLog ){
+     va_start(ap, zFormat);
+@@ -22410,7 +30631,7 @@
+   char zBuf[500];
+   sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+   va_start(ap,zFormat);
+-  sqlite3VXPrintf(&acc, 0, zFormat, ap);
++  sqlite3VXPrintf(&acc, zFormat, ap);
+   va_end(ap);
+   sqlite3StrAccumFinish(&acc);
+   fprintf(stdout,"%s", zBuf);
+@@ -22418,22 +30639,47 @@
+ }
+ #endif
+ 
+-#ifdef SQLITE_DEBUG
+-/*************************************************************************
+-** Routines for implementing the "TreeView" display of hierarchical
+-** data structures for debugging.
++
++/*
++** variable-argument wrapper around sqlite3VXPrintf().  The bFlags argument
++** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
++*/
++SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
++  va_list ap;
++  va_start(ap,zFormat);
++  sqlite3VXPrintf(p, zFormat, ap);
++  va_end(ap);
++}
++
++/************** End of printf.c **********************************************/
++/************** Begin file treeview.c ****************************************/
++/*
++** 2015-06-08
++**
++** 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.
++**
++*************************************************************************
+ **
+-** The main entry points (coded elsewhere) are:
+-**     sqlite3TreeViewExpr(0, pExpr, 0);
+-**     sqlite3TreeViewExprList(0, pList, 0, 0);
+-**     sqlite3TreeViewSelect(0, pSelect, 0);
+-** Insert calls to those routines while debugging in order to display
+-** a diagram of Expr, ExprList, and Select objects.
++** This file contains C code to implement the TreeView debugging routines.
++** These routines print a parse tree to standard output for debugging and
++** analysis. 
+ **
++** The interfaces in this file is only available when compiling
++** with SQLITE_DEBUG.
++*/
++/* #include "sqliteInt.h" */
++#ifdef SQLITE_DEBUG
++
++/*
++** Add a new subitem to the tree.  The moreToFollow flag indicates that this
++** is not the last item in the tree.
+ */
+-/* Add a new subitem to the tree.  The moreToFollow flag indicates that this
+-** is not the last item in the tree. */
+-SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
++static TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
+   if( p==0 ){
+     p = sqlite3_malloc64( sizeof(*p) );
+     if( p==0 ) return 0;
+@@ -22445,15 +30691,21 @@
+   if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
+   return p;
+ }
+-/* Finished with one layer of the tree */
+-SQLITE_PRIVATE void sqlite3TreeViewPop(TreeView *p){
++
++/*
++** Finished with one layer of the tree
++*/
++static void sqlite3TreeViewPop(TreeView *p){
+   if( p==0 ) return;
+   p->iLevel--;
+   if( p->iLevel<0 ) sqlite3_free(p);
+ }
+-/* Generate a single line of output for the tree, with a prefix that contains
+-** all the appropriate tree lines */
+-SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
++
++/*
++** Generate a single line of output for the tree, with a prefix that contains
++** all the appropriate tree lines
++*/
++static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
+   va_list ap;
+   int i;
+   StrAccum acc;
+@@ -22466,132 +30718,576 @@
+     sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
+   }
+   va_start(ap, zFormat);
+-  sqlite3VXPrintf(&acc, 0, zFormat, ap);
++  sqlite3VXPrintf(&acc, zFormat, ap);
+   va_end(ap);
++  assert( acc.nChar>0 );
+   if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
+   sqlite3StrAccumFinish(&acc);
+   fprintf(stdout,"%s", zBuf);
+   fflush(stdout);
+ }
+-/* Shorthand for starting a new tree item that consists of a single label */
+-SQLITE_PRIVATE void sqlite3TreeViewItem(TreeView *p, const char *zLabel, u8 moreToFollow){
+-  p = sqlite3TreeViewPush(p, moreToFollow);
+-  sqlite3TreeViewLine(p, "%s", zLabel);
+-}
+-#endif /* SQLITE_DEBUG */
+ 
+ /*
+-** variable-argument wrapper around sqlite3VXPrintf().
++** Shorthand for starting a new tree item that consists of a single label
+ */
+-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
+-  va_list ap;
+-  va_start(ap,zFormat);
+-  sqlite3VXPrintf(p, bFlags, zFormat, ap);
+-  va_end(ap);
++static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){
++  p = sqlite3TreeViewPush(p, moreFollows);
++  sqlite3TreeViewLine(p, "%s", zLabel);
+ }
+ 
+-/************** End of printf.c **********************************************/
+-/************** Begin file random.c ******************************************/
+ /*
+-** 2001 September 15
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
+-**
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-*************************************************************************
+-** This file contains code to implement a pseudo-random number
+-** generator (PRNG) for SQLite.
+-**
+-** Random numbers are used by some of the database backends in order
+-** to generate random integer keys for tables or random filenames.
++** Generate a human-readable description of a WITH clause.
+ */
++SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){
++  int i;
++  if( pWith==0 ) return;
++  if( pWith->nCte==0 ) return;
++  if( pWith->pOuter ){
++    sqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter);
++  }else{
++    sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith);
++  }
++  if( pWith->nCte>0 ){
++    pView = sqlite3TreeViewPush(pView, 1);
++    for(i=0; i<pWith->nCte; i++){
++      StrAccum x;
++      char zLine[1000];
++      const struct Cte *pCte = &pWith->a[i];
++      sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
++      sqlite3XPrintf(&x, "%s", pCte->zName);
++      if( pCte->pCols && pCte->pCols->nExpr>0 ){
++        char cSep = '(';
++        int j;
++        for(j=0; j<pCte->pCols->nExpr; j++){
++          sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
++          cSep = ',';
++        }
++        sqlite3XPrintf(&x, ")");
++      }
++      sqlite3XPrintf(&x, " AS");
++      sqlite3StrAccumFinish(&x);
++      sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
++      sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
++      sqlite3TreeViewPop(pView);
++    }
++    sqlite3TreeViewPop(pView);
++  }
++}
+ 
+ 
+-/* All threads share a single random number generator.
+-** This structure is the current state of the generator.
+-*/
+-static SQLITE_WSD struct sqlite3PrngType {
+-  unsigned char isInit;          /* True if initialized */
+-  unsigned char i, j;            /* State variables */
+-  unsigned char s[256];          /* State variables */
+-} sqlite3Prng;
+-
+ /*
+-** Return N random bytes.
++** Generate a human-readable description of a Select object.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *pBuf){
+-  unsigned char t;
+-  unsigned char *zBuf = pBuf;
+-
+-  /* The "wsdPrng" macro will resolve to the pseudo-random number generator
+-  ** state vector.  If writable static data is unsupported on the target,
+-  ** we have to locate the state vector at run-time.  In the more common
+-  ** case where writable static data is supported, wsdPrng can refer directly
+-  ** to the "sqlite3Prng" state vector declared above.
+-  */
+-#ifdef SQLITE_OMIT_WSD
+-  struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);
+-# define wsdPrng p[0]
+-#else
+-# define wsdPrng sqlite3Prng
+-#endif
+-
+-#if SQLITE_THREADSAFE
+-  sqlite3_mutex *mutex;
+-#endif
+-
+-#ifndef SQLITE_OMIT_AUTOINIT
+-  if( sqlite3_initialize() ) return;
+-#endif
+-
+-#if SQLITE_THREADSAFE
+-  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
+-#endif
+-
+-  sqlite3_mutex_enter(mutex);
+-  if( N<=0 || pBuf==0 ){
+-    wsdPrng.isInit = 0;
+-    sqlite3_mutex_leave(mutex);
++SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
++  int n = 0;
++  int cnt = 0;
++  if( p==0 ){
++    sqlite3TreeViewLine(pView, "nil-SELECT");
+     return;
++  } 
++  pView = sqlite3TreeViewPush(pView, moreToFollow);
++  if( p->pWith ){
++    sqlite3TreeViewWith(pView, p->pWith, 1);
++    cnt = 1;
++    sqlite3TreeViewPush(pView, 1);
+   }
+-
+-  /* Initialize the state of the random number generator once,
+-  ** the first time this routine is called.  The seed value does
+-  ** not need to contain a lot of randomness since we are not
+-  ** trying to do secure encryption or anything like that...
+-  **
+-  ** Nothing in this file or anywhere else in SQLite does any kind of
+-  ** encryption.  The RC4 algorithm is being used as a PRNG (pseudo-random
+-  ** number generator) not as an encryption device.
+-  */
+-  if( !wsdPrng.isInit ){
+-    int i;
+-    char k[256];
+-    wsdPrng.j = 0;
+-    wsdPrng.i = 0;
+-    sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k);
+-    for(i=0; i<256; i++){
+-      wsdPrng.s[i] = (u8)i;
++  do{
++    sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d",
++      ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
++      ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags,
++      (int)p->nSelectRow
++    );
++    if( cnt++ ) sqlite3TreeViewPop(pView);
++    if( p->pPrior ){
++      n = 1000;
++    }else{
++      n = 0;
++      if( p->pSrc && p->pSrc->nSrc ) n++;
++      if( p->pWhere ) n++;
++      if( p->pGroupBy ) n++;
++      if( p->pHaving ) n++;
++      if( p->pOrderBy ) n++;
++      if( p->pLimit ) n++;
++      if( p->pOffset ) n++;
+     }
+-    for(i=0; i<256; i++){
+-      wsdPrng.j += wsdPrng.s[i] + k[i];
+-      t = wsdPrng.s[wsdPrng.j];
+-      wsdPrng.s[wsdPrng.j] = wsdPrng.s[i];
+-      wsdPrng.s[i] = t;
++    sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
++    if( p->pSrc && p->pSrc->nSrc ){
++      int i;
++      pView = sqlite3TreeViewPush(pView, (n--)>0);
++      sqlite3TreeViewLine(pView, "FROM");
++      for(i=0; i<p->pSrc->nSrc; i++){
++        struct SrcList_item *pItem = &p->pSrc->a[i];
++        StrAccum x;
++        char zLine[100];
++        sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
++        sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor);
++        if( pItem->zDatabase ){
++          sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
++        }else if( pItem->zName ){
++          sqlite3XPrintf(&x, " %s", pItem->zName);
++        }
++        if( pItem->pTab ){
++          sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName);
++        }
++        if( pItem->zAlias ){
++          sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias);
++        }
++        if( pItem->fg.jointype & JT_LEFT ){
++          sqlite3XPrintf(&x, " LEFT-JOIN");
++        }
++        sqlite3StrAccumFinish(&x);
++        sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); 
++        if( pItem->pSelect ){
++          sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
++        }
++        if( pItem->fg.isTabFunc ){
++          sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
++        }
++        sqlite3TreeViewPop(pView);
++      }
++      sqlite3TreeViewPop(pView);
+     }
+-    wsdPrng.isInit = 1;
+-  }
++    if( p->pWhere ){
++      sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
++      sqlite3TreeViewExpr(pView, p->pWhere, 0);
++      sqlite3TreeViewPop(pView);
++    }
++    if( p->pGroupBy ){
++      sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
++    }
++    if( p->pHaving ){
++      sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
++      sqlite3TreeViewExpr(pView, p->pHaving, 0);
++      sqlite3TreeViewPop(pView);
++    }
++    if( p->pOrderBy ){
++      sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
++    }
++    if( p->pLimit ){
++      sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
++      sqlite3TreeViewExpr(pView, p->pLimit, 0);
++      sqlite3TreeViewPop(pView);
++    }
++    if( p->pOffset ){
++      sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
++      sqlite3TreeViewExpr(pView, p->pOffset, 0);
++      sqlite3TreeViewPop(pView);
++    }
++    if( p->pPrior ){
++      const char *zOp = "UNION";
++      switch( p->op ){
++        case TK_ALL:         zOp = "UNION ALL";  break;
++        case TK_INTERSECT:   zOp = "INTERSECT";  break;
++        case TK_EXCEPT:      zOp = "EXCEPT";     break;
++      }
++      sqlite3TreeViewItem(pView, zOp, 1);
++    }
++    p = p->pPrior;
++  }while( p!=0 );
++  sqlite3TreeViewPop(pView);
++}
+ 
+-  assert( N>0 );
+-  do{
+-    wsdPrng.i++;
+-    t = wsdPrng.s[wsdPrng.i];
+-    wsdPrng.j += t;
+-    wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
++/*
++** Generate a human-readable explanation of an expression tree.
++*/
++SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
++  const char *zBinOp = 0;   /* Binary operator */
++  const char *zUniOp = 0;   /* Unary operator */
++  char zFlgs[60];
++  pView = sqlite3TreeViewPush(pView, moreToFollow);
++  if( pExpr==0 ){
++    sqlite3TreeViewLine(pView, "nil");
++    sqlite3TreeViewPop(pView);
++    return;
++  }
++  if( pExpr->flags ){
++    if( ExprHasProperty(pExpr, EP_FromJoin) ){
++      sqlite3_snprintf(sizeof(zFlgs),zFlgs,"  flags=0x%x iRJT=%d",
++                       pExpr->flags, pExpr->iRightJoinTable);
++    }else{
++      sqlite3_snprintf(sizeof(zFlgs),zFlgs,"  flags=0x%x",pExpr->flags);
++    }
++  }else{
++    zFlgs[0] = 0;
++  }
++  switch( pExpr->op ){
++    case TK_AGG_COLUMN: {
++      sqlite3TreeViewLine(pView, "AGG{%d:%d}%s",
++            pExpr->iTable, pExpr->iColumn, zFlgs);
++      break;
++    }
++    case TK_COLUMN: {
++      if( pExpr->iTable<0 ){
++        /* This only happens when coding check constraints */
++        sqlite3TreeViewLine(pView, "COLUMN(%d)%s", pExpr->iColumn, zFlgs);
++      }else{
++        sqlite3TreeViewLine(pView, "{%d:%d}%s",
++                             pExpr->iTable, pExpr->iColumn, zFlgs);
++      }
++      break;
++    }
++    case TK_INTEGER: {
++      if( pExpr->flags & EP_IntValue ){
++        sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue);
++      }else{
++        sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken);
++      }
++      break;
++    }
++#ifndef SQLITE_OMIT_FLOATING_POINT
++    case TK_FLOAT: {
++      sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
++      break;
++    }
++#endif
++    case TK_STRING: {
++      sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken);
++      break;
++    }
++    case TK_NULL: {
++      sqlite3TreeViewLine(pView,"NULL");
++      break;
++    }
++#ifndef SQLITE_OMIT_BLOB_LITERAL
++    case TK_BLOB: {
++      sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
++      break;
++    }
++#endif
++    case TK_VARIABLE: {
++      sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)",
++                          pExpr->u.zToken, pExpr->iColumn);
++      break;
++    }
++    case TK_REGISTER: {
++      sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
++      break;
++    }
++    case TK_ID: {
++      sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
++      break;
++    }
++#ifndef SQLITE_OMIT_CAST
++    case TK_CAST: {
++      /* Expressions of the form:   CAST(pLeft AS token) */
++      sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);
++      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
++      break;
++    }
++#endif /* SQLITE_OMIT_CAST */
++    case TK_LT:      zBinOp = "LT";     break;
++    case TK_LE:      zBinOp = "LE";     break;
++    case TK_GT:      zBinOp = "GT";     break;
++    case TK_GE:      zBinOp = "GE";     break;
++    case TK_NE:      zBinOp = "NE";     break;
++    case TK_EQ:      zBinOp = "EQ";     break;
++    case TK_IS:      zBinOp = "IS";     break;
++    case TK_ISNOT:   zBinOp = "ISNOT";  break;
++    case TK_AND:     zBinOp = "AND";    break;
++    case TK_OR:      zBinOp = "OR";     break;
++    case TK_PLUS:    zBinOp = "ADD";    break;
++    case TK_STAR:    zBinOp = "MUL";    break;
++    case TK_MINUS:   zBinOp = "SUB";    break;
++    case TK_REM:     zBinOp = "REM";    break;
++    case TK_BITAND:  zBinOp = "BITAND"; break;
++    case TK_BITOR:   zBinOp = "BITOR";  break;
++    case TK_SLASH:   zBinOp = "DIV";    break;
++    case TK_LSHIFT:  zBinOp = "LSHIFT"; break;
++    case TK_RSHIFT:  zBinOp = "RSHIFT"; break;
++    case TK_CONCAT:  zBinOp = "CONCAT"; break;
++    case TK_DOT:     zBinOp = "DOT";    break;
++
++    case TK_UMINUS:  zUniOp = "UMINUS"; break;
++    case TK_UPLUS:   zUniOp = "UPLUS";  break;
++    case TK_BITNOT:  zUniOp = "BITNOT"; break;
++    case TK_NOT:     zUniOp = "NOT";    break;
++    case TK_ISNULL:  zUniOp = "ISNULL"; break;
++    case TK_NOTNULL: zUniOp = "NOTNULL"; break;
++
++    case TK_SPAN: {
++      sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
++      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
++      break;
++    }
++
++    case TK_COLLATE: {
++      sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
++      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
++      break;
++    }
++
++    case TK_AGG_FUNCTION:
++    case TK_FUNCTION: {
++      ExprList *pFarg;       /* List of function arguments */
++      if( ExprHasProperty(pExpr, EP_TokenOnly) ){
++        pFarg = 0;
++      }else{
++        pFarg = pExpr->x.pList;
++      }
++      if( pExpr->op==TK_AGG_FUNCTION ){
++        sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
++                             pExpr->op2, pExpr->u.zToken);
++      }else{
++        sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
++      }
++      if( pFarg ){
++        sqlite3TreeViewExprList(pView, pFarg, 0, 0);
++      }
++      break;
++    }
++#ifndef SQLITE_OMIT_SUBQUERY
++    case TK_EXISTS: {
++      sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags);
++      sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
++      break;
++    }
++    case TK_SELECT: {
++      sqlite3TreeViewLine(pView, "SELECT-expr flags=0x%x", pExpr->flags);
++      sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
++      break;
++    }
++    case TK_IN: {
++      sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags);
++      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
++      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
++        sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
++      }else{
++        sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
++      }
++      break;
++    }
++#endif /* SQLITE_OMIT_SUBQUERY */
++
++    /*
++    **    x BETWEEN y AND z
++    **
++    ** This is equivalent to
++    **
++    **    x>=y AND x<=z
++    **
++    ** X is stored in pExpr->pLeft.
++    ** Y is stored in pExpr->pList->a[0].pExpr.
++    ** Z is stored in pExpr->pList->a[1].pExpr.
++    */
++    case TK_BETWEEN: {
++      Expr *pX = pExpr->pLeft;
++      Expr *pY = pExpr->x.pList->a[0].pExpr;
++      Expr *pZ = pExpr->x.pList->a[1].pExpr;
++      sqlite3TreeViewLine(pView, "BETWEEN");
++      sqlite3TreeViewExpr(pView, pX, 1);
++      sqlite3TreeViewExpr(pView, pY, 1);
++      sqlite3TreeViewExpr(pView, pZ, 0);
++      break;
++    }
++    case TK_TRIGGER: {
++      /* If the opcode is TK_TRIGGER, then the expression is a reference
++      ** to a column in the new.* or old.* pseudo-tables available to
++      ** trigger programs. In this case Expr.iTable is set to 1 for the
++      ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
++      ** is set to the column of the pseudo-table to read, or to -1 to
++      ** read the rowid field.
++      */
++      sqlite3TreeViewLine(pView, "%s(%d)", 
++          pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
++      break;
++    }
++    case TK_CASE: {
++      sqlite3TreeViewLine(pView, "CASE");
++      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
++      sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
++      break;
++    }
++#ifndef SQLITE_OMIT_TRIGGER
++    case TK_RAISE: {
++      const char *zType = "unk";
++      switch( pExpr->affinity ){
++        case OE_Rollback:   zType = "rollback";  break;
++        case OE_Abort:      zType = "abort";     break;
++        case OE_Fail:       zType = "fail";      break;
++        case OE_Ignore:     zType = "ignore";    break;
++      }
++      sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
++      break;
++    }
++#endif
++    case TK_MATCH: {
++      sqlite3TreeViewLine(pView, "MATCH {%d:%d}%s",
++                          pExpr->iTable, pExpr->iColumn, zFlgs);
++      sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
++      break;
++    }
++    case TK_VECTOR: {
++      sqlite3TreeViewBareExprList(pView, pExpr->x.pList, "VECTOR");
++      break;
++    }
++    case TK_SELECT_COLUMN: {
++      sqlite3TreeViewLine(pView, "SELECT-COLUMN %d", pExpr->iColumn);
++      sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0);
++      break;
++    }
++    case TK_IF_NULL_ROW: {
++      sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable);
++      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
++      break;
++    }
++    default: {
++      sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
++      break;
++    }
++  }
++  if( zBinOp ){
++    sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs);
++    sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
++    sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
++  }else if( zUniOp ){
++    sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs);
++    sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
++  }
++  sqlite3TreeViewPop(pView);
++}
++
++
++/*
++** Generate a human-readable explanation of an expression list.
++*/
++SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
++  TreeView *pView,
++  const ExprList *pList,
++  const char *zLabel
++){
++  if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST";
++  if( pList==0 ){
++    sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
++  }else{
++    int i;
++    sqlite3TreeViewLine(pView, "%s", zLabel);
++    for(i=0; i<pList->nExpr; i++){
++      int j = pList->a[i].u.x.iOrderByCol;
++      if( j ){
++        sqlite3TreeViewPush(pView, 0);
++        sqlite3TreeViewLine(pView, "iOrderByCol=%d", j);
++      }
++      sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1);
++      if( j ) sqlite3TreeViewPop(pView);
++    }
++  }
++}
++SQLITE_PRIVATE void sqlite3TreeViewExprList(
++  TreeView *pView,
++  const ExprList *pList,
++  u8 moreToFollow,
++  const char *zLabel
++){
++  pView = sqlite3TreeViewPush(pView, moreToFollow);
++  sqlite3TreeViewBareExprList(pView, pList, zLabel);
++  sqlite3TreeViewPop(pView);
++}
++
++#endif /* SQLITE_DEBUG */
++
++/************** End of treeview.c ********************************************/
++/************** Begin file random.c ******************************************/
++/*
++** 2001 September 15
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This file contains code to implement a pseudo-random number
++** generator (PRNG) for SQLite.
++**
++** Random numbers are used by some of the database backends in order
++** to generate random integer keys for tables or random filenames.
++*/
++/* #include "sqliteInt.h" */
++
++
++/* All threads share a single random number generator.
++** This structure is the current state of the generator.
++*/
++static SQLITE_WSD struct sqlite3PrngType {
++  unsigned char isInit;          /* True if initialized */
++  unsigned char i, j;            /* State variables */
++  unsigned char s[256];          /* State variables */
++} sqlite3Prng;
++
++/*
++** Return N random bytes.
++*/
++SQLITE_API void sqlite3_randomness(int N, void *pBuf){
++  unsigned char t;
++  unsigned char *zBuf = pBuf;
++
++  /* The "wsdPrng" macro will resolve to the pseudo-random number generator
++  ** state vector.  If writable static data is unsupported on the target,
++  ** we have to locate the state vector at run-time.  In the more common
++  ** case where writable static data is supported, wsdPrng can refer directly
++  ** to the "sqlite3Prng" state vector declared above.
++  */
++#ifdef SQLITE_OMIT_WSD
++  struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);
++# define wsdPrng p[0]
++#else
++# define wsdPrng sqlite3Prng
++#endif
++
++#if SQLITE_THREADSAFE
++  sqlite3_mutex *mutex;
++#endif
++
++#ifndef SQLITE_OMIT_AUTOINIT
++  if( sqlite3_initialize() ) return;
++#endif
++
++#if SQLITE_THREADSAFE
++  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
++#endif
++
++  sqlite3_mutex_enter(mutex);
++  if( N<=0 || pBuf==0 ){
++    wsdPrng.isInit = 0;
++    sqlite3_mutex_leave(mutex);
++    return;
++  }
++
++  /* Initialize the state of the random number generator once,
++  ** the first time this routine is called.  The seed value does
++  ** not need to contain a lot of randomness since we are not
++  ** trying to do secure encryption or anything like that...
++  **
++  ** Nothing in this file or anywhere else in SQLite does any kind of
++  ** encryption.  The RC4 algorithm is being used as a PRNG (pseudo-random
++  ** number generator) not as an encryption device.
++  */
++  if( !wsdPrng.isInit ){
++    int i;
++    char k[256];
++    wsdPrng.j = 0;
++    wsdPrng.i = 0;
++    sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k);
++    for(i=0; i<256; i++){
++      wsdPrng.s[i] = (u8)i;
++    }
++    for(i=0; i<256; i++){
++      wsdPrng.j += wsdPrng.s[i] + k[i];
++      t = wsdPrng.s[wsdPrng.j];
++      wsdPrng.s[wsdPrng.j] = wsdPrng.s[i];
++      wsdPrng.s[i] = t;
++    }
++    wsdPrng.isInit = 1;
++  }
++
++  assert( N>0 );
++  do{
++    wsdPrng.i++;
++    t = wsdPrng.s[wsdPrng.i];
++    wsdPrng.j += t;
++    wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
+     wsdPrng.s[wsdPrng.j] = t;
+     t += wsdPrng.s[wsdPrng.i];
+     *(zBuf++) = wsdPrng.s[t];
+@@ -22599,7 +31295,7 @@
+   sqlite3_mutex_leave(mutex);
+ }
+ 
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
++#ifndef SQLITE_UNTESTABLE
+ /*
+ ** For testing purposes, we sometimes want to preserve the state of
+ ** PRNG and restore the PRNG to its saved state at a later time, or
+@@ -22624,7 +31320,7 @@
+     sizeof(sqlite3Prng)
+   );
+ }
+-#endif /* SQLITE_OMIT_BUILTIN_TEST */
++#endif /* SQLITE_UNTESTABLE */
+ 
+ /************** End of random.c **********************************************/
+ /************** Begin file threads.c *****************************************/
+@@ -22655,7 +31351,9 @@
+ ** of multiple cores can do so, while also allowing applications to stay
+ ** single-threaded if desired.
+ */
++/* #include "sqliteInt.h" */
+ #if SQLITE_OS_WIN
++/* #  include "os_win.h" */
+ #endif
+ 
+ #if SQLITE_MAX_WORKER_THREADS>0
+@@ -22691,10 +31389,14 @@
+ 
+   *ppThread = 0;
+   p = sqlite3Malloc(sizeof(*p));
+-  if( p==0 ) return SQLITE_NOMEM;
++  if( p==0 ) return SQLITE_NOMEM_BKPT;
+   memset(p, 0, sizeof(*p));
+   p->xTask = xTask;
+   p->pIn = pIn;
++  /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a 
++  ** function that returns SQLITE_ERROR when passed the argument 200, that
++  ** forces worker threads to run sequentially and deterministically 
++  ** for testing purposes. */
+   if( sqlite3FaultSim(200) ){
+     rc = 1;
+   }else{    
+@@ -22713,7 +31415,7 @@
+   int rc;
+ 
+   assert( ppOut!=0 );
+-  if( NEVER(p==0) ) return SQLITE_NOMEM;
++  if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
+   if( p->done ){
+     *ppOut = p->pOut;
+     rc = SQLITE_OK;
+@@ -22778,8 +31480,13 @@
+   assert( xTask!=0 );
+   *ppThread = 0;
+   p = sqlite3Malloc(sizeof(*p));
+-  if( p==0 ) return SQLITE_NOMEM;
+-  if( sqlite3GlobalConfig.bCoreMutex==0 ){
++  if( p==0 ) return SQLITE_NOMEM_BKPT;
++  /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a 
++  ** function that returns SQLITE_ERROR when passed the argument 200, that
++  ** forces worker threads to run sequentially and deterministically 
++  ** (via the sqlite3FaultSim() term of the conditional) for testing
++  ** purposes. */
++  if( sqlite3GlobalConfig.bCoreMutex==0 || sqlite3FaultSim(200) ){
+     memset(p, 0, sizeof(*p));
+   }else{
+     p->xTask = xTask;
+@@ -22805,9 +31512,9 @@
+   BOOL bRc;
+ 
+   assert( ppOut!=0 );
+-  if( NEVER(p==0) ) return SQLITE_NOMEM;
++  if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
+   if( p->xTask==0 ){
+-    assert( p->id==GetCurrentThreadId() );
++    /* assert( p->id==GetCurrentThreadId() ); */
+     rc = WAIT_OBJECT_0;
+     assert( p->tid==0 );
+   }else{
+@@ -22853,7 +31560,7 @@
+   assert( xTask!=0 );
+   *ppThread = 0;
+   p = sqlite3Malloc(sizeof(*p));
+-  if( p==0 ) return SQLITE_NOMEM;
++  if( p==0 ) return SQLITE_NOMEM_BKPT;
+   if( (SQLITE_PTR_TO_INT(p)/17)&1 ){
+     p->xTask = xTask;
+     p->pIn = pIn;
+@@ -22869,7 +31576,7 @@
+ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
+ 
+   assert( ppOut!=0 );
+-  if( NEVER(p==0) ) return SQLITE_NOMEM;
++  if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
+   if( p->xTask ){
+     *ppOut = p->xTask(p->pIn);
+   }else{
+@@ -22880,7 +31587,7 @@
+ #if defined(SQLITE_TEST)
+   {
+     void *pTstAlloc = sqlite3Malloc(10);
+-    if (!pTstAlloc) return SQLITE_NOMEM;
++    if (!pTstAlloc) return SQLITE_NOMEM_BKPT;
+     sqlite3_free(pTstAlloc);
+   }
+ #endif
+@@ -22929,15 +31636,17 @@
+ **     0xfe 0xff   big-endian utf-16 follows
+ **
+ */
++/* #include "sqliteInt.h" */
+ /* #include <assert.h> */
++/* #include "vdbeInt.h" */
+ 
+-#ifndef SQLITE_AMALGAMATION
++#if !defined(SQLITE_AMALGAMATION) && SQLITE_BYTEORDER==0
+ /*
+ ** The following constant value is used by the SQLITE_BIGENDIAN and
+ ** SQLITE_LITTLEENDIAN macros.
+ */
+ SQLITE_PRIVATE const int sqlite3one = 1;
+-#endif /* SQLITE_AMALGAMATION */
++#endif /* SQLITE_AMALGAMATION && SQLITE_BYTEORDER==0 */
+ 
+ /*
+ ** This lookup table is used to help decode the first byte of
+@@ -23125,7 +31834,7 @@
+     rc = sqlite3VdbeMemMakeWriteable(pMem);
+     if( rc!=SQLITE_OK ){
+       assert( rc==SQLITE_NOMEM );
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     zIn = (u8*)pMem->z;
+     zTerm = &zIn[pMem->n&~1];
+@@ -23167,7 +31876,7 @@
+   zTerm = &zIn[pMem->n];
+   zOut = sqlite3DbMallocRaw(pMem->db, len);
+   if( !zOut ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   z = zOut;
+ 
+@@ -23210,7 +31919,7 @@
+ 
+   c = pMem->flags;
+   sqlite3VdbeMemRelease(pMem);
+-  pMem->flags = MEM_Str|MEM_Term|(c&MEM_AffMask);
++  pMem->flags = MEM_Str|MEM_Term|(c&(MEM_AffMask|MEM_Subtype));
+   pMem->enc = desiredEnc;
+   pMem->z = (char*)zOut;
+   pMem->zMalloc = pMem->z;
+@@ -23226,7 +31935,9 @@
+ #endif
+   return SQLITE_OK;
+ }
++#endif /* SQLITE_OMIT_UTF16 */
+ 
++#ifndef SQLITE_OMIT_UTF16
+ /*
+ ** This routine checks for a byte-order mark at the beginning of the 
+ ** UTF-16 string stored in *pMem. If one is present, it is removed and
+@@ -23442,6 +32153,7 @@
+ ** strings, and stuff like that.
+ **
+ */
++/* #include "sqliteInt.h" */
+ /* #include <stdarg.h> */
+ #if HAVE_ISNAN || SQLITE_HAVE_ISNAN
+ # include <math.h>
+@@ -23468,7 +32180,7 @@
+ ** Return whatever integer value the test callback returns, or return
+ ** SQLITE_OK if no test callback is installed.
+ */
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
++#ifndef SQLITE_UNTESTABLE
+ SQLITE_PRIVATE int sqlite3FaultSim(int iTest){
+   int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback;
+   return xCallback ? xCallback(iTest) : SQLITE_OK;
+@@ -23531,19 +32243,53 @@
+ ** than 1GiB) the value returned might be less than the true string length.
+ */
+ SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
+-  const char *z2 = z;
+   if( z==0 ) return 0;
+-  while( *z2 ){ z2++; }
+-  return 0x3fffffff & (int)(z2 - z);
++  return 0x3fffffff & (int)strlen(z);
++}
++
++/*
++** Return the declared type of a column.  Or return zDflt if the column 
++** has no declared type.
++**
++** The column type is an extra string stored after the zero-terminator on
++** the column name if and only if the COLFLAG_HASTYPE flag is set.
++*/
++SQLITE_PRIVATE char *sqlite3ColumnType(Column *pCol, char *zDflt){
++  if( (pCol->colFlags & COLFLAG_HASTYPE)==0 ) return zDflt;
++  return pCol->zName + strlen(pCol->zName) + 1;
++}
++
++/*
++** Helper function for sqlite3Error() - called rarely.  Broken out into
++** a separate routine to avoid unnecessary register saves on entry to
++** sqlite3Error().
++*/
++static SQLITE_NOINLINE void  sqlite3ErrorFinish(sqlite3 *db, int err_code){
++  if( db->pErr ) sqlite3ValueSetNull(db->pErr);
++  sqlite3SystemError(db, err_code);
+ }
+ 
+ /*
+ ** Set the current error code to err_code and clear any prior error message.
++** Also set iSysErrno (by calling sqlite3System) if the err_code indicates
++** that would be appropriate.
+ */
+ SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){
+   assert( db!=0 );
+   db->errCode = err_code;
+-  if( db->pErr ) sqlite3ValueSetNull(db->pErr);
++  if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code);
++}
++
++/*
++** Load the sqlite3.iSysErrno field if that is an appropriate thing
++** to do based on the SQLite error code in rc.
++*/
++SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){
++  if( rc==SQLITE_IOERR_NOMEM ) return;
++  rc &= 0xff;
++  if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){
++    db->iSysErrno = sqlite3OsGetLastError(db->pVfs);
++  }
+ }
+ 
+ /*
+@@ -23570,6 +32316,7 @@
+ SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){
+   assert( db!=0 );
+   db->errCode = err_code;
++  sqlite3SystemError(db, err_code);
+   if( zFormat==0 ){
+     sqlite3Error(db, err_code);
+   }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){
+@@ -23633,18 +32380,13 @@
+ ** brackets from around identifiers.  For example:  "[a-b-c]" becomes
+ ** "a-b-c".
+ */
+-SQLITE_PRIVATE int sqlite3Dequote(char *z){
++SQLITE_PRIVATE void sqlite3Dequote(char *z){
+   char quote;
+   int i, j;
+-  if( z==0 ) return -1;
++  if( z==0 ) return;
+   quote = z[0];
+-  switch( quote ){
+-    case '\'':  break;
+-    case '"':   break;
+-    case '`':   break;                /* For MySQL compatibility */
+-    case '[':   quote = ']';  break;  /* For MS SqlServer compatibility */
+-    default:    return -1;
+-  }
++  if( !sqlite3Isquote(quote) ) return;
++  if( quote=='[' ) quote = ']';
+   for(i=1, j=0;; i++){
+     assert( z[i] );
+     if( z[i]==quote ){
+@@ -23659,7 +32401,14 @@
+     }
+   }
+   z[j] = 0;
+-  return j;
++}
++
++/*
++** Generate a Token object from a string
++*/
++SQLITE_PRIVATE void sqlite3TokenInit(Token *p, char *z){
++  p->z = z;
++  p->n = sqlite3Strlen30(z);
+ }
+ 
+ /* Convenient short-hand */
+@@ -23675,19 +32424,28 @@
+ ** case-independent fashion, using the same definition of "case
+ ** independence" that SQLite uses internally when comparing identifiers.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *zLeft, const char *zRight){
+-  register unsigned char *a, *b;
++SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
+   if( zLeft==0 ){
+     return zRight ? -1 : 0;
+   }else if( zRight==0 ){
+     return 1;
+   }
++  return sqlite3StrICmp(zLeft, zRight);
++}
++SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
++  unsigned char *a, *b;
++  int c;
+   a = (unsigned char *)zLeft;
+   b = (unsigned char *)zRight;
+-  while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
+-  return UpperToLower[*a] - UpperToLower[*b];
++  for(;;){
++    c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
++    if( c || *a==0 ) break;
++    a++;
++    b++;
++  }
++  return c;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
++SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
+   register unsigned char *a, *b;
+   if( zLeft==0 ){
+     return zRight ? -1 : 0;
+@@ -23735,7 +32493,7 @@
+   int eValid = 1;  /* True exponent is either not used or is well-formed */
+   double result;
+   int nDigits = 0;
+-  int nonNum = 0;
++  int nonNum = 0;  /* True if input contains UTF16 with high byte non-zero */
+ 
+   assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
+   *pResult = 0.0;   /* Default return value, in case of an error */
+@@ -23748,7 +32506,7 @@
+     assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
+     for(i=3-enc; i<length && z[i]==0; i+=2){}
+     nonNum = i<length;
+-    zEnd = z+i+enc-3;
++    zEnd = &z[i^1];
+     z += (enc&1);
+   }
+ 
+@@ -23764,9 +32522,6 @@
+     z+=incr;
+   }
+ 
+-  /* skip leading zeroes */
+-  while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++;
+-
+   /* copy max significant digits to significand */
+   while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
+     s = s*10 + (*z - '0');
+@@ -23783,12 +32538,13 @@
+     z+=incr;
+     /* copy digits from after decimal to significand
+     ** (decrease exponent by d to shift decimal right) */
+-    while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
+-      s = s*10 + (*z - '0');
+-      z+=incr, nDigits++, d--;
++    while( z<zEnd && sqlite3Isdigit(*z) ){
++      if( s<((LARGEST_INT64-9)/10) ){
++        s = s*10 + (*z - '0');
++        d--;
++      }
++      z+=incr, nDigits++;
+     }
+-    /* skip non-significant digits */
+-    while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++;
+   }
+   if( z>=zEnd ) goto do_atof_calc;
+ 
+@@ -23796,7 +32552,12 @@
+   if( *z=='e' || *z=='E' ){
+     z+=incr;
+     eValid = 0;
+-    if( z>=zEnd ) goto do_atof_calc;
++
++    /* This branch is needed to avoid a (harmless) buffer overread.  The 
++    ** special comment alerts the mutation tester that the correct answer
++    ** is obtained even if the branch is omitted */
++    if( z>=zEnd ) goto do_atof_calc;              /*PREVENTS-HARMLESS-OVERREAD*/
++
+     /* get sign of exponent */
+     if( *z=='-' ){
+       esign = -1;
+@@ -23813,9 +32574,7 @@
+   }
+ 
+   /* skip trailing spaces */
+-  if( nDigits && eValid ){
+-    while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
+-  }
++  while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
+ 
+ do_atof_calc:
+   /* adjust exponent by d, and update sign */
+@@ -23827,41 +32586,51 @@
+     esign = 1;
+   }
+ 
+-  /* if 0 significand */
+-  if( !s ) {
+-    /* In the IEEE 754 standard, zero is signed.
+-    ** Add the sign if we've seen at least one digit */
+-    result = (sign<0 && nDigits) ? -(double)0 : (double)0;
++  if( s==0 ) {
++    /* In the IEEE 754 standard, zero is signed. */
++    result = sign<0 ? -(double)0 : (double)0;
+   } else {
+-    /* attempt to reduce exponent */
+-    if( esign>0 ){
+-      while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
+-    }else{
+-      while( !(s%10) && e>0 ) e--,s/=10;
++    /* Attempt to reduce exponent.
++    **
++    ** Branches that are not required for the correct answer but which only
++    ** help to obtain the correct answer faster are marked with special
++    ** comments, as a hint to the mutation tester.
++    */
++    while( e>0 ){                                       /*OPTIMIZATION-IF-TRUE*/
++      if( esign>0 ){
++        if( s>=(LARGEST_INT64/10) ) break;             /*OPTIMIZATION-IF-FALSE*/
++        s *= 10;
++      }else{
++        if( s%10!=0 ) break;                           /*OPTIMIZATION-IF-FALSE*/
++        s /= 10;
++      }
++      e--;
+     }
+ 
+     /* adjust the sign of significand */
+     s = sign<0 ? -s : s;
+ 
+-    /* if exponent, scale significand as appropriate
+-    ** and store in result. */
+-    if( e ){
++    if( e==0 ){                                         /*OPTIMIZATION-IF-TRUE*/
++      result = (double)s;
++    }else{
+       LONGDOUBLE_TYPE scale = 1.0;
+       /* attempt to handle extremely small/large numbers better */
+-      if( e>307 && e<342 ){
+-        while( e%308 ) { scale *= 1.0e+1; e -= 1; }
+-        if( esign<0 ){
+-          result = s / scale;
+-          result /= 1.0e+308;
+-        }else{
+-          result = s * scale;
+-          result *= 1.0e+308;
+-        }
+-      }else if( e>=342 ){
+-        if( esign<0 ){
+-          result = 0.0*s;
+-        }else{
+-          result = 1e308*1e308*s;  /* Infinity */
++      if( e>307 ){                                      /*OPTIMIZATION-IF-TRUE*/
++        if( e<342 ){                                    /*OPTIMIZATION-IF-TRUE*/
++          while( e%308 ) { scale *= 1.0e+1; e -= 1; }
++          if( esign<0 ){
++            result = s / scale;
++            result /= 1.0e+308;
++          }else{
++            result = s * scale;
++            result *= 1.0e+308;
++          }
++        }else{ assert( e>=342 );
++          if( esign<0 ){
++            result = 0.0*s;
++          }else{
++            result = 1e308*1e308*s;  /* Infinity */
++          }
+         }
+       }else{
+         /* 1.0e+22 is the largest power of 10 than can be 
+@@ -23874,8 +32643,6 @@
+           result = s * scale;
+         }
+       }
+-    } else {
+-      result = (double)s;
+     }
+   }
+ 
+@@ -23883,7 +32650,7 @@
+   *pResult = result;
+ 
+   /* return true if number and no extra non-whitespace chracters after */
+-  return z>=zEnd && nDigits>0 && eValid && nonNum==0;
++  return z==zEnd && nDigits>0 && eValid && nonNum==0;
+ #else
+   return !sqlite3Atoi64(z, pResult, length, enc);
+ #endif /* SQLITE_OMIT_FLOATING_POINT */
+@@ -23945,7 +32712,7 @@
+   int neg = 0; /* assume positive */
+   int i;
+   int c = 0;
+-  int nonNum = 0;
++  int nonNum = 0;  /* True if input contains UTF16 with high byte non-zero */
+   const char *zStart;
+   const char *zEnd = zNum + length;
+   assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
+@@ -23956,7 +32723,7 @@
+     assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
+     for(i=3-enc; i<length && zNum[i]==0; i+=2){}
+     nonNum = i<length;
+-    zEnd = zNum+i+enc-3;
++    zEnd = &zNum[i^1];
+     zNum += (enc&1);
+   }
+   while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
+@@ -23983,7 +32750,11 @@
+   testcase( i==18 );
+   testcase( i==19 );
+   testcase( i==20 );
+-  if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr || nonNum ){
++  if( &zNum[i]<zEnd              /* Extra bytes at the end */
++   || (i==0 && zStart==zNum)     /* No digits */
++   || i>19*incr                  /* Too many digits */
++   || nonNum                     /* UTF16 with high-order bytes non-zero */
++  ){
+     /* zNum is empty or contains non-numeric text or is longer
+     ** than 19 digits (thus guaranteeing that it is too large) */
+     return 1;
+@@ -24025,7 +32796,6 @@
+ #ifndef SQLITE_OMIT_HEX_INTEGER
+   if( z[0]=='0'
+    && (z[1]=='x' || z[1]=='X')
+-   && sqlite3Isxdigit(z[2])
+   ){
+     u64 u = 0;
+     int i, k;
+@@ -24081,6 +32851,7 @@
+     }
+   }
+ #endif
++  if( !sqlite3Isdigit(zNum[0]) ) return 0;
+   while( zNum[0]=='0' ) zNum++;
+   for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
+     v = v*10 + c;
+@@ -24272,7 +33043,8 @@
+   /* a: p0<<28 | p2<<14 | p4 (unmasked) */
+   if (!(a&0x80))
+   {
+-    /* we can skip these cause they were (effectively) done above in calc'ing s */
++    /* we can skip these cause they were (effectively) done above
++    ** while calculating s */
+     /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
+     /* b &= (0x7f<<14)|(0x7f); */
+     b = b<<7;
+@@ -24493,11 +33265,8 @@
+ ** 64-bit integer.
+ */
+ SQLITE_PRIVATE int sqlite3VarintLen(u64 v){
+-  int i = 0;
+-  do{
+-    i++;
+-    v >>= 7;
+-  }while( v!=0 && ALWAYS(i<9) );
++  int i;
++  for(i=1; (v >>= 7)!=0; i++){ assert( i<10 ); }
+   return i;
+ }
+ 
+@@ -24506,14 +33275,38 @@
+ ** Read or write a four-byte big-endian integer value.
+ */
+ SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
++#if SQLITE_BYTEORDER==4321
++  u32 x;
++  memcpy(&x,p,4);
++  return x;
++#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
++  u32 x;
++  memcpy(&x,p,4);
++  return __builtin_bswap32(x);
++#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
++  u32 x;
++  memcpy(&x,p,4);
++  return _byteswap_ulong(x);
++#else
+   testcase( p[0]&0x80 );
+   return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
++#endif
+ }
+ SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){
++#if SQLITE_BYTEORDER==4321
++  memcpy(p,&v,4);
++#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
++  u32 x = __builtin_bswap32(v);
++  memcpy(p,&x,4);
++#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
++  u32 x = _byteswap_ulong(v);
++  memcpy(p,&x,4);
++#else
+   p[0] = (u8)(v>>24);
+   p[1] = (u8)(v>>16);
+   p[2] = (u8)(v>>8);
+   p[3] = (u8)v;
++#endif
+ }
+ 
+ 
+@@ -24545,7 +33338,7 @@
+   char *zBlob;
+   int i;
+ 
+-  zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1);
++  zBlob = (char *)sqlite3DbMallocRawNN(db, n/2 + 1);
+   n--;
+   if( zBlob ){
+     for(i=0; i<n; i+=2){
+@@ -24621,6 +33414,9 @@
+ ** overflow, leave *pA unchanged and return 1.
+ */
+ SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){
++#if GCC_VERSION>=5004000
++  return __builtin_add_overflow(*pA, iB, pA);
++#else
+   i64 iA = *pA;
+   testcase( iA==0 ); testcase( iA==1 );
+   testcase( iB==-1 ); testcase( iB==0 );
+@@ -24635,8 +33431,12 @@
+   }
+   *pA += iB;
+   return 0; 
++#endif
+ }
+ SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
++#if GCC_VERSION>=5004000
++  return __builtin_sub_overflow(*pA, iB, pA);
++#else
+   testcase( iB==SMALLEST_INT64+1 );
+   if( iB==SMALLEST_INT64 ){
+     testcase( (*pA)==(-1) ); testcase( (*pA)==0 );
+@@ -24646,38 +33446,28 @@
+   }else{
+     return sqlite3AddInt64(pA, -iB);
+   }
++#endif
+ }
+-#define TWOPOWER32 (((i64)1)<<32)
+-#define TWOPOWER31 (((i64)1)<<31)
+ SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){
++#if GCC_VERSION>=5004000
++  return __builtin_mul_overflow(*pA, iB, pA);
++#else
+   i64 iA = *pA;
+-  i64 iA1, iA0, iB1, iB0, r;
+-
+-  iA1 = iA/TWOPOWER32;
+-  iA0 = iA % TWOPOWER32;
+-  iB1 = iB/TWOPOWER32;
+-  iB0 = iB % TWOPOWER32;
+-  if( iA1==0 ){
+-    if( iB1==0 ){
+-      *pA *= iB;
+-      return 0;
++  if( iB>0 ){
++    if( iA>LARGEST_INT64/iB ) return 1;
++    if( iA<SMALLEST_INT64/iB ) return 1;
++  }else if( iB<0 ){
++    if( iA>0 ){
++      if( iB<SMALLEST_INT64/iA ) return 1;
++    }else if( iA<0 ){
++      if( iB==SMALLEST_INT64 ) return 1;
++      if( iA==SMALLEST_INT64 ) return 1;
++      if( -iA>LARGEST_INT64/-iB ) return 1;
+     }
+-    r = iA0*iB1;
+-  }else if( iB1==0 ){
+-    r = iA1*iB0;
+-  }else{
+-    /* If both iA1 and iB1 are non-zero, overflow will result */
+-    return 1;
+   }
+-  testcase( r==(-TWOPOWER31)-1 );
+-  testcase( r==(-TWOPOWER31) );
+-  testcase( r==TWOPOWER31 );
+-  testcase( r==TWOPOWER31-1 );
+-  if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1;
+-  r *= TWOPOWER32;
+-  if( sqlite3AddInt64(&r, iA0*iB0) ) return 1;
+-  *pA = r;
++  *pA = iA*iB;
+   return 0;
++#endif
+ }
+ 
+ /*
+@@ -24761,7 +33551,7 @@
+     if( x<2 ) return 0;
+     while( x<8 ){  y -= 10; x <<= 1; }
+   }else{
+-    while( x>255 ){ y += 40; x >>= 4; }
++    while( x>255 ){ y += 40; x >>= 4; }  /*OPTIMIZATION-IF-TRUE*/
+     while( x>15 ){  y += 10; x >>= 1; }
+   }
+   return a[x&7] + y - 10;
+@@ -24784,20 +33574,134 @@
+ }
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+ 
++#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
++    defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
++    defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
+ /*
+ ** Convert a LogEst into an integer.
++**
++** Note that this routine is only used when one or more of various
++** non-standard compile-time options is enabled.
+ */
+ SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){
+   u64 n;
+-  if( x<10 ) return 1;
+   n = x%10;
+   x /= 10;
+   if( n>=5 ) n -= 2;
+   else if( n>=1 ) n -= 1;
+-  if( x>=3 ){
+-    return x>60 ? (u64)LARGEST_INT64 : (n+8)<<(x-3);
+-  }
+-  return (n+8)>>(3-x);
++#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
++    defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
++  if( x>60 ) return (u64)LARGEST_INT64;
++#else
++  /* If only SQLITE_ENABLE_STAT3_OR_STAT4 is on, then the largest input
++  ** possible to this routine is 310, resulting in a maximum x of 31 */
++  assert( x<=60 );
++#endif
++  return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
++}
++#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */
++
++/*
++** Add a new name/number pair to a VList.  This might require that the
++** VList object be reallocated, so return the new VList.  If an OOM
++** error occurs, the original VList returned and the
++** db->mallocFailed flag is set.
++**
++** A VList is really just an array of integers.  To destroy a VList,
++** simply pass it to sqlite3DbFree().
++**
++** The first integer is the number of integers allocated for the whole
++** VList.  The second integer is the number of integers actually used.
++** Each name/number pair is encoded by subsequent groups of 3 or more
++** integers.
++**
++** Each name/number pair starts with two integers which are the numeric
++** value for the pair and the size of the name/number pair, respectively.
++** The text name overlays one or more following integers.  The text name
++** is always zero-terminated.
++**
++** Conceptually:
++**
++**    struct VList {
++**      int nAlloc;   // Number of allocated slots 
++**      int nUsed;    // Number of used slots 
++**      struct VListEntry {
++**        int iValue;    // Value for this entry
++**        int nSlot;     // Slots used by this entry
++**        // ... variable name goes here
++**      } a[0];
++**    }
++**
++** During code generation, pointers to the variable names within the
++** VList are taken.  When that happens, nAlloc is set to zero as an 
++** indication that the VList may never again be enlarged, since the
++** accompanying realloc() would invalidate the pointers.
++*/
++SQLITE_PRIVATE VList *sqlite3VListAdd(
++  sqlite3 *db,           /* The database connection used for malloc() */
++  VList *pIn,            /* The input VList.  Might be NULL */
++  const char *zName,     /* Name of symbol to add */
++  int nName,             /* Bytes of text in zName */
++  int iVal               /* Value to associate with zName */
++){
++  int nInt;              /* number of sizeof(int) objects needed for zName */
++  char *z;               /* Pointer to where zName will be stored */
++  int i;                 /* Index in pIn[] where zName is stored */
++
++  nInt = nName/4 + 3;
++  assert( pIn==0 || pIn[0]>=3 );  /* Verify ok to add new elements */
++  if( pIn==0 || pIn[1]+nInt > pIn[0] ){
++    /* Enlarge the allocation */
++    int nAlloc = (pIn ? pIn[0]*2 : 10) + nInt;
++    VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int));
++    if( pOut==0 ) return pIn;
++    if( pIn==0 ) pOut[1] = 2;
++    pIn = pOut;
++    pIn[0] = nAlloc;
++  }
++  i = pIn[1];
++  pIn[i] = iVal;
++  pIn[i+1] = nInt;
++  z = (char*)&pIn[i+2];
++  pIn[1] = i+nInt;
++  assert( pIn[1]<=pIn[0] );
++  memcpy(z, zName, nName);
++  z[nName] = 0;
++  return pIn;
++}
++
++/*
++** Return a pointer to the name of a variable in the given VList that
++** has the value iVal.  Or return a NULL if there is no such variable in
++** the list
++*/
++SQLITE_PRIVATE const char *sqlite3VListNumToName(VList *pIn, int iVal){
++  int i, mx;
++  if( pIn==0 ) return 0;
++  mx = pIn[1];
++  i = 2;
++  do{
++    if( pIn[i]==iVal ) return (char*)&pIn[i+2];
++    i += pIn[i+1];
++  }while( i<mx );
++  return 0;
++}
++
++/*
++** Return the number of the variable named zName, if it is in VList.
++** or return 0 if there is no such variable.
++*/
++SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nName){
++  int i, mx;
++  if( pIn==0 ) return 0;
++  mx = pIn[1];
++  i = 2;
++  do{
++    const char *z = (const char*)&pIn[i+2];
++    if( strncmp(z,zName,nName)==0 && z[nName]==0 ) return pIn[i];
++    i += pIn[i+1];
++  }while( i<mx );
++  return 0;
+ }
+ 
+ /************** End of util.c ************************************************/
+@@ -24816,6 +33720,7 @@
+ ** This is the implementation of generic hash-tables
+ ** used in SQLite.
+ */
++/* #include "sqliteInt.h" */
+ /* #include <assert.h> */
+ 
+ /* Turn bulk memory into a hash table object by initializing the
+@@ -24858,8 +33763,12 @@
+ static unsigned int strHash(const char *z){
+   unsigned int h = 0;
+   unsigned char c;
+-  while( (c = (unsigned char)*z++)!=0 ){
+-    h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
++  while( (c = (unsigned char)*z++)!=0 ){     /*OPTIMIZATION-IF-TRUE*/
++    /* Knuth multiplicative hashing.  (Sorting & Searching, p. 510).
++    ** 0x9e3779b1 is 2654435761 which is the closest prime number to
++    ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
++    h += sqlite3UpperToLower[c];
++    h *= 0x9e3779b1;
+   }
+   return h;
+ }
+@@ -24939,8 +33848,9 @@
+ }
+ 
+ /* This function (for internal use only) locates an element in an
+-** hash table that matches the given key.  The hash for this key is
+-** also computed and returned in the *pH parameter.
++** hash table that matches the given key.  If no element is found,
++** a pointer to a static null element with HashElem.data==0 is returned.
++** If pH is not NULL, then the hash for this key is written to *pH.
+ */
+ static HashElem *findElementWithHash(
+   const Hash *pH,     /* The pH to be searched */
+@@ -24950,8 +33860,9 @@
+   HashElem *elem;                /* Used to loop thru the element list */
+   int count;                     /* Number of elements left to test */
+   unsigned int h;                /* The computed hash */
++  static HashElem nullElement = { 0, 0, 0, 0 };
+ 
+-  if( pH->ht ){
++  if( pH->ht ){   /*OPTIMIZATION-IF-TRUE*/
+     struct _ht *pEntry;
+     h = strHash(pKey) % pH->htsize;
+     pEntry = &pH->ht[h];
+@@ -24962,7 +33873,7 @@
+     elem = pH->first;
+     count = pH->count;
+   }
+-  *pHash = h;
++  if( pHash ) *pHash = h;
+   while( count-- ){
+     assert( elem!=0 );
+     if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ 
+@@ -24970,7 +33881,7 @@
+     }
+     elem = elem->next;
+   }
+-  return 0;
++  return &nullElement;
+ }
+ 
+ /* Remove a single entry from the hash table given a pointer to that
+@@ -25012,13 +33923,9 @@
+ ** found, or NULL if there is no match.
+ */
+ SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){
+-  HashElem *elem;    /* The element that matches key */
+-  unsigned int h;    /* A hash on key */
+-
+   assert( pH!=0 );
+   assert( pKey!=0 );
+-  elem = findElementWithHash(pH, pKey, &h);
+-  return elem ? elem->data : 0;
++  return findElementWithHash(pH, pKey, 0)->data;
+ }
+ 
+ /* Insert an element into the hash table pH.  The key is pKey
+@@ -25043,7 +33950,7 @@
+   assert( pH!=0 );
+   assert( pKey!=0 );
+   elem = findElementWithHash(pH,pKey,&h);
+-  if( elem ){
++  if( elem->data ){
+     void *old_data = elem->data;
+     if( data==0 ){
+       removeElementGivenHash(pH,elem,h);
+@@ -25072,172 +33979,185 @@
+ /************** End of hash.c ************************************************/
+ /************** Begin file opcodes.c *****************************************/
+ /* Automatically generated.  Do not edit */
+-/* See the mkopcodec.awk script for details. */
+-#if !defined(SQLITE_OMIT_EXPLAIN) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
++/* See the tool/mkopcodec.tcl script for details. */
++#if !defined(SQLITE_OMIT_EXPLAIN) \
++ || defined(VDBE_PROFILE) \
++ || defined(SQLITE_DEBUG)
+ #if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG)
+ # define OpHelp(X) "\0" X
+ #else
+ # define OpHelp(X)
+ #endif
+ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
+- static const char *const azName[] = { "?",
+-     /*   1 */ "Function"         OpHelp("r[P3]=func(r[P2@P5])"),
+-     /*   2 */ "Savepoint"        OpHelp(""),
+-     /*   3 */ "AutoCommit"       OpHelp(""),
+-     /*   4 */ "Transaction"      OpHelp(""),
+-     /*   5 */ "SorterNext"       OpHelp(""),
+-     /*   6 */ "PrevIfOpen"       OpHelp(""),
+-     /*   7 */ "NextIfOpen"       OpHelp(""),
+-     /*   8 */ "Prev"             OpHelp(""),
+-     /*   9 */ "Next"             OpHelp(""),
+-     /*  10 */ "AggStep"          OpHelp("accum=r[P3] step(r[P2@P5])"),
+-     /*  11 */ "Checkpoint"       OpHelp(""),
+-     /*  12 */ "JournalMode"      OpHelp(""),
+-     /*  13 */ "Vacuum"           OpHelp(""),
+-     /*  14 */ "VFilter"          OpHelp("iplan=r[P3] zplan='P4'"),
+-     /*  15 */ "VUpdate"          OpHelp("data=r[P3@P2]"),
+-     /*  16 */ "Goto"             OpHelp(""),
+-     /*  17 */ "Gosub"            OpHelp(""),
+-     /*  18 */ "Return"           OpHelp(""),
+-     /*  19 */ "Not"              OpHelp("r[P2]= !r[P1]"),
+-     /*  20 */ "InitCoroutine"    OpHelp(""),
+-     /*  21 */ "EndCoroutine"     OpHelp(""),
+-     /*  22 */ "Yield"            OpHelp(""),
+-     /*  23 */ "HaltIfNull"       OpHelp("if r[P3]=null halt"),
+-     /*  24 */ "Halt"             OpHelp(""),
+-     /*  25 */ "Integer"          OpHelp("r[P2]=P1"),
+-     /*  26 */ "Int64"            OpHelp("r[P2]=P4"),
+-     /*  27 */ "String"           OpHelp("r[P2]='P4' (len=P1)"),
+-     /*  28 */ "Null"             OpHelp("r[P2..P3]=NULL"),
+-     /*  29 */ "SoftNull"         OpHelp("r[P1]=NULL"),
+-     /*  30 */ "Blob"             OpHelp("r[P2]=P4 (len=P1)"),
+-     /*  31 */ "Variable"         OpHelp("r[P2]=parameter(P1,P4)"),
+-     /*  32 */ "Move"             OpHelp("r[P2@P3]=r[P1@P3]"),
+-     /*  33 */ "Copy"             OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+-     /*  34 */ "SCopy"            OpHelp("r[P2]=r[P1]"),
+-     /*  35 */ "ResultRow"        OpHelp("output=r[P1@P2]"),
+-     /*  36 */ "CollSeq"          OpHelp(""),
+-     /*  37 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
+-     /*  38 */ "MustBeInt"        OpHelp(""),
+-     /*  39 */ "RealAffinity"     OpHelp(""),
+-     /*  40 */ "Cast"             OpHelp("affinity(r[P1])"),
+-     /*  41 */ "Permutation"      OpHelp(""),
+-     /*  42 */ "Compare"          OpHelp("r[P1@P3] <-> r[P2@P3]"),
+-     /*  43 */ "Jump"             OpHelp(""),
+-     /*  44 */ "Once"             OpHelp(""),
+-     /*  45 */ "If"               OpHelp(""),
+-     /*  46 */ "IfNot"            OpHelp(""),
+-     /*  47 */ "Column"           OpHelp("r[P3]=PX"),
+-     /*  48 */ "Affinity"         OpHelp("affinity(r[P1@P2])"),
+-     /*  49 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1@P2])"),
+-     /*  50 */ "Count"            OpHelp("r[P2]=count()"),
+-     /*  51 */ "ReadCookie"       OpHelp(""),
+-     /*  52 */ "SetCookie"        OpHelp(""),
+-     /*  53 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
+-     /*  54 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
+-     /*  55 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
+-     /*  56 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
+-     /*  57 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
+-     /*  58 */ "SorterOpen"       OpHelp(""),
+-     /*  59 */ "SequenceTest"     OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+-     /*  60 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
+-     /*  61 */ "Close"            OpHelp(""),
+-     /*  62 */ "SeekLT"           OpHelp("key=r[P3@P4]"),
+-     /*  63 */ "SeekLE"           OpHelp("key=r[P3@P4]"),
+-     /*  64 */ "SeekGE"           OpHelp("key=r[P3@P4]"),
+-     /*  65 */ "SeekGT"           OpHelp("key=r[P3@P4]"),
+-     /*  66 */ "Seek"             OpHelp("intkey=r[P2]"),
+-     /*  67 */ "NoConflict"       OpHelp("key=r[P3@P4]"),
+-     /*  68 */ "NotFound"         OpHelp("key=r[P3@P4]"),
+-     /*  69 */ "Found"            OpHelp("key=r[P3@P4]"),
+-     /*  70 */ "NotExists"        OpHelp("intkey=r[P3]"),
+-     /*  71 */ "Or"               OpHelp("r[P3]=(r[P1] || r[P2])"),
+-     /*  72 */ "And"              OpHelp("r[P3]=(r[P1] && r[P2])"),
+-     /*  73 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
+-     /*  74 */ "NewRowid"         OpHelp("r[P2]=rowid"),
+-     /*  75 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
+-     /*  76 */ "IsNull"           OpHelp("if r[P1]==NULL goto P2"),
+-     /*  77 */ "NotNull"          OpHelp("if r[P1]!=NULL goto P2"),
+-     /*  78 */ "Ne"               OpHelp("if r[P1]!=r[P3] goto P2"),
+-     /*  79 */ "Eq"               OpHelp("if r[P1]==r[P3] goto P2"),
+-     /*  80 */ "Gt"               OpHelp("if r[P1]>r[P3] goto P2"),
+-     /*  81 */ "Le"               OpHelp("if r[P1]<=r[P3] goto P2"),
+-     /*  82 */ "Lt"               OpHelp("if r[P1]<r[P3] goto P2"),
+-     /*  83 */ "Ge"               OpHelp("if r[P1]>=r[P3] goto P2"),
+-     /*  84 */ "InsertInt"        OpHelp("intkey=P3 data=r[P2]"),
+-     /*  85 */ "BitAnd"           OpHelp("r[P3]=r[P1]&r[P2]"),
+-     /*  86 */ "BitOr"            OpHelp("r[P3]=r[P1]|r[P2]"),
+-     /*  87 */ "ShiftLeft"        OpHelp("r[P3]=r[P2]<<r[P1]"),
+-     /*  88 */ "ShiftRight"       OpHelp("r[P3]=r[P2]>>r[P1]"),
+-     /*  89 */ "Add"              OpHelp("r[P3]=r[P1]+r[P2]"),
+-     /*  90 */ "Subtract"         OpHelp("r[P3]=r[P2]-r[P1]"),
+-     /*  91 */ "Multiply"         OpHelp("r[P3]=r[P1]*r[P2]"),
+-     /*  92 */ "Divide"           OpHelp("r[P3]=r[P2]/r[P1]"),
+-     /*  93 */ "Remainder"        OpHelp("r[P3]=r[P2]%r[P1]"),
+-     /*  94 */ "Concat"           OpHelp("r[P3]=r[P2]+r[P1]"),
+-     /*  95 */ "Delete"           OpHelp(""),
+-     /*  96 */ "BitNot"           OpHelp("r[P1]= ~r[P1]"),
+-     /*  97 */ "String8"          OpHelp("r[P2]='P4'"),
+-     /*  98 */ "ResetCount"       OpHelp(""),
+-     /*  99 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+-     /* 100 */ "SorterData"       OpHelp("r[P2]=data"),
+-     /* 101 */ "RowKey"           OpHelp("r[P2]=key"),
+-     /* 102 */ "RowData"          OpHelp("r[P2]=data"),
+-     /* 103 */ "Rowid"            OpHelp("r[P2]=rowid"),
+-     /* 104 */ "NullRow"          OpHelp(""),
+-     /* 105 */ "Last"             OpHelp(""),
+-     /* 106 */ "SorterSort"       OpHelp(""),
+-     /* 107 */ "Sort"             OpHelp(""),
+-     /* 108 */ "Rewind"           OpHelp(""),
+-     /* 109 */ "SorterInsert"     OpHelp(""),
+-     /* 110 */ "IdxInsert"        OpHelp("key=r[P2]"),
+-     /* 111 */ "IdxDelete"        OpHelp("key=r[P2@P3]"),
+-     /* 112 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
+-     /* 113 */ "IdxLE"            OpHelp("key=r[P3@P4]"),
+-     /* 114 */ "IdxGT"            OpHelp("key=r[P3@P4]"),
+-     /* 115 */ "IdxLT"            OpHelp("key=r[P3@P4]"),
+-     /* 116 */ "IdxGE"            OpHelp("key=r[P3@P4]"),
+-     /* 117 */ "Destroy"          OpHelp(""),
+-     /* 118 */ "Clear"            OpHelp(""),
+-     /* 119 */ "ResetSorter"      OpHelp(""),
+-     /* 120 */ "CreateIndex"      OpHelp("r[P2]=root iDb=P1"),
+-     /* 121 */ "CreateTable"      OpHelp("r[P2]=root iDb=P1"),
+-     /* 122 */ "ParseSchema"      OpHelp(""),
+-     /* 123 */ "LoadAnalysis"     OpHelp(""),
+-     /* 124 */ "DropTable"        OpHelp(""),
+-     /* 125 */ "DropIndex"        OpHelp(""),
+-     /* 126 */ "DropTrigger"      OpHelp(""),
+-     /* 127 */ "IntegrityCk"      OpHelp(""),
+-     /* 128 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
+-     /* 129 */ "RowSetRead"       OpHelp("r[P3]=rowset(P1)"),
+-     /* 130 */ "RowSetTest"       OpHelp("if r[P3] in rowset(P1) goto P2"),
+-     /* 131 */ "Program"          OpHelp(""),
+-     /* 132 */ "Param"            OpHelp(""),
+-     /* 133 */ "Real"             OpHelp("r[P2]=P4"),
+-     /* 134 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
+-     /* 135 */ "FkIfZero"         OpHelp("if fkctr[P1]==0 goto P2"),
+-     /* 136 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
+-     /* 137 */ "IfPos"            OpHelp("if r[P1]>0 goto P2"),
+-     /* 138 */ "IfNeg"            OpHelp("r[P1]+=P3, if r[P1]<0 goto P2"),
+-     /* 139 */ "IfNotZero"        OpHelp("if r[P1]!=0 then r[P1]+=P3, goto P2"),
+-     /* 140 */ "DecrJumpZero"     OpHelp("if (--r[P1])==0 goto P2"),
+-     /* 141 */ "JumpZeroIncr"     OpHelp("if (r[P1]++)==0 ) goto P2"),
+-     /* 142 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
+-     /* 143 */ "IncrVacuum"       OpHelp(""),
+-     /* 144 */ "Expire"           OpHelp(""),
+-     /* 145 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
+-     /* 146 */ "VBegin"           OpHelp(""),
+-     /* 147 */ "VCreate"          OpHelp(""),
+-     /* 148 */ "VDestroy"         OpHelp(""),
+-     /* 149 */ "VOpen"            OpHelp(""),
+-     /* 150 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
+-     /* 151 */ "VNext"            OpHelp(""),
+-     /* 152 */ "VRename"          OpHelp(""),
+-     /* 153 */ "Pagecount"        OpHelp(""),
+-     /* 154 */ "MaxPgcnt"         OpHelp(""),
+-     /* 155 */ "Init"             OpHelp("Start at P2"),
+-     /* 156 */ "Noop"             OpHelp(""),
+-     /* 157 */ "Explain"          OpHelp(""),
++ static const char *const azName[] = {
++    /*   0 */ "Savepoint"        OpHelp(""),
++    /*   1 */ "AutoCommit"       OpHelp(""),
++    /*   2 */ "Transaction"      OpHelp(""),
++    /*   3 */ "SorterNext"       OpHelp(""),
++    /*   4 */ "PrevIfOpen"       OpHelp(""),
++    /*   5 */ "NextIfOpen"       OpHelp(""),
++    /*   6 */ "Prev"             OpHelp(""),
++    /*   7 */ "Next"             OpHelp(""),
++    /*   8 */ "Checkpoint"       OpHelp(""),
++    /*   9 */ "JournalMode"      OpHelp(""),
++    /*  10 */ "Vacuum"           OpHelp(""),
++    /*  11 */ "VFilter"          OpHelp("iplan=r[P3] zplan='P4'"),
++    /*  12 */ "VUpdate"          OpHelp("data=r[P3@P2]"),
++    /*  13 */ "Goto"             OpHelp(""),
++    /*  14 */ "Gosub"            OpHelp(""),
++    /*  15 */ "InitCoroutine"    OpHelp(""),
++    /*  16 */ "Yield"            OpHelp(""),
++    /*  17 */ "MustBeInt"        OpHelp(""),
++    /*  18 */ "Jump"             OpHelp(""),
++    /*  19 */ "Not"              OpHelp("r[P2]= !r[P1]"),
++    /*  20 */ "Once"             OpHelp(""),
++    /*  21 */ "If"               OpHelp(""),
++    /*  22 */ "IfNot"            OpHelp(""),
++    /*  23 */ "IfNullRow"        OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
++    /*  24 */ "SeekLT"           OpHelp("key=r[P3@P4]"),
++    /*  25 */ "SeekLE"           OpHelp("key=r[P3@P4]"),
++    /*  26 */ "SeekGE"           OpHelp("key=r[P3@P4]"),
++    /*  27 */ "SeekGT"           OpHelp("key=r[P3@P4]"),
++    /*  28 */ "NoConflict"       OpHelp("key=r[P3@P4]"),
++    /*  29 */ "NotFound"         OpHelp("key=r[P3@P4]"),
++    /*  30 */ "Found"            OpHelp("key=r[P3@P4]"),
++    /*  31 */ "SeekRowid"        OpHelp("intkey=r[P3]"),
++    /*  32 */ "NotExists"        OpHelp("intkey=r[P3]"),
++    /*  33 */ "Last"             OpHelp(""),
++    /*  34 */ "IfSmaller"        OpHelp(""),
++    /*  35 */ "SorterSort"       OpHelp(""),
++    /*  36 */ "Sort"             OpHelp(""),
++    /*  37 */ "Rewind"           OpHelp(""),
++    /*  38 */ "IdxLE"            OpHelp("key=r[P3@P4]"),
++    /*  39 */ "IdxGT"            OpHelp("key=r[P3@P4]"),
++    /*  40 */ "IdxLT"            OpHelp("key=r[P3@P4]"),
++    /*  41 */ "IdxGE"            OpHelp("key=r[P3@P4]"),
++    /*  42 */ "RowSetRead"       OpHelp("r[P3]=rowset(P1)"),
++    /*  43 */ "RowSetTest"       OpHelp("if r[P3] in rowset(P1) goto P2"),
++    /*  44 */ "Program"          OpHelp(""),
++    /*  45 */ "FkIfZero"         OpHelp("if fkctr[P1]==0 goto P2"),
++    /*  46 */ "IfPos"            OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
++    /*  47 */ "IfNotZero"        OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
++    /*  48 */ "DecrJumpZero"     OpHelp("if (--r[P1])==0 goto P2"),
++    /*  49 */ "IncrVacuum"       OpHelp(""),
++    /*  50 */ "VNext"            OpHelp(""),
++    /*  51 */ "Init"             OpHelp("Start at P2"),
++    /*  52 */ "Return"           OpHelp(""),
++    /*  53 */ "EndCoroutine"     OpHelp(""),
++    /*  54 */ "HaltIfNull"       OpHelp("if r[P3]=null halt"),
++    /*  55 */ "Halt"             OpHelp(""),
++    /*  56 */ "Integer"          OpHelp("r[P2]=P1"),
++    /*  57 */ "Int64"            OpHelp("r[P2]=P4"),
++    /*  58 */ "String"           OpHelp("r[P2]='P4' (len=P1)"),
++    /*  59 */ "Null"             OpHelp("r[P2..P3]=NULL"),
++    /*  60 */ "SoftNull"         OpHelp("r[P1]=NULL"),
++    /*  61 */ "Blob"             OpHelp("r[P2]=P4 (len=P1)"),
++    /*  62 */ "Variable"         OpHelp("r[P2]=parameter(P1,P4)"),
++    /*  63 */ "Move"             OpHelp("r[P2@P3]=r[P1@P3]"),
++    /*  64 */ "Copy"             OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
++    /*  65 */ "SCopy"            OpHelp("r[P2]=r[P1]"),
++    /*  66 */ "IntCopy"          OpHelp("r[P2]=r[P1]"),
++    /*  67 */ "ResultRow"        OpHelp("output=r[P1@P2]"),
++    /*  68 */ "CollSeq"          OpHelp(""),
++    /*  69 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
++    /*  70 */ "Or"               OpHelp("r[P3]=(r[P1] || r[P2])"),
++    /*  71 */ "And"              OpHelp("r[P3]=(r[P1] && r[P2])"),
++    /*  72 */ "RealAffinity"     OpHelp(""),
++    /*  73 */ "Cast"             OpHelp("affinity(r[P1])"),
++    /*  74 */ "Permutation"      OpHelp(""),
++    /*  75 */ "IsNull"           OpHelp("if r[P1]==NULL goto P2"),
++    /*  76 */ "NotNull"          OpHelp("if r[P1]!=NULL goto P2"),
++    /*  77 */ "Ne"               OpHelp("IF r[P3]!=r[P1]"),
++    /*  78 */ "Eq"               OpHelp("IF r[P3]==r[P1]"),
++    /*  79 */ "Gt"               OpHelp("IF r[P3]>r[P1]"),
++    /*  80 */ "Le"               OpHelp("IF r[P3]<=r[P1]"),
++    /*  81 */ "Lt"               OpHelp("IF r[P3]<r[P1]"),
++    /*  82 */ "Ge"               OpHelp("IF r[P3]>=r[P1]"),
++    /*  83 */ "ElseNotEq"        OpHelp(""),
++    /*  84 */ "BitAnd"           OpHelp("r[P3]=r[P1]&r[P2]"),
++    /*  85 */ "BitOr"            OpHelp("r[P3]=r[P1]|r[P2]"),
++    /*  86 */ "ShiftLeft"        OpHelp("r[P3]=r[P2]<<r[P1]"),
++    /*  87 */ "ShiftRight"       OpHelp("r[P3]=r[P2]>>r[P1]"),
++    /*  88 */ "Add"              OpHelp("r[P3]=r[P1]+r[P2]"),
++    /*  89 */ "Subtract"         OpHelp("r[P3]=r[P2]-r[P1]"),
++    /*  90 */ "Multiply"         OpHelp("r[P3]=r[P1]*r[P2]"),
++    /*  91 */ "Divide"           OpHelp("r[P3]=r[P2]/r[P1]"),
++    /*  92 */ "Remainder"        OpHelp("r[P3]=r[P2]%r[P1]"),
++    /*  93 */ "Concat"           OpHelp("r[P3]=r[P2]+r[P1]"),
++    /*  94 */ "Compare"          OpHelp("r[P1@P3] <-> r[P2@P3]"),
++    /*  95 */ "BitNot"           OpHelp("r[P1]= ~r[P1]"),
++    /*  96 */ "Column"           OpHelp("r[P3]=PX"),
++    /*  97 */ "String8"          OpHelp("r[P2]='P4'"),
++    /*  98 */ "Affinity"         OpHelp("affinity(r[P1@P2])"),
++    /*  99 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1@P2])"),
++    /* 100 */ "Count"            OpHelp("r[P2]=count()"),
++    /* 101 */ "ReadCookie"       OpHelp(""),
++    /* 102 */ "SetCookie"        OpHelp(""),
++    /* 103 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
++    /* 104 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
++    /* 105 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
++    /* 106 */ "OpenDup"          OpHelp(""),
++    /* 107 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
++    /* 108 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
++    /* 109 */ "SorterOpen"       OpHelp(""),
++    /* 110 */ "SequenceTest"     OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
++    /* 111 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
++    /* 112 */ "Close"            OpHelp(""),
++    /* 113 */ "ColumnsUsed"      OpHelp(""),
++    /* 114 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
++    /* 115 */ "NewRowid"         OpHelp("r[P2]=rowid"),
++    /* 116 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
++    /* 117 */ "InsertInt"        OpHelp("intkey=P3 data=r[P2]"),
++    /* 118 */ "Delete"           OpHelp(""),
++    /* 119 */ "ResetCount"       OpHelp(""),
++    /* 120 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
++    /* 121 */ "SorterData"       OpHelp("r[P2]=data"),
++    /* 122 */ "RowData"          OpHelp("r[P2]=data"),
++    /* 123 */ "Rowid"            OpHelp("r[P2]=rowid"),
++    /* 124 */ "NullRow"          OpHelp(""),
++    /* 125 */ "SorterInsert"     OpHelp("key=r[P2]"),
++    /* 126 */ "IdxInsert"        OpHelp("key=r[P2]"),
++    /* 127 */ "IdxDelete"        OpHelp("key=r[P2@P3]"),
++    /* 128 */ "DeferredSeek"     OpHelp("Move P3 to P1.rowid if needed"),
++    /* 129 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
++    /* 130 */ "Destroy"          OpHelp(""),
++    /* 131 */ "Clear"            OpHelp(""),
++    /* 132 */ "Real"             OpHelp("r[P2]=P4"),
++    /* 133 */ "ResetSorter"      OpHelp(""),
++    /* 134 */ "CreateIndex"      OpHelp("r[P2]=root iDb=P1"),
++    /* 135 */ "CreateTable"      OpHelp("r[P2]=root iDb=P1"),
++    /* 136 */ "SqlExec"          OpHelp(""),
++    /* 137 */ "ParseSchema"      OpHelp(""),
++    /* 138 */ "LoadAnalysis"     OpHelp(""),
++    /* 139 */ "DropTable"        OpHelp(""),
++    /* 140 */ "DropIndex"        OpHelp(""),
++    /* 141 */ "DropTrigger"      OpHelp(""),
++    /* 142 */ "IntegrityCk"      OpHelp(""),
++    /* 143 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
++    /* 144 */ "Param"            OpHelp(""),
++    /* 145 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
++    /* 146 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
++    /* 147 */ "OffsetLimit"      OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
++    /* 148 */ "AggStep0"         OpHelp("accum=r[P3] step(r[P2@P5])"),
++    /* 149 */ "AggStep"          OpHelp("accum=r[P3] step(r[P2@P5])"),
++    /* 150 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
++    /* 151 */ "Expire"           OpHelp(""),
++    /* 152 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
++    /* 153 */ "VBegin"           OpHelp(""),
++    /* 154 */ "VCreate"          OpHelp(""),
++    /* 155 */ "VDestroy"         OpHelp(""),
++    /* 156 */ "VOpen"            OpHelp(""),
++    /* 157 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
++    /* 158 */ "VRename"          OpHelp(""),
++    /* 159 */ "Pagecount"        OpHelp(""),
++    /* 160 */ "MaxPgcnt"         OpHelp(""),
++    /* 161 */ "PureFunc0"        OpHelp(""),
++    /* 162 */ "Function0"        OpHelp("r[P3]=func(r[P2@P5])"),
++    /* 163 */ "PureFunc"         OpHelp(""),
++    /* 164 */ "Function"         OpHelp("r[P3]=func(r[P2@P5])"),
++    /* 165 */ "CursorHint"       OpHelp(""),
++    /* 166 */ "Noop"             OpHelp(""),
++    /* 167 */ "Explain"          OpHelp(""),
+   };
+   return azName[i];
+ }
+@@ -25290,6 +34210,7 @@
+ **   *  Definitions of sqlite3_vfs objects for all locking methods
+ **      plus implementations of sqlite3_os_init() and sqlite3_os_end().
+ */
++/* #include "sqliteInt.h" */
+ #if SQLITE_OS_UNIX              /* This file is used on unix only */
+ 
+ /*
+@@ -25317,18 +34238,31 @@
+ #  endif
+ #endif
+ 
++/* Use pread() and pwrite() if they are available */
++#if defined(__APPLE__)
++# define HAVE_PREAD 1
++# define HAVE_PWRITE 1
++#endif
++#if defined(HAVE_PREAD64) && defined(HAVE_PWRITE64)
++# undef USE_PREAD
++# define USE_PREAD64 1
++#elif defined(HAVE_PREAD) && defined(HAVE_PWRITE)
++# undef USE_PREAD64
++# define USE_PREAD 1
++#endif
++
+ /*
+ ** standard include files.
+ */
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+-#include <unistd.h>
++/* #include <unistd.h> */
+ /* #include <time.h> */
+ #include <sys/time.h>
+-#include <errno.h>
++/* #include <errno.h> */
+ #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+-# include <sys/mman.h>
++/* # include <sys/mman.h> */
+ #endif
+ 
+ #if SQLITE_ENABLE_LOCKING_STYLE
+@@ -25395,6 +34329,11 @@
+ */
+ #define MAX_PATHNAME 512
+ 
++/*
++** Maximum supported symbolic links
++*/
++#define SQLITE_MAX_SYMLINKS 100
++
+ /* Always cast the getpid() return type for compatibility with
+ ** kernel modules in VxWorks. */
+ #define osGetpid(X) (pid_t)getpid()
+@@ -25504,8 +34443,6 @@
+ #define UNIXFILE_DELETE      0x20     /* Delete on close */
+ #define UNIXFILE_URI         0x40     /* Filename might have query parameters */
+ #define UNIXFILE_NOLOCK      0x80     /* Do no file locking */
+-#define UNIXFILE_WARNED    0x0100     /* verifyDbFile() warnings issued */
+-#define UNIXFILE_BLOCK     0x0200     /* Next SHM lock might block */
+ 
+ /*
+ ** Include code that is common to all os_*.c files
+@@ -25549,8 +34486,8 @@
+ */
+ #ifdef SQLITE_PERFORMANCE_TRACE
+ 
+-/* 
+-** hwtime.h contains inline assembler code for implementing 
++/*
++** hwtime.h contains inline assembler code for implementing
+ ** high-performance timing routines.
+ */
+ /************** Include hwtime.h in the middle of os_common.h ****************/
+@@ -25570,8 +34507,8 @@
+ ** This file contains inline asm code for retrieving "high-performance"
+ ** counters for x86 class CPUs.
+ */
+-#ifndef _HWTIME_H_
+-#define _HWTIME_H_
++#ifndef SQLITE_HWTIME_H
++#define SQLITE_HWTIME_H
+ 
+ /*
+ ** The following routine only works on pentium-class (or newer) processors.
+@@ -25639,7 +34576,7 @@
+ 
+ #endif
+ 
+-#endif /* !defined(_HWTIME_H_) */
++#endif /* !defined(SQLITE_HWTIME_H) */
+ 
+ /************** End of hwtime.h **********************************************/
+ /************** Continuing where we left off in os_common.h ******************/
+@@ -25660,14 +34597,14 @@
+ ** 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;
++#if defined(SQLITE_TEST)
++SQLITE_API extern int sqlite3_io_error_hit;
++SQLITE_API extern int sqlite3_io_error_hardhit;
++SQLITE_API extern int sqlite3_io_error_pending;
++SQLITE_API extern int sqlite3_io_error_persist;
++SQLITE_API extern int sqlite3_io_error_benign;
++SQLITE_API extern int sqlite3_diskfull_pending;
++SQLITE_API extern int sqlite3_diskfull;
+ #define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
+ #define SimulateIOError(CODE)  \
+   if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
+@@ -25693,17 +34630,17 @@
+ #define SimulateIOErrorBenign(X)
+ #define SimulateIOError(A)
+ #define SimulateDiskfullError(A)
+-#endif
++#endif /* defined(SQLITE_TEST) */
+ 
+ /*
+ ** When testing, keep a count of the number of open files.
+ */
+-#ifdef SQLITE_TEST
+-SQLITE_API int sqlite3_open_file_count = 0;
++#if defined(SQLITE_TEST)
++SQLITE_API extern int sqlite3_open_file_count;
+ #define OpenCounter(X)  sqlite3_open_file_count+=(X)
+ #else
+ #define OpenCounter(X)
+-#endif
++#endif /* defined(SQLITE_TEST) */
+ 
+ #endif /* !defined(_OS_COMMON_H_) */
+ 
+@@ -25768,19 +34705,6 @@
+   return open(zFile, flags, mode);
+ }
+ 
+-/*
+-** On some systems, calls to fchown() will trigger a message in a security
+-** log if they come from non-root processes.  So avoid calling fchown() if
+-** we are not running as root.
+-*/
+-static int posixFchown(int fd, uid_t uid, gid_t gid){
+-#if OS_VXWORKS
+-  return 0;
+-#else
+-  return geteuid() ? 0 : fchown(fd,uid,gid);
+-#endif
+-}
+-
+ /* Forward reference */
+ static int openDirectory(const char*, int*);
+ static int unixGetpagesize(void);
+@@ -25846,7 +34770,7 @@
+ #else
+   { "pread64",      (sqlite3_syscall_ptr)0,          0  },
+ #endif
+-#define osPread64   ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent)
++#define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent)
+ 
+   { "write",        (sqlite3_syscall_ptr)write,      0  },
+ #define osWrite     ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
+@@ -25864,10 +34788,10 @@
+ #else
+   { "pwrite64",     (sqlite3_syscall_ptr)0,          0  },
+ #endif
+-#define osPwrite64  ((ssize_t(*)(int,const void*,size_t,off_t))\
++#define osPwrite64  ((ssize_t(*)(int,const void*,size_t,off64_t))\
+                     aSyscall[13].pCurrent)
+ 
+-  { "fchmod",       (sqlite3_syscall_ptr)fchmod,     0  },
++  { "fchmod",       (sqlite3_syscall_ptr)fchmod,          0  },
+ #define osFchmod    ((int(*)(int,mode_t))aSyscall[14].pCurrent)
+ 
+ #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
+@@ -25889,29 +34813,74 @@
+   { "rmdir",        (sqlite3_syscall_ptr)rmdir,           0 },
+ #define osRmdir     ((int(*)(const char*))aSyscall[19].pCurrent)
+ 
+-  { "fchown",       (sqlite3_syscall_ptr)posixFchown,     0 },
++#if defined(HAVE_FCHOWN)
++  { "fchown",       (sqlite3_syscall_ptr)fchown,          0 },
++#else
++  { "fchown",       (sqlite3_syscall_ptr)0,               0 },
++#endif
+ #define osFchown    ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
+ 
++  { "geteuid",      (sqlite3_syscall_ptr)geteuid,         0 },
++#define osGeteuid   ((uid_t(*)(void))aSyscall[21].pCurrent)
++
+ #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+-  { "mmap",       (sqlite3_syscall_ptr)mmap,     0 },
+-#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent)
++  { "mmap",         (sqlite3_syscall_ptr)mmap,            0 },
++#else
++  { "mmap",         (sqlite3_syscall_ptr)0,               0 },
++#endif
++#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent)
+ 
++#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+   { "munmap",       (sqlite3_syscall_ptr)munmap,          0 },
+-#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)
++#else
++  { "munmap",       (sqlite3_syscall_ptr)0,               0 },
++#endif
++#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent)
+ 
+-#if HAVE_MREMAP
++#if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
+   { "mremap",       (sqlite3_syscall_ptr)mremap,          0 },
+ #else
+   { "mremap",       (sqlite3_syscall_ptr)0,               0 },
+ #endif
+-#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
++#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent)
++
++#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+   { "getpagesize",  (sqlite3_syscall_ptr)unixGetpagesize, 0 },
+-#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
++#else
++  { "getpagesize",  (sqlite3_syscall_ptr)0,               0 },
++#endif
++#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent)
++
++#if defined(HAVE_READLINK)
++  { "readlink",     (sqlite3_syscall_ptr)readlink,        0 },
++#else
++  { "readlink",     (sqlite3_syscall_ptr)0,               0 },
++#endif
++#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
+ 
++#if defined(HAVE_LSTAT)
++  { "lstat",         (sqlite3_syscall_ptr)lstat,          0 },
++#else
++  { "lstat",         (sqlite3_syscall_ptr)0,              0 },
+ #endif
++#define osLstat      ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent)
+ 
+ }; /* End of the overrideable system calls */
+ 
++
++/*
++** On some systems, calls to fchown() will trigger a message in a security
++** log if they come from non-root processes.  So avoid calling fchown() if
++** we are not running as root.
++*/
++static int robustFchown(int fd, uid_t uid, gid_t gid){
++#if defined(HAVE_FCHOWN)
++  return osGeteuid() ? 0 : osFchown(fd,uid,gid);
++#else
++  return 0;
++#endif
++}
++
+ /*
+ ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
+ ** "unix" VFSes.  Return SQLITE_OK opon successfully updating the
+@@ -26073,14 +35042,14 @@
+ **   unixEnterLeave()
+ */
+ static void unixEnterMutex(void){
+-  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
++  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
+ }
+ static void unixLeaveMutex(void){
+-  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
++  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
+ }
+ #ifdef SQLITE_DEBUG
+ static int unixMutexHeld(void) {
+-  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
++  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
+ }
+ #endif
+ 
+@@ -26196,23 +35165,12 @@
+ ** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
+ */
+ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
++  assert( (sqliteIOErr == SQLITE_IOERR_LOCK) || 
++          (sqliteIOErr == SQLITE_IOERR_UNLOCK) || 
++          (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
++          (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) );
+   switch (posixError) {
+-#if 0
+-  /* At one point this code was not commented out. In theory, this branch
+-  ** should never be hit, as this function should only be called after
+-  ** a locking-related function (i.e. fcntl()) has returned non-zero with
+-  ** the value of errno as the first argument. Since a system call has failed,
+-  ** errno should be non-zero.
+-  **
+-  ** Despite this, if errno really is zero, we still don't want to return
+-  ** SQLITE_OK. The system call failed, and *some* SQLite error should be
+-  ** propagated back to the caller. Commenting this branch out means errno==0
+-  ** will be handled by the "default:" case below.
+-  */
+-  case 0: 
+-    return SQLITE_OK;
+-#endif
+-
++  case EACCES: 
+   case EAGAIN:
+   case ETIMEDOUT:
+   case EBUSY:
+@@ -26222,41 +35180,9 @@
+      * introspection, in which it actually means what it says */
+     return SQLITE_BUSY;
+     
+-  case EACCES: 
+-    /* EACCES is like EAGAIN during locking operations, but not any other time*/
+-    if( (sqliteIOErr == SQLITE_IOERR_LOCK) || 
+-        (sqliteIOErr == SQLITE_IOERR_UNLOCK) || 
+-        (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
+-        (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
+-      return SQLITE_BUSY;
+-    }
+-    /* else fall through */
+   case EPERM: 
+     return SQLITE_PERM;
+     
+-#if EOPNOTSUPP!=ENOTSUP
+-  case EOPNOTSUPP: 
+-    /* something went terribly awry, unless during file system support 
+-     * introspection, in which it actually means what it says */
+-#endif
+-#ifdef ENOTSUP
+-  case ENOTSUP: 
+-    /* invalid fd, unless during file system support introspection, in which 
+-     * it actually means what it says */
+-#endif
+-  case EIO:
+-  case EBADF:
+-  case EINVAL:
+-  case ENOTCONN:
+-  case ENODEV:
+-  case ENXIO:
+-  case ENOENT:
+-#ifdef ESTALE                     /* ESTALE is not defined on Interix systems */
+-  case ESTALE:
+-#endif
+-  case ENOSYS:
+-    /* these should force the client to close the file and reconnect */
+-    
+   default: 
+     return sqliteIOErr;
+   }
+@@ -26500,7 +35426,14 @@
+ #if OS_VXWORKS
+   struct vxworksFileId *pId;  /* Unique file ID for vxworks. */
+ #else
+-  ino_t ino;                  /* Inode number */
++  /* We are told that some versions of Android contain a bug that
++  ** sizes ino_t at only 32-bits instead of 64-bits. (See
++  ** https://android-review.googlesource.com/#/c/115351/3/dist/sqlite3.c)
++  ** To work around this, always allocate 64-bits for the inode number.  
++  ** On small machines that only have 32-bit inodes, this wastes 4 bytes,
++  ** but that should not be a big deal. */
++  /* WAS:  ino_t ino;   */
++  u64 ino;                   /* Inode number */
+ #endif
+ };
+ 
+@@ -26540,7 +35473,7 @@
+ 
+ /*
+ **
+-** This function - unixLogError_x(), is only ever called via the macro
++** This function - unixLogErrorAtLine(), is only ever called via the macro
+ ** unixLogError().
+ **
+ ** It is invoked after an error occurs in an OS function and errno has been
+@@ -26709,7 +35642,7 @@
+   rc = osFstat(fd, &statbuf);
+   if( rc!=0 ){
+     storeLastErrno(pFile, errno);
+-#ifdef EOVERFLOW
++#if defined(EOVERFLOW) && defined(SQLITE_DISABLE_LFS)
+     if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
+ #endif
+     return SQLITE_IOERR;
+@@ -26745,7 +35678,7 @@
+ #if OS_VXWORKS
+   fileId.pId = pFile->pId;
+ #else
+-  fileId.ino = statbuf.st_ino;
++  fileId.ino = (u64)statbuf.st_ino;
+ #endif
+   pInode = inodeList;
+   while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
+@@ -26754,7 +35687,7 @@
+   if( pInode==0 ){
+     pInode = sqlite3_malloc64( sizeof(*pInode) );
+     if( pInode==0 ){
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     memset(pInode, 0, sizeof(*pInode));
+     memcpy(&pInode->fileId, &fileId, sizeof(fileId));
+@@ -26779,7 +35712,8 @@
+ #else
+   struct stat buf;
+   return pFile->pInode!=0 &&
+-      (osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino);
++      (osStat(pFile->zPath, &buf)!=0 
++         || (u64)buf.st_ino!=pFile->pInode->fileId.ino);
+ #endif
+ }
+ 
+@@ -26796,30 +35730,25 @@
+ static void verifyDbFile(unixFile *pFile){
+   struct stat buf;
+   int rc;
+-  if( pFile->ctrlFlags & UNIXFILE_WARNED ){
+-    /* One or more of the following warnings have already been issued.  Do not
+-    ** repeat them so as not to clutter the error log */
+-    return;
+-  }
++
++  /* These verifications occurs for the main database only */
++  if( pFile->ctrlFlags & UNIXFILE_NOLOCK ) return;
++
+   rc = osFstat(pFile->h, &buf);
+   if( rc!=0 ){
+     sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
+-    pFile->ctrlFlags |= UNIXFILE_WARNED;
+     return;
+   }
+-  if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
++  if( buf.st_nlink==0 ){
+     sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
+-    pFile->ctrlFlags |= UNIXFILE_WARNED;
+     return;
+   }
+   if( buf.st_nlink>1 ){
+     sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath);
+-    pFile->ctrlFlags |= UNIXFILE_WARNED;
+     return;
+   }
+   if( fileHasMoved(pFile) ){
+     sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath);
+-    pFile->ctrlFlags |= UNIXFILE_WARNED;
+     return;
+   }
+ }
+@@ -26839,6 +35768,7 @@
+   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
+ 
+   assert( pFile );
++  assert( pFile->eFileLock<=SHARED_LOCK );
+   unixEnterMutex(); /* Because pFile->pInode is shared across threads */
+ 
+   /* Check if a thread in this process holds such a lock */
+@@ -26895,9 +35825,7 @@
+   unixInodeInfo *pInode = pFile->pInode;
+   assert( unixMutexHeld() );
+   assert( pInode!=0 );
+-  if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock)
+-   && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0)
+-  ){
++  if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){
+     if( pInode->bProcessLock==0 ){
+       struct flock lock;
+       assert( pInode->nLock==0 );
+@@ -26947,7 +35875,7 @@
+   ** lock transitions in terms of the POSIX advisory shared and exclusive
+   ** lock primitives (called read-locks and write-locks below, to avoid
+   ** confusion with SQLite lock names). The algorithms are complicated
+-  ** slightly in order to be compatible with windows systems simultaneously
++  ** slightly in order to be compatible with Windows95 systems simultaneously
+   ** accessing the same database file, in case that is ever required.
+   **
+   ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
+@@ -26955,8 +35883,14 @@
+   ** range', a range of 510 bytes at a well known offset.
+   **
+   ** To obtain a SHARED lock, a read-lock is obtained on the 'pending
+-  ** byte'.  If this is successful, a random byte from the 'shared byte
+-  ** range' is read-locked and the lock on the 'pending byte' released.
++  ** byte'.  If this is successful, 'shared byte range' is read-locked
++  ** and the lock on the 'pending byte' released.  (Legacy note:  When
++  ** SQLite was first developed, Windows95 systems were still very common,
++  ** and Widnows95 lacks a shared-lock capability.  So on Windows95, a
++  ** single randomly selected by from the 'shared byte range' is locked.
++  ** Windows95 is now pretty much extinct, but this work-around for the
++  ** lack of shared-locks on Windows95 lives on, for backwards
++  ** compatibility.)
+   **
+   ** A process may only obtain a RESERVED lock after it has a SHARED lock.
+   ** A RESERVED lock is implemented by grabbing a write-lock on the
+@@ -26975,11 +35909,6 @@
+   ** range'. Since all other locks require a read-lock on one of the bytes
+   ** within this range, this ensures that no other locks are held on the
+   ** database. 
+-  **
+-  ** The reason a single byte cannot be used instead of the 'shared byte
+-  ** range' is that some versions of windows do not support read-locks. By
+-  ** locking a random byte from a range, concurrent SHARED locks may exist
+-  ** even if the locking primitive used is always a write-lock.
+   */
+   int rc = SQLITE_OK;
+   unixFile *pFile = (unixFile*)id;
+@@ -27249,9 +36178,7 @@
+         if( unixFileLock(pFile, &lock)==(-1) ){
+           tErrno = errno;
+           rc = SQLITE_IOERR_UNLOCK;
+-          if( IS_LOCK_ERROR(rc) ){
+-            storeLastErrno(pFile, tErrno);
+-          }
++          storeLastErrno(pFile, tErrno);
+           goto end_unlock;
+         }
+         lock.l_type = F_RDLCK;
+@@ -27273,9 +36200,7 @@
+         if( unixFileLock(pFile, &lock)==(-1) ){
+           tErrno = errno;
+           rc = SQLITE_IOERR_UNLOCK;
+-          if( IS_LOCK_ERROR(rc) ){
+-            storeLastErrno(pFile, tErrno);
+-          }
++          storeLastErrno(pFile, tErrno);
+           goto end_unlock;
+         }
+       }else
+@@ -27526,17 +36451,7 @@
+   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
+   
+   assert( pFile );
+-
+-  /* Check if a thread in this process holds such a lock */
+-  if( pFile->eFileLock>SHARED_LOCK ){
+-    /* Either this connection or some other connection in the same process
+-    ** holds a lock on the file.  No need to check further. */
+-    reserved = 1;
+-  }else{
+-    /* The lock is held if and only if the lockfile exists */
+-    const char *zLockFile = (const char*)pFile->lockingContext;
+-    reserved = osAccess(zLockFile, 0)==0;
+-  }
++  reserved = osAccess((const char*)pFile->lockingContext, 0)==0;
+   OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
+   *pResOut = reserved;
+   return rc;
+@@ -27598,7 +36513,7 @@
+       rc = SQLITE_BUSY;
+     } else {
+       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
+-      if( IS_LOCK_ERROR(rc) ){
++      if( rc!=SQLITE_BUSY ){
+         storeLastErrno(pFile, tErrno);
+       }
+     }
+@@ -27645,14 +36560,12 @@
+   /* To fully unlock the database, delete the lock file */
+   assert( eFileLock==NO_LOCK );
+   rc = osRmdir(zLockFile);
+-  if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile);
+   if( rc<0 ){
+     int tErrno = errno;
+-    rc = 0;
+-    if( ENOENT != tErrno ){
++    if( tErrno==ENOENT ){
++      rc = SQLITE_OK;
++    }else{
+       rc = SQLITE_IOERR_UNLOCK;
+-    }
+-    if( IS_LOCK_ERROR(rc) ){
+       storeLastErrno(pFile, tErrno);
+     }
+     return rc; 
+@@ -27665,14 +36578,11 @@
+ ** Close a file.  Make sure the lock has been released before closing.
+ */
+ static int dotlockClose(sqlite3_file *id) {
+-  int rc = SQLITE_OK;
+-  if( id ){
+-    unixFile *pFile = (unixFile*)id;
+-    dotlockUnlock(id, NO_LOCK);
+-    sqlite3_free(pFile->lockingContext);
+-    rc = closeUnixFile(id);
+-  }
+-  return rc;
++  unixFile *pFile = (unixFile*)id;
++  assert( id!=0 );
++  dotlockUnlock(id, NO_LOCK);
++  sqlite3_free(pFile->lockingContext);
++  return closeUnixFile(id);
+ }
+ /****************** End of the dot-file lock implementation *******************
+ ******************************************************************************/
+@@ -27738,10 +36648,8 @@
+         int tErrno = errno;
+         /* unlock failed with an error */
+         lrc = SQLITE_IOERR_UNLOCK; 
+-        if( IS_LOCK_ERROR(lrc) ){
+-          storeLastErrno(pFile, tErrno);
+-          rc = lrc;
+-        }
++        storeLastErrno(pFile, tErrno);
++        rc = lrc;
+       }
+     } else {
+       int tErrno = errno;
+@@ -27874,12 +36782,9 @@
+ ** Close a file.
+ */
+ static int flockClose(sqlite3_file *id) {
+-  int rc = SQLITE_OK;
+-  if( id ){
+-    flockUnlock(id, NO_LOCK);
+-    rc = closeUnixFile(id);
+-  }
+-  return rc;
++  assert( id!=0 );
++  flockUnlock(id, NO_LOCK);
++  return closeUnixFile(id);
+ }
+ 
+ #endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
+@@ -28504,23 +37409,22 @@
+ */
+ static int afpClose(sqlite3_file *id) {
+   int rc = SQLITE_OK;
+-  if( id ){
+-    unixFile *pFile = (unixFile*)id;
+-    afpUnlock(id, NO_LOCK);
+-    unixEnterMutex();
+-    if( pFile->pInode && pFile->pInode->nLock ){
+-      /* If there are outstanding locks, do not actually close the file just
+-      ** yet because that would clear those locks.  Instead, add the file
+-      ** descriptor to pInode->aPending.  It will be automatically closed when
+-      ** the last lock is cleared.
+-      */
+-      setPendingFd(pFile);
+-    }
+-    releaseInodeInfo(pFile);
+-    sqlite3_free(pFile->lockingContext);
+-    rc = closeUnixFile(id);
+-    unixLeaveMutex();
++  unixFile *pFile = (unixFile*)id;
++  assert( id!=0 );
++  afpUnlock(id, NO_LOCK);
++  unixEnterMutex();
++  if( pFile->pInode && pFile->pInode->nLock ){
++    /* If there are outstanding locks, do not actually close the file just
++    ** yet because that would clear those locks.  Instead, add the file
++    ** descriptor to pInode->aPending.  It will be automatically closed when
++    ** the last lock is cleared.
++    */
++    setPendingFd(pFile);
+   }
++  releaseInodeInfo(pFile);
++  sqlite3_free(pFile->lockingContext);
++  rc = closeUnixFile(id);
++  unixLeaveMutex();
+   return rc;
+ }
+ 
+@@ -28590,7 +37494,6 @@
+   TIMER_START;
+   assert( cnt==(cnt&0x1ffff) );
+   assert( id->h>2 );
+-  cnt &= 0x1ffff;
+   do{
+ #if defined(USE_PREAD)
+     got = osPread(id->h, pBuf, cnt, offset);
+@@ -28600,13 +37503,9 @@
+     SimulateIOError( got = -1 );
+ #else
+     newOffset = lseek(id->h, offset, SEEK_SET);
+-    SimulateIOError( newOffset-- );
+-    if( newOffset!=offset ){
+-      if( newOffset == -1 ){
+-        storeLastErrno((unixFile*)id, errno);
+-      }else{
+-        storeLastErrno((unixFile*)id, 0);
+-      }
++    SimulateIOError( newOffset = -1 );
++    if( newOffset<0 ){
++      storeLastErrno((unixFile*)id, errno);
+       return -1;
+     }
+     got = osRead(id->h, pBuf, cnt);
+@@ -28705,6 +37604,7 @@
+ 
+   assert( nBuf==(nBuf&0x1ffff) );
+   assert( fd>2 );
++  assert( piErrno!=0 );
+   nBuf &= 0x1ffff;
+   TIMER_START;
+ 
+@@ -28715,11 +37615,10 @@
+ #else
+   do{
+     i64 iSeek = lseek(fd, iOff, SEEK_SET);
+-    SimulateIOError( iSeek-- );
+-
+-    if( iSeek!=iOff ){
+-      if( piErrno ) *piErrno = (iSeek==-1 ? errno : 0);
+-      return -1;
++    SimulateIOError( iSeek = -1 );
++    if( iSeek<0 ){
++      rc = -1;
++      break;
+     }
+     rc = osWrite(fd, pBuf, nBuf);
+   }while( rc<0 && errno==EINTR );
+@@ -28728,7 +37627,7 @@
+   TIMER_END;
+   OSTRACE(("WRITE   %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED));
+ 
+-  if( rc<0 && piErrno ) *piErrno = errno;
++  if( rc<0 ) *piErrno = errno;
+   return rc;
+ }
+ 
+@@ -28791,7 +37690,7 @@
+   }
+ #endif
+ 
+-#if SQLITE_MAX_MMAP_SIZE>0
++#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0
+   /* Deal with as much of this write request as possible by transfering
+   ** data from the memory mapping using memcpy().  */
+   if( offset<pFile->mmapSize ){
+@@ -28807,8 +37706,8 @@
+     }
+   }
+ #endif
+-
+-  while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
++ 
++  while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))<amt && wrote>0 ){
+     amt -= wrote;
+     offset += wrote;
+     pBuf = &((char*)pBuf)[wrote];
+@@ -28816,7 +37715,7 @@
+   SimulateIOError(( wrote=(-1), amt=1 ));
+   SimulateDiskfullError(( wrote=0, amt=1 ));
+ 
+-  if( amt>0 ){
++  if( amt>wrote ){
+     if( wrote<0 && pFile->lastErrno!=ENOSPC ){
+       /* lastErrno set by seekAndWrite */
+       return SQLITE_IOERR_WRITE;
+@@ -28912,10 +37811,15 @@
+ #endif
+ 
+   /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
+-  ** no-op
++  ** no-op.  But go ahead and call fstat() to validate the file
++  ** descriptor as we need a method to provoke a failure during
++  ** coverate testing.
+   */
+ #ifdef SQLITE_NO_SYNC
+-  rc = SQLITE_OK;
++  {
++    struct stat buf;
++    rc = osFstat(fd, &buf);
++  }
+ #elif HAVE_FULLFSYNC
+   if( fullSync ){
+     rc = osFcntl(fd, F_FULLFSYNC, 0);
+@@ -28981,16 +37885,20 @@
+   char zDirname[MAX_PATHNAME+1];
+ 
+   sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
+-  for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
++  for(ii=(int)strlen(zDirname); ii>0 && zDirname[ii]!='/'; ii--);
+   if( ii>0 ){
+     zDirname[ii] = '\0';
+-    fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
+-    if( fd>=0 ){
+-      OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
+-    }
++  }else{
++    if( zDirname[0]!='/' ) zDirname[0] = '.';
++    zDirname[1] = 0;
++  }
++  fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
++  if( fd>=0 ){
++    OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
+   }
+   *pFd = fd;
+-  return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname));
++  if( fd>=0 ) return SQLITE_OK;
++  return unixLogError(SQLITE_CANTOPEN_BKPT, "openDirectory", zDirname);
+ }
+ 
+ /*
+@@ -29043,10 +37951,11 @@
+     OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath,
+             HAVE_FULLFSYNC, isFullsync));
+     rc = osOpenDirectory(pFile->zPath, &dirfd);
+-    if( rc==SQLITE_OK && dirfd>=0 ){
++    if( rc==SQLITE_OK ){
+       full_fsync(dirfd, 0, 0);
+       robust_close(pFile, dirfd, __LINE__);
+-    }else if( rc==SQLITE_CANTOPEN ){
++    }else{
++      assert( rc==SQLITE_CANTOPEN );
+       rc = SQLITE_OK;
+     }
+     pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
+@@ -29178,18 +38087,14 @@
+       int nWrite = 0;             /* Number of bytes written by seekAndWrite */
+       i64 iWrite;                 /* Next offset to write to */
+ 
+-      iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
++      iWrite = (buf.st_size/nBlk)*nBlk + nBlk - 1;
+       assert( iWrite>=buf.st_size );
+-      assert( (iWrite/nBlk)==((buf.st_size+nBlk-1)/nBlk) );
+       assert( ((iWrite+1)%nBlk)==0 );
+-      for(/*no-op*/; iWrite<nSize; iWrite+=nBlk ){
++      for(/*no-op*/; iWrite<nSize+nBlk-1; iWrite+=nBlk ){
++        if( iWrite>=nSize ) iWrite = nSize - 1;
+         nWrite = seekAndWrite(pFile, iWrite, "", 1);
+         if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
+       }
+-      if( nWrite==0 || (nSize%nBlk) ){
+-        nWrite = seekAndWrite(pFile, nSize-1, "", 1);
+-        if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
+-      }
+ #endif
+     }
+   }
+@@ -29237,10 +38142,6 @@
+ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
+   unixFile *pFile = (unixFile*)id;
+   switch( op ){
+-    case SQLITE_FCNTL_WAL_BLOCK: {
+-      /* pFile->ctrlFlags |= UNIXFILE_BLOCK; // Deferred feature */
+-      return SQLITE_OK;
+-    }
+     case SQLITE_FCNTL_LOCKSTATE: {
+       *(int*)pArg = pFile->eFileLock;
+       return SQLITE_OK;
+@@ -29567,10 +38468,9 @@
+   assert( n==1 || lockType!=F_RDLCK );
+ 
+   /* Locks are within range */
+-  assert( n>=1 && n<SQLITE_SHM_NLOCK );
++  assert( n>=1 && n<=SQLITE_SHM_NLOCK );
+ 
+   if( pShmNode->h>=0 ){
+-    int lkType;
+     /* Initialize the locking parameters */
+     memset(&f, 0, sizeof(f));
+     f.l_type = lockType;
+@@ -29578,10 +38478,8 @@
+     f.l_start = ofst;
+     f.l_len = n;
+ 
+-    lkType = (pFile->ctrlFlags & UNIXFILE_BLOCK)!=0 ? F_SETLKW : F_SETLK;
+-    rc = osFcntl(pShmNode->h, lkType, &f);
++    rc = osFcntl(pShmNode->h, F_SETLK, &f);
+     rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
+-    pFile->ctrlFlags &= ~UNIXFILE_BLOCK;
+   }
+ 
+   /* Update the global lock state and do debug tracing */
+@@ -29648,7 +38546,7 @@
+ static void unixShmPurge(unixFile *pFd){
+   unixShmNode *p = pFd->pInode->pShmNode;
+   assert( unixMutexHeld() );
+-  if( p && p->nRef==0 ){
++  if( p && ALWAYS(p->nRef==0) ){
+     int nShmPerMap = unixShmRegionPerMap();
+     int i;
+     assert( p->pInode==pFd->pInode );
+@@ -29715,7 +38613,7 @@
+ 
+   /* Allocate space for the new unixShm object. */
+   p = sqlite3_malloc64( sizeof(*p) );
+-  if( p==0 ) return SQLITE_NOMEM;
++  if( p==0 ) return SQLITE_NOMEM_BKPT;
+   memset(p, 0, sizeof(*p));
+   assert( pDbFd->pShm==0 );
+ 
+@@ -29735,7 +38633,7 @@
+     ** a new *-shm file is created, an attempt will be made to create it
+     ** with the same permissions.
+     */
+-    if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){
++    if( osFstat(pDbFd->h, &sStat) ){
+       rc = SQLITE_IOERR_FSTAT;
+       goto shm_open_err;
+     }
+@@ -29747,7 +38645,7 @@
+ #endif
+     pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
+     if( pShmNode==0 ){
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+       goto shm_open_err;
+     }
+     memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
+@@ -29763,10 +38661,12 @@
+     pShmNode->h = -1;
+     pDbFd->pInode->pShmNode = pShmNode;
+     pShmNode->pInode = pDbFd->pInode;
+-    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+-    if( pShmNode->mutex==0 ){
+-      rc = SQLITE_NOMEM;
+-      goto shm_open_err;
++    if( sqlite3GlobalConfig.bCoreMutex ){
++      pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
++      if( pShmNode->mutex==0 ){
++        rc = SQLITE_NOMEM_BKPT;
++        goto shm_open_err;
++      }
+     }
+ 
+     if( pInode->bProcessLock==0 ){
+@@ -29785,7 +38685,7 @@
+       ** is owned by the same user that owns the original database.  Otherwise,
+       ** the original owner will not be able to connect.
+       */
+-      osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
++      robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
+   
+       /* Check to see if another process is holding the dead-man switch.
+       ** If not, truncate the file to zero length. 
+@@ -29922,7 +38822,8 @@
+           /* Write to the last byte of each newly allocated or extended page */
+           assert( (nByte % pgsz)==0 );
+           for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
+-            if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, 0)!=1 ){
++            int x = 0;
++            if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
+               const char *zFile = pShmNode->zFilename;
+               rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
+               goto shmpage_out;
+@@ -29937,7 +38838,7 @@
+         pShmNode->apRegion, nReqRegion*sizeof(char *)
+     );
+     if( !apNew ){
+-      rc = SQLITE_IOERR_NOMEM;
++      rc = SQLITE_IOERR_NOMEM_BKPT;
+       goto shmpage_out;
+     }
+     pShmNode->apRegion = apNew;
+@@ -29957,7 +38858,7 @@
+       }else{
+         pMem = sqlite3_malloc64(szRegion);
+         if( pMem==0 ){
+-          rc = SQLITE_NOMEM;
++          rc = SQLITE_NOMEM_BKPT;
+           goto shmpage_out;
+         }
+         memset(pMem, 0, szRegion);
+@@ -30105,7 +39006,8 @@
+   sqlite3_file *fd                /* Database file holding the shared memory */
+ ){
+   UNUSED_PARAMETER(fd);
+-  unixEnterMutex();
++  sqlite3MemoryBarrier();         /* compiler-defined memory barrier */
++  unixEnterMutex();               /* Also mutex, for redundancy */
+   unixLeaveMutex();
+ }
+ 
+@@ -30215,7 +39117,9 @@
+   assert( pFd->mmapSizeActual>=pFd->mmapSize );
+   assert( MAP_FAILED!=0 );
+ 
++#ifdef SQLITE_MMAP_READWRITE
+   if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
++#endif
+ 
+   if( pOrig ){
+ #if HAVE_MREMAP
+@@ -30287,17 +39191,14 @@
+ ** recreated as a result of outstanding references) or an SQLite error
+ ** code otherwise.
+ */
+-static int unixMapfile(unixFile *pFd, i64 nByte){
+-  i64 nMap = nByte;
+-  int rc;
+-
++static int unixMapfile(unixFile *pFd, i64 nMap){
+   assert( nMap>=0 || pFd->nFetchOut==0 );
++  assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
+   if( pFd->nFetchOut>0 ) return SQLITE_OK;
+ 
+   if( nMap<0 ){
+     struct stat statbuf;          /* Low-level file information */
+-    rc = osFstat(pFd->h, &statbuf);
+-    if( rc!=SQLITE_OK ){
++    if( osFstat(pFd->h, &statbuf) ){
+       return SQLITE_IOERR_FSTAT;
+     }
+     nMap = statbuf.st_size;
+@@ -30306,12 +39207,9 @@
+     nMap = pFd->mmapSizeMax;
+   }
+ 
++  assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
+   if( nMap!=pFd->mmapSize ){
+-    if( nMap>0 ){
+-      unixRemapfile(pFd, nMap);
+-    }else{
+-      unixUnmapfile(pFd);
+-    }
++    unixRemapfile(pFd, nMap);
+   }
+ 
+   return SQLITE_OK;
+@@ -30738,7 +39636,7 @@
+   pNew->pId = vxworksFindFileId(zFilename);
+   if( pNew->pId==0 ){
+     ctrlFlags |= UNIXFILE_NOLOCK;
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+   }
+ #endif
+ 
+@@ -30794,7 +39692,7 @@
+     afpLockingContext *pCtx;
+     pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
+     if( pCtx==0 ){
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+     }else{
+       /* NB: zFilename exists and remains valid until the file is closed
+       ** according to requirement F11141.  So we do not need to make a
+@@ -30824,7 +39722,7 @@
+     nFilename = (int)strlen(zFilename) + 6;
+     zLockFile = (char *)sqlite3_malloc64(nFilename);
+     if( zLockFile==0 ){
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+     }else{
+       sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
+     }
+@@ -30847,7 +39745,7 @@
+         if( zSemName[n]=='/' ) zSemName[n] = '_';
+       pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
+       if( pNew->pInode->pSem == SEM_FAILED ){
+-        rc = SQLITE_NOMEM;
++        rc = SQLITE_NOMEM_BKPT;
+         pNew->pInode->aSemName[0] = '\0';
+       }
+     }
+@@ -30882,27 +39780,29 @@
+   static const char *azDirs[] = {
+      0,
+      0,
+-     0,
+      "/var/tmp",
+      "/usr/tmp",
+      "/tmp",
+-     0        /* List terminator */
++     "."
+   };
+-  unsigned int i;
++  unsigned int i = 0;
+   struct stat buf;
+-  const char *zDir = 0;
++  const char *zDir = sqlite3_temp_directory;
+ 
+-  azDirs[0] = sqlite3_temp_directory;
+-  if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR");
+-  if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR");
+-  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
+-    if( zDir==0 ) continue;
+-    if( osStat(zDir, &buf) ) continue;
+-    if( !S_ISDIR(buf.st_mode) ) continue;
+-    if( osAccess(zDir, 07) ) continue;
+-    break;
++  if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
++  if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
++  while(1){
++    if( zDir!=0
++     && osStat(zDir, &buf)==0
++     && S_ISDIR(buf.st_mode)
++     && osAccess(zDir, 03)==0
++    ){
++      return zDir;
++    }
++    if( i>=sizeof(azDirs)/sizeof(azDirs[0]) ) break;
++    zDir = azDirs[i++];
+   }
+-  return zDir;
++  return 0;
+ }
+ 
+ /*
+@@ -30911,38 +39811,26 @@
+ ** pVfs->mxPathname bytes.
+ */
+ static int unixGetTempname(int nBuf, char *zBuf){
+-  static const unsigned char zChars[] =
+-    "abcdefghijklmnopqrstuvwxyz"
+-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+-    "0123456789";
+-  unsigned int i, j;
+   const char *zDir;
++  int iLimit = 0;
+ 
+   /* 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. 
+   */
++  zBuf[0] = 0;
+   SimulateIOError( return SQLITE_IOERR );
+ 
+   zDir = unixTempFileDir();
+-  if( zDir==0 ) zDir = ".";
+-
+-  /* Check that the output buffer is large enough for the temporary file 
+-  ** name. If it is not, return SQLITE_ERROR.
+-  */
+-  if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 18) >= (size_t)nBuf ){
+-    return SQLITE_ERROR;
+-  }
+-
++  if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH;
+   do{
+-    sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
+-    j = (int)strlen(zBuf);
+-    sqlite3_randomness(15, &zBuf[j]);
+-    for(i=0; i<15; i++, j++){
+-      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+-    }
+-    zBuf[j] = 0;
+-    zBuf[j+1] = 0;
++    u64 r;
++    sqlite3_randomness(sizeof(r), &r);
++    assert( nBuf>2 );
++    zBuf[nBuf-2] = 0;
++    sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c",
++                     zDir, r, 0);
++    if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR;
+   }while( osAccess(zBuf,0)==0 );
+   return SQLITE_OK;
+ }
+@@ -30997,7 +39885,7 @@
+     unixEnterMutex();
+     pInode = inodeList;
+     while( pInode && (pInode->fileId.dev!=sStat.st_dev
+-                     || pInode->fileId.ino!=sStat.st_ino) ){
++                     || pInode->fileId.ino!=(u64)sStat.st_ino) ){
+        pInode = pInode->pNext;
+     }
+     if( pInode ){
+@@ -31015,6 +39903,27 @@
+ }
+ 
+ /*
++** Find the mode, uid and gid of file zFile. 
++*/
++static int getFileMode(
++  const char *zFile,              /* File name */
++  mode_t *pMode,                  /* OUT: Permissions of zFile */
++  uid_t *pUid,                    /* OUT: uid of zFile. */
++  gid_t *pGid                     /* OUT: gid of zFile. */
++){
++  struct stat sStat;              /* Output of stat() on database file */
++  int rc = SQLITE_OK;
++  if( 0==osStat(zFile, &sStat) ){
++    *pMode = sStat.st_mode & 0777;
++    *pUid = sStat.st_uid;
++    *pGid = sStat.st_gid;
++  }else{
++    rc = SQLITE_IOERR_FSTAT;
++  }
++  return rc;
++}
++
++/*
+ ** This function is called by unixOpen() to determine the unix permissions
+ ** to create new files with. If no error occurs, then SQLITE_OK is returned
+ ** and a value suitable for passing as the third argument to open(2) is
+@@ -31049,7 +39958,6 @@
+   if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
+     char zDb[MAX_PATHNAME+1];     /* Database file path */
+     int nDb;                      /* Number of valid bytes in zDb */
+-    struct stat sStat;            /* Output of stat() on database file */
+ 
+     /* zPath is a path to a WAL or journal file. The following block derives
+     ** the path to the associated database file from zPath. This block handles
+@@ -31064,28 +39972,34 @@
+     ** used by the test_multiplex.c module.
+     */
+     nDb = sqlite3Strlen30(zPath) - 1; 
+-#ifdef SQLITE_ENABLE_8_3_NAMES
+-    while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--;
+-    if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK;
+-#else
+     while( zPath[nDb]!='-' ){
++#ifndef SQLITE_ENABLE_8_3_NAMES
++      /* In the normal case (8+3 filenames disabled) the journal filename
++      ** is guaranteed to contain a '-' character. */
+       assert( nDb>0 );
+-      assert( zPath[nDb]!='\n' );
++      assert( sqlite3Isalnum(zPath[nDb]) );
++#else
++      /* If 8+3 names are possible, then the journal file might not contain
++      ** a '-' character.  So check for that case and return early. */
++      if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
++#endif
+       nDb--;
+     }
+-#endif
+     memcpy(zDb, zPath, nDb);
+     zDb[nDb] = '\0';
+ 
+-    if( 0==osStat(zDb, &sStat) ){
+-      *pMode = sStat.st_mode & 0777;
+-      *pUid = sStat.st_uid;
+-      *pGid = sStat.st_gid;
+-    }else{
+-      rc = SQLITE_IOERR_FSTAT;
+-    }
++    rc = getFileMode(zDb, pMode, pUid, pGid);
+   }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
+     *pMode = 0600;
++  }else if( flags & SQLITE_OPEN_URI ){
++    /* If this is a main database file and the file was opened using a URI
++    ** filename, check for the "modeof" parameter. If present, interpret
++    ** its value as a filename and try to copy the mode, uid and gid from
++    ** that file.  */
++    const char *z = sqlite3_uri_parameter(zPath, "modeof");
++    if( z ){
++      rc = getFileMode(z, pMode, pUid, pGid);
++    }
+   }
+   return rc;
+ }
+@@ -31201,7 +40115,7 @@
+     }else{
+       pUnused = sqlite3_malloc64(sizeof(*pUnused));
+       if( !pUnused ){
+-        return SQLITE_NOMEM;
++        return SQLITE_NOMEM_BKPT;
+       }
+     }
+     p->pUnused = pUnused;
+@@ -31214,7 +40128,7 @@
+   }else if( !zName ){
+     /* If zName is NULL, the upper layer is requesting a temp file. */
+     assert(isDelete && !syncDir);
+-    rc = unixGetTempname(MAX_PATHNAME+2, zTmpname);
++    rc = unixGetTempname(pVfs->mxPathname, zTmpname);
+     if( rc!=SQLITE_OK ){
+       return rc;
+     }
+@@ -31247,7 +40161,8 @@
+     }
+     fd = robust_open(zName, openFlags, openMode);
+     OSTRACE(("OPENX   %-3d %s 0%o\n", fd, zName, openFlags));
+-    if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
++    assert( !isExclusive || (openFlags & O_CREAT)!=0 );
++    if( fd<0 && errno!=EISDIR && isReadWrite ){
+       /* Failed to open the file for read/write access. Try read-only. */
+       flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
+       openFlags &= ~(O_RDWR|O_CREAT);
+@@ -31266,7 +40181,7 @@
+     ** the same as the original database.
+     */
+     if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
+-      osFchown(fd, uid, gid);
++      robustFchown(fd, uid, gid);
+     }
+   }
+   assert( fd>=0 );
+@@ -31286,7 +40201,7 @@
+     zPath = sqlite3_mprintf("%s", zName);
+     if( zPath==0 ){
+       robust_close(p, fd, __LINE__);
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+ #else
+     osUnlink(zName);
+@@ -31297,9 +40212,6 @@
+     p->openFlags = openFlags;
+   }
+ #endif
+-
+-  noLock = eType!=SQLITE_OPEN_MAIN_DB;
+-
+   
+ #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
+   if( fstatfs(fd, &fsInfo) == -1 ){
+@@ -31318,6 +40230,7 @@
+   /* Set up appropriate ctrlFlags */
+   if( isDelete )                ctrlFlags |= UNIXFILE_DELETE;
+   if( isReadonly )              ctrlFlags |= UNIXFILE_RDONLY;
++  noLock = eType!=SQLITE_OPEN_MAIN_DB;
+   if( noLock )                  ctrlFlags |= UNIXFILE_NOLOCK;
+   if( syncDir )                 ctrlFlags |= UNIXFILE_DIRSYNC;
+   if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI;
+@@ -31394,16 +40307,12 @@
+     int fd;
+     rc = osOpenDirectory(zPath, &fd);
+     if( rc==SQLITE_OK ){
+-#if OS_VXWORKS
+-      if( fsync(fd)==-1 )
+-#else
+-      if( fsync(fd) )
+-#endif
+-      {
++      if( full_fsync(fd,0,0) ){
+         rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath);
+       }
+       robust_close(0, fd, __LINE__);
+-    }else if( rc==SQLITE_CANTOPEN ){
++    }else{
++      assert( rc==SQLITE_CANTOPEN );
+       rc = SQLITE_OK;
+     }
+   }
+@@ -31427,33 +40336,49 @@
+   int flags,              /* What do we want to learn about the zPath file? */
+   int *pResOut            /* Write result boolean here */
+ ){
+-  int amode = 0;
+   UNUSED_PARAMETER(NotUsed);
+   SimulateIOError( return SQLITE_IOERR_ACCESS; );
+-  switch( flags ){
+-    case SQLITE_ACCESS_EXISTS:
+-      amode = F_OK;
+-      break;
+-    case SQLITE_ACCESS_READWRITE:
+-      amode = W_OK|R_OK;
+-      break;
+-    case SQLITE_ACCESS_READ:
+-      amode = R_OK;
+-      break;
++  assert( pResOut!=0 );
+ 
+-    default:
+-      assert(!"Invalid flags argument");
+-  }
+-  *pResOut = (osAccess(zPath, amode)==0);
+-  if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
++  /* The spec says there are three possible values for flags.  But only
++  ** two of them are actually used */
++  assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE );
++
++  if( flags==SQLITE_ACCESS_EXISTS ){
+     struct stat buf;
+-    if( 0==osStat(zPath, &buf) && buf.st_size==0 ){
+-      *pResOut = 0;
+-    }
++    *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0);
++  }else{
++    *pResOut = osAccess(zPath, W_OK|R_OK)==0;
+   }
+   return SQLITE_OK;
+ }
+ 
++/*
++**
++*/
++static int mkFullPathname(
++  const char *zPath,              /* Input path */
++  char *zOut,                     /* Output buffer */
++  int nOut                        /* Allocated size of buffer zOut */
++){
++  int nPath = sqlite3Strlen30(zPath);
++  int iOff = 0;
++  if( zPath[0]!='/' ){
++    if( osGetcwd(zOut, nOut-2)==0 ){
++      return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
++    }
++    iOff = sqlite3Strlen30(zOut);
++    zOut[iOff++] = '/';
++  }
++  if( (iOff+nPath+1)>nOut ){
++    /* SQLite assumes that xFullPathname() nul-terminates the output buffer
++    ** even if it returns an error.  */
++    zOut[iOff] = '\0';
++    return SQLITE_CANTOPEN_BKPT;
++  }
++  sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath);
++  return SQLITE_OK;
++}
+ 
+ /*
+ ** Turn a relative pathname into a full pathname. The relative path
+@@ -31470,6 +40395,17 @@
+   int nOut,                     /* Size of output buffer in bytes */
+   char *zOut                    /* Output buffer */
+ ){
++#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT)
++  return mkFullPathname(zPath, zOut, nOut);
++#else
++  int rc = SQLITE_OK;
++  int nByte;
++  int nLink = 1;                /* Number of symbolic links followed so far */
++  const char *zIn = zPath;      /* Input path for each iteration of loop */
++  char *zDel = 0;
++
++  assert( pVfs->mxPathname==MAX_PATHNAME );
++  UNUSED_PARAMETER(pVfs);
+ 
+   /* 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
+@@ -31478,21 +40414,62 @@
+   */
+   SimulateIOError( return SQLITE_ERROR );
+ 
+-  assert( pVfs->mxPathname==MAX_PATHNAME );
+-  UNUSED_PARAMETER(pVfs);
++  do {
+ 
+-  zOut[nOut-1] = '\0';
+-  if( zPath[0]=='/' ){
+-    sqlite3_snprintf(nOut, zOut, "%s", zPath);
+-  }else{
+-    int nCwd;
+-    if( osGetcwd(zOut, nOut-1)==0 ){
+-      return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
++    /* Call stat() on path zIn. Set bLink to true if the path is a symbolic
++    ** link, or false otherwise.  */
++    int bLink = 0;
++    struct stat buf;
++    if( osLstat(zIn, &buf)!=0 ){
++      if( errno!=ENOENT ){
++        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
++      }
++    }else{
++      bLink = S_ISLNK(buf.st_mode);
+     }
+-    nCwd = (int)strlen(zOut);
+-    sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
+-  }
+-  return SQLITE_OK;
++
++    if( bLink ){
++      if( zDel==0 ){
++        zDel = sqlite3_malloc(nOut);
++        if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
++      }else if( ++nLink>SQLITE_MAX_SYMLINKS ){
++        rc = SQLITE_CANTOPEN_BKPT;
++      }
++
++      if( rc==SQLITE_OK ){
++        nByte = osReadlink(zIn, zDel, nOut-1);
++        if( nByte<0 ){
++          rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
++        }else{
++          if( zDel[0]!='/' ){
++            int n;
++            for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
++            if( nByte+n+1>nOut ){
++              rc = SQLITE_CANTOPEN_BKPT;
++            }else{
++              memmove(&zDel[n], zDel, nByte+1);
++              memcpy(zDel, zIn, n);
++              nByte += n;
++            }
++          }
++          zDel[nByte] = '\0';
++        }
++      }
++
++      zIn = zDel;
++    }
++
++    assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' );
++    if( rc==SQLITE_OK && zIn!=zOut ){
++      rc = mkFullPathname(zIn, zOut, nOut);
++    }
++    if( bLink==0 ) break;
++    zIn = zOut;
++  }while( rc==SQLITE_OK );
++
++  sqlite3_free(zDel);
++  return rc;
++#endif   /* HAVE_READLINK && HAVE_LSTAT */
+ }
+ 
+ 
+@@ -31661,11 +40638,8 @@
+   *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
+ #else
+   struct timeval sNow;
+-  if( gettimeofday(&sNow, 0)==0 ){
+-    *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
+-  }else{
+-    rc = SQLITE_ERROR;
+-  }
++  (void)gettimeofday(&sNow, 0);  /* Cannot fail given valid arguments */
++  *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
+ #endif
+ 
+ #ifdef SQLITE_TEST
+@@ -31677,6 +40651,7 @@
+   return rc;
+ }
+ 
++#ifndef SQLITE_OMIT_DEPRECATED
+ /*
+ ** Find the current time (in Universal Coordinated Time).  Write the
+ ** current time and date as a Julian Day number into *prNow and
+@@ -31690,19 +40665,21 @@
+   *prNow = i/86400000.0;
+   return rc;
+ }
++#else
++# define unixCurrentTime 0
++#endif
+ 
+ /*
+-** We added the xGetLastError() method with the intention of providing
+-** better low-level error messages when operating-system problems come up
+-** during SQLite operation.  But so far, none of that has been implemented
+-** in the core.  So this routine is never called.  For now, it is merely
+-** a place-holder.
++** The xGetLastError() method is designed to return a better
++** low-level error message when operating-system problems come up
++** during SQLite operation.  Only the integer return code is currently
++** used.
+ */
+ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
+   UNUSED_PARAMETER(NotUsed);
+   UNUSED_PARAMETER(NotUsed2);
+   UNUSED_PARAMETER(NotUsed3);
+-  return 0;
++  return errno;
+ }
+ 
+ 
+@@ -31957,7 +40934,7 @@
+     }
+     buf[i] = lockPath[i];
+   }
+-  OSTRACE(("CREATELOCKPATH  proxy lock path=%s pid=%d\n", lockPath, osGetpid(0)));
++  OSTRACE(("CREATELOCKPATH  proxy lock path=%s pid=%d\n",lockPath,osGetpid(0)));
+   return 0;
+ }
+ 
+@@ -31993,7 +40970,7 @@
+   }else{
+     pUnused = sqlite3_malloc64(sizeof(*pUnused));
+     if( !pUnused ){
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+   }
+   if( fd<0 ){
+@@ -32026,7 +41003,7 @@
+   
+   pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
+   if( pNew==NULL ){
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+     goto end_create_proxy;
+   }
+   memset(pNew, 0, sizeof(unixFile));
+@@ -32369,7 +41346,7 @@
+         writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]);
+         robust_ftruncate(conchFile->h, writeSize);
+         rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0);
+-        fsync(conchFile->h);
++        full_fsync(conchFile->h,0,0);
+         /* If we created a new conch file (not just updated the contents of a 
+          ** valid conch file), try to match the permissions of the database 
+          */
+@@ -32439,7 +41416,7 @@
+         if( tempLockPath ){
+           pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath);
+           if( !pCtx->lockProxyPath ){
+-            rc = SQLITE_NOMEM;
++            rc = SQLITE_NOMEM_BKPT;
+           }
+         }
+       }
+@@ -32504,7 +41481,7 @@
+   ** the name of the original database file. */  
+   *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
+   if( conchPath==0 ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   memcpy(conchPath, dbPath, len+1);
+   
+@@ -32620,7 +41597,7 @@
+ 
+   pCtx = sqlite3_malloc64( sizeof(*pCtx) );
+   if( pCtx==0 ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   memset(pCtx, 0, sizeof(*pCtx));
+ 
+@@ -32656,7 +41633,7 @@
+   if( rc==SQLITE_OK ){
+     pCtx->dbPath = sqlite3DbStrDup(0, dbPath);
+     if( pCtx->dbPath==NULL ){
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+     }
+   }
+   if( rc==SQLITE_OK ){
+@@ -32842,7 +41819,7 @@
+ ** Close a file that uses proxy locks.
+ */
+ static int proxyClose(sqlite3_file *id) {
+-  if( id ){
++  if( ALWAYS(id) ){
+     unixFile *pFile = (unixFile*)id;
+     proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
+     unixFile *lockProxy = pCtx->lockProxy;
+@@ -32903,7 +41880,7 @@
+ ** necessarily been initialized when this routine is called, and so they
+ ** should not be used.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){ 
++SQLITE_API int sqlite3_os_init(void){ 
+   /* 
+   ** The following macro defines an initializer for an sqlite3_vfs object.
+   ** The name of the VFS is NAME.  The pAppData is a pointer to a pointer
+@@ -32986,7 +41963,7 @@
+ 
+   /* Double-check that the aSyscall[] array has been constructed
+   ** correctly.  See ticket [bb3a86e890c8e96ab] */
+-  assert( ArraySize(aSyscall)==25 );
++  assert( ArraySize(aSyscall)==28 );
+ 
+   /* Register all VFSes defined in the aVfs[] array */
+   for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
+@@ -33002,7 +41979,7 @@
+ ** to release dynamically allocated objects.  But not on unix.
+ ** This routine is a no-op for unix.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){ 
++SQLITE_API int sqlite3_os_end(void){ 
+   return SQLITE_OK; 
+ }
+  
+@@ -33024,6 +42001,7 @@
+ **
+ ** This file contains code that is specific to Windows.
+ */
++/* #include "sqliteInt.h" */
+ #if SQLITE_OS_WIN               /* This file is used for Windows only */
+ 
+ /*
+@@ -33068,8 +42046,8 @@
+ */
+ #ifdef SQLITE_PERFORMANCE_TRACE
+ 
+-/* 
+-** hwtime.h contains inline assembler code for implementing 
++/*
++** hwtime.h contains inline assembler code for implementing
+ ** high-performance timing routines.
+ */
+ /************** Include hwtime.h in the middle of os_common.h ****************/
+@@ -33089,8 +42067,8 @@
+ ** This file contains inline asm code for retrieving "high-performance"
+ ** counters for x86 class CPUs.
+ */
+-#ifndef _HWTIME_H_
+-#define _HWTIME_H_
++#ifndef SQLITE_HWTIME_H
++#define SQLITE_HWTIME_H
+ 
+ /*
+ ** The following routine only works on pentium-class (or newer) processors.
+@@ -33158,7 +42136,7 @@
+ 
+ #endif
+ 
+-#endif /* !defined(_HWTIME_H_) */
++#endif /* !defined(SQLITE_HWTIME_H) */
+ 
+ /************** End of hwtime.h **********************************************/
+ /************** Continuing where we left off in os_common.h ******************/
+@@ -33179,14 +42157,14 @@
+ ** 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;
++#if defined(SQLITE_TEST)
++SQLITE_API extern int sqlite3_io_error_hit;
++SQLITE_API extern int sqlite3_io_error_hardhit;
++SQLITE_API extern int sqlite3_io_error_pending;
++SQLITE_API extern int sqlite3_io_error_persist;
++SQLITE_API extern int sqlite3_io_error_benign;
++SQLITE_API extern int sqlite3_diskfull_pending;
++SQLITE_API extern int sqlite3_diskfull;
+ #define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
+ #define SimulateIOError(CODE)  \
+   if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
+@@ -33212,17 +42190,17 @@
+ #define SimulateIOErrorBenign(X)
+ #define SimulateIOError(A)
+ #define SimulateDiskfullError(A)
+-#endif
++#endif /* defined(SQLITE_TEST) */
+ 
+ /*
+ ** When testing, keep a count of the number of open files.
+ */
+-#ifdef SQLITE_TEST
+-SQLITE_API int sqlite3_open_file_count = 0;
++#if defined(SQLITE_TEST)
++SQLITE_API extern int sqlite3_open_file_count;
+ #define OpenCounter(X)  sqlite3_open_file_count+=(X)
+ #else
+ #define OpenCounter(X)
+-#endif
++#endif /* defined(SQLITE_TEST) */
+ 
+ #endif /* !defined(_OS_COMMON_H_) */
+ 
+@@ -33232,6 +42210,7 @@
+ /*
+ ** Include the header file for the Windows VFS.
+ */
++/* #include "os_win.h" */
+ 
+ /*
+ ** Compiling and using WAL mode requires several APIs that are only
+@@ -33284,6 +42263,10 @@
+ #  define NTDDI_WINBLUE                     0x06030000
+ #endif
+ 
++#ifndef NTDDI_WINTHRESHOLD
++#  define NTDDI_WINTHRESHOLD                0x06040000
++#endif
++
+ /*
+ ** Check to see if the GetVersionEx[AW] functions are deprecated on the
+ ** target system.  GetVersionEx was first deprecated in Win8.1.
+@@ -33297,6 +42280,19 @@
+ #endif
+ 
+ /*
++** Check to see if the CreateFileMappingA function is supported on the
++** target system.  It is unavailable when using "mincore.lib" on Win10.
++** When compiling for Windows 10, always assume "mincore.lib" is in use.
++*/
++#ifndef SQLITE_WIN32_CREATEFILEMAPPINGA
++#  if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINTHRESHOLD
++#    define SQLITE_WIN32_CREATEFILEMAPPINGA   0
++#  else
++#    define SQLITE_WIN32_CREATEFILEMAPPINGA   1
++#  endif
++#endif
++
++/*
+ ** This constant should already be defined (in the "WinDef.h" SDK file).
+ */
+ #ifndef MAX_PATH
+@@ -33482,6 +42478,17 @@
+ };
+ 
+ /*
++** The winVfsAppData structure is used for the pAppData member for all of the
++** Win32 VFS variants.
++*/
++typedef struct winVfsAppData winVfsAppData;
++struct winVfsAppData {
++  const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */
++  void *pAppData;                    /* The extra pAppData, if any. */
++  BOOL bNoLock;                      /* Non-zero if locking is disabled. */
++};
++
++/*
+ ** Allowed values for winFile.ctrlFlags
+ */
+ #define WINFILE_RDONLY          0x02   /* Connection is read only */
+@@ -33532,22 +42539,72 @@
+  ******************************************************************************
+  */
+ #ifndef SQLITE_WIN32_HEAP_CREATE
+-#  define SQLITE_WIN32_HEAP_CREATE    (TRUE)
++#  define SQLITE_WIN32_HEAP_CREATE        (TRUE)
++#endif
++
++/*
++ * This is the maximum possible initial size of the Win32-specific heap, in
++ * bytes.
++ */
++#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE
++#  define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U)
++#endif
++
++/*
++ * This is the extra space for the initial size of the Win32-specific heap,
++ * in bytes.  This value may be zero.
++ */
++#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA
++#  define SQLITE_WIN32_HEAP_INIT_EXTRA  (4194304)
++#endif
++
++/*
++ * Calculate the maximum legal cache size, in pages, based on the maximum
++ * possible initial heap size and the default page size, setting aside the
++ * needed extra space.
++ */
++#ifndef SQLITE_WIN32_MAX_CACHE_SIZE
++#  define SQLITE_WIN32_MAX_CACHE_SIZE   (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \
++                                          (SQLITE_WIN32_HEAP_INIT_EXTRA)) / \
++                                         (SQLITE_DEFAULT_PAGE_SIZE))
++#endif
++
++/*
++ * This is cache size used in the calculation of the initial size of the
++ * Win32-specific heap.  It cannot be negative.
++ */
++#ifndef SQLITE_WIN32_CACHE_SIZE
++#  if SQLITE_DEFAULT_CACHE_SIZE>=0
++#    define SQLITE_WIN32_CACHE_SIZE     (SQLITE_DEFAULT_CACHE_SIZE)
++#  else
++#    define SQLITE_WIN32_CACHE_SIZE     (-(SQLITE_DEFAULT_CACHE_SIZE))
++#  endif
++#endif
++
++/*
++ * Make sure that the calculated cache size, in pages, cannot cause the
++ * initial size of the Win32-specific heap to exceed the maximum amount
++ * of memory that can be specified in the call to HeapCreate.
++ */
++#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE
++#  undef SQLITE_WIN32_CACHE_SIZE
++#  define SQLITE_WIN32_CACHE_SIZE       (2000)
+ #endif
+ 
+ /*
+  * The initial size of the Win32-specific heap.  This value may be zero.
+  */
+ #ifndef SQLITE_WIN32_HEAP_INIT_SIZE
+-#  define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \
+-                                       (SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
++#  define SQLITE_WIN32_HEAP_INIT_SIZE   ((SQLITE_WIN32_CACHE_SIZE) * \
++                                         (SQLITE_DEFAULT_PAGE_SIZE) + \
++                                         (SQLITE_WIN32_HEAP_INIT_EXTRA))
+ #endif
+ 
+ /*
+  * The maximum size of the Win32-specific heap.  This value may be zero.
+  */
+ #ifndef SQLITE_WIN32_HEAP_MAX_SIZE
+-#  define SQLITE_WIN32_HEAP_MAX_SIZE  (0)
++#  define SQLITE_WIN32_HEAP_MAX_SIZE    (0)
+ #endif
+ 
+ /*
+@@ -33555,7 +42612,7 @@
+  * zero for the default behavior.
+  */
+ #ifndef SQLITE_WIN32_HEAP_FLAGS
+-#  define SQLITE_WIN32_HEAP_FLAGS     (0)
++#  define SQLITE_WIN32_HEAP_FLAGS       (0)
+ #endif
+ 
+ 
+@@ -33702,8 +42759,9 @@
+ #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
+         LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
+ 
+-#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
+-        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
++        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \
++        SQLITE_WIN32_CREATEFILEMAPPINGA
+   { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
+ #else
+   { "CreateFileMappingA",      (SYSCALL)0,                       0 },
+@@ -33933,8 +42991,7 @@
+ 
+ #define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
+ 
+-#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \
+-        SQLITE_WIN32_GETVERSIONEX
++#if defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_GETVERSIONEX
+   { "GetVersionExA",           (SYSCALL)GetVersionExA,           0 },
+ #else
+   { "GetVersionExA",           (SYSCALL)0,                       0 },
+@@ -33944,7 +43001,7 @@
+         LPOSVERSIONINFOA))aSyscall[34].pCurrent)
+ 
+ #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
+-        defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
++        SQLITE_WIN32_GETVERSIONEX
+   { "GetVersionExW",           (SYSCALL)GetVersionExW,           0 },
+ #else
+   { "GetVersionExW",           (SYSCALL)0,                       0 },
+@@ -34395,7 +43452,7 @@
+ ** "pnLargest" argument, if non-zero, will be used to return the size of the
+ ** largest committed free block in the heap, in bytes.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
++SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){
+   int rc = SQLITE_OK;
+   UINT nLargest = 0;
+   HANDLE hHeap;
+@@ -34413,7 +43470,7 @@
+     if( lastErrno==NO_ERROR ){
+       sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
+                   (void*)hHeap);
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+     }else{
+       sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
+                   osGetLastError(), (void*)hHeap);
+@@ -34435,12 +43492,12 @@
+ ** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
+ ** be returned and no changes will be made to the Win32 native heap.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
++SQLITE_API int sqlite3_win32_reset_heap(){
+   int rc;
+   MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
+   MUTEX_LOGIC( sqlite3_mutex *pMem; )    /* The memsys static mutex */
+-  MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
+-  MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
++  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
++  MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
+   sqlite3_mutex_enter(pMaster);
+   sqlite3_mutex_enter(pMem);
+   winMemAssertMagic();
+@@ -34480,11 +43537,17 @@
+ ** (if available).
+ */
+ 
+-SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int nBuf){
++SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
+   char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
+   int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
+   if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
+   assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !zBuf ){
++    (void)SQLITE_MISUSE_BKPT;
++    return;
++  }
++#endif
+ #if defined(SQLITE_WIN32_HAS_ANSI)
+   if( nMin>0 ){
+     memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
+@@ -34520,7 +43583,7 @@
+ static HANDLE sleepObj = NULL;
+ #endif
+ 
+-SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds){
++SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
+ #if SQLITE_OS_WINRT
+   if ( sleepObj==NULL ){
+     sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
+@@ -34555,7 +43618,7 @@
+ ** the LockFileEx() API.
+ */
+ 
+-#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX
++#if !SQLITE_WIN32_GETVERSIONEX
+ # define osIsNT()  (1)
+ #elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
+ # define osIsNT()  (1)
+@@ -34569,14 +43632,14 @@
+ ** This function determines if the machine is running a version of Windows
+ ** based on the NT kernel.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){
++SQLITE_API int sqlite3_win32_is_nt(void){
+ #if SQLITE_OS_WINRT
+   /*
+   ** NOTE: The WinRT sub-platform is always assumed to be based on the NT
+   **       kernel.
+   */
+   return 1;
+-#elif defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
++#elif SQLITE_WIN32_GETVERSIONEX
+   if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){
+ #if defined(SQLITE_WIN32_HAS_ANSI)
+     OSVERSIONINFOA sInfo;
+@@ -34733,7 +43796,7 @@
+           "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
+           osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
+           dwMaximumSize);
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     pWinMemData->bOwned = TRUE;
+     assert( pWinMemData->bOwned );
+@@ -34743,7 +43806,7 @@
+   if( !pWinMemData->hHeap ){
+     sqlite3_log(SQLITE_NOMEM,
+         "failed to GetProcessHeap (%lu)", osGetLastError());
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   pWinMemData->bOwned = FALSE;
+   assert( !pWinMemData->bOwned );
+@@ -34810,147 +43873,244 @@
+ #endif /* SQLITE_WIN32_MALLOC */
+ 
+ /*
+-** Convert a UTF-8 string to Microsoft Unicode (UTF-16?).
++** Convert a UTF-8 string to Microsoft Unicode.
+ **
+-** Space to hold the returned string is obtained from malloc.
++** Space to hold the returned string is obtained from sqlite3_malloc().
+ */
+-static LPWSTR winUtf8ToUnicode(const char *zFilename){
++static LPWSTR winUtf8ToUnicode(const char *zText){
+   int nChar;
+-  LPWSTR zWideFilename;
++  LPWSTR zWideText;
+ 
+-  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
++  nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0);
+   if( nChar==0 ){
+     return 0;
+   }
+-  zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
+-  if( zWideFilename==0 ){
++  zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) );
++  if( zWideText==0 ){
+     return 0;
+   }
+-  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
++  nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText,
+                                 nChar);
+   if( nChar==0 ){
+-    sqlite3_free(zWideFilename);
+-    zWideFilename = 0;
++    sqlite3_free(zWideText);
++    zWideText = 0;
+   }
+-  return zWideFilename;
++  return zWideText;
+ }
+ 
+ /*
+-** Convert Microsoft Unicode to UTF-8.  Space to hold the returned string is
+-** obtained from sqlite3_malloc().
++** Convert a Microsoft Unicode string to UTF-8.
++**
++** Space to hold the returned string is obtained from sqlite3_malloc().
+ */
+-static char *winUnicodeToUtf8(LPCWSTR zWideFilename){
++static char *winUnicodeToUtf8(LPCWSTR zWideText){
+   int nByte;
+-  char *zFilename;
++  char *zText;
+ 
+-  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
++  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0);
+   if( nByte == 0 ){
+     return 0;
+   }
+-  zFilename = sqlite3MallocZero( nByte );
+-  if( zFilename==0 ){
++  zText = sqlite3MallocZero( nByte );
++  if( zText==0 ){
+     return 0;
+   }
+-  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
++  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte,
+                                 0, 0);
+   if( nByte == 0 ){
+-    sqlite3_free(zFilename);
+-    zFilename = 0;
++    sqlite3_free(zText);
++    zText = 0;
+   }
+-  return zFilename;
++  return zText;
+ }
+ 
+ /*
+-** Convert an ANSI string to Microsoft Unicode, based on the
+-** current codepage settings for file apis.
++** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM
++** code page.
+ **
+-** Space to hold the returned string is obtained
+-** from sqlite3_malloc.
++** Space to hold the returned string is obtained from sqlite3_malloc().
+ */
+-static LPWSTR winMbcsToUnicode(const char *zFilename){
++static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){
+   int nByte;
+-  LPWSTR zMbcsFilename;
+-  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
++  LPWSTR zMbcsText;
++  int codepage = useAnsi ? CP_ACP : CP_OEMCP;
+ 
+-  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
++  nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL,
+                                 0)*sizeof(WCHAR);
+   if( nByte==0 ){
+     return 0;
+   }
+-  zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
+-  if( zMbcsFilename==0 ){
++  zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) );
++  if( zMbcsText==0 ){
+     return 0;
+   }
+-  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
++  nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText,
+                                 nByte);
+   if( nByte==0 ){
+-    sqlite3_free(zMbcsFilename);
+-    zMbcsFilename = 0;
++    sqlite3_free(zMbcsText);
++    zMbcsText = 0;
+   }
+-  return zMbcsFilename;
++  return zMbcsText;
+ }
+ 
+ /*
+-** Convert Microsoft Unicode to multi-byte character string, based on the
+-** user's ANSI codepage.
++** Convert a Microsoft Unicode string to a multi-byte character string,
++** using the ANSI or OEM code page.
+ **
+-** Space to hold the returned string is obtained from
+-** sqlite3_malloc().
++** Space to hold the returned string is obtained from sqlite3_malloc().
+ */
+-static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
++static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){
+   int nByte;
+-  char *zFilename;
+-  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
++  char *zText;
++  int codepage = useAnsi ? CP_ACP : CP_OEMCP;
+ 
+-  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
++  nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0);
+   if( nByte == 0 ){
+     return 0;
+   }
+-  zFilename = sqlite3MallocZero( nByte );
+-  if( zFilename==0 ){
++  zText = sqlite3MallocZero( nByte );
++  if( zText==0 ){
+     return 0;
+   }
+-  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename,
++  nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText,
+                                 nByte, 0, 0);
+   if( nByte == 0 ){
+-    sqlite3_free(zFilename);
+-    zFilename = 0;
++    sqlite3_free(zText);
++    zText = 0;
+   }
+-  return zFilename;
++  return zText;
+ }
+ 
+ /*
+-** Convert multibyte character string to UTF-8.  Space to hold the
+-** returned string is obtained from sqlite3_malloc().
++** Convert a multi-byte character string to UTF-8.
++**
++** Space to hold the returned string is obtained from sqlite3_malloc().
+ */
+-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename){
+-  char *zFilenameUtf8;
++static char *winMbcsToUtf8(const char *zText, int useAnsi){
++  char *zTextUtf8;
+   LPWSTR zTmpWide;
+ 
+-  zTmpWide = winMbcsToUnicode(zFilename);
++  zTmpWide = winMbcsToUnicode(zText, useAnsi);
+   if( zTmpWide==0 ){
+     return 0;
+   }
+-  zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
++  zTextUtf8 = winUnicodeToUtf8(zTmpWide);
+   sqlite3_free(zTmpWide);
+-  return zFilenameUtf8;
++  return zTextUtf8;
+ }
+ 
+ /*
+-** Convert UTF-8 to multibyte character string.  Space to hold the
+-** returned string is obtained from sqlite3_malloc().
++** Convert a UTF-8 string to a multi-byte character string.
++**
++** Space to hold the returned string is obtained from sqlite3_malloc().
+ */
+-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename){
+-  char *zFilenameMbcs;
++static char *winUtf8ToMbcs(const char *zText, int useAnsi){
++  char *zTextMbcs;
+   LPWSTR zTmpWide;
+ 
+-  zTmpWide = winUtf8ToUnicode(zFilename);
++  zTmpWide = winUtf8ToUnicode(zText);
+   if( zTmpWide==0 ){
+     return 0;
+   }
+-  zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
++  zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi);
+   sqlite3_free(zTmpWide);
+-  return zFilenameMbcs;
++  return zTextMbcs;
++}
++
++/*
++** This is a public wrapper for the winUtf8ToUnicode() function.
++*/
++SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !zText ){
++    (void)SQLITE_MISUSE_BKPT;
++    return 0;
++  }
++#endif
++#ifndef SQLITE_OMIT_AUTOINIT
++  if( sqlite3_initialize() ) return 0;
++#endif
++  return winUtf8ToUnicode(zText);
++}
++
++/*
++** This is a public wrapper for the winUnicodeToUtf8() function.
++*/
++SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !zWideText ){
++    (void)SQLITE_MISUSE_BKPT;
++    return 0;
++  }
++#endif
++#ifndef SQLITE_OMIT_AUTOINIT
++  if( sqlite3_initialize() ) return 0;
++#endif
++  return winUnicodeToUtf8(zWideText);
++}
++
++/*
++** This is a public wrapper for the winMbcsToUtf8() function.
++*/
++SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !zText ){
++    (void)SQLITE_MISUSE_BKPT;
++    return 0;
++  }
++#endif
++#ifndef SQLITE_OMIT_AUTOINIT
++  if( sqlite3_initialize() ) return 0;
++#endif
++  return winMbcsToUtf8(zText, osAreFileApisANSI());
++}
++
++/*
++** This is a public wrapper for the winMbcsToUtf8() function.
++*/
++SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !zText ){
++    (void)SQLITE_MISUSE_BKPT;
++    return 0;
++  }
++#endif
++#ifndef SQLITE_OMIT_AUTOINIT
++  if( sqlite3_initialize() ) return 0;
++#endif
++  return winMbcsToUtf8(zText, useAnsi);
++}
++
++/*
++** This is a public wrapper for the winUtf8ToMbcs() function.
++*/
++SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zText){
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !zText ){
++    (void)SQLITE_MISUSE_BKPT;
++    return 0;
++  }
++#endif
++#ifndef SQLITE_OMIT_AUTOINIT
++  if( sqlite3_initialize() ) return 0;
++#endif
++  return winUtf8ToMbcs(zText, osAreFileApisANSI());
++}
++
++/*
++** This is a public wrapper for the winUtf8ToMbcs() function.
++*/
++SQLITE_API char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !zText ){
++    (void)SQLITE_MISUSE_BKPT;
++    return 0;
++  }
++#endif
++#ifndef SQLITE_OMIT_AUTOINIT
++  if( sqlite3_initialize() ) return 0;
++#endif
++  return winUtf8ToMbcs(zText, useAnsi);
+ }
+ 
+ /*
+@@ -34960,7 +44120,7 @@
+ ** argument is the name of the directory to use.  The return value will be
+ ** SQLITE_OK if successful.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
++SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
+   char **ppDirectory = 0;
+ #ifndef SQLITE_OMIT_AUTOINIT
+   int rc = sqlite3_initialize();
+@@ -34980,7 +44140,7 @@
+     if( zValue && zValue[0] ){
+       zValueUtf8 = winUnicodeToUtf8(zValue);
+       if ( zValueUtf8==0 ){
+-        return SQLITE_NOMEM;
++        return SQLITE_NOMEM_BKPT;
+       }
+     }
+     sqlite3_free(*ppDirectory);
+@@ -35052,7 +44212,7 @@
+     if( dwLen > 0 ){
+       /* allocate a buffer and convert to UTF8 */
+       sqlite3BeginBenignMalloc();
+-      zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
++      zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
+       sqlite3EndBenignMalloc();
+       /* free the system buffer allocated by FormatMessage */
+       osLocalFree(zTemp);
+@@ -35194,16 +44354,17 @@
+   }
+ }
+ 
+-#if SQLITE_OS_WINCE
+-/*************************************************************************
+-** This section contains code for WinCE only.
++/*
++** This #if does not rely on the SQLITE_OS_WINCE define because the
++** corresponding section in "date.c" cannot use it.
+ */
+-#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API
++#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
++    (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
+ /*
+-** The MSVC CRT on Windows CE may not have a localtime() function.  So
+-** create a substitute.
++** The MSVC CRT on Windows CE may not have a localtime() function.
++** So define a substitute.
+ */
+-/* #include <time.h> */
++/* #  include <time.h> */
+ struct tm *__cdecl localtime(const time_t *t)
+ {
+   static struct tm y;
+@@ -35227,6 +44388,10 @@
+ }
+ #endif
+ 
++#if SQLITE_OS_WINCE
++/*************************************************************************
++** This section contains code for WinCE only.
++*/
+ #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
+ 
+ /*
+@@ -35257,7 +44422,7 @@
+   zName = winUtf8ToUnicode(zFilename);
+   if( zName==0 ){
+     /* out of memory */
+-    return SQLITE_IOERR_NOMEM;
++    return SQLITE_IOERR_NOMEM_BKPT;
+   }
+ 
+   /* Initialize the local lockdata */
+@@ -35682,7 +44847,12 @@
+   }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
+ #if SQLITE_OS_WINCE
+ #define WINCE_DELETION_ATTEMPTS 3
+-  winceDestroyLock(pFile);
++  {
++    winVfsAppData *pAppData = (winVfsAppData*)pFile->pVfs->pAppData;
++    if( pAppData==NULL || !pAppData->bNoLock ){
++      winceDestroyLock(pFile);
++    }
++  }
+   if( pFile->zDeleteOnClose ){
+     int cnt = 0;
+     while(
+@@ -35810,7 +44980,7 @@
+            "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
+            pFile->h, pBuf, amt, offset, pFile->locktype));
+ 
+-#if SQLITE_MAX_MMAP_SIZE>0
++#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0
+   /* Deal with as much of this write request as possible by transfering
+   ** data from the memory mapping using memcpy().  */
+   if( offset<pFile->mmapSize ){
+@@ -36223,6 +45393,12 @@
+     return SQLITE_OK;
+   }
+ 
++  /* Do not allow any kind of write-lock on a read-only database
++  */
++  if( (pFile->ctrlFlags & WINFILE_RDONLY)!=0 && locktype>=RESERVED_LOCK ){
++    return SQLITE_IOERR_LOCK;
++  }
++
+   /* Make sure the locking sequence is correct
+   */
+   assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
+@@ -36234,9 +45410,8 @@
+   ** the PENDING_LOCK byte is temporary.
+   */
+   newLocktype = pFile->locktype;
+-  if(   (pFile->locktype==NO_LOCK)
+-     || (   (locktype==EXCLUSIVE_LOCK)
+-         && (pFile->locktype==RESERVED_LOCK))
++  if( pFile->locktype==NO_LOCK
++   || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK)
+   ){
+     int cnt = 3;
+     while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
+@@ -36352,7 +45527,7 @@
+     res = 1;
+     OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res));
+   }else{
+-    res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0);
++    res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE,0,1,0);
+     if( res ){
+       winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
+     }
+@@ -36409,6 +45584,44 @@
+   return rc;
+ }
+ 
++/******************************************************************************
++****************************** No-op Locking **********************************
++**
++** Of the various locking implementations available, this is by far the
++** simplest:  locking is ignored.  No attempt is made to lock the database
++** file for reading or writing.
++**
++** This locking mode is appropriate for use on read-only databases
++** (ex: databases that are burned into CD-ROM, for example.)  It can
++** also be used if the application employs some external mechanism to
++** prevent simultaneous access of the same database by two or more
++** database connections.  But there is a serious risk of database
++** corruption if this locking mode is used in situations where multiple
++** database connections are accessing the same database file at the same
++** time and one or more of those connections are writing.
++*/
++
++static int winNolockLock(sqlite3_file *id, int locktype){
++  UNUSED_PARAMETER(id);
++  UNUSED_PARAMETER(locktype);
++  return SQLITE_OK;
++}
++
++static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){
++  UNUSED_PARAMETER(id);
++  UNUSED_PARAMETER(pResOut);
++  return SQLITE_OK;
++}
++
++static int winNolockUnlock(sqlite3_file *id, int locktype){
++  UNUSED_PARAMETER(id);
++  UNUSED_PARAMETER(locktype);
++  return SQLITE_OK;
++}
++
++/******************* End of the no-op lock implementation *********************
++******************************************************************************/
++
+ /*
+ ** If *pArg is initially negative then this is a query.  Set *pArg to
+ ** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
+@@ -36442,7 +45655,7 @@
+       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+       return SQLITE_OK;
+     }
+-    case SQLITE_LAST_ERRNO: {
++    case SQLITE_FCNTL_LAST_ERRNO: {
+       *(int*)pArg = (int)pFile->lastErrno;
+       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+       return SQLITE_OK;
+@@ -36500,6 +45713,12 @@
+       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+       return SQLITE_OK;
+     }
++    case SQLITE_FCNTL_WIN32_GET_HANDLE: {
++      LPHANDLE phFile = (LPHANDLE)pArg;
++      *phFile = pFile->h;
++      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
++      return SQLITE_OK;
++    }
+ #ifdef SQLITE_TEST
+     case SQLITE_FCNTL_WIN32_SET_HANDLE: {
+       LPHANDLE phFile = (LPHANDLE)pArg;
+@@ -36592,14 +45811,14 @@
+ **   winShmLeaveMutex()
+ */
+ static void winShmEnterMutex(void){
+-  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
++  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
+ }
+ static void winShmLeaveMutex(void){
+-  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
++  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
+ }
+ #ifndef NDEBUG
+ static int winShmMutexHeld(void) {
+-  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
++  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
+ }
+ #endif
+ 
+@@ -36687,12 +45906,12 @@
+ /*
+ ** Apply advisory locks for all n bytes beginning at ofst.
+ */
+-#define _SHM_UNLCK  1
+-#define _SHM_RDLCK  2
+-#define _SHM_WRLCK  3
++#define WINSHM_UNLCK  1
++#define WINSHM_RDLCK  2
++#define WINSHM_WRLCK  3
+ static int winShmSystemLock(
+   winShmNode *pFile,    /* Apply locks to this open shared-memory segment */
+-  int lockType,         /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
++  int lockType,         /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */
+   int ofst,             /* Offset to first byte to be locked/unlocked */
+   int nByte             /* Number of bytes to lock or unlock */
+ ){
+@@ -36705,12 +45924,12 @@
+            pFile->hFile.h, lockType, ofst, nByte));
+ 
+   /* Release/Acquire the system-level lock */
+-  if( lockType==_SHM_UNLCK ){
++  if( lockType==WINSHM_UNLCK ){
+     rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
+   }else{
+     /* Initialize the locking parameters */
+     DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
+-    if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
++    if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
+     rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
+   }
+ 
+@@ -36722,7 +45941,7 @@
+   }
+ 
+   OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n",
+-           pFile->hFile.h, (lockType == _SHM_UNLCK) ? "winUnlockFile" :
++           pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" :
+            "winLockFile", pFile->lastErrno, sqlite3ErrName(rc)));
+ 
+   return rc;
+@@ -36800,12 +46019,12 @@
+   ** allocate space for a new winShmNode and filename.
+   */
+   p = sqlite3MallocZero( sizeof(*p) );
+-  if( p==0 ) return SQLITE_IOERR_NOMEM;
++  if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT;
+   nName = sqlite3Strlen30(pDbFd->zPath);
+   pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
+   if( pNew==0 ){
+     sqlite3_free(p);
+-    return SQLITE_IOERR_NOMEM;
++    return SQLITE_IOERR_NOMEM_BKPT;
+   }
+   pNew->zFilename = (char*)&pNew[1];
+   sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
+@@ -36830,10 +46049,12 @@
+     pShmNode->pNext = winShmNodeList;
+     winShmNodeList = pShmNode;
+ 
+-    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+-    if( pShmNode->mutex==0 ){
+-      rc = SQLITE_IOERR_NOMEM;
+-      goto shm_open_err;
++    if( sqlite3GlobalConfig.bCoreMutex ){
++      pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
++      if( pShmNode->mutex==0 ){
++        rc = SQLITE_IOERR_NOMEM_BKPT;
++        goto shm_open_err;
++      }
+     }
+ 
+     rc = winOpen(pDbFd->pVfs,
+@@ -36848,7 +46069,7 @@
+     /* Check to see if another process is holding the dead-man switch.
+     ** If not, truncate the file to zero length.
+     */
+-    if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
++    if( winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
+       rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
+       if( rc!=SQLITE_OK ){
+         rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
+@@ -36856,8 +46077,8 @@
+       }
+     }
+     if( rc==SQLITE_OK ){
+-      winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
+-      rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
++      winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
++      rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
+     }
+     if( rc ) goto shm_open_err;
+   }
+@@ -36886,7 +46107,7 @@
+ 
+   /* Jump here on any error */
+ shm_open_err:
+-  winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
++  winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+   winShmPurge(pDbFd->pVfs, 0);      /* This call frees pShmNode if required */
+   sqlite3_free(p);
+   sqlite3_free(pNew);
+@@ -36975,7 +46196,7 @@
+ 
+     /* Unlock the system-level locks */
+     if( (mask & allMask)==0 ){
+-      rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
++      rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n);
+     }else{
+       rc = SQLITE_OK;
+     }
+@@ -37003,7 +46224,7 @@
+     /* Get shared locks at the system level, if necessary */
+     if( rc==SQLITE_OK ){
+       if( (allShared & mask)==0 ){
+-        rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n);
++        rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n);
+       }else{
+         rc = SQLITE_OK;
+       }
+@@ -37028,7 +46249,7 @@
+     ** also mark the local connection as being locked.
+     */
+     if( rc==SQLITE_OK ){
+-      rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n);
++      rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n);
+       if( rc==SQLITE_OK ){
+         assert( (p->sharedMask & mask)==0 );
+         p->exclMask |= mask;
+@@ -37052,8 +46273,8 @@
+   sqlite3_file *fd          /* Database holding the shared memory */
+ ){
+   UNUSED_PARAMETER(fd);
+-  /* MemoryBarrier(); // does not work -- do not know why not */
+-  winShmEnterMutex();
++  sqlite3MemoryBarrier();   /* compiler-defined memory barrier */
++  winShmEnterMutex();       /* Also mutex, for redundancy */
+   winShmLeaveMutex();
+ }
+ 
+@@ -37137,7 +46358,7 @@
+         pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
+     );
+     if( !apNew ){
+-      rc = SQLITE_IOERR_NOMEM;
++      rc = SQLITE_IOERR_NOMEM_BKPT;
+       goto shmpage_out;
+     }
+     pShmNode->aRegion = apNew;
+@@ -37154,7 +46375,7 @@
+       hMap = osCreateFileMappingW(pShmNode->hFile.h,
+           NULL, PAGE_READWRITE, 0, nByte, NULL
+       );
+-#elif defined(SQLITE_WIN32_HAS_ANSI)
++#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
+       hMap = osCreateFileMappingA(pShmNode->hFile.h,
+           NULL, PAGE_READWRITE, 0, nByte, NULL
+       );
+@@ -37298,17 +46519,19 @@
+     DWORD flags = FILE_MAP_READ;
+ 
+     winUnmapfile(pFd);
++#ifdef SQLITE_MMAP_READWRITE
+     if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){
+       protect = PAGE_READWRITE;
+       flags |= FILE_MAP_WRITE;
+     }
++#endif
+ #if SQLITE_OS_WINRT
+     pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL);
+ #elif defined(SQLITE_WIN32_HAS_WIDE)
+     pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect,
+                                 (DWORD)((nMap>>32) & 0xffffffff),
+                                 (DWORD)(nMap & 0xffffffff), NULL);
+-#elif defined(SQLITE_WIN32_HAS_ANSI)
++#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
+     pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
+                                 (DWORD)((nMap>>32) & 0xffffffff),
+                                 (DWORD)(nMap & 0xffffffff), NULL);
+@@ -37469,6 +46692,44 @@
+   winUnfetch                      /* xUnfetch */
+ };
+ 
++/*
++** This vector defines all the methods that can operate on an
++** sqlite3_file for win32 without performing any locking.
++*/
++static const sqlite3_io_methods winIoNolockMethod = {
++  3,                              /* iVersion */
++  winClose,                       /* xClose */
++  winRead,                        /* xRead */
++  winWrite,                       /* xWrite */
++  winTruncate,                    /* xTruncate */
++  winSync,                        /* xSync */
++  winFileSize,                    /* xFileSize */
++  winNolockLock,                  /* xLock */
++  winNolockUnlock,                /* xUnlock */
++  winNolockCheckReservedLock,     /* xCheckReservedLock */
++  winFileControl,                 /* xFileControl */
++  winSectorSize,                  /* xSectorSize */
++  winDeviceCharacteristics,       /* xDeviceCharacteristics */
++  winShmMap,                      /* xShmMap */
++  winShmLock,                     /* xShmLock */
++  winShmBarrier,                  /* xShmBarrier */
++  winShmUnmap,                    /* xShmUnmap */
++  winFetch,                       /* xFetch */
++  winUnfetch                      /* xUnfetch */
++};
++
++static winVfsAppData winAppData = {
++  &winIoMethod,       /* pMethod */
++  0,                  /* pAppData */
++  0                   /* bNoLock */
++};
++
++static winVfsAppData winNolockAppData = {
++  &winIoNolockMethod, /* pMethod */
++  0,                  /* pAppData */
++  1                   /* bNoLock */
++};
++
+ /****************************************************************************
+ **************************** sqlite3_vfs methods ****************************
+ **
+@@ -37489,7 +46750,7 @@
+   }
+ #ifdef SQLITE_WIN32_HAS_ANSI
+   else{
+-    zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
++    zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI());
+   }
+ #endif
+   /* caller will handle out of memory */
+@@ -37510,7 +46771,7 @@
+   }
+ #ifdef SQLITE_WIN32_HAS_ANSI
+   else{
+-    zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
++    zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI());
+   }
+ #endif
+   /* caller will handle out of memory */
+@@ -37565,7 +46826,7 @@
+   zBuf = sqlite3MallocZero( nBuf );
+   if( !zBuf ){
+     OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-    return SQLITE_IOERR_NOMEM;
++    return SQLITE_IOERR_NOMEM_BKPT;
+   }
+ 
+   /* Figure out the effective temporary directory.  First, check if one
+@@ -37623,7 +46884,7 @@
+         if( !zConverted ){
+           sqlite3_free(zBuf);
+           OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-          return SQLITE_IOERR_NOMEM;
++          return SQLITE_IOERR_NOMEM_BKPT;
+         }
+         if( winIsDir(zConverted) ){
+           sqlite3_snprintf(nMax, zBuf, "%s", zDir);
+@@ -37636,7 +46897,7 @@
+         if( !zConverted ){
+           sqlite3_free(zBuf);
+           OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-          return SQLITE_IOERR_NOMEM;
++          return SQLITE_IOERR_NOMEM_BKPT;
+         }
+         if( cygwin_conv_path(
+                 osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
+@@ -37657,7 +46918,7 @@
+             sqlite3_free(zConverted);
+             sqlite3_free(zBuf);
+             OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-            return SQLITE_IOERR_NOMEM;
++            return SQLITE_IOERR_NOMEM_BKPT;
+           }
+           sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
+           sqlite3_free(zUtf8);
+@@ -37675,7 +46936,7 @@
+     if( !zWidePath ){
+       sqlite3_free(zBuf);
+       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-      return SQLITE_IOERR_NOMEM;
++      return SQLITE_IOERR_NOMEM_BKPT;
+     }
+     if( osGetTempPathW(nMax, zWidePath)==0 ){
+       sqlite3_free(zWidePath);
+@@ -37693,7 +46954,7 @@
+       sqlite3_free(zWidePath);
+       sqlite3_free(zBuf);
+       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-      return SQLITE_IOERR_NOMEM;
++      return SQLITE_IOERR_NOMEM_BKPT;
+     }
+   }
+ #ifdef SQLITE_WIN32_HAS_ANSI
+@@ -37703,7 +46964,7 @@
+     if( !zMbcsPath ){
+       sqlite3_free(zBuf);
+       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-      return SQLITE_IOERR_NOMEM;
++      return SQLITE_IOERR_NOMEM_BKPT;
+     }
+     if( osGetTempPathA(nMax, zMbcsPath)==0 ){
+       sqlite3_free(zBuf);
+@@ -37711,14 +46972,14 @@
+       return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
+                          "winGetTempname3", 0);
+     }
+-    zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
++    zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI());
+     if( zUtf8 ){
+       sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
+       sqlite3_free(zUtf8);
+     }else{
+       sqlite3_free(zBuf);
+       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-      return SQLITE_IOERR_NOMEM;
++      return SQLITE_IOERR_NOMEM_BKPT;
+     }
+   }
+ #endif /* SQLITE_WIN32_HAS_ANSI */
+@@ -37801,7 +47062,7 @@
+ ** Open a file.
+ */
+ static int winOpen(
+-  sqlite3_vfs *pVfs,        /* Used to get maximum path name length */
++  sqlite3_vfs *pVfs,        /* Used to get maximum path length and AppData */
+   const char *zName,        /* Name of the file (UTF-8) */
+   sqlite3_file *id,         /* Write the SQLite file handle here */
+   int flags,                /* Open mode flags */
+@@ -37816,6 +47077,7 @@
+ #if SQLITE_OS_WINCE
+   int isTemp = 0;
+ #endif
++  winVfsAppData *pAppData;
+   winFile *pFile = (winFile*)id;
+   void *zConverted;              /* Filename in OS encoding */
+   const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
+@@ -37910,7 +47172,7 @@
+   if( zConverted==0 ){
+     sqlite3_free(zTmpname);
+     OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
+-    return SQLITE_IOERR_NOMEM;
++    return SQLITE_IOERR_NOMEM_BKPT;
+   }
+ 
+   if( winIsDir(zConverted) ){
+@@ -38037,15 +47299,20 @@
+            "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ?
+            *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
+ 
++  pAppData = (winVfsAppData*)pVfs->pAppData;
++
+ #if SQLITE_OS_WINCE
+-  if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
+-       && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
+-  ){
+-    osCloseHandle(h);
+-    sqlite3_free(zConverted);
+-    sqlite3_free(zTmpname);
+-    OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
+-    return rc;
++  {
++    if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
++         && ((pAppData==NULL) || !pAppData->bNoLock)
++         && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
++    ){
++      osCloseHandle(h);
++      sqlite3_free(zConverted);
++      sqlite3_free(zTmpname);
++      OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
++      return rc;
++    }
+   }
+   if( isTemp ){
+     pFile->zDeleteOnClose = zConverted;
+@@ -38056,7 +47323,7 @@
+   }
+ 
+   sqlite3_free(zTmpname);
+-  pFile->pMethod = &winIoMethod;
++  pFile->pMethod = pAppData ? pAppData->pMethod : &winIoMethod;
+   pFile->pVfs = pVfs;
+   pFile->h = h;
+   if( isReadonly ){
+@@ -38110,7 +47377,7 @@
+   zConverted = winConvertFromUtf8Filename(zFilename);
+   if( zConverted==0 ){
+     OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
+-    return SQLITE_IOERR_NOMEM;
++    return SQLITE_IOERR_NOMEM_BKPT;
+   }
+   if( osIsNT() ){
+     do {
+@@ -38218,7 +47485,7 @@
+   zConverted = winConvertFromUtf8Filename(zFilename);
+   if( zConverted==0 ){
+     OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
+-    return SQLITE_IOERR_NOMEM;
++    return SQLITE_IOERR_NOMEM_BKPT;
+   }
+   if( osIsNT() ){
+     int cnt = 0;
+@@ -38331,6 +47598,18 @@
+   int nFull,                    /* Size of output buffer in bytes */
+   char *zFull                   /* Output buffer */
+ ){
++#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
++  DWORD nByte;
++  void *zConverted;
++  char *zOut;
++#endif
++
++  /* If this path name begins with "/X:", where "X" is any alphabetic
++  ** character, discard the initial "/" from the pathname.
++  */
++  if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
++    zRelative++;
++  }
+ 
+ #if defined(__CYGWIN__)
+   SimulateIOError( return SQLITE_ERROR );
+@@ -38345,7 +47624,7 @@
+     */
+     char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
+     if( !zOut ){
+-      return SQLITE_IOERR_NOMEM;
++      return SQLITE_IOERR_NOMEM_BKPT;
+     }
+     if( cygwin_conv_path(
+             (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
+@@ -38357,7 +47636,7 @@
+       char *zUtf8 = winConvertToUtf8Filename(zOut);
+       if( !zUtf8 ){
+         sqlite3_free(zOut);
+-        return SQLITE_IOERR_NOMEM;
++        return SQLITE_IOERR_NOMEM_BKPT;
+       }
+       sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+                        sqlite3_data_directory, winGetDirSep(), zUtf8);
+@@ -38367,7 +47646,7 @@
+   }else{
+     char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
+     if( !zOut ){
+-      return SQLITE_IOERR_NOMEM;
++      return SQLITE_IOERR_NOMEM_BKPT;
+     }
+     if( cygwin_conv_path(
+             (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
+@@ -38379,7 +47658,7 @@
+       char *zUtf8 = winConvertToUtf8Filename(zOut);
+       if( !zUtf8 ){
+         sqlite3_free(zOut);
+-        return SQLITE_IOERR_NOMEM;
++        return SQLITE_IOERR_NOMEM_BKPT;
+       }
+       sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
+       sqlite3_free(zUtf8);
+@@ -38409,17 +47688,6 @@
+ #endif
+ 
+ #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
+-  DWORD nByte;
+-  void *zConverted;
+-  char *zOut;
+-
+-  /* If this path name begins with "/X:", where "X" is any alphabetic
+-  ** character, discard the initial "/" from the pathname.
+-  */
+-  if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
+-    zRelative++;
+-  }
+-
+   /* It's odd to simulate an io-error here, but really this is just
+   ** using the io-error infrastructure to test that SQLite handles this
+   ** function failing. This function could fail if, for example, the
+@@ -38439,7 +47707,7 @@
+   }
+   zConverted = winConvertFromUtf8Filename(zRelative);
+   if( zConverted==0 ){
+-    return SQLITE_IOERR_NOMEM;
++    return SQLITE_IOERR_NOMEM_BKPT;
+   }
+   if( osIsNT() ){
+     LPWSTR zTemp;
+@@ -38453,7 +47721,7 @@
+     zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
+     if( zTemp==0 ){
+       sqlite3_free(zConverted);
+-      return SQLITE_IOERR_NOMEM;
++      return SQLITE_IOERR_NOMEM_BKPT;
+     }
+     nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
+     if( nByte==0 ){
+@@ -38479,7 +47747,7 @@
+     zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
+     if( zTemp==0 ){
+       sqlite3_free(zConverted);
+-      return SQLITE_IOERR_NOMEM;
++      return SQLITE_IOERR_NOMEM_BKPT;
+     }
+     nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
+     if( nByte==0 ){
+@@ -38489,7 +47757,7 @@
+                          "winFullPathname4", zRelative);
+     }
+     sqlite3_free(zConverted);
+-    zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
++    zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
+     sqlite3_free(zTemp);
+   }
+ #endif
+@@ -38498,7 +47766,7 @@
+     sqlite3_free(zOut);
+     return SQLITE_OK;
+   }else{
+-    return SQLITE_IOERR_NOMEM;
++    return SQLITE_IOERR_NOMEM_BKPT;
+   }
+ #endif
+ }
+@@ -38573,65 +47841,85 @@
+   #define winDlClose 0
+ #endif
+ 
++/* State information for the randomness gatherer. */
++typedef struct EntropyGatherer EntropyGatherer;
++struct EntropyGatherer {
++  unsigned char *a;   /* Gather entropy into this buffer */
++  int na;             /* Size of a[] in bytes */
++  int i;              /* XOR next input into a[i] */
++  int nXor;           /* Number of XOR operations done */
++};
++
++#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
++/* Mix sz bytes of entropy into p. */
++static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){
++  int j, k;
++  for(j=0, k=p->i; j<sz; j++){
++    p->a[k++] ^= x[j];
++    if( k>=p->na ) k = 0;
++  }
++  p->i = k;
++  p->nXor += sz;
++}
++#endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */
+ 
+ /*
+ ** Write up to nBuf bytes of randomness into zBuf.
+ */
+ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
+-  int n = 0;
+-  UNUSED_PARAMETER(pVfs);
+ #if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
+-  n = nBuf;
++  UNUSED_PARAMETER(pVfs);
+   memset(zBuf, 0, nBuf);
++  return nBuf;
+ #else
+-  if( sizeof(SYSTEMTIME)<=nBuf-n ){
++  EntropyGatherer e;
++  UNUSED_PARAMETER(pVfs);
++  memset(zBuf, 0, nBuf);
++#if defined(_MSC_VER) && _MSC_VER>=1400 && !SQLITE_OS_WINCE
++  rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */
++#endif /* defined(_MSC_VER) && _MSC_VER>=1400 */
++  e.a = (unsigned char*)zBuf;
++  e.na = nBuf;
++  e.nXor = 0;
++  e.i = 0;
++  {
+     SYSTEMTIME x;
+     osGetSystemTime(&x);
+-    memcpy(&zBuf[n], &x, sizeof(x));
+-    n += sizeof(x);
++    xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME));
+   }
+-  if( sizeof(DWORD)<=nBuf-n ){
++  {
+     DWORD pid = osGetCurrentProcessId();
+-    memcpy(&zBuf[n], &pid, sizeof(pid));
+-    n += sizeof(pid);
++    xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD));
+   }
+ #if SQLITE_OS_WINRT
+-  if( sizeof(ULONGLONG)<=nBuf-n ){
++  {
+     ULONGLONG cnt = osGetTickCount64();
+-    memcpy(&zBuf[n], &cnt, sizeof(cnt));
+-    n += sizeof(cnt);
++    xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG));
+   }
+ #else
+-  if( sizeof(DWORD)<=nBuf-n ){
++  {
+     DWORD cnt = osGetTickCount();
+-    memcpy(&zBuf[n], &cnt, sizeof(cnt));
+-    n += sizeof(cnt);
++    xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD));
+   }
+-#endif
+-  if( sizeof(LARGE_INTEGER)<=nBuf-n ){
++#endif /* SQLITE_OS_WINRT */
++  {
+     LARGE_INTEGER i;
+     osQueryPerformanceCounter(&i);
+-    memcpy(&zBuf[n], &i, sizeof(i));
+-    n += sizeof(i);
++    xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER));
+   }
+ #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
+-  if( sizeof(UUID)<=nBuf-n ){
++  {
+     UUID id;
+     memset(&id, 0, sizeof(UUID));
+     osUuidCreate(&id);
+-    memcpy(zBuf, &id, sizeof(UUID));
+-    n += sizeof(UUID);
+-  }
+-  if( sizeof(UUID)<=nBuf-n ){
+-    UUID id;
++    xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
+     memset(&id, 0, sizeof(UUID));
+     osUuidCreateSequential(&id);
+-    memcpy(zBuf, &id, sizeof(UUID));
+-    n += sizeof(UUID);
++    xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
+   }
+-#endif
+-#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
+-  return n;
++#endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */
++  return e.nXor>nBuf ? nBuf : e.nXor;
++#endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */
+ }
+ 
+ 
+@@ -38747,62 +48035,114 @@
+ ** sqlite3_errmsg(), possibly making IO errors easier to debug.
+ */
+ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
++  DWORD e = osGetLastError();
+   UNUSED_PARAMETER(pVfs);
+-  return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf);
++  if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf);
++  return e;
+ }
+ 
+ /*
+ ** Initialize and deinitialize the operating system interface.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
++SQLITE_API int sqlite3_os_init(void){
+   static sqlite3_vfs winVfs = {
+-    3,                   /* iVersion */
+-    sizeof(winFile),     /* szOsFile */
++    3,                     /* iVersion */
++    sizeof(winFile),       /* szOsFile */
+     SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
+-    0,                   /* pNext */
+-    "win32",             /* zName */
+-    0,                   /* pAppData */
+-    winOpen,             /* xOpen */
+-    winDelete,           /* xDelete */
+-    winAccess,           /* xAccess */
+-    winFullPathname,     /* xFullPathname */
+-    winDlOpen,           /* xDlOpen */
+-    winDlError,          /* xDlError */
+-    winDlSym,            /* xDlSym */
+-    winDlClose,          /* xDlClose */
+-    winRandomness,       /* xRandomness */
+-    winSleep,            /* xSleep */
+-    winCurrentTime,      /* xCurrentTime */
+-    winGetLastError,     /* xGetLastError */
+-    winCurrentTimeInt64, /* xCurrentTimeInt64 */
+-    winSetSystemCall,    /* xSetSystemCall */
+-    winGetSystemCall,    /* xGetSystemCall */
+-    winNextSystemCall,   /* xNextSystemCall */
++    0,                     /* pNext */
++    "win32",               /* zName */
++    &winAppData,           /* pAppData */
++    winOpen,               /* xOpen */
++    winDelete,             /* xDelete */
++    winAccess,             /* xAccess */
++    winFullPathname,       /* xFullPathname */
++    winDlOpen,             /* xDlOpen */
++    winDlError,            /* xDlError */
++    winDlSym,              /* xDlSym */
++    winDlClose,            /* xDlClose */
++    winRandomness,         /* xRandomness */
++    winSleep,              /* xSleep */
++    winCurrentTime,        /* xCurrentTime */
++    winGetLastError,       /* xGetLastError */
++    winCurrentTimeInt64,   /* xCurrentTimeInt64 */
++    winSetSystemCall,      /* xSetSystemCall */
++    winGetSystemCall,      /* xGetSystemCall */
++    winNextSystemCall,     /* xNextSystemCall */
+   };
+ #if defined(SQLITE_WIN32_HAS_WIDE)
+   static sqlite3_vfs winLongPathVfs = {
+-    3,                   /* iVersion */
+-    sizeof(winFile),     /* szOsFile */
++    3,                     /* iVersion */
++    sizeof(winFile),       /* szOsFile */
++    SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
++    0,                     /* pNext */
++    "win32-longpath",      /* zName */
++    &winAppData,           /* pAppData */
++    winOpen,               /* xOpen */
++    winDelete,             /* xDelete */
++    winAccess,             /* xAccess */
++    winFullPathname,       /* xFullPathname */
++    winDlOpen,             /* xDlOpen */
++    winDlError,            /* xDlError */
++    winDlSym,              /* xDlSym */
++    winDlClose,            /* xDlClose */
++    winRandomness,         /* xRandomness */
++    winSleep,              /* xSleep */
++    winCurrentTime,        /* xCurrentTime */
++    winGetLastError,       /* xGetLastError */
++    winCurrentTimeInt64,   /* xCurrentTimeInt64 */
++    winSetSystemCall,      /* xSetSystemCall */
++    winGetSystemCall,      /* xGetSystemCall */
++    winNextSystemCall,     /* xNextSystemCall */
++  };
++#endif
++  static sqlite3_vfs winNolockVfs = {
++    3,                     /* iVersion */
++    sizeof(winFile),       /* szOsFile */
++    SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
++    0,                     /* pNext */
++    "win32-none",          /* zName */
++    &winNolockAppData,     /* pAppData */
++    winOpen,               /* xOpen */
++    winDelete,             /* xDelete */
++    winAccess,             /* xAccess */
++    winFullPathname,       /* xFullPathname */
++    winDlOpen,             /* xDlOpen */
++    winDlError,            /* xDlError */
++    winDlSym,              /* xDlSym */
++    winDlClose,            /* xDlClose */
++    winRandomness,         /* xRandomness */
++    winSleep,              /* xSleep */
++    winCurrentTime,        /* xCurrentTime */
++    winGetLastError,       /* xGetLastError */
++    winCurrentTimeInt64,   /* xCurrentTimeInt64 */
++    winSetSystemCall,      /* xSetSystemCall */
++    winGetSystemCall,      /* xGetSystemCall */
++    winNextSystemCall,     /* xNextSystemCall */
++  };
++#if defined(SQLITE_WIN32_HAS_WIDE)
++  static sqlite3_vfs winLongPathNolockVfs = {
++    3,                     /* iVersion */
++    sizeof(winFile),       /* szOsFile */
+     SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
+-    0,                   /* pNext */
+-    "win32-longpath",    /* zName */
+-    0,                   /* pAppData */
+-    winOpen,             /* xOpen */
+-    winDelete,           /* xDelete */
+-    winAccess,           /* xAccess */
+-    winFullPathname,     /* xFullPathname */
+-    winDlOpen,           /* xDlOpen */
+-    winDlError,          /* xDlError */
+-    winDlSym,            /* xDlSym */
+-    winDlClose,          /* xDlClose */
+-    winRandomness,       /* xRandomness */
+-    winSleep,            /* xSleep */
+-    winCurrentTime,      /* xCurrentTime */
+-    winGetLastError,     /* xGetLastError */
+-    winCurrentTimeInt64, /* xCurrentTimeInt64 */
+-    winSetSystemCall,    /* xSetSystemCall */
+-    winGetSystemCall,    /* xGetSystemCall */
+-    winNextSystemCall,   /* xNextSystemCall */
++    0,                     /* pNext */
++    "win32-longpath-none", /* zName */
++    &winNolockAppData,     /* pAppData */
++    winOpen,               /* xOpen */
++    winDelete,             /* xDelete */
++    winAccess,             /* xAccess */
++    winFullPathname,       /* xFullPathname */
++    winDlOpen,             /* xDlOpen */
++    winDlError,            /* xDlError */
++    winDlSym,              /* xDlSym */
++    winDlClose,            /* xDlClose */
++    winRandomness,         /* xRandomness */
++    winSleep,              /* xSleep */
++    winCurrentTime,        /* xCurrentTime */
++    winGetLastError,       /* xGetLastError */
++    winCurrentTimeInt64,   /* xCurrentTimeInt64 */
++    winSetSystemCall,      /* xSetSystemCall */
++    winGetSystemCall,      /* xGetSystemCall */
++    winNextSystemCall,     /* xNextSystemCall */
+   };
+ #endif
+ 
+@@ -38826,10 +48166,16 @@
+   sqlite3_vfs_register(&winLongPathVfs, 0);
+ #endif
+ 
++  sqlite3_vfs_register(&winNolockVfs, 0);
++
++#if defined(SQLITE_WIN32_HAS_WIDE)
++  sqlite3_vfs_register(&winLongPathNolockVfs, 0);
++#endif
++
+   return SQLITE_OK;
+ }
+ 
+-SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
++SQLITE_API int sqlite3_os_end(void){
+ #if SQLITE_OS_WINRT
+   if( sleepObj!=NULL ){
+     osCloseHandle(sleepObj);
+@@ -38879,13 +48225,15 @@
+ ** start of a transaction, and is thus usually less than a few thousand,
+ ** but can be as large as 2 billion for a really big database.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /* Size of the Bitvec structure in bytes. */
+ #define BITVEC_SZ        512
+ 
+ /* Round the union size down to the nearest pointer boundary, since that's how 
+ ** it will be aligned within the Bitvec struct. */
+-#define BITVEC_USIZE     (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))
++#define BITVEC_USIZE \
++    (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))
+ 
+ /* Type of the array "element" for the bitmap representation. 
+ ** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. 
+@@ -38970,10 +48318,10 @@
+ ** If p is NULL (if the bitmap has not been created) or if
+ ** i is out of range, then return false.
+ */
+-SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){
+-  if( p==0 ) return 0;
+-  if( i>p->iSize || i==0 ) return 0;
++SQLITE_PRIVATE int sqlite3BitvecTestNotNull(Bitvec *p, u32 i){
++  assert( p!=0 );
+   i--;
++  if( i>=p->iSize ) return 0;
+   while( p->iDivisor ){
+     u32 bin = i/p->iDivisor;
+     i = i%p->iDivisor;
+@@ -38993,6 +48341,9 @@
+     return 0;
+   }
+ }
++SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){
++  return p!=0 && sqlite3BitvecTestNotNull(p,i);
++}
+ 
+ /*
+ ** Set the i-th bit.  Return 0 on success and an error code if
+@@ -39017,7 +48368,7 @@
+     i = i%p->iDivisor;
+     if( p->u.apSub[bin]==0 ){
+       p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
+-      if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
++      if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM_BKPT;
+     }
+     p = p->u.apSub[bin];
+   }
+@@ -39052,7 +48403,7 @@
+     int rc;
+     u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
+     if( aiValues==0 ){
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }else{
+       memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
+       memset(p->u.apSub, 0, sizeof(p->u.apSub));
+@@ -39133,7 +48484,7 @@
+   return p->iSize;
+ }
+ 
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
++#ifndef SQLITE_UNTESTABLE
+ /*
+ ** Let V[] be an array of unsigned characters sufficient to hold
+ ** up to N bits.  Let I be an integer between 0 and N.  0<=I<N.
+@@ -39248,7 +48599,7 @@
+   sqlite3BitvecDestroy(pBitvec);
+   return rc;
+ }
+-#endif /* SQLITE_OMIT_BUILTIN_TEST */
++#endif /* SQLITE_UNTESTABLE */
+ 
+ /************** End of bitvec.c **********************************************/
+ /************** Begin file pcache.c ******************************************/
+@@ -39265,15 +48616,39 @@
+ *************************************************************************
+ ** This file implements that page cache.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /*
+-** A complete page cache is an instance of this structure.
++** A complete page cache is an instance of this structure.  Every
++** entry in the cache holds a single page of the database file.  The
++** btree layer only operates on the cached copy of the database pages.
++**
++** A page cache entry is "clean" if it exactly matches what is currently
++** on disk.  A page is "dirty" if it has been modified and needs to be
++** persisted to disk.
++**
++** pDirty, pDirtyTail, pSynced:
++**   All dirty pages are linked into the doubly linked list using
++**   PgHdr.pDirtyNext and pDirtyPrev. The list is maintained in LRU order
++**   such that p was added to the list more recently than p->pDirtyNext.
++**   PCache.pDirty points to the first (newest) element in the list and
++**   pDirtyTail to the last (oldest).
++**
++**   The PCache.pSynced variable is used to optimize searching for a dirty
++**   page to eject from the cache mid-transaction. It is better to eject
++**   a page that does not require a journal sync than one that does. 
++**   Therefore, pSynced is maintained to that it *almost* always points
++**   to either the oldest page in the pDirty/pDirtyTail list that has a
++**   clear PGHDR_NEED_SYNC flag or to a page that is older than this one
++**   (so that the right page to eject can be found by following pDirtyPrev
++**   pointers).
+ */
+ struct PCache {
+   PgHdr *pDirty, *pDirtyTail;         /* List of dirty pages in LRU order */
+   PgHdr *pSynced;                     /* Last synced page in dirty page list */
+-  int nRef;                           /* Number of referenced pages */
++  int nRefSum;                        /* Sum of ref counts over all pages */
+   int szCache;                        /* Configured cache size */
++  int szSpill;                        /* Size before spilling occurs */
+   int szPage;                         /* Size of every page in this cache */
+   int szExtra;                        /* Size of extra space for each page */
+   u8 bPurgeable;                      /* True if pages are on backing store */
+@@ -39281,9 +48656,97 @@
+   int (*xStress)(void*,PgHdr*);       /* Call to try make a page clean */
+   void *pStress;                      /* Argument to xStress */
+   sqlite3_pcache *pCache;             /* Pluggable cache module */
+-  PgHdr *pPage1;                      /* Reference to page 1 */
+ };
+ 
++/********************************** Test and Debug Logic **********************/
++/*
++** Debug tracing macros.  Enable by by changing the "0" to "1" and
++** recompiling.
++**
++** When sqlite3PcacheTrace is 1, single line trace messages are issued.
++** When sqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries
++** is displayed for many operations, resulting in a lot of output.
++*/
++#if defined(SQLITE_DEBUG) && 0
++  int sqlite3PcacheTrace = 2;       /* 0: off  1: simple  2: cache dumps */
++  int sqlite3PcacheMxDump = 9999;   /* Max cache entries for pcacheDump() */
++# define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;}
++  void pcacheDump(PCache *pCache){
++    int N;
++    int i, j;
++    sqlite3_pcache_page *pLower;
++    PgHdr *pPg;
++    unsigned char *a;
++  
++    if( sqlite3PcacheTrace<2 ) return;
++    if( pCache->pCache==0 ) return;
++    N = sqlite3PcachePagecount(pCache);
++    if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump;
++    for(i=1; i<=N; i++){
++       pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0);
++       if( pLower==0 ) continue;
++       pPg = (PgHdr*)pLower->pExtra;
++       printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags);
++       a = (unsigned char *)pLower->pBuf;
++       for(j=0; j<12; j++) printf("%02x", a[j]);
++       printf("\n");
++       if( pPg->pPage==0 ){
++         sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0);
++       }
++    }
++  }
++  #else
++# define pcacheTrace(X)
++# define pcacheDump(X)
++#endif
++
++/*
++** Check invariants on a PgHdr entry.  Return true if everything is OK.
++** Return false if any invariant is violated.
++**
++** This routine is for use inside of assert() statements only.  For
++** example:
++**
++**          assert( sqlite3PcachePageSanity(pPg) );
++*/
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){
++  PCache *pCache;
++  assert( pPg!=0 );
++  assert( pPg->pgno>0 || pPg->pPager==0 );    /* Page number is 1 or more */
++  pCache = pPg->pCache;
++  assert( pCache!=0 );      /* Every page has an associated PCache */
++  if( pPg->flags & PGHDR_CLEAN ){
++    assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */
++    assert( pCache->pDirty!=pPg );          /* CLEAN pages not on dirty list */
++    assert( pCache->pDirtyTail!=pPg );
++  }
++  /* WRITEABLE pages must also be DIRTY */
++  if( pPg->flags & PGHDR_WRITEABLE ){
++    assert( pPg->flags & PGHDR_DIRTY );     /* WRITEABLE implies DIRTY */
++  }
++  /* NEED_SYNC can be set independently of WRITEABLE.  This can happen,
++  ** for example, when using the sqlite3PagerDontWrite() optimization:
++  **    (1)  Page X is journalled, and gets WRITEABLE and NEED_SEEK.
++  **    (2)  Page X moved to freelist, WRITEABLE is cleared
++  **    (3)  Page X reused, WRITEABLE is set again
++  ** If NEED_SYNC had been cleared in step 2, then it would not be reset
++  ** in step 3, and page might be written into the database without first
++  ** syncing the rollback journal, which might cause corruption on a power
++  ** loss.
++  **
++  ** Another example is when the database page size is smaller than the
++  ** disk sector size.  When any page of a sector is journalled, all pages
++  ** in that sector are marked NEED_SYNC even if they are still CLEAN, just
++  ** in case they are later modified, since all pages in the same sector
++  ** must be journalled and synced before any of those pages can be safely
++  ** written.
++  */
++  return 1;
++}
++#endif /* SQLITE_DEBUG */
++
++
+ /********************************** Linked List Management ********************/
+ 
+ /* Allowed values for second argument to pcacheManageDirtyList() */
+@@ -39300,17 +48763,16 @@
+ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
+   PCache *p = pPage->pCache;
+ 
++  pcacheTrace(("%p.DIRTYLIST.%s %d\n", p,
++                addRemove==1 ? "REMOVE" : addRemove==2 ? "ADD" : "FRONT",
++                pPage->pgno));
+   if( addRemove & PCACHE_DIRTYLIST_REMOVE ){
+     assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
+     assert( pPage->pDirtyPrev || pPage==p->pDirty );
+   
+     /* Update the PCache1.pSynced variable if necessary. */
+     if( p->pSynced==pPage ){
+-      PgHdr *pSynced = pPage->pDirtyPrev;
+-      while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){
+-        pSynced = pSynced->pDirtyPrev;
+-      }
+-      p->pSynced = pSynced;
++      p->pSynced = pPage->pDirtyPrev;
+     }
+   
+     if( pPage->pDirtyNext ){
+@@ -39322,10 +48784,15 @@
+     if( pPage->pDirtyPrev ){
+       pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
+     }else{
++      /* If there are now no dirty pages in the cache, set eCreate to 2. 
++      ** This is an optimization that allows sqlite3PcacheFetch() to skip
++      ** searching for a dirty page to eject from the cache when it might
++      ** otherwise have to.  */
+       assert( pPage==p->pDirty );
+       p->pDirty = pPage->pDirtyNext;
+-      if( p->pDirty==0 && p->bPurgeable ){
+-        assert( p->eCreate==1 );
++      assert( p->bPurgeable || p->eCreate==2 );
++      if( p->pDirty==0 ){         /*OPTIMIZATION-IF-TRUE*/
++        assert( p->bPurgeable==0 || p->eCreate==1 );
+         p->eCreate = 2;
+       }
+     }
+@@ -39347,10 +48814,19 @@
+       }
+     }
+     p->pDirty = pPage;
+-    if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
++
++    /* If pSynced is NULL and this page has a clear NEED_SYNC flag, set
++    ** pSynced to point to it. Checking the NEED_SYNC flag is an 
++    ** optimization, as if pSynced points to a page with the NEED_SYNC
++    ** flag set sqlite3PcacheFetchStress() searches through all newer 
++    ** entries of the dirty-list for a page with NEED_SYNC clear anyway.  */
++    if( !p->pSynced 
++     && 0==(pPage->flags&PGHDR_NEED_SYNC)   /*OPTIMIZATION-IF-FALSE*/
++    ){
+       p->pSynced = pPage;
+     }
+   }
++  pcacheDump(p);
+ }
+ 
+ /*
+@@ -39359,18 +48835,15 @@
+ */
+ static void pcacheUnpin(PgHdr *p){
+   if( p->pCache->bPurgeable ){
+-    if( p->pgno==1 ){
+-      p->pCache->pPage1 = 0;
+-    }
++    pcacheTrace(("%p.UNPIN %d\n", p->pCache, p->pgno));
+     sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0);
++    pcacheDump(p->pCache);
+   }
+ }
+ 
+ /*
+-** Compute the number of pages of cache requested.  p->szCache is the
++** Compute the number of pages of cache requested.   p->szCache is the
+ ** cache size requested by the "PRAGMA cache_size" statement.
+-**
+-**
+ */
+ static int numberOfCachePages(PCache *p){
+   if( p->szCache>=0 ){
+@@ -39416,6 +48889,12 @@
+ ** has already been allocated and is passed in as the p pointer. 
+ ** The caller discovers how much space needs to be allocated by 
+ ** calling sqlite3PcacheSize().
++**
++** szExtra is some extra space allocated for each page.  The first
++** 8 bytes of the extra space will be zeroed as the page is allocated,
++** but remaining content will be uninitialized.  Though it is opaque
++** to this module, the extra space really ends up being the MemPage
++** structure in the pager.
+ */
+ SQLITE_PRIVATE int sqlite3PcacheOpen(
+   int szPage,                  /* Size of every page */
+@@ -39428,11 +48907,14 @@
+   memset(p, 0, sizeof(PCache));
+   p->szPage = 1;
+   p->szExtra = szExtra;
++  assert( szExtra>=8 );  /* First 8 bytes will be zeroed */
+   p->bPurgeable = bPurgeable;
+   p->eCreate = 2;
+   p->xStress = xStress;
+   p->pStress = pStress;
+   p->szCache = 100;
++  p->szSpill = 1;
++  pcacheTrace(("%p.OPEN szPage %d bPurgeable %d\n",p,szPage,bPurgeable));
+   return sqlite3PcacheSetPageSize(p, szPage);
+ }
+ 
+@@ -39441,21 +48923,21 @@
+ ** are no outstanding page references when this function is called.
+ */
+ SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
+-  assert( pCache->nRef==0 && pCache->pDirty==0 );
++  assert( pCache->nRefSum==0 && pCache->pDirty==0 );
+   if( pCache->szPage ){
+     sqlite3_pcache *pNew;
+     pNew = sqlite3GlobalConfig.pcache2.xCreate(
+                 szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
+                 pCache->bPurgeable
+     );
+-    if( pNew==0 ) return SQLITE_NOMEM;
++    if( pNew==0 ) return SQLITE_NOMEM_BKPT;
+     sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
+     if( pCache->pCache ){
+       sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
+     }
+     pCache->pCache = pNew;
+-    pCache->pPage1 = 0;
+     pCache->szPage = szPage;
++    pcacheTrace(("%p.PAGESIZE %d\n",pCache,szPage));
+   }
+   return SQLITE_OK;
+ }
+@@ -39490,11 +48972,12 @@
+   int createFlag        /* If true, create page if it does not exist already */
+ ){
+   int eCreate;
++  sqlite3_pcache_page *pRes;
+ 
+   assert( pCache!=0 );
+   assert( pCache->pCache!=0 );
+   assert( createFlag==3 || createFlag==0 );
+-  assert( pgno>0 );
++  assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) );
+ 
+   /* eCreate defines what to do if the page does not exist.
+   **    0     Do not allocate a new page.  (createFlag==0)
+@@ -39507,12 +48990,15 @@
+   assert( eCreate==0 || eCreate==1 || eCreate==2 );
+   assert( createFlag==0 || pCache->eCreate==eCreate );
+   assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) );
+-  return sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
++  pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
++  pcacheTrace(("%p.FETCH %d%s (result: %p)\n",pCache,pgno,
++               createFlag?" create":"",pRes));
++  return pRes;
+ }
+ 
+ /*
+ ** If the sqlite3PcacheFetch() routine is unable to allocate a new
+-** page because new clean pages are available for reuse and the cache
++** page because no clean pages are available for reuse and the cache
+ ** size limit has been reached, then this routine can be invoked to 
+ ** try harder to allocate a page.  This routine might invoke the stress
+ ** callback to spill dirty pages to the journal.  It will then try to
+@@ -39529,36 +49015,43 @@
+   PgHdr *pPg;
+   if( pCache->eCreate==2 ) return 0;
+ 
+-
+-  /* Find a dirty page to write-out and recycle. First try to find a 
+-  ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
+-  ** cleared), but if that is not possible settle for any other 
+-  ** unreferenced dirty page.
+-  */
+-  for(pPg=pCache->pSynced; 
+-      pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); 
+-      pPg=pPg->pDirtyPrev
+-  );
+-  pCache->pSynced = pPg;
+-  if( !pPg ){
+-    for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
+-  }
+-  if( pPg ){
+-    int rc;
++  if( sqlite3PcachePagecount(pCache)>pCache->szSpill ){
++    /* Find a dirty page to write-out and recycle. First try to find a 
++    ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
++    ** cleared), but if that is not possible settle for any other 
++    ** unreferenced dirty page.
++    **
++    ** If the LRU page in the dirty list that has a clear PGHDR_NEED_SYNC
++    ** flag is currently referenced, then the following may leave pSynced
++    ** set incorrectly (pointing to other than the LRU page with NEED_SYNC
++    ** cleared). This is Ok, as pSynced is just an optimization.  */
++    for(pPg=pCache->pSynced; 
++        pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); 
++        pPg=pPg->pDirtyPrev
++    );
++    pCache->pSynced = pPg;
++    if( !pPg ){
++      for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
++    }
++    if( pPg ){
++      int rc;
+ #ifdef SQLITE_LOG_CACHE_SPILL
+-    sqlite3_log(SQLITE_FULL, 
+-                "spill page %d making room for %d - cache used: %d/%d",
+-                pPg->pgno, pgno,
+-                sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
++      sqlite3_log(SQLITE_FULL, 
++                  "spill page %d making room for %d - cache used: %d/%d",
++                  pPg->pgno, pgno,
++                  sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
+                 numberOfCachePages(pCache));
+ #endif
+-    rc = pCache->xStress(pCache->pStress, pPg);
+-    if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
+-      return rc;
++      pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno));
++      rc = pCache->xStress(pCache->pStress, pPg);
++      pcacheDump(pCache);
++      if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
++        return rc;
++      }
+     }
+   }
+   *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
+-  return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK;
++  return *ppPage==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
+ }
+ 
+ /*
+@@ -39579,13 +49072,14 @@
+   assert( pPage!=0 );
+   pPgHdr = (PgHdr*)pPage->pExtra;
+   assert( pPgHdr->pPage==0 );
+- memset(pPgHdr, 0, sizeof(PgHdr));
++  memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty));
+   pPgHdr->pPage = pPage;
+   pPgHdr->pData = pPage->pBuf;
+   pPgHdr->pExtra = (void *)&pPgHdr[1];
+-  memset(pPgHdr->pExtra, 0, pCache->szExtra);
++  memset(pPgHdr->pExtra, 0, 8);
+   pPgHdr->pCache = pCache;
+   pPgHdr->pgno = pgno;
++  pPgHdr->flags = PGHDR_CLEAN;
+   return sqlite3PcacheFetchFinish(pCache,pgno,pPage);
+ }
+ 
+@@ -39602,19 +49096,15 @@
+ ){
+   PgHdr *pPgHdr;
+ 
+-  if( pPage==0 ) return 0;
++  assert( pPage!=0 );
+   pPgHdr = (PgHdr *)pPage->pExtra;
+ 
+   if( !pPgHdr->pPage ){
+     return pcacheFetchFinishWithInit(pCache, pgno, pPage);
+   }
+-  if( 0==pPgHdr->nRef ){
+-    pCache->nRef++;
+-  }
++  pCache->nRefSum++;
+   pPgHdr->nRef++;
+-  if( pgno==1 ){
+-    pCache->pPage1 = pPgHdr;
+-  }
++  assert( sqlite3PcachePageSanity(pPgHdr) );
+   return pPgHdr;
+ }
+ 
+@@ -39624,13 +49114,15 @@
+ */
+ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
+   assert( p->nRef>0 );
+-  p->nRef--;
+-  if( p->nRef==0 ){
+-    p->pCache->nRef--;
+-    if( (p->flags&PGHDR_DIRTY)==0 ){
++  p->pCache->nRefSum--;
++  if( (--p->nRef)==0 ){
++    if( p->flags&PGHDR_CLEAN ){
+       pcacheUnpin(p);
+-    }else if( p->pDirtyPrev!=0 ){
+-      /* Move the page to the head of the dirty list. */
++    }else if( p->pDirtyPrev!=0 ){ /*OPTIMIZATION-IF-FALSE*/
++      /* Move the page to the head of the dirty list. If p->pDirtyPrev==0,
++      ** then page p is already at the head of the dirty list and the
++      ** following call would be a no-op. Hence the OPTIMIZATION-IF-FALSE
++      ** tag above.  */
+       pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
+     }
+   }
+@@ -39641,7 +49133,9 @@
+ */
+ SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
+   assert(p->nRef>0);
++  assert( sqlite3PcachePageSanity(p) );
+   p->nRef++;
++  p->pCache->nRefSum++;
+ }
+ 
+ /*
+@@ -39651,13 +49145,11 @@
+ */
+ SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
+   assert( p->nRef==1 );
++  assert( sqlite3PcachePageSanity(p) );
+   if( p->flags&PGHDR_DIRTY ){
+     pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
+   }
+-  p->pCache->nRef--;
+-  if( p->pgno==1 ){
+-    p->pCache->pPage1 = 0;
+-  }
++  p->pCache->nRefSum--;
+   sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1);
+ }
+ 
+@@ -39666,11 +49158,17 @@
+ ** make it so.
+ */
+ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
+-  p->flags &= ~PGHDR_DONT_WRITE;
+   assert( p->nRef>0 );
+-  if( 0==(p->flags & PGHDR_DIRTY) ){
+-    p->flags |= PGHDR_DIRTY;
+-    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
++  assert( sqlite3PcachePageSanity(p) );
++  if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){    /*OPTIMIZATION-IF-FALSE*/
++    p->flags &= ~PGHDR_DONT_WRITE;
++    if( p->flags & PGHDR_CLEAN ){
++      p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN);
++      pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno));
++      assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY );
++      pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
++    }
++    assert( sqlite3PcachePageSanity(p) );
+   }
+ }
+ 
+@@ -39679,9 +49177,14 @@
+ ** make it so.
+ */
+ SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
+-  if( (p->flags & PGHDR_DIRTY) ){
++  assert( sqlite3PcachePageSanity(p) );
++  if( ALWAYS((p->flags & PGHDR_DIRTY)!=0) ){
++    assert( (p->flags & PGHDR_CLEAN)==0 );
+     pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
+-    p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC);
++    p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
++    p->flags |= PGHDR_CLEAN;
++    pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno));
++    assert( sqlite3PcachePageSanity(p) );
+     if( p->nRef==0 ){
+       pcacheUnpin(p);
+     }
+@@ -39693,12 +49196,25 @@
+ */
+ SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){
+   PgHdr *p;
++  pcacheTrace(("%p.CLEAN-ALL\n",pCache));
+   while( (p = pCache->pDirty)!=0 ){
+     sqlite3PcacheMakeClean(p);
+   }
+ }
+ 
+ /*
++** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages.
++*/
++SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache *pCache){
++  PgHdr *p;
++  pcacheTrace(("%p.CLEAR-WRITEABLE\n",pCache));
++  for(p=pCache->pDirty; p; p=p->pDirtyNext){
++    p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
++  }
++  pCache->pSynced = pCache->pDirtyTail;
++}
++
++/*
+ ** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
+ */
+ SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){
+@@ -39716,6 +49232,8 @@
+   PCache *pCache = p->pCache;
+   assert( p->nRef>0 );
+   assert( newPgno>0 );
++  assert( sqlite3PcachePageSanity(p) );
++  pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
+   sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
+   p->pgno = newPgno;
+   if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
+@@ -39736,6 +49254,7 @@
+   if( pCache->pCache ){
+     PgHdr *p;
+     PgHdr *pNext;
++    pcacheTrace(("%p.TRUNCATE %d\n",pCache,pgno));
+     for(p=pCache->pDirty; p; p=pNext){
+       pNext = p->pDirtyNext;
+       /* This routine never gets call with a positive pgno except right
+@@ -39743,14 +49262,19 @@
+       ** it must be that pgno==0.
+       */
+       assert( p->pgno>0 );
+-      if( ALWAYS(p->pgno>pgno) ){
++      if( p->pgno>pgno ){
+         assert( p->flags&PGHDR_DIRTY );
+         sqlite3PcacheMakeClean(p);
+       }
+     }
+-    if( pgno==0 && pCache->pPage1 ){
+-      memset(pCache->pPage1->pData, 0, pCache->szPage);
+-      pgno = 1;
++    if( pgno==0 && pCache->nRefSum ){
++      sqlite3_pcache_page *pPage1;
++      pPage1 = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache,1,0);
++      if( ALWAYS(pPage1) ){  /* Page 1 is always available in cache, because
++                             ** pCache->nRefSum>0 */
++        memset(pPage1->pBuf, 0, pCache->szPage);
++        pgno = 1;
++      }
+     }
+     sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
+   }
+@@ -39761,6 +49285,7 @@
+ */
+ SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
+   assert( pCache->pCache!=0 );
++  pcacheTrace(("%p.CLOSE\n",pCache));
+   sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
+ }
+ 
+@@ -39773,29 +49298,31 @@
+ 
+ /*
+ ** Merge two lists of pages connected by pDirty and in pgno order.
+-** Do not both fixing the pDirtyPrev pointers.
++** Do not bother fixing the pDirtyPrev pointers.
+ */
+ static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
+   PgHdr result, *pTail;
+   pTail = &result;
+-  while( pA && pB ){
++  assert( pA!=0 && pB!=0 );
++  for(;;){
+     if( pA->pgno<pB->pgno ){
+       pTail->pDirty = pA;
+       pTail = pA;
+       pA = pA->pDirty;
++      if( pA==0 ){
++        pTail->pDirty = pB;
++        break;
++      }
+     }else{
+       pTail->pDirty = pB;
+       pTail = pB;
+       pB = pB->pDirty;
++      if( pB==0 ){
++        pTail->pDirty = pA;
++        break;
++      }
+     }
+   }
+-  if( pA ){
+-    pTail->pDirty = pA;
+-  }else if( pB ){
+-    pTail->pDirty = pB;
+-  }else{
+-    pTail->pDirty = 0;
+-  }
+   return result.pDirty;
+ }
+ 
+@@ -39836,7 +49363,8 @@
+   }
+   p = a[0];
+   for(i=1; i<N_SORT_BUCKET; i++){
+-    p = pcacheMergeDirtyList(p, a[i]);
++    if( a[i]==0 ) continue;
++    p = p ? pcacheMergeDirtyList(p, a[i]) : a[i];
+   }
+   return p;
+ }
+@@ -39853,10 +49381,13 @@
+ }
+ 
+ /* 
+-** Return the total number of referenced pages held by the cache.
++** Return the total number of references to all pages held by the cache.
++**
++** This is not the total number of pages referenced, but the sum of the
++** reference count for all pages.
+ */
+ SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
+-  return pCache->nRef;
++  return pCache->nRefSum;
+ }
+ 
+ /*
+@@ -39894,6 +49425,25 @@
+ }
+ 
+ /*
++** Set the suggested cache-spill value.  Make no changes if if the
++** argument is zero.  Return the effective cache-spill size, which will
++** be the larger of the szSpill and szCache.
++*/
++SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *p, int mxPage){
++  int res;
++  assert( p->pCache!=0 );
++  if( mxPage ){
++    if( mxPage<0 ){
++      mxPage = (int)((-1024*(i64)mxPage)/(p->szPage+p->szExtra));
++    }
++    p->szSpill = mxPage;
++  }
++  res = numberOfCachePages(p);
++  if( res<p->szSpill ) res = p->szSpill; 
++  return res;
++}
++
++/*
+ ** Free up as much memory as possible from the page cache.
+ */
+ SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
+@@ -39907,6 +49457,17 @@
+ */
+ SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
+ 
++/*
++** Return the number of dirty pages currently in the cache, as a percentage
++** of the configured cache size.
++*/
++SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache *pCache){
++  PgHdr *pDirty;
++  int nDirty = 0;
++  int nCache = numberOfCachePages(pCache);
++  for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++;
++  return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
++}
+ 
+ #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
+ /*
+@@ -39941,14 +49502,96 @@
+ ** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
+ ** If the default page cache implementation is overridden, then neither of
+ ** these two features are available.
++**
++** A Page cache line looks like this:
++**
++**  -------------------------------------------------------------
++**  |  database page content   |  PgHdr1  |  MemPage  |  PgHdr  |
++**  -------------------------------------------------------------
++**
++** The database page content is up front (so that buffer overreads tend to
++** flow harmlessly into the PgHdr1, MemPage, and PgHdr extensions).   MemPage
++** is the extension added by the btree.c module containing information such
++** as the database page number and how that database page is used.  PgHdr
++** is added by the pcache.c layer and contains information used to keep track
++** of which pages are "dirty".  PgHdr1 is an extension added by this
++** module (pcache1.c).  The PgHdr1 header is a subclass of sqlite3_pcache_page.
++** PgHdr1 contains information needed to look up a page by its page number.
++** The superclass sqlite3_pcache_page.pBuf points to the start of the
++** database page content and sqlite3_pcache_page.pExtra points to PgHdr.
++**
++** The size of the extension (MemPage+PgHdr+PgHdr1) can be determined at
++** runtime using sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &size).  The
++** sizes of the extensions sum to 272 bytes on x64 for 3.8.10, but this
++** size can vary according to architecture, compile-time options, and
++** SQLite library version number.
++**
++** If SQLITE_PCACHE_SEPARATE_HEADER is defined, then the extension is obtained
++** using a separate memory allocation from the database page content.  This
++** seeks to overcome the "clownshoe" problem (also called "internal
++** fragmentation" in academic literature) of allocating a few bytes more
++** than a power of two with the memory allocator rounding up to the next
++** power of two, and leaving the rounded-up space unused.
++**
++** This module tracks pointers to PgHdr1 objects.  Only pcache.c communicates
++** with this module.  Information is passed back and forth as PgHdr1 pointers.
++**
++** The pcache.c and pager.c modules deal pointers to PgHdr objects.
++** The btree.c module deals with pointers to MemPage objects.
++**
++** SOURCE OF PAGE CACHE MEMORY:
++**
++** Memory for a page might come from any of three sources:
++**
++**    (1)  The general-purpose memory allocator - sqlite3Malloc()
++**    (2)  Global page-cache memory provided using sqlite3_config() with
++**         SQLITE_CONFIG_PAGECACHE.
++**    (3)  PCache-local bulk allocation.
++**
++** The third case is a chunk of heap memory (defaulting to 100 pages worth)
++** that is allocated when the page cache is created.  The size of the local
++** bulk allocation can be adjusted using 
++**
++**     sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, N).
++**
++** If N is positive, then N pages worth of memory are allocated using a single
++** sqlite3Malloc() call and that memory is used for the first N pages allocated.
++** Or if N is negative, then -1024*N bytes of memory are allocated and used
++** for as many pages as can be accomodated.
++**
++** Only one of (2) or (3) can be used.  Once the memory available to (2) or
++** (3) is exhausted, subsequent allocations fail over to the general-purpose
++** memory allocator (1).
++**
++** Earlier versions of SQLite used only methods (1) and (2).  But experiments
++** show that method (3) with N==100 provides about a 5% performance boost for
++** common workloads.
+ */
+-
++/* #include "sqliteInt.h" */
+ 
+ typedef struct PCache1 PCache1;
+ typedef struct PgHdr1 PgHdr1;
+ typedef struct PgFreeslot PgFreeslot;
+ typedef struct PGroup PGroup;
+ 
++/*
++** Each cache entry is represented by an instance of the following 
++** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
++** PgHdr1.pCache->szPage bytes is allocated directly before this structure 
++** in memory.
++*/
++struct PgHdr1 {
++  sqlite3_pcache_page page;      /* Base class. Must be first. pBuf & pExtra */
++  unsigned int iKey;             /* Key value (page number) */
++  u8 isPinned;                   /* Page in use, not on the LRU list */
++  u8 isBulkLocal;                /* This page from bulk local storage */
++  u8 isAnchor;                   /* This is the PGroup.lru element */
++  PgHdr1 *pNext;                 /* Next in hash table chain */
++  PCache1 *pCache;               /* Cache that currently owns this page */
++  PgHdr1 *pLruNext;              /* Next in LRU list of unpinned pages */
++  PgHdr1 *pLruPrev;              /* Previous in LRU list of unpinned pages */
++};
++
+ /* Each page cache (or PCache) belongs to a PGroup.  A PGroup is a set 
+ ** of one or more PCaches that are able to recycle each other's unpinned
+ ** pages when they are under memory pressure.  A PGroup is an instance of
+@@ -39977,7 +49620,7 @@
+   unsigned int nMinPage;         /* Sum of nMin for purgeable caches */
+   unsigned int mxPinned;         /* nMaxpage + 10 - nMinPage */
+   unsigned int nCurrentPage;     /* Number of purgeable pages allocated */
+-  PgHdr1 *pLruHead, *pLruTail;   /* LRU list of unpinned pages */
++  PgHdr1 lru;                    /* The beginning and end of the LRU list */
+ };
+ 
+ /* Each page cache is an instance of the following object.  Every
+@@ -39995,8 +49638,9 @@
+   ** The PGroup mutex must be held when accessing nMax.
+   */
+   PGroup *pGroup;                     /* PGroup this cache belongs to */
+-  int szPage;                         /* Size of allocated pages in bytes */
+-  int szExtra;                        /* Size of extra space in bytes */
++  int szPage;                         /* Size of database content section */
++  int szExtra;                        /* sizeof(MemPage)+sizeof(PgHdr) */
++  int szAlloc;                        /* Total size of one pcache line */
+   int bPurgeable;                     /* True if cache is purgeable */
+   unsigned int nMin;                  /* Minimum number of pages reserved */
+   unsigned int nMax;                  /* Configured "cache_size" value */
+@@ -40010,27 +49654,13 @@
+   unsigned int nPage;                 /* Total number of pages in apHash */
+   unsigned int nHash;                 /* Number of slots in apHash[] */
+   PgHdr1 **apHash;                    /* Hash table for fast lookup by key */
++  PgHdr1 *pFree;                      /* List of unused pcache-local pages */
++  void *pBulk;                        /* Bulk memory used by pcache-local */
+ };
+ 
+ /*
+-** Each cache entry is represented by an instance of the following 
+-** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
+-** PgHdr1.pCache->szPage bytes is allocated directly before this structure 
+-** in memory.
+-*/
+-struct PgHdr1 {
+-  sqlite3_pcache_page page;
+-  unsigned int iKey;             /* Key value (page number) */
+-  u8 isPinned;                   /* Page in use, not on the LRU list */
+-  PgHdr1 *pNext;                 /* Next in hash table chain */
+-  PCache1 *pCache;               /* Cache that currently owns this page */
+-  PgHdr1 *pLruNext;              /* Next in LRU list of unpinned pages */
+-  PgHdr1 *pLruPrev;              /* Previous in LRU list of unpinned pages */
+-};
+-
+-/*
+-** Free slots in the allocator used to divide up the buffer provided using
+-** the SQLITE_CONFIG_PAGECACHE mechanism.
++** Free slots in the allocator used to divide up the global page cache
++** buffer provided using the SQLITE_CONFIG_PAGECACHE mechanism.
+ */
+ struct PgFreeslot {
+   PgFreeslot *pNext;  /* Next free slot */
+@@ -40048,10 +49678,12 @@
+   ** The nFreeSlot and pFree values do require mutex protection.
+   */
+   int isInit;                    /* True if initialized */
++  int separateCache;             /* Use a new PGroup for each PCache */
++  int nInitPage;                 /* Initial bulk allocation size */   
+   int szSlot;                    /* Size of each free slot */
+   int nSlot;                     /* The number of pcache slots */
+   int nReserve;                  /* Try to keep nFreeSlot above this */
+-  void *pStart, *pEnd;           /* Bounds of pagecache malloc range */
++  void *pStart, *pEnd;           /* Bounds of global page cache memory */
+   /* Above requires no mutex.  Use mutex below for variable that follow. */
+   sqlite3_mutex *mutex;          /* Mutex for accessing the following: */
+   PgFreeslot *pFree;             /* Free page blocks */
+@@ -40073,12 +49705,20 @@
+ /*
+ ** Macros to enter and leave the PCache LRU mutex.
+ */
+-#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
+-#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
++#if !defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
++# define pcache1EnterMutex(X)  assert((X)->mutex==0)
++# define pcache1LeaveMutex(X)  assert((X)->mutex==0)
++# define PCACHE1_MIGHT_USE_GROUP_MUTEX 0
++#else
++# define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
++# define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
++# define PCACHE1_MIGHT_USE_GROUP_MUTEX 1
++#endif
+ 
+ /******************************************************************************/
+ /******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
+ 
++
+ /*
+ ** This function is called during initialization if a static buffer is 
+ ** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE
+@@ -40091,6 +49731,7 @@
+ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
+   if( pcache1.isInit ){
+     PgFreeslot *p;
++    if( pBuf==0 ) sz = n = 0;
+     sz = ROUNDDOWN8(sz);
+     pcache1.szSlot = sz;
+     pcache1.nSlot = pcache1.nFreeSlot = n;
+@@ -40109,6 +49750,43 @@
+ }
+ 
+ /*
++** Try to initialize the pCache->pFree and pCache->pBulk fields.  Return
++** true if pCache->pFree ends up containing one or more free pages.
++*/
++static int pcache1InitBulk(PCache1 *pCache){
++  i64 szBulk;
++  char *zBulk;
++  if( pcache1.nInitPage==0 ) return 0;
++  /* Do not bother with a bulk allocation if the cache size very small */
++  if( pCache->nMax<3 ) return 0;
++  sqlite3BeginBenignMalloc();
++  if( pcache1.nInitPage>0 ){
++    szBulk = pCache->szAlloc * (i64)pcache1.nInitPage;
++  }else{
++    szBulk = -1024 * (i64)pcache1.nInitPage;
++  }
++  if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){
++    szBulk = pCache->szAlloc*(i64)pCache->nMax;
++  }
++  zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
++  sqlite3EndBenignMalloc();
++  if( zBulk ){
++    int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
++    do{
++      PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage];
++      pX->page.pBuf = zBulk;
++      pX->page.pExtra = &pX[1];
++      pX->isBulkLocal = 1;
++      pX->isAnchor = 0;
++      pX->pNext = pCache->pFree;
++      pCache->pFree = pX;
++      zBulk += pCache->szAlloc;
++    }while( --nBulk );
++  }
++  return pCache->pFree!=0;
++}
++
++/*
+ ** Malloc function used within this file to allocate space from the buffer
+ ** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no 
+ ** such buffer exists or there is no space left in it, this function falls 
+@@ -40128,7 +49806,7 @@
+       pcache1.nFreeSlot--;
+       pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
+       assert( pcache1.nFreeSlot>=0 );
+-      sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
++      sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
+       sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
+     }
+     sqlite3_mutex_leave(pcache1.mutex);
+@@ -40142,7 +49820,7 @@
+     if( p ){
+       int sz = sqlite3MallocSize(p);
+       sqlite3_mutex_enter(pcache1.mutex);
+-      sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
++      sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
+       sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
+       sqlite3_mutex_leave(pcache1.mutex);
+     }
+@@ -40155,10 +49833,9 @@
+ /*
+ ** Free an allocated buffer obtained from pcache1Alloc().
+ */
+-static int pcache1Free(void *p){
+-  int nFreed = 0;
+-  if( p==0 ) return 0;
+-  if( p>=pcache1.pStart && p<pcache1.pEnd ){
++static void pcache1Free(void *p){
++  if( p==0 ) return;
++  if( SQLITE_WITHIN(p, pcache1.pStart, pcache1.pEnd) ){
+     PgFreeslot *pSlot;
+     sqlite3_mutex_enter(pcache1.mutex);
+     sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1);
+@@ -40172,15 +49849,17 @@
+   }else{
+     assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
+     sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
+-    nFreed = sqlite3MallocSize(p);
+ #ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
+-    sqlite3_mutex_enter(pcache1.mutex);
+-    sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
+-    sqlite3_mutex_leave(pcache1.mutex);
++    {
++      int nFreed = 0;
++      nFreed = sqlite3MallocSize(p);
++      sqlite3_mutex_enter(pcache1.mutex);
++      sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
++      sqlite3_mutex_leave(pcache1.mutex);
++    }
+ #endif
+     sqlite3_free(p);
+   }
+-  return nFreed;
+ }
+ 
+ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+@@ -40204,58 +49883,72 @@
+ /*
+ ** Allocate a new page object initially associated with cache pCache.
+ */
+-static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
++static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
+   PgHdr1 *p = 0;
+   void *pPg;
+ 
+-  /* The group mutex must be released before pcache1Alloc() is called. This
+-  ** is because it may call sqlite3_release_memory(), which assumes that 
+-  ** this mutex is not held. */
+   assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
+-  pcache1LeaveMutex(pCache->pGroup);
++  if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){
++    p = pCache->pFree;
++    pCache->pFree = p->pNext;
++    p->pNext = 0;
++  }else{
++#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
++    /* The group mutex must be released before pcache1Alloc() is called. This
++    ** is because it might call sqlite3_release_memory(), which assumes that 
++    ** this mutex is not held. */
++    assert( pcache1.separateCache==0 );
++    assert( pCache->pGroup==&pcache1.grp );
++    pcache1LeaveMutex(pCache->pGroup);
++#endif
++    if( benignMalloc ){ sqlite3BeginBenignMalloc(); }
+ #ifdef SQLITE_PCACHE_SEPARATE_HEADER
+-  pPg = pcache1Alloc(pCache->szPage);
+-  p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
+-  if( !pPg || !p ){
+-    pcache1Free(pPg);
+-    sqlite3_free(p);
+-    pPg = 0;
+-  }
++    pPg = pcache1Alloc(pCache->szPage);
++    p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
++    if( !pPg || !p ){
++      pcache1Free(pPg);
++      sqlite3_free(p);
++      pPg = 0;
++    }
+ #else
+-  pPg = pcache1Alloc(ROUND8(sizeof(PgHdr1)) + pCache->szPage + pCache->szExtra);
+-  p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
++    pPg = pcache1Alloc(pCache->szAlloc);
++    p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
+ #endif
+-  pcache1EnterMutex(pCache->pGroup);
+-
+-  if( pPg ){
++    if( benignMalloc ){ sqlite3EndBenignMalloc(); }
++#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
++    pcache1EnterMutex(pCache->pGroup);
++#endif
++    if( pPg==0 ) return 0;
+     p->page.pBuf = pPg;
+     p->page.pExtra = &p[1];
+-    if( pCache->bPurgeable ){
+-      pCache->pGroup->nCurrentPage++;
+-    }
+-    return p;
++    p->isBulkLocal = 0;
++    p->isAnchor = 0;
+   }
+-  return 0;
++  if( pCache->bPurgeable ){
++    pCache->pGroup->nCurrentPage++;
++  }
++  return p;
+ }
+ 
+ /*
+ ** Free a page object allocated by pcache1AllocPage().
+-**
+-** The pointer is allowed to be NULL, which is prudent.  But it turns out
+-** that the current implementation happens to never call this routine
+-** with a NULL pointer, so we mark the NULL test with ALWAYS().
+ */
+ static void pcache1FreePage(PgHdr1 *p){
+-  if( ALWAYS(p) ){
+-    PCache1 *pCache = p->pCache;
+-    assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
++  PCache1 *pCache;
++  assert( p!=0 );
++  pCache = p->pCache;
++  assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
++  if( p->isBulkLocal ){
++    p->pNext = pCache->pFree;
++    pCache->pFree = p;
++  }else{
+     pcache1Free(p->page.pBuf);
+ #ifdef SQLITE_PCACHE_SEPARATE_HEADER
+     sqlite3_free(p);
+ #endif
+-    if( pCache->bPurgeable ){
+-      pCache->pGroup->nCurrentPage--;
+-    }
++  }
++  if( pCache->bPurgeable ){
++    pCache->pGroup->nCurrentPage--;
+   }
+ }
+ 
+@@ -40350,41 +50043,35 @@
+ **
+ ** The PGroup mutex must be held when this function is called.
+ */
+-static void pcache1PinPage(PgHdr1 *pPage){
++static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){
+   PCache1 *pCache;
+-  PGroup *pGroup;
+ 
+   assert( pPage!=0 );
+   assert( pPage->isPinned==0 );
+   pCache = pPage->pCache;
+-  pGroup = pCache->pGroup;
+-  assert( pPage->pLruNext || pPage==pGroup->pLruTail );
+-  assert( pPage->pLruPrev || pPage==pGroup->pLruHead );
+-  assert( sqlite3_mutex_held(pGroup->mutex) );
+-  if( pPage->pLruPrev ){
+-    pPage->pLruPrev->pLruNext = pPage->pLruNext;
+-  }else{
+-    pGroup->pLruHead = pPage->pLruNext;
+-  }
+-  if( pPage->pLruNext ){
+-    pPage->pLruNext->pLruPrev = pPage->pLruPrev;
+-  }else{
+-    pGroup->pLruTail = pPage->pLruPrev;
+-  }
++  assert( pPage->pLruNext );
++  assert( pPage->pLruPrev );
++  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
++  pPage->pLruPrev->pLruNext = pPage->pLruNext;
++  pPage->pLruNext->pLruPrev = pPage->pLruPrev;
+   pPage->pLruNext = 0;
+   pPage->pLruPrev = 0;
+   pPage->isPinned = 1;
++  assert( pPage->isAnchor==0 );
++  assert( pCache->pGroup->lru.isAnchor==1 );
+   pCache->nRecyclable--;
++  return pPage;
+ }
+ 
+ 
+ /*
+ ** Remove the page supplied as an argument from the hash table 
+ ** (PCache1.apHash structure) that it is currently stored in.
++** Also free the page if freePage is true.
+ **
+ ** The PGroup mutex must be held when this function is called.
+ */
+-static void pcache1RemoveFromHash(PgHdr1 *pPage){
++static void pcache1RemoveFromHash(PgHdr1 *pPage, int freeFlag){
+   unsigned int h;
+   PCache1 *pCache = pPage->pCache;
+   PgHdr1 **pp;
+@@ -40395,21 +50082,28 @@
+   *pp = (*pp)->pNext;
+ 
+   pCache->nPage--;
++  if( freeFlag ) pcache1FreePage(pPage);
+ }
+ 
+ /*
+ ** If there are currently more than nMaxPage pages allocated, try
+ ** to recycle pages to reduce the number allocated to nMaxPage.
+ */
+-static void pcache1EnforceMaxPage(PGroup *pGroup){
++static void pcache1EnforceMaxPage(PCache1 *pCache){
++  PGroup *pGroup = pCache->pGroup;
++  PgHdr1 *p;
+   assert( sqlite3_mutex_held(pGroup->mutex) );
+-  while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){
+-    PgHdr1 *p = pGroup->pLruTail;
++  while( pGroup->nCurrentPage>pGroup->nMaxPage
++      && (p=pGroup->lru.pLruPrev)->isAnchor==0
++  ){
+     assert( p->pCache->pGroup==pGroup );
+     assert( p->isPinned==0 );
+     pcache1PinPage(p);
+-    pcache1RemoveFromHash(p);
+-    pcache1FreePage(p);
++    pcache1RemoveFromHash(p, 1);
++  }
++  if( pCache->nPage==0 && pCache->pBulk ){
++    sqlite3_free(pCache->pBulk);
++    pCache->pBulk = pCache->pFree = 0;
+   }
+ }
+ 
+@@ -40424,12 +50118,30 @@
+   PCache1 *pCache,             /* The cache to truncate */
+   unsigned int iLimit          /* Drop pages with this pgno or larger */
+ ){
+-  TESTONLY( unsigned int nPage = 0; )  /* To assert pCache->nPage is correct */
+-  unsigned int h;
++  TESTONLY( int nPage = 0; )  /* To assert pCache->nPage is correct */
++  unsigned int h, iStop;
+   assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
+-  for(h=0; h<pCache->nHash; h++){
+-    PgHdr1 **pp = &pCache->apHash[h]; 
++  assert( pCache->iMaxKey >= iLimit );
++  assert( pCache->nHash > 0 );
++  if( pCache->iMaxKey - iLimit < pCache->nHash ){
++    /* If we are just shaving the last few pages off the end of the
++    ** cache, then there is no point in scanning the entire hash table.
++    ** Only scan those hash slots that might contain pages that need to
++    ** be removed. */
++    h = iLimit % pCache->nHash;
++    iStop = pCache->iMaxKey % pCache->nHash;
++    TESTONLY( nPage = -10; )  /* Disable the pCache->nPage validity check */
++  }else{
++    /* This is the general case where many pages are being removed.
++    ** It is necessary to scan the entire hash table */
++    h = pCache->nHash/2;
++    iStop = h - 1;
++  }
++  for(;;){
++    PgHdr1 **pp;
+     PgHdr1 *pPage;
++    assert( h<pCache->nHash );
++    pp = &pCache->apHash[h]; 
+     while( (pPage = *pp)!=0 ){
+       if( pPage->iKey>=iLimit ){
+         pCache->nPage--;
+@@ -40438,11 +50150,13 @@
+         pcache1FreePage(pPage);
+       }else{
+         pp = &pPage->pNext;
+-        TESTONLY( nPage++; )
++        TESTONLY( if( nPage>=0 ) nPage++; )
+       }
+     }
++    if( h==iStop ) break;
++    h = (h+1) % pCache->nHash;
+   }
+-  assert( pCache->nPage==nPage );
++  assert( nPage<0 || pCache->nPage==(unsigned)nPage );
+ }
+ 
+ /******************************************************************************/
+@@ -40455,9 +50169,44 @@
+   UNUSED_PARAMETER(NotUsed);
+   assert( pcache1.isInit==0 );
+   memset(&pcache1, 0, sizeof(pcache1));
++
++
++  /*
++  ** The pcache1.separateCache variable is true if each PCache has its own
++  ** private PGroup (mode-1).  pcache1.separateCache is false if the single
++  ** PGroup in pcache1.grp is used for all page caches (mode-2).
++  **
++  **   *  Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
++  **
++  **   *  Use a unified cache in single-threaded applications that have
++  **      configured a start-time buffer for use as page-cache memory using
++  **      sqlite3_config(SQLITE_CONFIG_PAGECACHE, pBuf, sz, N) with non-NULL 
++  **      pBuf argument.
++  **
++  **   *  Otherwise use separate caches (mode-1)
++  */
++#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)
++  pcache1.separateCache = 0;
++#elif SQLITE_THREADSAFE
++  pcache1.separateCache = sqlite3GlobalConfig.pPage==0
++                          || sqlite3GlobalConfig.bCoreMutex>0;
++#else
++  pcache1.separateCache = sqlite3GlobalConfig.pPage==0;
++#endif
++
++#if SQLITE_THREADSAFE
+   if( sqlite3GlobalConfig.bCoreMutex ){
+-    pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
+-    pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
++    pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU);
++    pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM);
++  }
++#endif
++  if( pcache1.separateCache
++   && sqlite3GlobalConfig.nPage!=0
++   && sqlite3GlobalConfig.pPage==0
++  ){
++    pcache1.nInitPage = sqlite3GlobalConfig.nPage;
++  }else{
++    pcache1.nInitPage = 0;
+   }
+   pcache1.grp.mxPinned = 10;
+   pcache1.isInit = 1;
+@@ -40488,39 +50237,26 @@
+   PGroup *pGroup;       /* The group the new page cache will belong to */
+   int sz;               /* Bytes of memory required to allocate the new cache */
+ 
+-  /*
+-  ** The separateCache variable is true if each PCache has its own private
+-  ** PGroup.  In other words, separateCache is true for mode (1) where no
+-  ** mutexing is required.
+-  **
+-  **   *  Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
+-  **
+-  **   *  Always use a unified cache in single-threaded applications
+-  **
+-  **   *  Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off)
+-  **      use separate caches (mode-1)
+-  */
+-#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
+-  const int separateCache = 0;
+-#else
+-  int separateCache = sqlite3GlobalConfig.bCoreMutex>0;
+-#endif
+-
+   assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
+   assert( szExtra < 300 );
+ 
+-  sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
++  sz = sizeof(PCache1) + sizeof(PGroup)*pcache1.separateCache;
+   pCache = (PCache1 *)sqlite3MallocZero(sz);
+   if( pCache ){
+-    if( separateCache ){
++    if( pcache1.separateCache ){
+       pGroup = (PGroup*)&pCache[1];
+       pGroup->mxPinned = 10;
+     }else{
+       pGroup = &pcache1.grp;
+     }
++    if( pGroup->lru.isAnchor==0 ){
++      pGroup->lru.isAnchor = 1;
++      pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru;
++    }
+     pCache->pGroup = pGroup;
+     pCache->szPage = szPage;
+     pCache->szExtra = szExtra;
++    pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1));
+     pCache->bPurgeable = (bPurgeable ? 1 : 0);
+     pcache1EnterMutex(pGroup);
+     pcache1ResizeHash(pCache);
+@@ -40552,7 +50288,7 @@
+     pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
+     pCache->nMax = nMax;
+     pCache->n90pct = pCache->nMax*9/10;
+-    pcache1EnforceMaxPage(pGroup);
++    pcache1EnforceMaxPage(pCache);
+     pcache1LeaveMutex(pGroup);
+   }
+ }
+@@ -40570,7 +50306,7 @@
+     pcache1EnterMutex(pGroup);
+     savedMaxPage = pGroup->nMaxPage;
+     pGroup->nMaxPage = 0;
+-    pcache1EnforceMaxPage(pGroup);
++    pcache1EnforceMaxPage(pCache);
+     pGroup->nMaxPage = savedMaxPage;
+     pcache1LeaveMutex(pGroup);
+   }
+@@ -40623,26 +50359,17 @@
+   assert( pCache->nHash>0 && pCache->apHash );
+ 
+   /* Step 4. Try to recycle a page. */
+-  if( pCache->bPurgeable && pGroup->pLruTail && (
+-         (pCache->nPage+1>=pCache->nMax)
+-      || pGroup->nCurrentPage>=pGroup->nMaxPage
+-      || pcache1UnderMemoryPressure(pCache)
+-  )){
++  if( pCache->bPurgeable
++   && !pGroup->lru.pLruPrev->isAnchor
++   && ((pCache->nPage+1>=pCache->nMax) || pcache1UnderMemoryPressure(pCache))
++  ){
+     PCache1 *pOther;
+-    pPage = pGroup->pLruTail;
++    pPage = pGroup->lru.pLruPrev;
+     assert( pPage->isPinned==0 );
+-    pcache1RemoveFromHash(pPage);
++    pcache1RemoveFromHash(pPage, 0);
+     pcache1PinPage(pPage);
+     pOther = pPage->pCache;
+-
+-    /* We want to verify that szPage and szExtra are the same for pOther
+-    ** and pCache.  Assert that we can verify this by comparing sums. */
+-    assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 );
+-    assert( pCache->szExtra<512 );
+-    assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 );
+-    assert( pOther->szExtra<512 );
+-
+-    if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
++    if( pOther->szAlloc != pCache->szAlloc ){
+       pcache1FreePage(pPage);
+       pPage = 0;
+     }else{
+@@ -40654,9 +50381,7 @@
+   ** attempt to allocate a new one. 
+   */
+   if( !pPage ){
+-    if( createFlag==1 ) sqlite3BeginBenignMalloc();
+-    pPage = pcache1AllocPage(pCache);
+-    if( createFlag==1 ) sqlite3EndBenignMalloc();
++    pPage = pcache1AllocPage(pCache, createFlag==1);
+   }
+ 
+   if( pPage ){
+@@ -40730,8 +50455,13 @@
+ **      proceed to step 5. 
+ **
+ **   5. Otherwise, allocate and return a new page buffer.
++**
++** There are two versions of this routine.  pcache1FetchWithMutex() is
++** the general case.  pcache1FetchNoMutex() is a faster implementation for
++** the common case where pGroup->mutex is NULL.  The pcache1Fetch() wrapper
++** invokes the appropriate routine.
+ */
+-static sqlite3_pcache_page *pcache1Fetch(
++static PgHdr1 *pcache1FetchNoMutex(
+   sqlite3_pcache *p, 
+   unsigned int iKey, 
+   int createFlag
+@@ -40739,28 +50469,66 @@
+   PCache1 *pCache = (PCache1 *)p;
+   PgHdr1 *pPage = 0;
+ 
+-  assert( offsetof(PgHdr1,page)==0 );
+-  assert( pCache->bPurgeable || createFlag!=1 );
+-  assert( pCache->bPurgeable || pCache->nMin==0 );
+-  assert( pCache->bPurgeable==0 || pCache->nMin==10 );
+-  assert( pCache->nMin==0 || pCache->bPurgeable );
+-  assert( pCache->nHash>0 );
+-  pcache1EnterMutex(pCache->pGroup);
+-
+   /* Step 1: Search the hash table for an existing entry. */
+   pPage = pCache->apHash[iKey % pCache->nHash];
+   while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; }
+ 
+-  /* Step 2: Abort if no existing page is found and createFlag is 0 */
++  /* Step 2: If the page was found in the hash table, then return it.
++  ** If the page was not in the hash table and createFlag is 0, abort.
++  ** Otherwise (page not in hash and createFlag!=0) continue with
++  ** subsequent steps to try to create the page. */
+   if( pPage ){
+-    if( !pPage->isPinned ) pcache1PinPage(pPage);
++    if( !pPage->isPinned ){
++      return pcache1PinPage(pPage);
++    }else{
++      return pPage;
++    }
+   }else if( createFlag ){
+     /* Steps 3, 4, and 5 implemented by this subroutine */
+-    pPage = pcache1FetchStage2(pCache, iKey, createFlag);
++    return pcache1FetchStage2(pCache, iKey, createFlag);
++  }else{
++    return 0;
+   }
++}
++#if PCACHE1_MIGHT_USE_GROUP_MUTEX
++static PgHdr1 *pcache1FetchWithMutex(
++  sqlite3_pcache *p, 
++  unsigned int iKey, 
++  int createFlag
++){
++  PCache1 *pCache = (PCache1 *)p;
++  PgHdr1 *pPage;
++
++  pcache1EnterMutex(pCache->pGroup);
++  pPage = pcache1FetchNoMutex(p, iKey, createFlag);
+   assert( pPage==0 || pCache->iMaxKey>=iKey );
+   pcache1LeaveMutex(pCache->pGroup);
+-  return (sqlite3_pcache_page*)pPage;
++  return pPage;
++}
++#endif
++static sqlite3_pcache_page *pcache1Fetch(
++  sqlite3_pcache *p, 
++  unsigned int iKey, 
++  int createFlag
++){
++#if PCACHE1_MIGHT_USE_GROUP_MUTEX || defined(SQLITE_DEBUG)
++  PCache1 *pCache = (PCache1 *)p;
++#endif
++
++  assert( offsetof(PgHdr1,page)==0 );
++  assert( pCache->bPurgeable || createFlag!=1 );
++  assert( pCache->bPurgeable || pCache->nMin==0 );
++  assert( pCache->bPurgeable==0 || pCache->nMin==10 );
++  assert( pCache->nMin==0 || pCache->bPurgeable );
++  assert( pCache->nHash>0 );
++#if PCACHE1_MIGHT_USE_GROUP_MUTEX
++  if( pCache->pGroup->mutex ){
++    return (sqlite3_pcache_page*)pcache1FetchWithMutex(p, iKey, createFlag);
++  }else
++#endif
++  {
++    return (sqlite3_pcache_page*)pcache1FetchNoMutex(p, iKey, createFlag);
++  }
+ }
+ 
+ 
+@@ -40785,22 +50553,16 @@
+   ** part of the PGroup LRU list.
+   */
+   assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
+-  assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage );
+   assert( pPage->isPinned==1 );
+ 
+   if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
+-    pcache1RemoveFromHash(pPage);
+-    pcache1FreePage(pPage);
++    pcache1RemoveFromHash(pPage, 1);
+   }else{
+     /* Add the page to the PGroup LRU list. */
+-    if( pGroup->pLruHead ){
+-      pGroup->pLruHead->pLruPrev = pPage;
+-      pPage->pLruNext = pGroup->pLruHead;
+-      pGroup->pLruHead = pPage;
+-    }else{
+-      pGroup->pLruTail = pPage;
+-      pGroup->pLruHead = pPage;
+-    }
++    PgHdr1 **ppFirst = &pGroup->lru.pLruNext;
++    pPage->pLruPrev = &pGroup->lru;
++    (pPage->pLruNext = *ppFirst)->pLruPrev = pPage;
++    *ppFirst = pPage;
+     pCache->nRecyclable++;
+     pPage->isPinned = 0;
+   }
+@@ -40871,14 +50633,15 @@
+   PGroup *pGroup = pCache->pGroup;
+   assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
+   pcache1EnterMutex(pGroup);
+-  pcache1TruncateUnsafe(pCache, 0);
++  if( pCache->nPage ) pcache1TruncateUnsafe(pCache, 0);
+   assert( pGroup->nMaxPage >= pCache->nMax );
+   pGroup->nMaxPage -= pCache->nMax;
+   assert( pGroup->nMinPage >= pCache->nMin );
+   pGroup->nMinPage -= pCache->nMin;
+   pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
+-  pcache1EnforceMaxPage(pGroup);
++  pcache1EnforceMaxPage(pCache);
+   pcache1LeaveMutex(pGroup);
++  sqlite3_free(pCache->pBulk);
+   sqlite3_free(pCache->apHash);
+   sqlite3_free(pCache);
+ }
+@@ -40934,18 +50697,20 @@
+   int nFree = 0;
+   assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
+   assert( sqlite3_mutex_notheld(pcache1.mutex) );
+-  if( pcache1.pStart==0 ){
++  if( sqlite3GlobalConfig.pPage==0 ){
+     PgHdr1 *p;
+     pcache1EnterMutex(&pcache1.grp);
+-    while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
++    while( (nReq<0 || nFree<nReq)
++       &&  (p=pcache1.grp.lru.pLruPrev)!=0
++       &&  p->isAnchor==0
++    ){
+       nFree += pcache1MemSize(p->page.pBuf);
+ #ifdef SQLITE_PCACHE_SEPARATE_HEADER
+       nFree += sqlite3MemSize(p);
+ #endif
+       assert( p->isPinned==0 );
+       pcache1PinPage(p);
+-      pcache1RemoveFromHash(p);
+-      pcache1FreePage(p);
++      pcache1RemoveFromHash(p, 1);
+     }
+     pcache1LeaveMutex(&pcache1.grp);
+   }
+@@ -40966,7 +50731,7 @@
+ ){
+   PgHdr1 *p;
+   int nRecyclable = 0;
+-  for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){
++  for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){
+     assert( p->isPinned==0 );
+     nRecyclable++;
+   }
+@@ -41038,9 +50803,11 @@
+ ** of the first SMALLEST is O(NlogN).  Second and subsequent SMALLEST
+ ** primitives are constant time.  The cost of DESTROY is O(N).
+ **
+-** There is an added cost of O(N) when switching between TEST and
+-** SMALLEST primitives.
++** TEST and SMALLEST may not be used by the same RowSet.  This used to
++** be possible, but the feature was not used, so it was removed in order
++** to simplify the code.
+ */
++/* #include "sqliteInt.h" */
+ 
+ 
+ /*
+@@ -41159,9 +50926,11 @@
+ */
+ static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
+   assert( p!=0 );
+-  if( p->nFresh==0 ){
++  if( p->nFresh==0 ){  /*OPTIMIZATION-IF-FALSE*/
++    /* We could allocate a fresh RowSetEntry each time one is needed, but it
++    ** is more efficient to pull a preallocated entry from the pool */
+     struct RowSetChunk *pNew;
+-    pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew));
++    pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew));
+     if( pNew==0 ){
+       return 0;
+     }
+@@ -41193,7 +50962,9 @@
+   pEntry->pRight = 0;
+   pLast = p->pLast;
+   if( pLast ){
+-    if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){
++    if( rowid<=pLast->v ){  /*OPTIMIZATION-IF-FALSE*/
++      /* Avoid unnecessary sorts by preserving the ROWSET_SORTED flags
++      ** where possible */
+       p->rsFlags &= ~ROWSET_SORTED;
+     }
+     pLast->pRight = pEntry;
+@@ -41217,28 +50988,26 @@
+   struct RowSetEntry *pTail;
+ 
+   pTail = &head;
+-  while( pA && pB ){
++  assert( pA!=0 && pB!=0 );
++  for(;;){
+     assert( pA->pRight==0 || pA->v<=pA->pRight->v );
+     assert( pB->pRight==0 || pB->v<=pB->pRight->v );
+-    if( pA->v<pB->v ){
+-      pTail->pRight = pA;
++    if( pA->v<=pB->v ){
++      if( pA->v<pB->v ) pTail = pTail->pRight = pA;
+       pA = pA->pRight;
+-      pTail = pTail->pRight;
+-    }else if( pB->v<pA->v ){
+-      pTail->pRight = pB;
+-      pB = pB->pRight;
+-      pTail = pTail->pRight;
++      if( pA==0 ){
++        pTail->pRight = pB;
++        break;
++      }
+     }else{
+-      pA = pA->pRight;
++      pTail = pTail->pRight = pB;
++      pB = pB->pRight;
++      if( pB==0 ){
++        pTail->pRight = pA;
++        break;
++      }
+     }
+   }
+-  if( pA ){
+-    assert( pA->pRight==0 || pA->v<=pA->pRight->v );
+-    pTail->pRight = pA;
+-  }else{
+-    assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v );
+-    pTail->pRight = pB;
+-  }
+   return head.pRight;
+ }
+ 
+@@ -41261,9 +51030,10 @@
+     aBucket[i] = pIn;
+     pIn = pNext;
+   }
+-  pIn = 0;
+-  for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
+-    pIn = rowSetEntryMerge(pIn, aBucket[i]);
++  pIn = aBucket[0];
++  for(i=1; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
++    if( aBucket[i]==0 ) continue;
++    pIn = pIn ? rowSetEntryMerge(pIn, aBucket[i]) : aBucket[i];
+   }
+   return pIn;
+ }
+@@ -41315,23 +51085,29 @@
+ ){
+   struct RowSetEntry *p;         /* Root of the new tree */
+   struct RowSetEntry *pLeft;     /* Left subtree */
+-  if( *ppList==0 ){
+-    return 0;
+-  }
+-  if( iDepth==1 ){
++  if( *ppList==0 ){ /*OPTIMIZATION-IF-TRUE*/
++    /* Prevent unnecessary deep recursion when we run out of entries */
++    return 0; 
++  }
++  if( iDepth>1 ){   /*OPTIMIZATION-IF-TRUE*/
++    /* This branch causes a *balanced* tree to be generated.  A valid tree
++    ** is still generated without this branch, but the tree is wildly
++    ** unbalanced and inefficient. */
++    pLeft = rowSetNDeepTree(ppList, iDepth-1);
++    p = *ppList;
++    if( p==0 ){     /*OPTIMIZATION-IF-FALSE*/
++      /* It is safe to always return here, but the resulting tree
++      ** would be unbalanced */
++      return pLeft;
++    }
++    p->pLeft = pLeft;
++    *ppList = p->pRight;
++    p->pRight = rowSetNDeepTree(ppList, iDepth-1);
++  }else{
+     p = *ppList;
+     *ppList = p->pRight;
+     p->pLeft = p->pRight = 0;
+-    return p;
+   }
+-  pLeft = rowSetNDeepTree(ppList, iDepth-1);
+-  p = *ppList;
+-  if( p==0 ){
+-    return pLeft;
+-  }
+-  p->pLeft = pLeft;
+-  *ppList = p->pRight;
+-  p->pRight = rowSetNDeepTree(ppList, iDepth-1);
+   return p;
+ }
+ 
+@@ -41359,58 +51135,36 @@
+ }
+ 
+ /*
+-** Take all the entries on p->pEntry and on the trees in p->pForest and
+-** sort them all together into one big ordered list on p->pEntry.
+-**
+-** This routine should only be called once in the life of a RowSet.
+-*/
+-static void rowSetToList(RowSet *p){
+-
+-  /* This routine is called only once */
+-  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
+-
+-  if( (p->rsFlags & ROWSET_SORTED)==0 ){
+-    p->pEntry = rowSetEntrySort(p->pEntry);
+-  }
+-
+-  /* While this module could theoretically support it, sqlite3RowSetNext()
+-  ** is never called after sqlite3RowSetText() for the same RowSet.  So
+-  ** there is never a forest to deal with.  Should this change, simply
+-  ** remove the assert() and the #if 0. */
+-  assert( p->pForest==0 );
+-#if 0
+-  while( p->pForest ){
+-    struct RowSetEntry *pTree = p->pForest->pLeft;
+-    if( pTree ){
+-      struct RowSetEntry *pHead, *pTail;
+-      rowSetTreeToList(pTree, &pHead, &pTail);
+-      p->pEntry = rowSetEntryMerge(p->pEntry, pHead);
+-    }
+-    p->pForest = p->pForest->pRight;
+-  }
+-#endif
+-  p->rsFlags |= ROWSET_NEXT;  /* Verify this routine is never called again */
+-}
+-
+-/*
+ ** Extract the smallest element from the RowSet.
+ ** Write the element into *pRowid.  Return 1 on success.  Return
+ ** 0 if the RowSet is already empty.
+ **
+ ** After this routine has been called, the sqlite3RowSetInsert()
+-** routine may not be called again.  
++** routine may not be called again.
++**
++** This routine may not be called after sqlite3RowSetTest() has
++** been used.  Older versions of RowSet allowed that, but as the
++** capability was not used by the code generator, it was removed
++** for code economy.
+ */
+ SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
+   assert( p!=0 );
++  assert( p->pForest==0 );  /* Cannot be used with sqlite3RowSetText() */
+ 
+   /* Merge the forest into a single sorted list on first call */
+-  if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p);
++  if( (p->rsFlags & ROWSET_NEXT)==0 ){  /*OPTIMIZATION-IF-FALSE*/
++    if( (p->rsFlags & ROWSET_SORTED)==0 ){  /*OPTIMIZATION-IF-FALSE*/
++      p->pEntry = rowSetEntrySort(p->pEntry);
++    }
++    p->rsFlags |= ROWSET_SORTED|ROWSET_NEXT;
++  }
+ 
+   /* Return the next entry on the list */
+   if( p->pEntry ){
+     *pRowid = p->pEntry->v;
+     p->pEntry = p->pEntry->pRight;
+-    if( p->pEntry==0 ){
++    if( p->pEntry==0 ){ /*OPTIMIZATION-IF-TRUE*/
++      /* Free memory immediately, rather than waiting on sqlite3_finalize() */
+       sqlite3RowSetClear(p);
+     }
+     return 1;
+@@ -41433,13 +51187,15 @@
+   /* This routine is never called after sqlite3RowSetNext() */
+   assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
+ 
+-  /* Sort entries into the forest on the first test of a new batch 
++  /* Sort entries into the forest on the first test of a new batch.
++  ** To save unnecessary work, only do this when the batch number changes.
+   */
+-  if( iBatch!=pRowSet->iBatch ){
++  if( iBatch!=pRowSet->iBatch ){  /*OPTIMIZATION-IF-FALSE*/
+     p = pRowSet->pEntry;
+     if( p ){
+       struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
+-      if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){
++      if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
++        /* Only sort the current set of entiries if they need it */
+         p = rowSetEntrySort(p);
+       }
+       for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
+@@ -41510,6 +51266,7 @@
+ ** another is writing.
+ */
+ #ifndef SQLITE_OMIT_DISKIO
++/* #include "sqliteInt.h" */
+ /************** Include wal.h in the middle of pager.c ***********************/
+ /************** Begin file wal.h *********************************************/
+ /*
+@@ -41528,9 +51285,10 @@
+ ** the implementation of each function in log.c for further details.
+ */
+ 
+-#ifndef _WAL_H_
+-#define _WAL_H_
++#ifndef SQLITE_WAL_H
++#define SQLITE_WAL_H
+ 
++/* #include "sqliteInt.h" */
+ 
+ /* Additional values that can be added to the sync_flags argument of
+ ** sqlite3WalFrames():
+@@ -41541,7 +51299,7 @@
+ #ifdef SQLITE_OMIT_WAL
+ # define sqlite3WalOpen(x,y,z)                   0
+ # define sqlite3WalLimit(x,y)
+-# define sqlite3WalClose(w,x,y,z)                0
++# define sqlite3WalClose(v,w,x,y,z)              0
+ # define sqlite3WalBeginReadTransaction(y,z)     0
+ # define sqlite3WalEndReadTransaction(z)
+ # define sqlite3WalDbsize(y)                     0
+@@ -41551,12 +51309,13 @@
+ # define sqlite3WalSavepoint(y,z)
+ # define sqlite3WalSavepointUndo(y,z)            0
+ # define sqlite3WalFrames(u,v,w,x,y,z)           0
+-# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0
++# define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0
+ # define sqlite3WalCallback(z)                   0
+ # define sqlite3WalExclusiveMode(y,z)            0
+ # define sqlite3WalHeapMemory(z)                 0
+ # define sqlite3WalFramesize(z)                  0
+ # define sqlite3WalFindFrame(x,y,z)              0
++# define sqlite3WalFile(x)                       0
+ #else
+ 
+ #define WAL_SAVEPOINT_NDATA 4
+@@ -41568,7 +51327,7 @@
+ 
+ /* Open and close a connection to a write-ahead log. */
+ SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
+-SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
++SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *);
+ 
+ /* Set the limiting size of a WAL file. */
+ SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
+@@ -41611,6 +51370,7 @@
+ /* Copy pages from the log to the database file */ 
+ SQLITE_PRIVATE int sqlite3WalCheckpoint(
+   Wal *pWal,                      /* Write-ahead log connection */
++  sqlite3 *db,                    /* Check this handle's interrupt flag */
+   int eMode,                      /* One of PASSIVE, FULL and RESTART */
+   int (*xBusy)(void*),            /* Function to call when busy */
+   void *pBusyArg,                 /* Context argument for xBusyHandler */
+@@ -41639,6 +51399,12 @@
+ */
+ SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
+ 
++#ifdef SQLITE_ENABLE_SNAPSHOT
++SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot);
++SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot);
++SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal);
++#endif
++
+ #ifdef SQLITE_ENABLE_ZIPVFS
+ /* If the WAL file is not empty, return the number of bytes of content
+ ** stored in each frame (i.e. the db page-size when the WAL was created).
+@@ -41646,8 +51412,11 @@
+ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
+ #endif
+ 
++/* Return the sqlite3_file object for the WAL file */
++SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal);
++
+ #endif /* ifndef SQLITE_OMIT_WAL */
+-#endif /* _WAL_H_ */
++#endif /* SQLITE_WAL_H */
+ 
+ /************** End of wal.h *************************************************/
+ /************** Continuing where we left off in pager.c **********************/
+@@ -42058,6 +51827,7 @@
+ */
+ #define MAX_SECTOR_SIZE 0x10000
+ 
++
+ /*
+ ** An instance of the following structure is allocated for each active
+ ** savepoint and statement transaction in the system. All such structures
+@@ -42086,9 +51856,9 @@
+ /*
+ ** Bits of the Pager.doNotSpill flag.  See further description below.
+ */
+-#define SPILLFLAG_OFF         0x01      /* Never spill cache.  Set via pragma */
+-#define SPILLFLAG_ROLLBACK    0x02      /* Current rolling back, so do not spill */
+-#define SPILLFLAG_NOSYNC      0x04      /* Spill is ok, but do not sync */
++#define SPILLFLAG_OFF         0x01 /* Never spill cache.  Set via pragma */
++#define SPILLFLAG_ROLLBACK    0x02 /* Current rolling back, so do not spill */
++#define SPILLFLAG_NOSYNC      0x04 /* Spill is ok, but do not sync */
+ 
+ /*
+ ** An open page cache is an instance of struct Pager. A description of
+@@ -42170,11 +51940,11 @@
+ **   while it is being traversed by code in pager_playback().  The SPILLFLAG_OFF
+ **   case is a user preference.
+ ** 
+-**   If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStress()
+-**   is permitted, but syncing the journal file is not. This flag is set
+-**   by sqlite3PagerWrite() when the file-system sector-size is larger than
+-**   the database page-size in order to prevent a journal sync from happening 
+-**   in between the journalling of two pages on the same sector. 
++**   If the SPILLFLAG_NOSYNC bit is set, writing to the database from
++**   pagerStress() is permitted, but syncing the journal file is not.
++**   This flag is set by sqlite3PagerWrite() when the file-system sector-size
++**   is larger than the database page-size in order to prevent a journal sync
++**   from happening in between the journalling of two pages on the same sector. 
+ **
+ ** subjInMemory
+ **
+@@ -42253,6 +52023,7 @@
+   u8 useJournal;              /* Use a rollback journal on this file */
+   u8 noSync;                  /* Do not sync the journal if true */
+   u8 fullSync;                /* Do extra syncs of the journal for robustness */
++  u8 extraSync;               /* sync directory after journal delete */
+   u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
+   u8 walSyncFlags;            /* SYNC_NORMAL or SYNC_FULL for wal writes */
+   u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
+@@ -42277,7 +52048,7 @@
+   u8 doNotSpill;              /* Do not spill the cache when non-zero */
+   u8 subjInMemory;            /* True to use in-memory sub-journals */
+   u8 bUseFetch;               /* True to use xFetch() */
+-  u8 hasBeenUsed;             /* True if any content previously read from this pager*/
++  u8 hasHeldSharedLock;       /* True if a shared lock has ever been held */
+   Pgno dbSize;                /* Number of pages in the database */
+   Pgno dbOrigSize;            /* dbSize before the current transaction */
+   Pgno dbFileSize;            /* Number of pages in the database file */
+@@ -42321,6 +52092,7 @@
+   int nRead;                  /* Database pages read */
+ #endif
+   void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
++  int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */
+ #ifdef SQLITE_HAS_CODEC
+   void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
+   void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
+@@ -42438,16 +52210,23 @@
+ **
+ **   if( pPager->jfd->pMethods ){ ...
+ */
+-#define isOpen(pFd) ((pFd)->pMethods)
++#define isOpen(pFd) ((pFd)->pMethods!=0)
+ 
+ /*
+-** Return true if this pager uses a write-ahead log instead of the usual
+-** rollback journal. Otherwise false.
++** Return true if this pager uses a write-ahead log to read page pgno.
++** Return false if the pager reads pgno directly from the database.
+ */
+-#ifndef SQLITE_OMIT_WAL
+-static int pagerUseWal(Pager *pPager){
+-  return (pPager->pWal!=0);
++#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ)
++SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){
++  u32 iRead = 0;
++  int rc;
++  if( pPager->pWal==0 ) return 0;
++  rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
++  return rc || iRead;
+ }
++#endif
++#ifndef SQLITE_OMIT_WAL
++# define pagerUseWal(x) ((x)->pWal!=0)
+ #else
+ # define pagerUseWal(x) 0
+ # define pagerRollbackWal(x) 0
+@@ -42500,6 +52279,7 @@
+   ** state.
+   */
+   if( MEMDB ){
++    assert( !isOpen(p->fd) );
+     assert( p->noSync );
+     assert( p->journalMode==PAGER_JOURNALMODE_OFF 
+          || p->journalMode==PAGER_JOURNALMODE_MEMORY 
+@@ -42586,7 +52366,7 @@
+       ** back to OPEN state.
+       */
+       assert( pPager->errCode!=SQLITE_OK );
+-      assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
++      assert( sqlite3PcacheRefCount(pPager->pPCache)>0 || pPager->tempFile );
+       break;
+   }
+ 
+@@ -42645,6 +52425,33 @@
+ }
+ #endif
+ 
++/* Forward references to the various page getters */
++static int getPageNormal(Pager*,Pgno,DbPage**,int);
++static int getPageError(Pager*,Pgno,DbPage**,int);
++#if SQLITE_MAX_MMAP_SIZE>0
++static int getPageMMap(Pager*,Pgno,DbPage**,int);
++#endif
++
++/*
++** Set the Pager.xGet method for the appropriate routine used to fetch
++** content from the pager.
++*/
++static void setGetterMethod(Pager *pPager){
++  if( pPager->errCode ){
++    pPager->xGet = getPageError;
++#if SQLITE_MAX_MMAP_SIZE>0
++  }else if( USEFETCH(pPager)
++#ifdef SQLITE_HAS_CODEC
++   && pPager->xCodec==0
++#endif
++  ){
++    pPager->xGet = getPageMMap;
++#endif /* SQLITE_MAX_MMAP_SIZE>0 */
++  }else{
++    pPager->xGet = getPageNormal;
++  }
++}
++
+ /*
+ ** Return true if it is necessary to write page *pPg into the sub-journal.
+ ** A page needs to be written into the sub-journal if there exists one
+@@ -42661,19 +52468,21 @@
+   int i;
+   for(i=0; i<pPager->nSavepoint; i++){
+     p = &pPager->aSavepoint[i];
+-    if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
++    if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){
+       return 1;
+     }
+   }
+   return 0;
+ }
+ 
++#ifdef SQLITE_DEBUG
+ /*
+ ** Return true if the page is already in the journal file.
+ */
+ static int pageInJournal(Pager *pPager, PgHdr *pPg){
+   return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno);
+ }
++#endif
+ 
+ /*
+ ** Read a 32-bit integer from the given file descriptor.  Store the integer
+@@ -42796,6 +52605,8 @@
+ 
+   return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
+ }
++#else
++# define jrnlBufferSize(x) 0
+ #endif
+ 
+ /*
+@@ -42956,6 +52767,7 @@
+ static int zeroJournalHdr(Pager *pPager, int doTruncate){
+   int rc = SQLITE_OK;                               /* Return code */
+   assert( isOpen(pPager->jfd) );
++  assert( !sqlite3JournalIsInMemory(pPager->jfd) );
+   if( pPager->journalOff ){
+     const i64 iLimit = pPager->journalSizeLimit;    /* Local cache of jsl */
+ 
+@@ -43285,7 +53097,8 @@
+    || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4)))
+    || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster)))
+    || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum)))
+-   || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8)))
++   || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8,
++                                 iHdrOff+4+nMaster+8)))
+   ){
+     return rc;
+   }
+@@ -43336,7 +53149,7 @@
+   for(ii=0; ii<pPager->nSavepoint; ii++){
+     sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
+   }
+-  if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){
++  if( !pPager->exclusiveMode || sqlite3JournalIsInMemory(pPager->sjfd) ){
+     sqlite3OsClose(pPager->sjfd);
+   }
+   sqlite3_free(pPager->aSavepoint);
+@@ -43442,13 +53255,18 @@
+   ** it can safely move back to PAGER_OPEN state. This happens in both
+   ** normal and exclusive-locking mode.
+   */
++  assert( pPager->errCode==SQLITE_OK || !MEMDB );
+   if( pPager->errCode ){
+-    assert( !MEMDB );
+-    pager_reset(pPager);
+-    pPager->changeCountDone = pPager->tempFile;
+-    pPager->eState = PAGER_OPEN;
+-    pPager->errCode = SQLITE_OK;
++    if( pPager->tempFile==0 ){
++      pager_reset(pPager);
++      pPager->changeCountDone = 0;
++      pPager->eState = PAGER_OPEN;
++    }else{
++      pPager->eState = (isOpen(pPager->jfd) ? PAGER_OPEN : PAGER_READER);
++    }
+     if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
++    pPager->errCode = SQLITE_OK;
++    setGetterMethod(pPager);
+   }
+ 
+   pPager->journalOff = 0;
+@@ -43486,6 +53304,7 @@
+   if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
+     pPager->errCode = rc;
+     pPager->eState = PAGER_ERROR;
++    setGetterMethod(pPager);
+   }
+   return rc;
+ }
+@@ -43493,6 +53312,29 @@
+ static int pager_truncate(Pager *pPager, Pgno nPage);
+ 
+ /*
++** The write transaction open on pPager is being committed (bCommit==1)
++** or rolled back (bCommit==0).
++**
++** Return TRUE if and only if all dirty pages should be flushed to disk.
++**
++** Rules:
++**
++**   *  For non-TEMP databases, always sync to disk.  This is necessary
++**      for transactions to be durable.
++**
++**   *  Sync TEMP database only on a COMMIT (not a ROLLBACK) when the backing
++**      file has been created already (via a spill on pagerStress()) and
++**      when the number of dirty pages in memory exceeds 25% of the total
++**      cache size.
++*/
++static int pagerFlushOnCommit(Pager *pPager, int bCommit){
++  if( pPager->tempFile==0 ) return 1;
++  if( !bCommit ) return 0;
++  if( !isOpen(pPager->fd) ) return 0;
++  return (sqlite3PCachePercentDirty(pPager->pPCache)>=25);
++}
++
++/*
+ ** This routine ends a transaction. A transaction is usually ended by 
+ ** either a COMMIT or a ROLLBACK operation. This routine may be called 
+ ** after rollback of a hot-journal, or if an error occurs while opening
+@@ -43574,8 +53416,8 @@
+     assert( !pagerUseWal(pPager) );
+ 
+     /* Finalize the journal file. */
+-    if( sqlite3IsMemJournal(pPager->jfd) ){
+-      assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
++    if( sqlite3JournalIsInMemory(pPager->jfd) ){
++      /* assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); */
+       sqlite3OsClose(pPager->jfd);
+     }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
+       if( pPager->journalOff==0 ){
+@@ -43595,22 +53437,23 @@
+     }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
+       || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
+     ){
+-      rc = zeroJournalHdr(pPager, hasMaster);
++      rc = zeroJournalHdr(pPager, hasMaster||pPager->tempFile);
+       pPager->journalOff = 0;
+     }else{
+       /* This branch may be executed with Pager.journalMode==MEMORY if
+       ** a hot-journal was just rolled back. In this case the journal
+       ** file should be closed and deleted. If this connection writes to
+-      ** the database file, it will do so using an in-memory journal. 
++      ** the database file, it will do so using an in-memory journal.
+       */
+-      int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
++      int bDelete = !pPager->tempFile;
++      assert( sqlite3JournalIsInMemory(pPager->jfd)==0 );
+       assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE 
+            || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
+            || pPager->journalMode==PAGER_JOURNALMODE_WAL 
+       );
+       sqlite3OsClose(pPager->jfd);
+       if( bDelete ){
+-        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
++        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, pPager->extraSync);
+       }
+     }
+   }
+@@ -43629,8 +53472,14 @@
+   sqlite3BitvecDestroy(pPager->pInJournal);
+   pPager->pInJournal = 0;
+   pPager->nRec = 0;
+-  sqlite3PcacheCleanAll(pPager->pPCache);
+-  sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
++  if( rc==SQLITE_OK ){
++    if( MEMDB || pagerFlushOnCommit(pPager, bCommit) ){
++      sqlite3PcacheCleanAll(pPager->pPCache);
++    }else{
++      sqlite3PcacheClearWritable(pPager->pPCache);
++    }
++    sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
++  }
+ 
+   if( pagerUseWal(pPager) ){
+     /* Drop the WAL write-lock, if any. Also, if the connection was in 
+@@ -43743,6 +53592,20 @@
+ # define pagerReportSize(X)     /* No-op if we do not support a codec */
+ #endif
+ 
++#ifdef SQLITE_HAS_CODEC
++/*
++** Make sure the number of reserved bits is the same in the destination
++** pager as it is in the source.  This comes up when a VACUUM changes the
++** number of reserved bits to the "optimal" amount.
++*/
++SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){
++  if( pDest->nReserve!=pSrc->nReserve ){
++    pDest->nReserve = pSrc->nReserve;
++    pagerReportSize(pDest);
++  }
++}
++#endif
++
+ /*
+ ** Read a single page from either the journal file (if isMainJrnl==1) or
+ ** from the sub-journal (if isMainJrnl==0) and playback that page.
+@@ -43794,6 +53657,11 @@
+   char *aData;                  /* Temporary storage for the page */
+   sqlite3_file *jfd;            /* The file descriptor for the journal file */
+   int isSynced;                 /* True if journal page is synced */
++#ifdef SQLITE_HAS_CODEC
++  /* The jrnlEnc flag is true if Journal pages should be passed through
++  ** the codec.  It is false for pure in-memory journals. */
++  const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0);
++#endif
+ 
+   assert( (isMainJrnl&~1)==0 );      /* isMainJrnl is 0 or 1 */
+   assert( (isSavepnt&~1)==0 );       /* isSavepnt is 0 or 1 */
+@@ -43845,7 +53713,7 @@
+     }
+   }
+ 
+-  /* If this page has already been played by before during the current
++  /* If this page has already been played back before during the current
+   ** rollback, then don't bother to play it back again.
+   */
+   if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
+@@ -43900,7 +53768,7 @@
+     pPg = sqlite3PagerLookup(pPager, pgno);
+   }
+   assert( pPg || !MEMDB );
+-  assert( pPager->eState!=PAGER_OPEN || pPg==0 );
++  assert( pPager->eState!=PAGER_OPEN || pPg==0 || pPager->tempFile );
+   PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
+            PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData),
+            (isMainJrnl?"main-journal":"sub-journal")
+@@ -43917,14 +53785,34 @@
+     i64 ofst = (pgno-1)*(i64)pPager->pageSize;
+     testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
+     assert( !pagerUseWal(pPager) );
++
++    /* Write the data read from the journal back into the database file.
++    ** This is usually safe even for an encrypted database - as the data
++    ** was encrypted before it was written to the journal file. The exception
++    ** is if the data was just read from an in-memory sub-journal. In that
++    ** case it must be encrypted here before it is copied into the database
++    ** file.  */
++#ifdef SQLITE_HAS_CODEC
++    if( !jrnlEnc ){
++      CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
++      rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
++      CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
++    }else
++#endif
+     rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
++
+     if( pgno>pPager->dbFileSize ){
+       pPager->dbFileSize = pgno;
+     }
+     if( pPager->pBackup ){
+-      CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM);
++#ifdef SQLITE_HAS_CODEC
++      if( jrnlEnc ){
++        CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
++        sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
++        CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData);
++      }else
++#endif
+       sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
+-      CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData);
+     }
+   }else if( !isMainJrnl && pPg==0 ){
+     /* If this is a rollback of a savepoint and data was not written to
+@@ -43946,11 +53834,10 @@
+     assert( isSavepnt );
+     assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
+     pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
+-    rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
++    rc = sqlite3PagerGet(pPager, pgno, &pPg, 1);
+     assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
+     pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
+     if( rc!=SQLITE_OK ) return rc;
+-    pPg->flags &= ~PGHDR_NEED_READ;
+     sqlite3PcacheMakeDirty(pPg);
+   }
+   if( pPg ){
+@@ -43964,29 +53851,10 @@
+     pData = pPg->pData;
+     memcpy(pData, (u8*)aData, pPager->pageSize);
+     pPager->xReiniter(pPg);
+-    if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){
+-      /* If the contents of this page were just restored from the main 
+-      ** journal file, then its content must be as they were when the 
+-      ** transaction was first opened. In this case we can mark the page
+-      ** as clean, since there will be no need to write it out to the
+-      ** database.
+-      **
+-      ** There is one exception to this rule. If the page is being rolled
+-      ** back as part of a savepoint (or statement) rollback from an 
+-      ** unsynced portion of the main journal file, then it is not safe
+-      ** to mark the page as clean. This is because marking the page as
+-      ** clean will clear the PGHDR_NEED_SYNC flag. Since the page is
+-      ** already in the journal file (recorded in Pager.pInJournal) and
+-      ** the PGHDR_NEED_SYNC flag is cleared, if the page is written to
+-      ** again within this transaction, it will be marked as dirty but
+-      ** the PGHDR_NEED_SYNC flag will not be set. It could then potentially
+-      ** be written out into the database file before its journal file
+-      ** segment is synced. If a crash occurs during or following this,
+-      ** database corruption may ensue.
+-      */
+-      assert( !pagerUseWal(pPager) );
+-      sqlite3PcacheMakeClean(pPg);
+-    }
++    /* It used to be that sqlite3PcacheMakeClean(pPg) was called here.  But
++    ** that call was dangerous and had no detectable benefit since the cache
++    ** is normally cleaned by sqlite3PcacheCleanAll() after rollback and so
++    ** has been removed. */
+     pager_set_pagehash(pPg);
+ 
+     /* If this was page 1, then restore the value of Pager.dbFileVers.
+@@ -43996,7 +53864,9 @@
+     }
+ 
+     /* Decode the page just read from disk */
+-    CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
++#if SQLITE_HAS_CODEC
++    if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); }
++#endif
+     sqlite3PcacheRelease(pPg);
+   }
+   return rc;
+@@ -44062,7 +53932,7 @@
+   pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
+   pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
+   if( !pMaster ){
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+   }else{
+     const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
+     rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
+@@ -44079,7 +53949,7 @@
+   nMasterPtr = pVfs->mxPathname+1;
+   zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
+   if( !zMasterJournal ){
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+     goto delmaster_out;
+   }
+   zMasterPtr = &zMasterJournal[nMasterJournal+1];
+@@ -44327,7 +54197,7 @@
+   ** TODO: Technically the following is an error because it assumes that
+   ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
+   ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
+-  **  mxPathname is 512, which is the same as the minimum allowable value
++  ** mxPathname is 512, which is the same as the minimum allowable value
+   ** for pageSize.
+   */
+   zMaster = pPager->pTmpSpace;
+@@ -44549,7 +54419,7 @@
+       memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
+     }
+   }
+-  CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
++  CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM_BKPT);
+ 
+   PAGER_INCR(sqlite3_pager_readdb_count);
+   PAGER_INCR(pPager->nRead);
+@@ -44777,22 +54647,20 @@
+   */
+   assert( pPager->eState==PAGER_OPEN );
+   assert( pPager->eLock>=SHARED_LOCK );
++  assert( isOpen(pPager->fd) );
++  assert( pPager->tempFile==0 );
+   nPage = sqlite3WalDbsize(pPager->pWal);
+ 
+-  /* If the database size was not available from the WAL sub-system,
+-  ** determine it based on the size of the database file. If the size
+-  ** of the database file is not an integer multiple of the page-size,
+-  ** round down to the nearest page. Except, any file larger than 0
+-  ** bytes in size is considered to contain at least one page.
++  /* If the number of pages in the database is not available from the
++  ** WAL sub-system, determine the page count based on the size of
++  ** the database file.  If the size of the database file is not an
++  ** integer multiple of the page-size, round up the result.
+   */
+-  if( nPage==0 ){
++  if( nPage==0 && ALWAYS(isOpen(pPager->fd)) ){
+     i64 n = 0;                    /* Size of db file in bytes */
+-    assert( isOpen(pPager->fd) || pPager->tempFile );
+-    if( isOpen(pPager->fd) ){
+-      int rc = sqlite3OsFileSize(pPager->fd, &n);
+-      if( rc!=SQLITE_OK ){
+-        return rc;
+-      }
++    int rc = sqlite3OsFileSize(pPager->fd, &n);
++    if( rc!=SQLITE_OK ){
++      return rc;
+     }
+     nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize);
+   }
+@@ -44835,23 +54703,21 @@
+ 
+   if( !pPager->tempFile ){
+     int isWal;                    /* True if WAL file exists */
+-    Pgno nPage;                   /* Size of the database file */
+-
+-    rc = pagerPagecount(pPager, &nPage);
+-    if( rc ) return rc;
+-    if( nPage==0 ){
+-      rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
+-      if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
+-      isWal = 0;
+-    }else{
+-      rc = sqlite3OsAccess(
+-          pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
+-      );
+-    }
++    rc = sqlite3OsAccess(
++        pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
++    );
+     if( rc==SQLITE_OK ){
+       if( isWal ){
+-        testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
+-        rc = sqlite3PagerOpenWal(pPager, 0);
++        Pgno nPage;                   /* Size of the database file */
++
++        rc = pagerPagecount(pPager, &nPage);
++        if( rc ) return rc;
++        if( nPage==0 ){
++          rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
++        }else{
++          testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
++          rc = sqlite3PagerOpenWal(pPager, 0);
++        }
+       }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
+         pPager->journalMode = PAGER_JOURNALMODE_DELETE;
+       }
+@@ -44910,7 +54776,7 @@
+   if( pSavepoint ){
+     pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
+     if( !pDone ){
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+   }
+ 
+@@ -45006,13 +54872,22 @@
+ }
+ 
+ /*
+-** Change the maximum number of in-memory pages that are allowed.
++** Change the maximum number of in-memory pages that are allowed
++** before attempting to recycle clean and unused pages.
+ */
+ SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
+   sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
+ }
+ 
+ /*
++** Change the maximum number of in-memory pages that are allowed
++** before attempting to spill pages to journal.
++*/
++SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager *pPager, int mxPage){
++  return sqlite3PcacheSetSpillsize(pPager->pPCache, mxPage);
++}
++
++/*
+ ** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap.
+ */
+ static void pagerFixMaplimit(Pager *pPager){
+@@ -45022,6 +54897,7 @@
+     sqlite3_int64 sz;
+     sz = pPager->szMmap;
+     pPager->bUseFetch = (sz>0);
++    setGetterMethod(pPager);
+     sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
+   }
+ #endif
+@@ -45048,7 +54924,7 @@
+ ** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness
+ ** of the database to damage due to OS crashes or power failures by
+ ** changing the number of syncs()s when writing the journals.
+-** There are three levels:
++** There are four levels:
+ **
+ **    OFF       sqlite3OsSync() is never called.  This is the default
+ **              for temporary and transient files.
+@@ -45068,6 +54944,10 @@
+ **              assurance that the journal will not be corrupted to the
+ **              point of causing damage to the database during rollback.
+ **
++**    EXTRA     This is like FULL except that is also syncs the directory
++**              that contains the rollback journal after the rollback
++**              journal is unlinked.
++**
+ ** The above is for a rollback-journal mode.  For WAL mode, OFF continues
+ ** to mean that no syncs ever occur.  NORMAL means that the WAL is synced
+ ** prior to the start of checkpoint and that the database file is synced
+@@ -45075,7 +54955,8 @@
+ ** was written back into the database.  But no sync operations occur for
+ ** an ordinary commit in NORMAL mode with WAL.  FULL means that the WAL
+ ** file is synced following each commit operation, in addition to the
+-** syncs associated with NORMAL.
++** syncs associated with NORMAL.  There is no difference between FULL
++** and EXTRA for WAL mode.
+ **
+ ** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL.  The
+ ** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync
+@@ -45094,9 +54975,15 @@
+   unsigned pgFlags      /* Various flags */
+ ){
+   unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
+-  assert( level>=1 && level<=3 );
+-  pPager->noSync =  (level==1 || pPager->tempFile) ?1:0;
+-  pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
++  if( pPager->tempFile ){
++    pPager->noSync = 1;
++    pPager->fullSync = 0;
++    pPager->extraSync = 0;
++  }else{
++    pPager->noSync =  level==PAGER_SYNCHRONOUS_OFF ?1:0;
++    pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0;
++    pPager->extraSync = level==PAGER_SYNCHRONOUS_EXTRA ?1:0;
++  }
+   if( pPager->noSync ){
+     pPager->syncFlags = 0;
+     pPager->ckptSyncFlags = 0;
+@@ -45258,7 +55145,7 @@
+     }
+     if( rc==SQLITE_OK ){
+       pNew = (char *)sqlite3PageMalloc(pageSize);
+-      if( !pNew ) rc = SQLITE_NOMEM;
++      if( !pNew ) rc = SQLITE_NOMEM_BKPT;
+     }
+ 
+     if( rc==SQLITE_OK ){
+@@ -45507,6 +55394,7 @@
+   return rc;
+ }
+ 
++#if SQLITE_MAX_MMAP_SIZE>0
+ /*
+ ** Obtain a reference to a memory mapped page object for page number pgno. 
+ ** The new object will use the pointer pData, obtained from xFetch().
+@@ -45529,12 +55417,13 @@
+     *ppPage = p = pPager->pMmapFreelist;
+     pPager->pMmapFreelist = p->pDirty;
+     p->pDirty = 0;
+-    memset(p->pExtra, 0, pPager->nExtra);
++    assert( pPager->nExtra>=8 );
++    memset(p->pExtra, 0, 8);
+   }else{
+     *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
+     if( p==0 ){
+       sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     p->pExtra = (void *)&p[1];
+     p->flags = PGHDR_MMAP;
+@@ -45554,6 +55443,7 @@
+ 
+   return SQLITE_OK;
+ }
++#endif
+ 
+ /*
+ ** Release a reference to page pPg. pPg must have been returned by an 
+@@ -45596,9 +55486,10 @@
+ ** a hot journal may be left in the filesystem but no error is returned
+ ** to the caller.
+ */
+-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
++SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
+   u8 *pTmp = (u8 *)pPager->pTmpSpace;
+ 
++  assert( db || pagerUseWal(pPager)==0 );
+   assert( assert_pager_state(pPager) );
+   disable_simulated_io_errors();
+   sqlite3BeginBenignMalloc();
+@@ -45606,7 +55497,10 @@
+   /* pPager->errCode = 0; */
+   pPager->exclusiveMode = 0;
+ #ifndef SQLITE_OMIT_WAL
+-  sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
++  assert( db || pPager->pWal==0 );
++  sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize,
++      (db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp)
++  );
+   pPager->pWal = 0;
+ #endif
+   pager_reset(pPager);
+@@ -45848,8 +55742,9 @@
+ 
+   /* This function is only called for rollback pagers in WRITER_DBMOD state. */
+   assert( !pagerUseWal(pPager) );
+-  assert( pPager->eState==PAGER_WRITER_DBMOD );
++  assert( pPager->tempFile || pPager->eState==PAGER_WRITER_DBMOD );
+   assert( pPager->eLock==EXCLUSIVE_LOCK );
++  assert( isOpen(pPager->fd) || pList->pDirty==0 );
+ 
+   /* If the file is a temp-file has not yet been opened, open it now. It
+   ** is not possible for rc to be other than SQLITE_OK if this branch
+@@ -45892,7 +55787,7 @@
+       if( pList->pgno==1 ) pager_write_changecounter(pList);
+ 
+       /* Encode the database */
+-      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
++      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM_BKPT, pData);
+ 
+       /* Write out the page data. */
+       rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
+@@ -45937,19 +55832,20 @@
+ static int openSubJournal(Pager *pPager){
+   int rc = SQLITE_OK;
+   if( !isOpen(pPager->sjfd) ){
++    const int flags =  SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE 
++      | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE 
++      | SQLITE_OPEN_DELETEONCLOSE;
++    int nStmtSpill = sqlite3Config.nStmtSpill;
+     if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
+-      sqlite3MemJournalOpen(pPager->sjfd);
+-    }else{
+-      rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
++      nStmtSpill = -1;
+     }
++    rc = sqlite3JournalOpen(pPager->pVfs, 0, pPager->sjfd, flags, nStmtSpill);
+   }
+   return rc;
+ }
+ 
+ /*
+ ** Append a record of the current state of page pPg to the sub-journal. 
+-** It is the callers responsibility to use subjRequiresPage() to check 
+-** that it is really required before calling this function.
+ **
+ ** If successful, set the bit corresponding to pPg->pgno in the bitvecs
+ ** for all open savepoints before returning.
+@@ -45980,8 +55876,13 @@
+       void *pData = pPg->pData;
+       i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
+       char *pData2;
+-  
+-      CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
++
++#if SQLITE_HAS_CODEC   
++      if( !pPager->subjInMemory ){
++        CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
++      }else
++#endif
++      pData2 = pData;
+       PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
+       rc = write32bits(pPager->sjfd, offset, pPg->pgno);
+       if( rc==SQLITE_OK ){
+@@ -45996,6 +55897,13 @@
+   }
+   return rc;
+ }
++static int subjournalPageIfRequired(PgHdr *pPg){
++  if( subjRequiresPage(pPg) ){
++    return subjournalPage(pPg);
++  }else{
++    return SQLITE_OK;
++  }
++}
+ 
+ /*
+ ** This function is called by the pcache layer when it has reached some
+@@ -46053,9 +55961,7 @@
+   pPg->pDirty = 0;
+   if( pagerUseWal(pPager) ){
+     /* Write a single frame for this page to the log. */
+-    if( subjRequiresPage(pPg) ){ 
+-      rc = subjournalPage(pPg); 
+-    }
++    rc = subjournalPageIfRequired(pPg); 
+     if( rc==SQLITE_OK ){
+       rc = pagerWalFrames(pPager, pPg, 0, 0);
+     }
+@@ -46068,39 +55974,6 @@
+       rc = syncJournal(pPager, 1);
+     }
+   
+-    /* If the page number of this page is larger than the current size of
+-    ** the database image, it may need to be written to the sub-journal.
+-    ** This is because the call to pager_write_pagelist() below will not
+-    ** actually write data to the file in this case.
+-    **
+-    ** Consider the following sequence of events:
+-    **
+-    **   BEGIN;
+-    **     <journal page X>
+-    **     <modify page X>
+-    **     SAVEPOINT sp;
+-    **       <shrink database file to Y pages>
+-    **       pagerStress(page X)
+-    **     ROLLBACK TO sp;
+-    **
+-    ** If (X>Y), then when pagerStress is called page X will not be written
+-    ** out to the database file, but will be dropped from the cache. Then,
+-    ** following the "ROLLBACK TO sp" statement, reading page X will read
+-    ** data from the database file. This will be the copy of page X as it
+-    ** was when the transaction started, not as it was when "SAVEPOINT sp"
+-    ** was executed.
+-    **
+-    ** The solution is to write the current data for page X into the 
+-    ** sub-journal file now (if it is not already there), so that it will
+-    ** be restored to its current value when the "ROLLBACK TO sp" is 
+-    ** executed.
+-    */
+-    if( NEVER(
+-        rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
+-    ) ){
+-      rc = subjournalPage(pPg);
+-    }
+-  
+     /* Write the contents of the page out to the database file. */
+     if( rc==SQLITE_OK ){
+       assert( (pPg->flags&PGHDR_NEED_SYNC)==0 );
+@@ -46117,6 +55990,25 @@
+   return pager_error(pPager, rc); 
+ }
+ 
++/*
++** Flush all unreferenced dirty pages to disk.
++*/
++SQLITE_PRIVATE int sqlite3PagerFlush(Pager *pPager){
++  int rc = pPager->errCode;
++  if( !MEMDB ){
++    PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
++    assert( assert_pager_state(pPager) );
++    while( rc==SQLITE_OK && pList ){
++      PgHdr *pNext = pList->pDirty;
++      if( pList->nRef==0 ){
++        rc = pagerStress((void*)pPager, pList);
++      }
++      pList = pNext;
++    }
++  }
++
++  return rc;
++}
+ 
+ /*
+ ** Allocate and initialize a new Pager object and put a pointer to it
+@@ -46132,7 +56024,9 @@
+ **
+ ** The nExtra parameter specifies the number of bytes of space allocated
+ ** along with each page reference. This space is available to the user
+-** via the sqlite3PagerGetExtra() API.
++** via the sqlite3PagerGetExtra() API.  When a new page is allocated, the
++** first 8 bytes of this space are zeroed but the remainder is uninitialized.
++** (The extra space is used by btree as the MemPage object.)
+ **
+ ** The flags argument is used to specify properties that affect the
+ ** operation of the pager. It should be passed some bitwise combination
+@@ -46173,18 +56067,8 @@
+   int nUri = 0;            /* Number of bytes of URI args at *zUri */
+ 
+   /* Figure out how much space is required for each journal file-handle
+-  ** (there are two of them, the main journal and the sub-journal). This
+-  ** is the maximum space required for an in-memory journal file handle 
+-  ** and a regular journal file-handle. Note that a "regular journal-handle"
+-  ** may be a wrapper capable of caching the first portion of the journal
+-  ** file in memory to implement the atomic-write optimization (see 
+-  ** source file journal.c).
+-  */
+-  if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
+-    journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
+-  }else{
+-    journalFileSize = ROUND8(sqlite3MemJournalSize());
+-  }
++  ** (there are two of them, the main journal and the sub-journal).  */
++  journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
+ 
+   /* Set the output variable to NULL in case an error occurs. */
+   *ppPager = 0;
+@@ -46194,7 +56078,7 @@
+     memDb = 1;
+     if( zFilename && zFilename[0] ){
+       zPathname = sqlite3DbStrDup(0, zFilename);
+-      if( zPathname==0  ) return SQLITE_NOMEM;
++      if( zPathname==0  ) return SQLITE_NOMEM_BKPT;
+       nPathname = sqlite3Strlen30(zPathname);
+       zFilename = 0;
+     }
+@@ -46210,7 +56094,7 @@
+     nPathname = pVfs->mxPathname+1;
+     zPathname = sqlite3DbMallocRaw(0, nPathname*2);
+     if( zPathname==0 ){
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
+     rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
+@@ -46263,7 +56147,7 @@
+   assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
+   if( !pPtr ){
+     sqlite3DbFree(0, zPathname);
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   pPager =              (Pager*)(pPtr);
+   pPager->pPCache =    (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
+@@ -46356,7 +56240,7 @@
+ act_like_temp_file:
+     tempFile = 1;
+     pPager->eState = PAGER_READER;     /* Pretend we already have a lock */
+-    pPager->eLock = EXCLUSIVE_LOCK;    /* Pretend we are in EXCLUSIVE locking mode */
++    pPager->eLock = EXCLUSIVE_LOCK;    /* Pretend we are in EXCLUSIVE mode */
+     pPager->noLock = 1;                /* Do no locking */
+     readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
+   }
+@@ -46372,10 +56256,10 @@
+ 
+   /* Initialize the PCache object. */
+   if( rc==SQLITE_OK ){
+-    assert( nExtra<1000 );
+     nExtra = ROUND8(nExtra);
++    assert( nExtra>=8 && nExtra<1000 );
+     rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
+-                           !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
++                       !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
+   }
+ 
+   /* If an error occurred above, free the  Pager structure and close the file.
+@@ -46412,11 +56296,13 @@
+   pPager->noSync = pPager->tempFile;
+   if( pPager->noSync ){
+     assert( pPager->fullSync==0 );
++    assert( pPager->extraSync==0 );
+     assert( pPager->syncFlags==0 );
+     assert( pPager->walSyncFlags==0 );
+     assert( pPager->ckptSyncFlags==0 );
+   }else{
+     pPager->fullSync = 1;
++    pPager->extraSync = 0;
+     pPager->syncFlags = SQLITE_SYNC_NORMAL;
+     pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS;
+     pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
+@@ -46436,6 +56322,7 @@
+   /* pPager->xBusyHandler = 0; */
+   /* pPager->pBusyHandlerArg = 0; */
+   pPager->xReiniter = xReinit;
++  setGetterMethod(pPager);
+   /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
+   /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
+ 
+@@ -46533,6 +56420,7 @@
+     if( rc==SQLITE_OK && !locked ){
+       Pgno nPage;                 /* Number of pages in database file */
+ 
++      assert( pPager->tempFile==0 );
+       rc = pagerPagecount(pPager, &nPage);
+       if( rc==SQLITE_OK ){
+         /* If the database is zero pages in size, that means that either (1) the
+@@ -46594,7 +56482,7 @@
+ 
+ /*
+ ** This function is called to obtain a shared lock on the database file.
+-** It is illegal to call sqlite3PagerAcquire() until after this function
++** It is illegal to call sqlite3PagerGet() until after this function
+ ** has been successfully called. If a shared-lock is already held when
+ ** this function is called, it is a no-op.
+ **
+@@ -46625,17 +56513,17 @@
+   /* This routine is only called from b-tree and only when there are no
+   ** outstanding pages. This implies that the pager state should either
+   ** be OPEN or READER. READER is only possible if the pager is or was in 
+-  ** exclusive access mode.
+-  */
++  ** exclusive access mode.  */
+   assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
+   assert( assert_pager_state(pPager) );
+   assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
+-  if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
++  assert( pPager->errCode==SQLITE_OK );
+ 
+   if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
+     int bHotJournal = 1;          /* True if there exists a hot journal-file */
+ 
+     assert( !MEMDB );
++    assert( pPager->tempFile==0 || pPager->eLock==EXCLUSIVE_LOCK );
+ 
+     rc = pager_wait_on_lock(pPager, SHARED_LOCK);
+     if( rc!=SQLITE_OK ){
+@@ -46721,7 +56609,7 @@
+         assert( rc==SQLITE_OK );
+         rc = pagerSyncHotJournal(pPager);
+         if( rc==SQLITE_OK ){
+-          rc = pager_playback(pPager, 1);
++          rc = pager_playback(pPager, !pPager->tempFile);
+           pPager->eState = PAGER_OPEN;
+         }
+       }else if( !pPager->exclusiveMode ){
+@@ -46755,14 +56643,14 @@
+       );
+     }
+ 
+-    if( !pPager->tempFile && pPager->hasBeenUsed ){
++    if( !pPager->tempFile && pPager->hasHeldSharedLock ){
+       /* The shared-lock has just been acquired then check to
+       ** see if the database has been modified.  If the database has changed,
+-      ** flush the cache.  The pPager->hasBeenUsed flag prevents this from
++      ** flush the cache.  The hasHeldSharedLock flag prevents this from
+       ** occurring on the very first access to a file, in order to save a
+       ** single unnecessary sqlite3OsRead() call at the start-up.
+       **
+-      ** Database changes is detected by looking at 15 bytes beginning
++      ** Database changes are detected by looking at 15 bytes beginning
+       ** at offset 24 into the file.  The first 4 of these 16 bytes are
+       ** a 32-bit counter that is incremented with each change.  The
+       ** other bytes change randomly with each file change when
+@@ -46772,19 +56660,14 @@
+       ** detected.  The chance of an undetected change is so small that
+       ** it can be neglected.
+       */
+-      Pgno nPage = 0;
+       char dbFileVers[sizeof(pPager->dbFileVers)];
+ 
+-      rc = pagerPagecount(pPager, &nPage);
+-      if( rc ) goto failed;
+-
+-      if( nPage>0 ){
+-        IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
+-        rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
+-        if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
++      IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
++      rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
++      if( rc!=SQLITE_OK ){
++        if( rc!=SQLITE_IOERR_SHORT_READ ){
+           goto failed;
+         }
+-      }else{
+         memset(dbFileVers, 0, sizeof(dbFileVers));
+       }
+ 
+@@ -46817,7 +56700,7 @@
+     rc = pagerBeginReadTransaction(pPager);
+   }
+ 
+-  if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
++  if( pPager->tempFile==0 && pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
+     rc = pagerPagecount(pPager, &pPager->dbSize);
+   }
+ 
+@@ -46828,6 +56711,7 @@
+     assert( pPager->eState==PAGER_OPEN );
+   }else{
+     pPager->eState = PAGER_READER;
++    pPager->hasHeldSharedLock = 1;
+   }
+   return rc;
+ }
+@@ -46847,10 +56731,17 @@
+ }
+ 
+ /*
+-** Acquire a reference to page number pgno in pager pPager (a page
+-** reference has type DbPage*). If the requested reference is 
++** The page getter methods each try to acquire a reference to a
++** page with page number pgno. If the requested reference is 
+ ** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
+ **
++** There are different implementations of the getter method depending
++** on the current state of the pager.
++**
++**     getPageNormal()         --  The normal getter
++**     getPageError()          --  Used if the pager is in an error state
++**     getPageMmap()           --  Used if memory-mapped I/O is enabled
++**
+ ** If the requested page is already in the cache, it is returned. 
+ ** Otherwise, a new page object is allocated and populated with data
+ ** read from the database file. In some cases, the pcache module may
+@@ -46862,14 +56753,14 @@
+ ** already in the cache when this function is called, then the extra
+ ** data is left as it was when the page object was last used.
+ **
+-** If the database image is smaller than the requested page or if a 
+-** non-zero value is passed as the noContent parameter and the 
++** If the database image is smaller than the requested page or if 
++** the flags parameter contains the PAGER_GET_NOCONTENT bit and the 
+ ** requested page is not already stored in the cache, then no 
+ ** actual disk read occurs. In this case the memory image of the 
+ ** page is initialized to all zeros. 
+ **
+-** If noContent is true, it means that we do not care about the contents
+-** of the page. This occurs in two scenarios:
++** If PAGER_GET_NOCONTENT is true, it means that we do not care about
++** the contents of the page. This occurs in two scenarios:
+ **
+ **   a) When reading a free-list leaf page from the database, and
+ **
+@@ -46877,8 +56768,8 @@
+ **      a new page into the cache to be filled with the data read
+ **      from the savepoint journal.
+ **
+-** If noContent is true, then the data returned is zeroed instead of
+-** being read from the database. Additionally, the bits corresponding
++** If PAGER_GET_NOCONTENT is true, then the data returned is zeroed instead
++** of being read from the database. Additionally, the bits corresponding
+ ** to pgno in Pager.pInJournal (bitvec of pages already written to the
+ ** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
+ ** savepoints are set. This means if the page is made writable at any
+@@ -46896,97 +56787,40 @@
+ ** Since Lookup() never goes to disk, it never has to deal with locks
+ ** or journal files.
+ */
+-SQLITE_PRIVATE int sqlite3PagerAcquire(
++static int getPageNormal(
+   Pager *pPager,      /* The pager open on the database file */
+   Pgno pgno,          /* Page number to fetch */
+   DbPage **ppPage,    /* Write a pointer to the page here */
+   int flags           /* PAGER_GET_XXX flags */
+ ){
+   int rc = SQLITE_OK;
+-  PgHdr *pPg = 0;
+-  u32 iFrame = 0;                 /* Frame to read from WAL file */
+-  const int noContent = (flags & PAGER_GET_NOCONTENT);
+-
+-  /* It is acceptable to use a read-only (mmap) page for any page except
+-  ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
+-  ** flag was specified by the caller. And so long as the db is not a 
+-  ** temporary or in-memory database.  */
+-  const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
+-   && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
+-#ifdef SQLITE_HAS_CODEC
+-   && pPager->xCodec==0
+-#endif
+-  );
++  PgHdr *pPg;
++  u8 noContent;                   /* True if PAGER_GET_NOCONTENT is set */
++  sqlite3_pcache_page *pBase;
+ 
++  assert( pPager->errCode==SQLITE_OK );
+   assert( pPager->eState>=PAGER_READER );
+   assert( assert_pager_state(pPager) );
+-  assert( noContent==0 || bMmapOk==0 );
+-
+-  if( pgno==0 ){
+-    return SQLITE_CORRUPT_BKPT;
+-  }
+-  pPager->hasBeenUsed = 1;
+-
+-  /* If the pager is in the error state, return an error immediately. 
+-  ** Otherwise, request the page from the PCache layer. */
+-  if( pPager->errCode!=SQLITE_OK ){
+-    rc = pPager->errCode;
+-  }else{
+-    if( bMmapOk && pagerUseWal(pPager) ){
+-      rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
+-      if( rc!=SQLITE_OK ) goto pager_acquire_err;
+-    }
+-
+-    if( bMmapOk && iFrame==0 ){
+-      void *pData = 0;
+-
+-      rc = sqlite3OsFetch(pPager->fd, 
+-          (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
+-      );
+-
+-      if( rc==SQLITE_OK && pData ){
+-        if( pPager->eState>PAGER_READER ){
+-          pPg = sqlite3PagerLookup(pPager, pgno);
+-        }
+-        if( pPg==0 ){
+-          rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
+-        }else{
+-          sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
+-        }
+-        if( pPg ){
+-          assert( rc==SQLITE_OK );
+-          *ppPage = pPg;
+-          return SQLITE_OK;
+-        }
+-      }
+-      if( rc!=SQLITE_OK ){
+-        goto pager_acquire_err;
+-      }
+-    }
++  assert( pPager->hasHeldSharedLock==1 );
+ 
+-    {
+-      sqlite3_pcache_page *pBase;
+-      pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
+-      if( pBase==0 ){
+-        rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
+-        if( rc!=SQLITE_OK ) goto pager_acquire_err;
+-      }
+-      pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
+-      if( pPg==0 ) rc = SQLITE_NOMEM;
+-    }
+-  }
+-
+-  if( rc!=SQLITE_OK ){
+-    /* Either the call to sqlite3PcacheFetch() returned an error or the
+-    ** pager was already in the error-state when this function was called.
+-    ** Set pPg to 0 and jump to the exception handler.  */
++  if( pgno==0 ) return SQLITE_CORRUPT_BKPT;
++  pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
++  if( pBase==0 ){
+     pPg = 0;
+-    goto pager_acquire_err;
++    rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
++    if( rc!=SQLITE_OK ) goto pager_acquire_err;
++    if( pBase==0 ){
++      rc = SQLITE_NOMEM_BKPT;
++      goto pager_acquire_err;
++    }
+   }
+-  assert( (*ppPage)->pgno==pgno );
+-  assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 );
++  pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
++  assert( pPg==(*ppPage) );
++  assert( pPg->pgno==pgno );
++  assert( pPg->pPager==pPager || pPg->pPager==0 );
+ 
+-  if( (*ppPage)->pPager && !noContent ){
++  noContent = (flags & PAGER_GET_NOCONTENT)!=0;
++  if( pPg->pPager && !noContent ){
+     /* In this case the pcache already contains an initialized copy of
+     ** the page. Return without further ado.  */
+     assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
+@@ -46995,19 +56829,20 @@
+ 
+   }else{
+     /* The pager cache has created a new page. Its content needs to 
+-    ** be initialized.  */
+-
+-    pPg = *ppPage;
+-    pPg->pPager = pPager;
+-
+-    /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
+-    ** number greater than this, or the unused locking-page, is requested. */
++    ** be initialized. But first some error checks:
++    **
++    ** (1) The maximum page number is 2^31
++    ** (2) Never try to fetch the locking page
++    */
+     if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
+       rc = SQLITE_CORRUPT_BKPT;
+       goto pager_acquire_err;
+     }
+ 
+-    if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){
++    pPg->pPager = pPager;
++
++    assert( !isOpen(pPager->fd) || !MEMDB );
++    if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){
+       if( pgno>pPager->mxPgno ){
+         rc = SQLITE_FULL;
+         goto pager_acquire_err;
+@@ -47031,7 +56866,8 @@
+       memset(pPg->pData, 0, pPager->pageSize);
+       IOTRACE(("ZERO %p %d\n", pPager, pgno));
+     }else{
+-      if( pagerUseWal(pPager) && bMmapOk==0 ){
++      u32 iFrame = 0;                 /* Frame to read from WAL file */
++      if( pagerUseWal(pPager) ){
+         rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
+         if( rc!=SQLITE_OK ) goto pager_acquire_err;
+       }
+@@ -47044,7 +56880,6 @@
+     }
+     pager_set_pagehash(pPg);
+   }
+-
+   return SQLITE_OK;
+ 
+ pager_acquire_err:
+@@ -47053,11 +56888,109 @@
+     sqlite3PcacheDrop(pPg);
+   }
+   pagerUnlockIfUnused(pPager);
+-
+   *ppPage = 0;
+   return rc;
+ }
+ 
++#if SQLITE_MAX_MMAP_SIZE>0
++/* The page getter for when memory-mapped I/O is enabled */
++static int getPageMMap(
++  Pager *pPager,      /* The pager open on the database file */
++  Pgno pgno,          /* Page number to fetch */
++  DbPage **ppPage,    /* Write a pointer to the page here */
++  int flags           /* PAGER_GET_XXX flags */
++){
++  int rc = SQLITE_OK;
++  PgHdr *pPg = 0;
++  u32 iFrame = 0;                 /* Frame to read from WAL file */
++
++  /* It is acceptable to use a read-only (mmap) page for any page except
++  ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
++  ** flag was specified by the caller. And so long as the db is not a 
++  ** temporary or in-memory database.  */
++  const int bMmapOk = (pgno>1
++   && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
++  );
++
++  assert( USEFETCH(pPager) );
++#ifdef SQLITE_HAS_CODEC
++  assert( pPager->xCodec==0 );
++#endif
++
++  /* Optimization note:  Adding the "pgno<=1" term before "pgno==0" here
++  ** allows the compiler optimizer to reuse the results of the "pgno>1"
++  ** test in the previous statement, and avoid testing pgno==0 in the
++  ** common case where pgno is large. */
++  if( pgno<=1 && pgno==0 ){
++    return SQLITE_CORRUPT_BKPT;
++  }
++  assert( pPager->eState>=PAGER_READER );
++  assert( assert_pager_state(pPager) );
++  assert( pPager->hasHeldSharedLock==1 );
++  assert( pPager->errCode==SQLITE_OK );
++
++  if( bMmapOk && pagerUseWal(pPager) ){
++    rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
++    if( rc!=SQLITE_OK ){
++      *ppPage = 0;
++      return rc;
++    }
++  }
++  if( bMmapOk && iFrame==0 ){
++    void *pData = 0;
++    rc = sqlite3OsFetch(pPager->fd, 
++        (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
++    );
++    if( rc==SQLITE_OK && pData ){
++      if( pPager->eState>PAGER_READER || pPager->tempFile ){
++        pPg = sqlite3PagerLookup(pPager, pgno);
++      }
++      if( pPg==0 ){
++        rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
++     }else{
++        sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
++      }
++      if( pPg ){
++        assert( rc==SQLITE_OK );
++        *ppPage = pPg;
++        return SQLITE_OK;
++      }
++    }
++    if( rc!=SQLITE_OK ){
++      *ppPage = 0;
++      return rc;
++    }
++  }
++  return getPageNormal(pPager, pgno, ppPage, flags);
++}
++#endif /* SQLITE_MAX_MMAP_SIZE>0 */
++
++/* The page getter method for when the pager is an error state */
++static int getPageError(
++  Pager *pPager,      /* The pager open on the database file */
++  Pgno pgno,          /* Page number to fetch */
++  DbPage **ppPage,    /* Write a pointer to the page here */
++  int flags           /* PAGER_GET_XXX flags */
++){
++  UNUSED_PARAMETER(pgno);
++  UNUSED_PARAMETER(flags);
++  assert( pPager->errCode!=SQLITE_OK );
++  *ppPage = 0;
++  return pPager->errCode;
++}
++
++
++/* Dispatch all page fetch requests to the appropriate getter method.
++*/
++SQLITE_PRIVATE int sqlite3PagerGet(
++  Pager *pPager,      /* The pager open on the database file */
++  Pgno pgno,          /* Page number to fetch */
++  DbPage **ppPage,    /* Write a pointer to the page here */
++  int flags           /* PAGER_GET_XXX flags */
++){
++  return pPager->xGet(pPager, pgno, ppPage, flags);
++}
++
+ /*
+ ** Acquire a page if it is already in the in-memory cache.  Do
+ ** not read the page from disk.  Return a pointer to the page,
+@@ -47075,7 +57008,8 @@
+   assert( pgno!=0 );
+   assert( pPager->pPCache!=0 );
+   pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
+-  assert( pPage==0 || pPager->hasBeenUsed );
++  assert( pPage==0 || pPager->hasHeldSharedLock );
++  if( pPage==0 ) return 0;
+   return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
+ }
+ 
+@@ -47140,7 +57074,7 @@
+   if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
+     pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
+     if( pPager->pInJournal==0 ){
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+   
+     /* Open the journal file if it is not already open. */
+@@ -47148,24 +57082,24 @@
+       if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
+         sqlite3MemJournalOpen(pPager->jfd);
+       }else{
+-        const int flags =                   /* VFS flags to open journal file */
+-          SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
+-          (pPager->tempFile ? 
+-            (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
+-            (SQLITE_OPEN_MAIN_JOURNAL)
+-          );
++        int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
++        int nSpill;
+ 
++        if( pPager->tempFile ){
++          flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL);
++          nSpill = sqlite3Config.nStmtSpill;
++        }else{
++          flags |= SQLITE_OPEN_MAIN_JOURNAL;
++          nSpill = jrnlBufferSize(pPager);
++        }
++          
+         /* Verify that the database still has the same name as it did when
+         ** it was originally opened. */
+         rc = databaseIsUnmoved(pPager);
+         if( rc==SQLITE_OK ){
+-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+-          rc = sqlite3JournalOpen(
+-              pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
++          rc = sqlite3JournalOpen (
++              pVfs, pPager->zJournal, pPager->jfd, flags, nSpill
+           );
+-#else
+-          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
+-#endif
+         }
+       }
+       assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
+@@ -47232,7 +57166,7 @@
+         if( rc!=SQLITE_OK ){
+           return rc;
+         }
+-        sqlite3WalExclusiveMode(pPager->pWal, 1);
++        (void)sqlite3WalExclusiveMode(pPager->pWal, 1);
+       }
+ 
+       /* Grab the write lock on the log file. If successful, upgrade to
+@@ -47280,6 +57214,59 @@
+ }
+ 
+ /*
++** Write page pPg onto the end of the rollback journal.
++*/
++static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){
++  Pager *pPager = pPg->pPager;
++  int rc;
++  u32 cksum;
++  char *pData2;
++  i64 iOff = pPager->journalOff;
++
++  /* We should never write to the journal file the page that
++  ** contains the database locks.  The following assert verifies
++  ** that we do not. */
++  assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
++
++  assert( pPager->journalHdr<=pPager->journalOff );
++  CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
++  cksum = pager_cksum(pPager, (u8*)pData2);
++
++  /* Even if an IO or diskfull error occurs while journalling the
++  ** page in the block above, set the need-sync flag for the page.
++  ** Otherwise, when the transaction is rolled back, the logic in
++  ** playback_one_page() will think that the page needs to be restored
++  ** in the database file. And if an IO error occurs while doing so,
++  ** then corruption may follow.
++  */
++  pPg->flags |= PGHDR_NEED_SYNC;
++
++  rc = write32bits(pPager->jfd, iOff, pPg->pgno);
++  if( rc!=SQLITE_OK ) return rc;
++  rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4);
++  if( rc!=SQLITE_OK ) return rc;
++  rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum);
++  if( rc!=SQLITE_OK ) return rc;
++
++  IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, 
++           pPager->journalOff, pPager->pageSize));
++  PAGER_INCR(sqlite3_pager_writej_count);
++  PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n",
++       PAGERID(pPager), pPg->pgno, 
++       ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg)));
++
++  pPager->journalOff += 8 + pPager->pageSize;
++  pPager->nRec++;
++  assert( pPager->pInJournal!=0 );
++  rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
++  testcase( rc==SQLITE_NOMEM );
++  assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
++  rc |= addToSavepointBitvecs(pPager, pPg->pgno);
++  assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
++  return rc;
++}
++
++/*
+ ** Mark a single data page as writeable. The page is written into the 
+ ** main journal or sub-journal as required. If the page is written into
+ ** one of the journals, the corresponding bit is set in the 
+@@ -47289,7 +57276,6 @@
+ static int pager_write(PgHdr *pPg){
+   Pager *pPager = pPg->pPager;
+   int rc = SQLITE_OK;
+-  int inJournal;
+ 
+   /* This routine is not called unless a write-transaction has already 
+   ** been started. The journal file may or may not be open at this point.
+@@ -47302,7 +57288,6 @@
+   assert( assert_pager_state(pPager) );
+   assert( pPager->errCode==0 );
+   assert( pPager->readOnly==0 );
+-
+   CHECK_PAGE(pPg);
+ 
+   /* The journal file needs to be opened. Higher level routines have already
+@@ -47321,91 +57306,48 @@
+   assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
+   assert( assert_pager_state(pPager) );
+ 
+-  /* Mark the page as dirty.  If the page has already been written
+-  ** to the journal then we can return right away.
+-  */
++  /* Mark the page that is about to be modified as dirty. */
+   sqlite3PcacheMakeDirty(pPg);
+-  inJournal = pageInJournal(pPager, pPg);
+-  if( inJournal && (pPager->nSavepoint==0 || !subjRequiresPage(pPg)) ){
+-    assert( !pagerUseWal(pPager) );
+-  }else{
+-  
+-    /* The transaction journal now exists and we have a RESERVED or an
+-    ** EXCLUSIVE lock on the main database file.  Write the current page to
+-    ** the transaction journal if it is not there already.
+-    */
+-    if( !inJournal && !pagerUseWal(pPager) ){
+-      assert( pagerUseWal(pPager)==0 );
+-      if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){
+-        u32 cksum;
+-        char *pData2;
+-        i64 iOff = pPager->journalOff;
+-
+-        /* We should never write to the journal file the page that
+-        ** contains the database locks.  The following assert verifies
+-        ** that we do not. */
+-        assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
+-
+-        assert( pPager->journalHdr<=pPager->journalOff );
+-        CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
+-        cksum = pager_cksum(pPager, (u8*)pData2);
+-
+-        /* Even if an IO or diskfull error occurs while journalling the
+-        ** page in the block above, set the need-sync flag for the page.
+-        ** Otherwise, when the transaction is rolled back, the logic in
+-        ** playback_one_page() will think that the page needs to be restored
+-        ** in the database file. And if an IO error occurs while doing so,
+-        ** then corruption may follow.
+-        */
+-        pPg->flags |= PGHDR_NEED_SYNC;
+-
+-        rc = write32bits(pPager->jfd, iOff, pPg->pgno);
+-        if( rc!=SQLITE_OK ) return rc;
+-        rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4);
+-        if( rc!=SQLITE_OK ) return rc;
+-        rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum);
+-        if( rc!=SQLITE_OK ) return rc;
+ 
+-        IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, 
+-                 pPager->journalOff, pPager->pageSize));
+-        PAGER_INCR(sqlite3_pager_writej_count);
+-        PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n",
+-             PAGERID(pPager), pPg->pgno, 
+-             ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg)));
+-
+-        pPager->journalOff += 8 + pPager->pageSize;
+-        pPager->nRec++;
+-        assert( pPager->pInJournal!=0 );
+-        rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
+-        testcase( rc==SQLITE_NOMEM );
+-        assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+-        rc |= addToSavepointBitvecs(pPager, pPg->pgno);
+-        if( rc!=SQLITE_OK ){
+-          assert( rc==SQLITE_NOMEM );
+-          return rc;
+-        }
+-      }else{
+-        if( pPager->eState!=PAGER_WRITER_DBMOD ){
+-          pPg->flags |= PGHDR_NEED_SYNC;
+-        }
+-        PAGERTRACE(("APPEND %d page %d needSync=%d\n",
+-                PAGERID(pPager), pPg->pgno,
+-               ((pPg->flags&PGHDR_NEED_SYNC)?1:0)));
++  /* If a rollback journal is in use, them make sure the page that is about
++  ** to change is in the rollback journal, or if the page is a new page off
++  ** then end of the file, make sure it is marked as PGHDR_NEED_SYNC.
++  */
++  assert( (pPager->pInJournal!=0) == isOpen(pPager->jfd) );
++  if( pPager->pInJournal!=0
++   && sqlite3BitvecTestNotNull(pPager->pInJournal, pPg->pgno)==0
++  ){
++    assert( pagerUseWal(pPager)==0 );
++    if( pPg->pgno<=pPager->dbOrigSize ){
++      rc = pagerAddPageToRollbackJournal(pPg);
++      if( rc!=SQLITE_OK ){
++        return rc;
+       }
+-    }
+-  
+-    /* If the statement journal is open and the page is not in it,
+-    ** then write the current page to the statement journal.  Note that
+-    ** the statement journal format differs from the standard journal format
+-    ** in that it omits the checksums and the header.
+-    */
+-    if( pPager->nSavepoint>0 && subjRequiresPage(pPg) ){
+-      rc = subjournalPage(pPg);
++    }else{
++      if( pPager->eState!=PAGER_WRITER_DBMOD ){
++        pPg->flags |= PGHDR_NEED_SYNC;
++      }
++      PAGERTRACE(("APPEND %d page %d needSync=%d\n",
++              PAGERID(pPager), pPg->pgno,
++             ((pPg->flags&PGHDR_NEED_SYNC)?1:0)));
+     }
+   }
+ 
+-  /* Update the database size and return.
++  /* The PGHDR_DIRTY bit is set above when the page was added to the dirty-list
++  ** and before writing the page into the rollback journal.  Wait until now,
++  ** after the page has been successfully journalled, before setting the
++  ** PGHDR_WRITEABLE bit that indicates that the page can be safely modified.
++  */
++  pPg->flags |= PGHDR_WRITEABLE;
++  
++  /* If the statement journal is open and the page is not in it,
++  ** then write the page into the statement journal.
+   */
++  if( pPager->nSavepoint>0 ){
++    rc = subjournalPageIfRequired(pPg);
++  }
++
++  /* Update the database size and return. */
+   if( pPager->dbSize<pPg->pgno ){
+     pPager->dbSize = pPg->pgno;
+   }
+@@ -47420,17 +57362,17 @@
+ ** a write.
+ **
+ ** Usually, the sector size is less than or equal to the page size, in which
+-** case pages can be individually written.  This routine only runs in the exceptional
+-** case where the page size is smaller than the sector size.
++** case pages can be individually written.  This routine only runs in the
++** exceptional case where the page size is smaller than the sector size.
+ */
+ static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){
+-  int rc = SQLITE_OK;            /* Return code */
+-  Pgno nPageCount;               /* Total number of pages in database file */
+-  Pgno pg1;                      /* First page of the sector pPg is located on. */
+-  int nPage = 0;                 /* Number of pages starting at pg1 to journal */
+-  int ii;                        /* Loop counter */
+-  int needSync = 0;              /* True if any page has PGHDR_NEED_SYNC */
+-  Pager *pPager = pPg->pPager;   /* The pager that owns pPg */
++  int rc = SQLITE_OK;          /* Return code */
++  Pgno nPageCount;             /* Total number of pages in database file */
++  Pgno pg1;                    /* First page of the sector pPg is located on. */
++  int nPage = 0;               /* Number of pages starting at pg1 to journal */
++  int ii;                      /* Loop counter */
++  int needSync = 0;            /* True if any page has PGHDR_NEED_SYNC */
++  Pager *pPager = pPg->pPager; /* The pager that owns pPg */
+   Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
+ 
+   /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
+@@ -47464,7 +57406,7 @@
+     PgHdr *pPage;
+     if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
+       if( pg!=PAGER_MJ_PGNO(pPager) ){
+-        rc = sqlite3PagerGet(pPager, pg, &pPage);
++        rc = sqlite3PagerGet(pPager, pg, &pPage, 0);
+         if( rc==SQLITE_OK ){
+           rc = pager_write(pPage);
+           if( pPage->flags&PGHDR_NEED_SYNC ){
+@@ -47518,11 +57460,17 @@
+ ** as appropriate. Otherwise, SQLITE_OK.
+ */
+ SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){
++  Pager *pPager = pPg->pPager;
+   assert( (pPg->flags & PGHDR_MMAP)==0 );
+-  assert( pPg->pPager->eState>=PAGER_WRITER_LOCKED );
+-  assert( pPg->pPager->eState!=PAGER_ERROR );
+-  assert( assert_pager_state(pPg->pPager) );
+-  if( pPg->pPager->sectorSize > (u32)pPg->pPager->pageSize ){
++  assert( pPager->eState>=PAGER_WRITER_LOCKED );
++  assert( assert_pager_state(pPager) );
++  if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){
++    if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg);
++    return SQLITE_OK;
++  }else if( pPager->errCode ){
++    return pPager->errCode;
++  }else if( pPager->sectorSize > (u32)pPager->pageSize ){
++    assert( pPager->tempFile==0 );
+     return pagerWriteLargeSector(pPg);
+   }else{
+     return pager_write(pPg);
+@@ -47536,7 +57484,7 @@
+ */
+ #ifndef NDEBUG
+ SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){
+-  return pPg->flags&PGHDR_DIRTY;
++  return pPg->flags & PGHDR_WRITEABLE;
+ }
+ #endif
+ 
+@@ -47553,13 +57501,21 @@
+ **
+ ** Tests show that this optimization can quadruple the speed of large 
+ ** DELETE operations.
++**
++** This optimization cannot be used with a temp-file, as the page may
++** have been dirty at the start of the transaction. In that case, if
++** memory pressure forces page pPg out of the cache, the data does need 
++** to be written out to disk so that it may be read back in if the 
++** current transaction is rolled back.
+ */
+ SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
+   Pager *pPager = pPg->pPager;
+-  if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
++  if( !pPager->tempFile && (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
+     PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
+     IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
+     pPg->flags |= PGHDR_DONT_WRITE;
++    pPg->flags &= ~PGHDR_WRITEABLE;
++    testcase( pPg->flags & PGHDR_NEED_SYNC );
+     pager_set_pagehash(pPg);
+   }
+ }
+@@ -47618,7 +57574,7 @@
+     assert( !pPager->tempFile && isOpen(pPager->fd) );
+ 
+     /* Open page 1 of the file for writing. */
+-    rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
++    rc = sqlite3PagerGet(pPager, 1, &pPgHdr, 0);
+     assert( pPgHdr==0 || rc==SQLITE_OK );
+ 
+     /* If page one was fetched successfully, and this function is not
+@@ -47638,7 +57594,7 @@
+       if( DIRECT_MODE ){
+         const void *zBuf;
+         assert( pPager->dbFileSize>0 );
+-        CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf);
++        CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM_BKPT, zBuf);
+         if( rc==SQLITE_OK ){
+           rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
+           pPager->aStat[PAGER_STAT_WRITE]++;
+@@ -47696,14 +57652,17 @@
+ ** returned.
+ */
+ SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){
+-  int rc = SQLITE_OK;
+-  assert( pPager->eState==PAGER_WRITER_CACHEMOD 
+-       || pPager->eState==PAGER_WRITER_DBMOD 
+-       || pPager->eState==PAGER_WRITER_LOCKED 
+-  );
++  int rc = pPager->errCode;
+   assert( assert_pager_state(pPager) );
+-  if( 0==pagerUseWal(pPager) ){
+-    rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
++  if( rc==SQLITE_OK ){
++    assert( pPager->eState==PAGER_WRITER_CACHEMOD 
++         || pPager->eState==PAGER_WRITER_DBMOD 
++         || pPager->eState==PAGER_WRITER_LOCKED 
++    );
++    assert( assert_pager_state(pPager) );
++    if( 0==pagerUseWal(pPager) ){
++      rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
++    }
+   }
+   return rc;
+ }
+@@ -47751,17 +57710,21 @@
+   /* If a prior error occurred, report that error again. */
+   if( NEVER(pPager->errCode) ) return pPager->errCode;
+ 
++  /* Provide the ability to easily simulate an I/O error during testing */
++  if( sqlite3FaultSim(400) ) return SQLITE_IOERR;
++
+   PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
+       pPager->zFilename, zMaster, pPager->dbSize));
+ 
+   /* If no database changes have been made, return early. */
+   if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
+ 
+-  if( MEMDB ){
++  assert( MEMDB==0 || pPager->tempFile );
++  assert( isOpen(pPager->fd) || pPager->tempFile );
++  if( 0==pagerFlushOnCommit(pPager, 1) ){
+     /* If this is an in-memory db, or no pages have been written to, or this
+     ** function has already been called, it is mostly a no-op.  However, any
+-    ** backup in progress needs to be restarted.
+-    */
++    ** backup in progress needs to be restarted.  */
+     sqlite3BackupRestart(pPager->pBackup);
+   }else{
+     if( pagerUseWal(pPager) ){
+@@ -47770,7 +57733,7 @@
+       if( pList==0 ){
+         /* Must have at least one page for the WAL commit flag.
+         ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
+-        rc = sqlite3PagerGet(pPager, 1, &pPageOne);
++        rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0);
+         pList = pPageOne;
+         pList->pDirty = 0;
+       }
+@@ -48000,6 +57963,7 @@
+       */
+       pPager->errCode = SQLITE_ABORT;
+       pPager->eState = PAGER_ERROR;
++      setGetterMethod(pPager);
+       return rc;
+     }
+   }else{
+@@ -48026,12 +57990,14 @@
+   return pPager->readOnly;
+ }
+ 
++#ifdef SQLITE_DEBUG
+ /*
+-** Return the number of references to the pager.
++** Return the sum of the reference counts for all pages held by pPager.
+ */
+ SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){
+   return sqlite3PcacheRefCount(pPager->pPCache);
+ }
++#endif
+ 
+ /*
+ ** Return the approximate number of bytes of memory currently
+@@ -48098,10 +58064,10 @@
+ }
+ 
+ /*
+-** Return true if this is an in-memory pager.
++** Return true if this is an in-memory or temp-file backed pager.
+ */
+ SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
+-  return MEMDB;
++  return pPager->tempFile;
+ }
+ 
+ /*
+@@ -48114,54 +58080,62 @@
+ ** occurs while opening the sub-journal file, then an IO error code is
+ ** returned. Otherwise, SQLITE_OK.
+ */
+-SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
++static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){
+   int rc = SQLITE_OK;                       /* Return code */
+   int nCurrent = pPager->nSavepoint;        /* Current number of savepoints */
++  int ii;                                   /* Iterator variable */
++  PagerSavepoint *aNew;                     /* New Pager.aSavepoint array */
+ 
+   assert( pPager->eState>=PAGER_WRITER_LOCKED );
+   assert( assert_pager_state(pPager) );
++  assert( nSavepoint>nCurrent && pPager->useJournal );
+ 
+-  if( nSavepoint>nCurrent && pPager->useJournal ){
+-    int ii;                                 /* Iterator variable */
+-    PagerSavepoint *aNew;                   /* New Pager.aSavepoint array */
+-
+-    /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
+-    ** if the allocation fails. Otherwise, zero the new portion in case a 
+-    ** malloc failure occurs while populating it in the for(...) loop below.
+-    */
+-    aNew = (PagerSavepoint *)sqlite3Realloc(
+-        pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
+-    );
+-    if( !aNew ){
+-      return SQLITE_NOMEM;
+-    }
+-    memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
+-    pPager->aSavepoint = aNew;
++  /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
++  ** if the allocation fails. Otherwise, zero the new portion in case a 
++  ** malloc failure occurs while populating it in the for(...) loop below.
++  */
++  aNew = (PagerSavepoint *)sqlite3Realloc(
++      pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
++  );
++  if( !aNew ){
++    return SQLITE_NOMEM_BKPT;
++  }
++  memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
++  pPager->aSavepoint = aNew;
+ 
+-    /* Populate the PagerSavepoint structures just allocated. */
+-    for(ii=nCurrent; ii<nSavepoint; ii++){
+-      aNew[ii].nOrig = pPager->dbSize;
+-      if( isOpen(pPager->jfd) && pPager->journalOff>0 ){
+-        aNew[ii].iOffset = pPager->journalOff;
+-      }else{
+-        aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager);
+-      }
+-      aNew[ii].iSubRec = pPager->nSubRec;
+-      aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
+-      if( !aNew[ii].pInSavepoint ){
+-        return SQLITE_NOMEM;
+-      }
+-      if( pagerUseWal(pPager) ){
+-        sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
+-      }
+-      pPager->nSavepoint = ii+1;
++  /* Populate the PagerSavepoint structures just allocated. */
++  for(ii=nCurrent; ii<nSavepoint; ii++){
++    aNew[ii].nOrig = pPager->dbSize;
++    if( isOpen(pPager->jfd) && pPager->journalOff>0 ){
++      aNew[ii].iOffset = pPager->journalOff;
++    }else{
++      aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager);
++    }
++    aNew[ii].iSubRec = pPager->nSubRec;
++    aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
++    if( !aNew[ii].pInSavepoint ){
++      return SQLITE_NOMEM_BKPT;
+     }
+-    assert( pPager->nSavepoint==nSavepoint );
+-    assertTruncateConstraint(pPager);
++    if( pagerUseWal(pPager) ){
++      sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
++    }
++    pPager->nSavepoint = ii+1;
+   }
+-
++  assert( pPager->nSavepoint==nSavepoint );
++  assertTruncateConstraint(pPager);
+   return rc;
+ }
++SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
++  assert( pPager->eState>=PAGER_WRITER_LOCKED );
++  assert( assert_pager_state(pPager) );
++
++  if( nSavepoint>pPager->nSavepoint && pPager->useJournal ){
++    return pagerOpenSavepoint(pPager, nSavepoint);
++  }else{
++    return SQLITE_OK;
++  }
++}
++
+ 
+ /*
+ ** This function is called to rollback or release (commit) a savepoint.
+@@ -48194,7 +58168,11 @@
+ ** savepoint. If no errors occur, SQLITE_OK is returned.
+ */ 
+ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
+-  int rc = pPager->errCode;       /* Return code */
++  int rc = pPager->errCode;
++  
++#ifdef SQLITE_ENABLE_ZIPVFS
++  if( op==SAVEPOINT_RELEASE ) rc = SQLITE_OK;
++#endif
+ 
+   assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
+   assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
+@@ -48218,7 +58196,7 @@
+     if( op==SAVEPOINT_RELEASE ){
+       if( nNew==0 && isOpen(pPager->sjfd) ){
+         /* Only truncate if it is an in-memory sub-journal. */
+-        if( sqlite3IsMemJournal(pPager->sjfd) ){
++        if( sqlite3JournalIsInMemory(pPager->sjfd) ){
+           rc = sqlite3OsTruncate(pPager->sjfd, 0);
+           assert( rc==SQLITE_OK );
+         }
+@@ -48235,6 +58213,21 @@
+       rc = pagerPlaybackSavepoint(pPager, pSavepoint);
+       assert(rc!=SQLITE_DONE);
+     }
++    
++#ifdef SQLITE_ENABLE_ZIPVFS
++    /* If the cache has been modified but the savepoint cannot be rolled 
++    ** back journal_mode=off, put the pager in the error state. This way,
++    ** if the VFS used by this pager includes ZipVFS, the entire transaction
++    ** can be rolled back at the ZipVFS level.  */
++    else if( 
++        pPager->journalMode==PAGER_JOURNALMODE_OFF 
++     && pPager->eState>=PAGER_WRITER_CACHEMOD
++    ){
++      pPager->errCode = SQLITE_ABORT;
++      pPager->eState = PAGER_ERROR;
++      setGetterMethod(pPager);
++    }
++#endif
+   }
+ 
+   return rc;
+@@ -48257,7 +58250,7 @@
+ /*
+ ** Return the VFS structure for the pager.
+ */
+-SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
++SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
+   return pPager->pVfs;
+ }
+ 
+@@ -48271,18 +58264,22 @@
+ }
+ 
+ /*
+-** Return the full pathname of the journal file.
++** Return the file handle for the journal file (if it exists).
++** This will be either the rollback journal or the WAL file.
+ */
+-SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
+-  return pPager->zJournal;
++SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
++#if SQLITE_OMIT_WAL
++  return pPager->jfd;
++#else
++  return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd;
++#endif
+ }
+ 
+ /*
+-** Return true if fsync() calls are disabled for this pager.  Return FALSE
+-** if fsync()s are executed normally.
++** Return the full pathname of the journal file.
+ */
+-SQLITE_PRIVATE int sqlite3PagerNosync(Pager *pPager){
+-  return pPager->noSync;
++SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
++  return pPager->zJournal;
+ }
+ 
+ #ifdef SQLITE_HAS_CODEC
+@@ -48301,6 +58298,7 @@
+   pPager->xCodecSizeChng = xCodecSizeChng;
+   pPager->xCodecFree = xCodecFree;
+   pPager->pCodec = pCodec;
++  setGetterMethod(pPager);
+   pagerReportSize(pPager);
+ }
+ SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
+@@ -48369,7 +58367,8 @@
+   /* In order to be able to rollback, an in-memory database must journal
+   ** the page we are moving from.
+   */
+-  if( MEMDB ){
++  assert( pPager->tempFile || !MEMDB );
++  if( pPager->tempFile ){
+     rc = sqlite3PagerWrite(pPg);
+     if( rc ) return rc;
+   }
+@@ -48392,9 +58391,8 @@
+   ** one or more savepoint bitvecs. This is the reason this function
+   ** may return SQLITE_NOMEM.
+   */
+-  if( pPg->flags&PGHDR_DIRTY
+-   && subjRequiresPage(pPg)
+-   && SQLITE_OK!=(rc = subjournalPage(pPg))
++  if( (pPg->flags & PGHDR_DIRTY)!=0
++   && SQLITE_OK!=(rc = subjournalPageIfRequired(pPg))
+   ){
+     return rc;
+   }
+@@ -48427,7 +58425,7 @@
+   assert( !pPgOld || pPgOld->nRef==1 );
+   if( pPgOld ){
+     pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
+-    if( MEMDB ){
++    if( pPager->tempFile ){
+       /* Do not discard pages from an in-memory database since we might
+       ** need to rollback later.  Just move the page out of the way. */
+       sqlite3PcacheMove(pPgOld, pPager->dbSize+1);
+@@ -48444,8 +58442,7 @@
+   ** to exist, in case the transaction needs to roll back.  Use pPgOld
+   ** as the original page since it has already been allocated.
+   */
+-  if( MEMDB ){
+-    assert( pPgOld );
++  if( pPager->tempFile && pPgOld ){
+     sqlite3PcacheMove(pPgOld, origPgno);
+     sqlite3PagerUnrefNotNull(pPgOld);
+   }
+@@ -48466,7 +58463,7 @@
+     ** the journal file twice, but that is not a problem.
+     */
+     PgHdr *pPgHdr;
+-    rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
++    rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr, 0);
+     if( rc!=SQLITE_OK ){
+       if( needSyncPgno<=pPager->dbOrigSize ){
+         assert( pPager->pTmpSpace!=0 );
+@@ -48697,10 +58694,12 @@
+ ** Unless this is an in-memory or temporary database, clear the pager cache.
+ */
+ SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
+-  if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager);
++  assert( MEMDB==0 || pPager->tempFile );
++  if( pPager->tempFile==0 ) pager_reset(pPager);
+ }
+ #endif
+ 
++
+ #ifndef SQLITE_OMIT_WAL
+ /*
+ ** This function is called when the user invokes "PRAGMA wal_checkpoint",
+@@ -48709,10 +58708,16 @@
+ **
+ ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
+ */
+-SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
++SQLITE_PRIVATE int sqlite3PagerCheckpoint(
++  Pager *pPager,                  /* Checkpoint on this pager */
++  sqlite3 *db,                    /* Db handle used to check for interrupts */
++  int eMode,                      /* Type of checkpoint */
++  int *pnLog,                     /* OUT: Final number of frames in log */
++  int *pnCkpt                     /* OUT: Final number of checkpointed frames */
++){
+   int rc = SQLITE_OK;
+   if( pPager->pWal ){
+-    rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
++    rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
+         (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
+         pPager->pBusyHandlerArg,
+         pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
+@@ -48732,6 +58737,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){
+   const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
++  if( pPager->noLock ) return 0;
+   return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap);
+ }
+ 
+@@ -48843,7 +58849,7 @@
+ ** error (SQLITE_BUSY) is returned and the log connection is not closed.
+ ** If successful, the EXCLUSIVE lock is not released before returning.
+ */
+-SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
++SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
+   int rc = SQLITE_OK;
+ 
+   assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
+@@ -48871,15 +58877,58 @@
+   if( rc==SQLITE_OK && pPager->pWal ){
+     rc = pagerExclusiveLock(pPager);
+     if( rc==SQLITE_OK ){
+-      rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
++      rc = sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags,
+                            pPager->pageSize, (u8*)pPager->pTmpSpace);
+       pPager->pWal = 0;
+       pagerFixMaplimit(pPager);
++      if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
+     }
+   }
+   return rc;
+ }
+ 
++#ifdef SQLITE_ENABLE_SNAPSHOT
++/*
++** If this is a WAL database, obtain a snapshot handle for the snapshot
++** currently open. Otherwise, return an error.
++*/
++SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){
++  int rc = SQLITE_ERROR;
++  if( pPager->pWal ){
++    rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot);
++  }
++  return rc;
++}
++
++/*
++** If this is a WAL database, store a pointer to pSnapshot. Next time a
++** read transaction is opened, attempt to read from the snapshot it 
++** identifies. If this is not a WAL database, return an error.
++*/
++SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){
++  int rc = SQLITE_OK;
++  if( pPager->pWal ){
++    sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
++  }else{
++    rc = SQLITE_ERROR;
++  }
++  return rc;
++}
++
++/*
++** If this is a WAL database, call sqlite3WalSnapshotRecover(). If this 
++** is not a WAL database, return an error.
++*/
++SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager){
++  int rc;
++  if( pPager->pWal ){
++    rc = sqlite3WalSnapshotRecover(pPager->pWal);
++  }else{
++    rc = SQLITE_ERROR;
++  }
++  return rc;
++}
++#endif /* SQLITE_ENABLE_SNAPSHOT */
+ #endif /* !SQLITE_OMIT_WAL */
+ 
+ #ifdef SQLITE_ENABLE_ZIPVFS
+@@ -48896,9 +58945,41 @@
+ }
+ #endif
+ 
+-
+ #endif /* SQLITE_OMIT_DISKIO */
+ 
++/* BEGIN SQLCIPHER */
++#ifdef SQLITE_HAS_CODEC
++SQLITE_API void sqlite3pager_get_codec(Pager *pPager, void **ctx) {
++  *ctx = pPager->pCodec;
++}
++
++SQLITE_API int sqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno) {
++  return (PAGER_MJ_PGNO(pPager) == pgno) ? 1 : 0;
++}
++
++SQLITE_PRIVATE sqlite3_file *sqlite3Pager_get_fd(Pager *pPager) {
++  return (isOpen(pPager->fd)) ? pPager->fd : NULL;
++}
++
++SQLITE_API void sqlite3pager_sqlite3PagerSetCodec(
++  Pager *pPager,
++  void *(*xCodec)(void*,void*,Pgno,int),
++  void (*xCodecSizeChng)(void*,int,int),
++  void (*xCodecFree)(void*),
++  void *pCodec
++){
++  sqlite3PagerSetCodec(pPager, xCodec, xCodecSizeChng, xCodecFree, pCodec); 
++}
++
++SQLITE_API void sqlite3pager_sqlite3PagerSetError( Pager *pPager, int error) {
++  pPager->errCode = error;
++  setGetterMethod(pPager);
++}
++
++#endif
++/* END SQLCIPHER */
++
++
+ /************** End of pager.c ***********************************************/
+ /************** Begin file wal.c *********************************************/
+ /*
+@@ -49145,6 +59226,7 @@
+ */
+ #ifndef SQLITE_OMIT_WAL
+ 
++/* #include "wal.h" */
+ 
+ /*
+ ** Trace output macros
+@@ -49174,7 +59256,8 @@
+ 
+ /*
+ ** Indices of various locking bytes.   WAL_NREADER is the number
+-** of available reader locks and should be at least 3.
++** of available reader locks and should be at least 3.  The default
++** is SQLITE_SHM_NLOCK==8 and  WAL_NREADER==5.
+ */
+ #define WAL_WRITE_LOCK         0
+ #define WAL_ALL_BUT_WRITE      1
+@@ -49194,7 +59277,10 @@
+ ** The following object holds a copy of the wal-index header content.
+ **
+ ** The actual header in the wal-index consists of two copies of this
+-** object.
++** object followed by one instance of the WalCkptInfo object.
++** For all versions of SQLite through 3.10.0 and probably beyond,
++** the locking bytes (WalCkptInfo.aLock) start at offset 120 and
++** the total header size is 136 bytes.
+ **
+ ** The szPage value can be any power of 2 between 512 and 32768, inclusive.
+ ** Or it can be 1 to represent a 65536-byte page.  The latter case was
+@@ -49227,6 +59313,16 @@
+ ** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from
+ ** mxFrame back to zero when the WAL is reset.
+ **
++** nBackfillAttempted is the largest value of nBackfill that a checkpoint
++** has attempted to achieve.  Normally nBackfill==nBackfillAtempted, however
++** the nBackfillAttempted is set before any backfilling is done and the
++** nBackfill is only set after all backfilling completes.  So if a checkpoint
++** crashes, nBackfillAttempted might be larger than nBackfill.  The
++** WalIndexHdr.mxFrame must never be less than nBackfillAttempted.
++**
++** The aLock[] field is a set of bytes used for locking.  These bytes should
++** never be read or written.
++**
+ ** There is one entry in aReadMark[] for each reader lock.  If a reader
+ ** holds read-lock K, then the value in aReadMark[K] is no greater than
+ ** the mxFrame for that reader.  The value READMARK_NOT_USED (0xffffffff)
+@@ -49266,6 +59362,9 @@
+ struct WalCkptInfo {
+   u32 nBackfill;                  /* Number of WAL frames backfilled into DB */
+   u32 aReadMark[WAL_NREADER];     /* Reader marks */
++  u8 aLock[SQLITE_SHM_NLOCK];     /* Reserved space for locks */
++  u32 nBackfillAttempted;         /* WAL frames perhaps written, or maybe not */
++  u32 notUsed0;                   /* Available for future enhancements */
+ };
+ #define READMARK_NOT_USED  0xffffffff
+ 
+@@ -49275,9 +59374,8 @@
+ ** only support mandatory file-locks, we do not read or write data
+ ** from the region of the file on which locks are applied.
+ */
+-#define WALINDEX_LOCK_OFFSET   (sizeof(WalIndexHdr)*2 + sizeof(WalCkptInfo))
+-#define WALINDEX_LOCK_RESERVED 16
+-#define WALINDEX_HDR_SIZE      (WALINDEX_LOCK_OFFSET+WALINDEX_LOCK_RESERVED)
++#define WALINDEX_LOCK_OFFSET (sizeof(WalIndexHdr)*2+offsetof(WalCkptInfo,aLock))
++#define WALINDEX_HDR_SIZE    (sizeof(WalIndexHdr)*2+sizeof(WalCkptInfo))
+ 
+ /* Size of header before each frame in wal */
+ #define WAL_FRAME_HDRSIZE 24
+@@ -49330,11 +59428,16 @@
+   u8 syncHeader;             /* Fsync the WAL header if true */
+   u8 padToSectorBoundary;    /* Pad transactions out to the next sector */
+   WalIndexHdr hdr;           /* Wal-index header for current transaction */
++  u32 minFrame;              /* Ignore wal frames before this one */
++  u32 iReCksum;              /* On commit, recalculate checksums from here */
+   const char *zWalName;      /* Name of WAL file */
+   u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
+ #ifdef SQLITE_DEBUG
+   u8 lockError;              /* True if a locking error has occurred */
+ #endif
++#ifdef SQLITE_ENABLE_SNAPSHOT
++  WalIndexHdr *pSnapshot;    /* Start transaction here if not NULL */
++#endif
+ };
+ 
+ /*
+@@ -49427,7 +59530,7 @@
+     apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
+     if( !apNew ){
+       *ppPage = 0;
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     memset((void*)&apNew[pWal->nWiData], 0,
+            sizeof(u32*)*(iPage+1-pWal->nWiData));
+@@ -49439,7 +59542,7 @@
+   if( pWal->apWiData[iPage]==0 ){
+     if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
+       pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
+-      if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM;
++      if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
+     }else{
+       rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
+           pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
+@@ -49550,9 +59653,9 @@
+   pWal->hdr.isInit = 1;
+   pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
+   walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
+-  memcpy((void *)&aHdr[1], (void *)&pWal->hdr, sizeof(WalIndexHdr));
++  memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
+   walShmBarrier(pWal);
+-  memcpy((void *)&aHdr[0], (void *)&pWal->hdr, sizeof(WalIndexHdr));
++  memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
+ }
+ 
+ /*
+@@ -49580,14 +59683,18 @@
+   assert( WAL_FRAME_HDRSIZE==24 );
+   sqlite3Put4byte(&aFrame[0], iPage);
+   sqlite3Put4byte(&aFrame[4], nTruncate);
+-  memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
++  if( pWal->iReCksum==0 ){
++    memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
+ 
+-  nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
+-  walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
+-  walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
++    nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
++    walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
++    walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
+ 
+-  sqlite3Put4byte(&aFrame[16], aCksum[0]);
+-  sqlite3Put4byte(&aFrame[20], aCksum[1]);
++    sqlite3Put4byte(&aFrame[16], aCksum[0]);
++    sqlite3Put4byte(&aFrame[20], aCksum[1]);
++  }else{
++    memset(&aFrame[8], 0, 16);
++  }
+ }
+ 
+ /*
+@@ -49690,10 +59797,9 @@
+                          SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
+   WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
+ }
+-static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){
++static int walLockExclusive(Wal *pWal, int lockIdx, int n){
+   int rc;
+   if( pWal->exclusiveMode ) return SQLITE_OK;
+-  if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0);
+   rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
+                         SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
+   WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
+@@ -49854,13 +59960,13 @@
+   ** via the hash table even after the cleanup.
+   */
+   if( iLimit ){
+-    int i;           /* Loop counter */
++    int j;           /* Loop counter */
+     int iKey;        /* Hash key */
+-    for(i=1; i<=iLimit; i++){
+-      for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
+-        if( aHash[iKey]==i ) break;
++    for(j=1; j<=iLimit; j++){
++      for(iKey=walHash(aPgno[j]); aHash[iKey]; iKey=walNextHash(iKey)){
++        if( aHash[iKey]==j ) break;
+       }
+-      assert( aHash[iKey]==i );
++      assert( aHash[iKey]==j );
+     }
+   }
+ #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
+@@ -49979,7 +60085,7 @@
+   assert( pWal->writeLock );
+   iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
+   nLock = SQLITE_SHM_NLOCK - iLock;
+-  rc = walLockExclusive(pWal, iLock, nLock, 0);
++  rc = walLockExclusive(pWal, iLock, nLock);
+   if( rc ){
+     return rc;
+   }
+@@ -50051,7 +60157,7 @@
+     szFrame = szPage + WAL_FRAME_HDRSIZE;
+     aFrame = (u8 *)sqlite3_malloc64(szFrame);
+     if( !aFrame ){
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+       goto recovery_error;
+     }
+     aData = &aFrame[WAL_FRAME_HDRSIZE];
+@@ -50100,6 +60206,7 @@
+     */
+     pInfo = walCkptInfo(pWal);
+     pInfo->nBackfill = 0;
++    pInfo->nBackfillAttempted = pWal->hdr.mxFrame;
+     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;
+@@ -50171,7 +60278,11 @@
+   /* In the amalgamation, the os_unix.c and os_win.c source files come before
+   ** this source file.  Verify that the #defines of the locking byte offsets
+   ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value.
++  ** For that matter, if the lock offset ever changes from its initial design
++  ** value of 120, we need to know that so there is an assert() to check it.
+   */
++  assert( 120==WALINDEX_LOCK_OFFSET );
++  assert( 136==WALINDEX_HDR_SIZE );
+ #ifdef WIN_SHM_BASE
+   assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET );
+ #endif
+@@ -50184,7 +60295,7 @@
+   *ppWal = 0;
+   pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile);
+   if( !pRet ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+ 
+   pRet->pVfs = pVfs;
+@@ -50362,7 +60473,7 @@
+   int nMerge = 0;                 /* Number of elements in list aMerge */
+   ht_slot *aMerge = 0;            /* List to be merged */
+   int iList;                      /* Index into input list */
+-  int iSub = 0;                   /* Index into aSub array */
++  u32 iSub = 0;                   /* Index into aSub array */
+   struct Sublist aSub[13];        /* Array of sub-lists */
+ 
+   memset(aSub, 0, sizeof(aSub));
+@@ -50373,7 +60484,9 @@
+     nMerge = 1;
+     aMerge = &aList[iList];
+     for(iSub=0; iList & (1<<iSub); iSub++){
+-      struct Sublist *p = &aSub[iSub];
++      struct Sublist *p;
++      assert( iSub<ArraySize(aSub) );
++      p = &aSub[iSub];
+       assert( p->aList && p->nList<=(1<<iSub) );
+       assert( p->aList==&aList[iList&~((2<<iSub)-1)] );
+       walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
+@@ -50384,7 +60497,9 @@
+ 
+   for(iSub++; iSub<ArraySize(aSub); iSub++){
+     if( nList & (1<<iSub) ){
+-      struct Sublist *p = &aSub[iSub];
++      struct Sublist *p;
++      assert( iSub<ArraySize(aSub) );
++      p = &aSub[iSub];
+       assert( p->nList<=(1<<iSub) );
+       assert( p->aList==&aList[nList&~((2<<iSub)-1)] );
+       walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
+@@ -50444,7 +60559,7 @@
+         + iLast*sizeof(ht_slot);
+   p = (WalIterator *)sqlite3_malloc64(nByte);
+   if( !p ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   memset(p, 0, nByte);
+   p->nSegment = nSegment;
+@@ -50456,7 +60571,7 @@
+       sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
+   );
+   if( !aTmp ){
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+   }
+ 
+   for(i=0; rc==SQLITE_OK && i<nSegment; i++){
+@@ -50513,7 +60628,7 @@
+ ){
+   int rc;
+   do {
+-    rc = walLockExclusive(pWal, lockIdx, n, 0);
++    rc = walLockExclusive(pWal, lockIdx, n);
+   }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
+   return rc;
+ }
+@@ -50553,6 +60668,7 @@
+   memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
+   walIndexWriteHdr(pWal);
+   pInfo->nBackfill = 0;
++  pInfo->nBackfillAttempted = 0;
+   pInfo->aReadMark[1] = 0;
+   for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
+   assert( pInfo->aReadMark[0]==0 );
+@@ -50591,6 +60707,7 @@
+ */
+ static int walCheckpoint(
+   Wal *pWal,                      /* Wal connection */
++  sqlite3 *db,                    /* Check for interrupts on this handle */
+   int eMode,                      /* One of PASSIVE, FULL or RESTART */
+   int (*xBusy)(void*),            /* Function to call when busy */
+   void *pBusyArg,                 /* Context argument for xBusyHandler */
+@@ -50662,6 +60779,8 @@
+       i64 nSize;                    /* Current size of database file */
+       u32 nBackfill = pInfo->nBackfill;
+ 
++      pInfo->nBackfillAttempted = mxSafeFrame;
++
+       /* Sync the WAL to disk */
+       if( sync_flags ){
+         rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
+@@ -50683,6 +60802,10 @@
+       while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
+         i64 iOffset;
+         assert( walFramePgno(pWal, iFrame)==iDbpage );
++        if( db->u1.isInterrupted ){
++          rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
++          break;
++        }
+         if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
+           continue;
+         }
+@@ -50787,6 +60910,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3WalClose(
+   Wal *pWal,                      /* Wal to close */
++  sqlite3 *db,                    /* For interrupt flag */
+   int sync_flags,                 /* Flags to pass to OsSync() (or 0) */
+   int nBuf,
+   u8 *zBuf                        /* Buffer of at least nBuf bytes */
+@@ -50803,13 +60927,14 @@
+     **
+     ** The EXCLUSIVE lock is not released before returning.
+     */
+-    rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
+-    if( rc==SQLITE_OK ){
++    if( zBuf!=0
++     && SQLITE_OK==(rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE))
++    ){
+       if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
+         pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
+       }
+-      rc = sqlite3WalCheckpoint(
+-          pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
++      rc = sqlite3WalCheckpoint(pWal, db, 
++          SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
+       );
+       if( rc==SQLITE_OK ){
+         int bPersist = -1;
+@@ -50954,7 +61079,7 @@
+         walUnlockShared(pWal, WAL_WRITE_LOCK);
+         rc = SQLITE_READONLY_RECOVERY;
+       }
+-    }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 1)) ){
++    }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
+       pWal->writeLock = 1;
+       if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
+         badHdr = walIndexTryHdr(pWal, pChanged);
+@@ -51045,6 +61170,7 @@
+   int mxI;                        /* Index of largest aReadMark[] value */
+   int i;                          /* Loop counter */
+   int rc = SQLITE_OK;             /* Return code  */
++  u32 mxFrame;                    /* Wal frame to lock to */
+ 
+   assert( pWal->readLock<0 );     /* Not currently locked */
+ 
+@@ -51108,7 +61234,12 @@
+   }
+ 
+   pInfo = walCkptInfo(pWal);
+-  if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame ){
++  if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame 
++#ifdef SQLITE_ENABLE_SNAPSHOT
++   && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0
++     || 0==memcmp(&pWal->hdr, pWal->pSnapshot, sizeof(WalIndexHdr)))
++#endif
++  ){
+     /* The WAL has been completely backfilled (or it is empty).
+     ** and can be safely ignored.
+     */
+@@ -51146,73 +61277,169 @@
+   */
+   mxReadMark = 0;
+   mxI = 0;
++  mxFrame = pWal->hdr.mxFrame;
++#ifdef SQLITE_ENABLE_SNAPSHOT
++  if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){
++    mxFrame = pWal->pSnapshot->mxFrame;
++  }
++#endif
+   for(i=1; i<WAL_NREADER; i++){
+     u32 thisMark = pInfo->aReadMark[i];
+-    if( mxReadMark<=thisMark && thisMark<=pWal->hdr.mxFrame ){
++    if( mxReadMark<=thisMark && thisMark<=mxFrame ){
+       assert( thisMark!=READMARK_NOT_USED );
+       mxReadMark = thisMark;
+       mxI = i;
+     }
+   }
+-  /* There was once an "if" here. The extra "{" is to preserve indentation. */
+-  {
+-    if( (pWal->readOnly & WAL_SHM_RDONLY)==0
+-     && (mxReadMark<pWal->hdr.mxFrame || mxI==0)
+-    ){
+-      for(i=1; i<WAL_NREADER; i++){
+-        rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1, 0);
+-        if( rc==SQLITE_OK ){
+-          mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame;
+-          mxI = i;
+-          walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
+-          break;
+-        }else if( rc!=SQLITE_BUSY ){
+-          return rc;
+-        }
++  if( (pWal->readOnly & WAL_SHM_RDONLY)==0
++   && (mxReadMark<mxFrame || mxI==0)
++  ){
++    for(i=1; i<WAL_NREADER; i++){
++      rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
++      if( rc==SQLITE_OK ){
++        mxReadMark = pInfo->aReadMark[i] = mxFrame;
++        mxI = i;
++        walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
++        break;
++      }else if( rc!=SQLITE_BUSY ){
++        return rc;
+       }
+     }
+-    if( mxI==0 ){
+-      assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
+-      return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
+-    }
++  }
++  if( mxI==0 ){
++    assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
++    return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
++  }
+ 
+-    rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
+-    if( rc ){
+-      return rc==SQLITE_BUSY ? WAL_RETRY : rc;
+-    }
+-    /* Now that the read-lock has been obtained, check that neither the
+-    ** value in the aReadMark[] array or the contents of the wal-index
+-    ** header have changed.
+-    **
+-    ** It is necessary to check that the wal-index header did not change
+-    ** between the time it was read and when the shared-lock was obtained
+-    ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility
+-    ** that the log file may have been wrapped by a writer, or that frames
+-    ** that occur later in the log than pWal->hdr.mxFrame may have been
+-    ** copied into the database by a checkpointer. If either of these things
+-    ** happened, then reading the database with the current value of
+-    ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry
+-    ** instead.
+-    **
+-    ** This does not guarantee that the copy of the wal-index header is up to
+-    ** date before proceeding. That would not be possible without somehow
+-    ** blocking writers. It only guarantees that a dangerous checkpoint or 
+-    ** log-wrap (either of which would require an exclusive lock on
+-    ** WAL_READ_LOCK(mxI)) has not occurred since the snapshot was valid.
+-    */
+-    walShmBarrier(pWal);
+-    if( pInfo->aReadMark[mxI]!=mxReadMark
+-     || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
+-    ){
+-      walUnlockShared(pWal, WAL_READ_LOCK(mxI));
+-      return WAL_RETRY;
+-    }else{
+-      assert( mxReadMark<=pWal->hdr.mxFrame );
+-      pWal->readLock = (i16)mxI;
++  rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
++  if( rc ){
++    return rc==SQLITE_BUSY ? WAL_RETRY : rc;
++  }
++  /* Now that the read-lock has been obtained, check that neither the
++  ** value in the aReadMark[] array or the contents of the wal-index
++  ** header have changed.
++  **
++  ** It is necessary to check that the wal-index header did not change
++  ** between the time it was read and when the shared-lock was obtained
++  ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility
++  ** that the log file may have been wrapped by a writer, or that frames
++  ** that occur later in the log than pWal->hdr.mxFrame may have been
++  ** copied into the database by a checkpointer. If either of these things
++  ** happened, then reading the database with the current value of
++  ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry
++  ** instead.
++  **
++  ** Before checking that the live wal-index header has not changed
++  ** since it was read, set Wal.minFrame to the first frame in the wal
++  ** file that has not yet been checkpointed. This client will not need
++  ** to read any frames earlier than minFrame from the wal file - they
++  ** can be safely read directly from the database file.
++  **
++  ** Because a ShmBarrier() call is made between taking the copy of 
++  ** nBackfill and checking that the wal-header in shared-memory still
++  ** matches the one cached in pWal->hdr, it is guaranteed that the 
++  ** checkpointer that set nBackfill was not working with a wal-index
++  ** header newer than that cached in pWal->hdr. If it were, that could
++  ** cause a problem. The checkpointer could omit to checkpoint
++  ** a version of page X that lies before pWal->minFrame (call that version
++  ** A) on the basis that there is a newer version (version B) of the same
++  ** page later in the wal file. But if version B happens to like past
++  ** frame pWal->hdr.mxFrame - then the client would incorrectly assume
++  ** that it can read version A from the database file. However, since
++  ** we can guarantee that the checkpointer that set nBackfill could not
++  ** see any pages past pWal->hdr.mxFrame, this problem does not come up.
++  */
++  pWal->minFrame = pInfo->nBackfill+1;
++  walShmBarrier(pWal);
++  if( pInfo->aReadMark[mxI]!=mxReadMark
++   || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
++  ){
++    walUnlockShared(pWal, WAL_READ_LOCK(mxI));
++    return WAL_RETRY;
++  }else{
++    assert( mxReadMark<=pWal->hdr.mxFrame );
++    pWal->readLock = (i16)mxI;
++  }
++  return rc;
++}
++
++#ifdef SQLITE_ENABLE_SNAPSHOT
++/*
++** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted 
++** variable so that older snapshots can be accessed. To do this, loop
++** through all wal frames from nBackfillAttempted to (nBackfill+1), 
++** comparing their content to the corresponding page with the database
++** file, if any. Set nBackfillAttempted to the frame number of the
++** first frame for which the wal file content matches the db file.
++**
++** This is only really safe if the file-system is such that any page 
++** writes made by earlier checkpointers were atomic operations, which 
++** is not always true. It is also possible that nBackfillAttempted
++** may be left set to a value larger than expected, if a wal frame
++** contains content that duplicate of an earlier version of the same
++** page.
++**
++** SQLITE_OK is returned if successful, or an SQLite error code if an
++** error occurs. It is not an error if nBackfillAttempted cannot be
++** decreased at all.
++*/
++SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){
++  int rc;
++
++  assert( pWal->readLock>=0 );
++  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
++  if( rc==SQLITE_OK ){
++    volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
++    int szPage = (int)pWal->szPage;
++    i64 szDb;                   /* Size of db file in bytes */
++
++    rc = sqlite3OsFileSize(pWal->pDbFd, &szDb);
++    if( rc==SQLITE_OK ){
++      void *pBuf1 = sqlite3_malloc(szPage);
++      void *pBuf2 = sqlite3_malloc(szPage);
++      if( pBuf1==0 || pBuf2==0 ){
++        rc = SQLITE_NOMEM;
++      }else{
++        u32 i = pInfo->nBackfillAttempted;
++        for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){
++          volatile ht_slot *dummy;
++          volatile u32 *aPgno;      /* Array of page numbers */
++          u32 iZero;                /* Frame corresponding to aPgno[0] */
++          u32 pgno;                 /* Page number in db file */
++          i64 iDbOff;               /* Offset of db file entry */
++          i64 iWalOff;              /* Offset of wal file entry */
++
++          rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero);
++          if( rc!=SQLITE_OK ) break;
++          pgno = aPgno[i-iZero];
++          iDbOff = (i64)(pgno-1) * szPage;
++
++          if( iDbOff+szPage<=szDb ){
++            iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
++            rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
++
++            if( rc==SQLITE_OK ){
++              rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff);
++            }
++
++            if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){
++              break;
++            }
++          }
++
++          pInfo->nBackfillAttempted = i-1;
++        }
++      }
++
++      sqlite3_free(pBuf1);
++      sqlite3_free(pBuf2);
+     }
++    walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
+   }
++
+   return rc;
+ }
++#endif /* SQLITE_ENABLE_SNAPSHOT */
+ 
+ /*
+ ** Begin a read transaction on the database.
+@@ -51232,6 +61459,14 @@
+   int rc;                         /* Return code */
+   int cnt = 0;                    /* Number of TryBeginRead attempts */
+ 
++#ifdef SQLITE_ENABLE_SNAPSHOT
++  int bChanged = 0;
++  WalIndexHdr *pSnapshot = pWal->pSnapshot;
++  if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
++    bChanged = 1;
++  }
++#endif
++
+   do{
+     rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
+   }while( rc==WAL_RETRY );
+@@ -51239,6 +61474,70 @@
+   testcase( (rc&0xff)==SQLITE_IOERR );
+   testcase( rc==SQLITE_PROTOCOL );
+   testcase( rc==SQLITE_OK );
++
++#ifdef SQLITE_ENABLE_SNAPSHOT
++  if( rc==SQLITE_OK ){
++    if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
++      /* At this point the client has a lock on an aReadMark[] slot holding
++      ** a value equal to or smaller than pSnapshot->mxFrame, but pWal->hdr
++      ** is populated with the wal-index header corresponding to the head
++      ** of the wal file. Verify that pSnapshot is still valid before
++      ** continuing.  Reasons why pSnapshot might no longer be valid:
++      **
++      **    (1)  The WAL file has been reset since the snapshot was taken.
++      **         In this case, the salt will have changed.
++      **
++      **    (2)  A checkpoint as been attempted that wrote frames past
++      **         pSnapshot->mxFrame into the database file.  Note that the
++      **         checkpoint need not have completed for this to cause problems.
++      */
++      volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
++
++      assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
++      assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
++
++      /* It is possible that there is a checkpointer thread running 
++      ** concurrent with this code. If this is the case, it may be that the
++      ** checkpointer has already determined that it will checkpoint 
++      ** snapshot X, where X is later in the wal file than pSnapshot, but 
++      ** has not yet set the pInfo->nBackfillAttempted variable to indicate 
++      ** its intent. To avoid the race condition this leads to, ensure that
++      ** there is no checkpointer process by taking a shared CKPT lock 
++      ** before checking pInfo->nBackfillAttempted.  
++      **
++      ** TODO: Does the aReadMark[] lock prevent a checkpointer from doing
++      **       this already?
++      */
++      rc = walLockShared(pWal, WAL_CKPT_LOCK);
++
++      if( rc==SQLITE_OK ){
++        /* Check that the wal file has not been wrapped. Assuming that it has
++        ** not, also check that no checkpointer has attempted to checkpoint any
++        ** frames beyond pSnapshot->mxFrame. If either of these conditions are
++        ** true, return SQLITE_BUSY_SNAPSHOT. Otherwise, overwrite pWal->hdr
++        ** with *pSnapshot and set *pChanged as appropriate for opening the
++        ** snapshot.  */
++        if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
++         && pSnapshot->mxFrame>=pInfo->nBackfillAttempted
++        ){
++          assert( pWal->readLock>0 );
++          memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
++          *pChanged = bChanged;
++        }else{
++          rc = SQLITE_BUSY_SNAPSHOT;
++        }
++
++        /* Release the shared CKPT lock obtained above. */
++        walUnlockShared(pWal, WAL_CKPT_LOCK);
++      }
++
++
++      if( rc!=SQLITE_OK ){
++        sqlite3WalEndReadTransaction(pWal);
++      }
++    }
++  }
++#endif
+   return rc;
+ }
+ 
+@@ -51270,6 +61569,7 @@
+   u32 iRead = 0;                  /* If !=0, WAL frame to return data from */
+   u32 iLast = pWal->hdr.mxFrame;  /* Last page in WAL for this reader */
+   int iHash;                      /* Used to loop through N hash tables */
++  int iMinHash;
+ 
+   /* This routine is only be called from within a read transaction. */
+   assert( pWal->readLock>=0 || pWal->lockError );
+@@ -51310,7 +61610,8 @@
+   **     This condition filters out entries that were added to the hash
+   **     table after the current read-transaction had started.
+   */
+-  for(iHash=walFramePage(iLast); iHash>=0 && iRead==0; iHash--){
++  iMinHash = walFramePage(pWal->minFrame);
++  for(iHash=walFramePage(iLast); iHash>=iMinHash && iRead==0; iHash--){
+     volatile ht_slot *aHash;      /* Pointer to hash table */
+     volatile u32 *aPgno;          /* Pointer to array of page numbers */
+     u32 iZero;                    /* Frame number corresponding to aPgno[0] */
+@@ -51325,7 +61626,7 @@
+     nCollide = HASHTABLE_NSLOT;
+     for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
+       u32 iFrame = aHash[iKey] + iZero;
+-      if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){
++      if( iFrame<=iLast && iFrame>=pWal->minFrame && aPgno[aHash[iKey]]==pgno ){
+         assert( iFrame>iRead || CORRUPT_DB );
+         iRead = iFrame;
+       }
+@@ -51342,7 +61643,8 @@
+   {
+     u32 iRead2 = 0;
+     u32 iTest;
+-    for(iTest=iLast; iTest>0; iTest--){
++    assert( pWal->minFrame>0 );
++    for(iTest=iLast; iTest>=pWal->minFrame; iTest--){
+       if( walFramePgno(pWal, iTest)==pgno ){
+         iRead2 = iTest;
+         break;
+@@ -51408,6 +61710,7 @@
+   /* Cannot start a write transaction without first holding a read
+   ** transaction. */
+   assert( pWal->readLock>=0 );
++  assert( pWal->writeLock==0 && pWal->iReCksum==0 );
+ 
+   if( pWal->readOnly ){
+     return SQLITE_READONLY;
+@@ -51416,7 +61719,7 @@
+   /* Only one writer allowed at a time.  Get the write lock.  Return
+   ** SQLITE_BUSY if unable.
+   */
+-  rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0);
++  rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
+   if( rc ){
+     return rc;
+   }
+@@ -51443,6 +61746,7 @@
+   if( pWal->writeLock ){
+     walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
+     pWal->writeLock = 0;
++    pWal->iReCksum = 0;
+     pWal->truncateOnCommit = 0;
+   }
+   return SQLITE_OK;
+@@ -51561,7 +61865,7 @@
+     if( pInfo->nBackfill>0 ){
+       u32 salt1;
+       sqlite3_randomness(4, &salt1);
+-      rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0);
++      rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
+       if( rc==SQLITE_OK ){
+         /* If all readers are using WAL_READ_LOCK(0) (in other words if no
+         ** readers are currently using the WAL), then the transactions
+@@ -51649,7 +61953,7 @@
+   void *pData;                    /* Data actually written */
+   u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-header in */
+ #if defined(SQLITE_HAS_CODEC)
+-  if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM;
++  if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT;
+ #else
+   pData = pPage->pData;
+ #endif
+@@ -51661,6 +61965,59 @@
+   return rc;
+ }
+ 
++/*
++** This function is called as part of committing a transaction within which
++** one or more frames have been overwritten. It updates the checksums for
++** all frames written to the wal file by the current transaction starting
++** with the earliest to have been overwritten.
++**
++** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
++*/
++static int walRewriteChecksums(Wal *pWal, u32 iLast){
++  const int szPage = pWal->szPage;/* Database page size */
++  int rc = SQLITE_OK;             /* Return code */
++  u8 *aBuf;                       /* Buffer to load data from wal file into */
++  u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-headers in */
++  u32 iRead;                      /* Next frame to read from wal file */
++  i64 iCksumOff;
++
++  aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE);
++  if( aBuf==0 ) return SQLITE_NOMEM_BKPT;
++
++  /* Find the checksum values to use as input for the recalculating the
++  ** first checksum. If the first frame is frame 1 (implying that the current
++  ** transaction restarted the wal file), these values must be read from the
++  ** wal-file header. Otherwise, read them from the frame header of the
++  ** previous frame.  */
++  assert( pWal->iReCksum>0 );
++  if( pWal->iReCksum==1 ){
++    iCksumOff = 24;
++  }else{
++    iCksumOff = walFrameOffset(pWal->iReCksum-1, szPage) + 16;
++  }
++  rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, iCksumOff);
++  pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf);
++  pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]);
++
++  iRead = pWal->iReCksum;
++  pWal->iReCksum = 0;
++  for(; rc==SQLITE_OK && iRead<=iLast; iRead++){
++    i64 iOff = walFrameOffset(iRead, szPage);
++    rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff);
++    if( rc==SQLITE_OK ){
++      u32 iPgno, nDbSize;
++      iPgno = sqlite3Get4byte(aBuf);
++      nDbSize = sqlite3Get4byte(&aBuf[4]);
++
++      walEncodeFrame(pWal, iPgno, nDbSize, &aBuf[WAL_FRAME_HDRSIZE], aFrame);
++      rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOff);
++    }
++  }
++
++  sqlite3_free(aBuf);
++  return rc;
++}
++
+ /* 
+ ** Write a set of frames to the log. The caller must hold the write-lock
+ ** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
+@@ -51681,6 +62038,8 @@
+   int szFrame;                    /* The size of a single frame */
+   i64 iOffset;                    /* Next byte to write in WAL file */
+   WalWriter w;                    /* The writer */
++  u32 iFirst = 0;                 /* First frame that may be overwritten */
++  WalIndexHdr *pLive;             /* Pointer to shared header */
+ 
+   assert( pList );
+   assert( pWal->writeLock );
+@@ -51696,6 +62055,11 @@
+   }
+ #endif
+ 
++  pLive = (WalIndexHdr*)walIndexHdr(pWal);
++  if( memcmp(&pWal->hdr, (void *)pLive, sizeof(WalIndexHdr))!=0 ){
++    iFirst = pLive->mxFrame+1;
++  }
++
+   /* See if it is possible to write these frames into the start of the
+   ** log file, instead of appending to it at pWal->hdr.mxFrame.
+   */
+@@ -51760,6 +62124,33 @@
+   /* Write all frames into the log file exactly once */
+   for(p=pList; p; p=p->pDirty){
+     int nDbSize;   /* 0 normally.  Positive == commit flag */
++
++    /* Check if this page has already been written into the wal file by
++    ** the current transaction. If so, overwrite the existing frame and
++    ** set Wal.writeLock to WAL_WRITELOCK_RECKSUM - indicating that 
++    ** checksums must be recomputed when the transaction is committed.  */
++    if( iFirst && (p->pDirty || isCommit==0) ){
++      u32 iWrite = 0;
++      VVA_ONLY(rc =) sqlite3WalFindFrame(pWal, p->pgno, &iWrite);
++      assert( rc==SQLITE_OK || iWrite==0 );
++      if( iWrite>=iFirst ){
++        i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE;
++        void *pData;
++        if( pWal->iReCksum==0 || iWrite<pWal->iReCksum ){
++          pWal->iReCksum = iWrite;
++        }
++#if defined(SQLITE_HAS_CODEC)
++        if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM;
++#else
++        pData = p->pData;
++#endif
++        rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff);
++        if( rc ) return rc;
++        p->flags &= ~PGHDR_WAL_APPEND;
++        continue;
++      }
++    }
++
+     iFrame++;
+     assert( iOffset==walFrameOffset(iFrame, szPage) );
+     nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0;
+@@ -51767,6 +62158,13 @@
+     if( rc ) return rc;
+     pLast = p;
+     iOffset += szFrame;
++    p->flags |= PGHDR_WAL_APPEND;
++  }
++
++  /* Recalculate checksums within the wal file if required. */
++  if( isCommit && pWal->iReCksum ){
++    rc = walRewriteChecksums(pWal, iFrame);
++    if( rc ) return rc;
+   }
+ 
+   /* If this is the end of a transaction, then we might need to pad
+@@ -51784,16 +62182,21 @@
+   ** past the sector boundary is written after the sync.
+   */
+   if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
++    int bSync = 1;
+     if( pWal->padToSectorBoundary ){
+       int sectorSize = sqlite3SectorSize(pWal->pWalFd);
+       w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
++      bSync = (w.iSyncPoint==iOffset);
++      testcase( bSync );
+       while( iOffset<w.iSyncPoint ){
+         rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
+         if( rc ) return rc;
+         iOffset += szFrame;
+         nExtra++;
+       }
+-    }else{
++    }
++    if( bSync ){
++      assert( rc==SQLITE_OK );
+       rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK);
+     }
+   }
+@@ -51818,6 +62221,7 @@
+   */
+   iFrame = pWal->hdr.mxFrame;
+   for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){
++    if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue;
+     iFrame++;
+     rc = walIndexAppend(pWal, iFrame, p->pgno);
+   }
+@@ -51860,6 +62264,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3WalCheckpoint(
+   Wal *pWal,                      /* Wal connection */
++  sqlite3 *db,                    /* Check this handle's interrupt flag */
+   int eMode,                      /* PASSIVE, FULL, RESTART, or TRUNCATE */
+   int (*xBusy)(void*),            /* Function to call when busy */
+   void *pBusyArg,                 /* Context argument for xBusyHandler */
+@@ -51886,7 +62291,7 @@
+ 
+   /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive 
+   ** "checkpoint" lock on the database file. */
+-  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0);
++  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
+   if( rc ){
+     /* EVIDENCE-OF: R-10421-19736 If any other process is running a
+     ** checkpoint operation at the same time, the lock cannot be obtained and
+@@ -51930,10 +62335,11 @@
+ 
+   /* Copy data from the log to the database file. */
+   if( rc==SQLITE_OK ){
++
+     if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
+       rc = SQLITE_CORRUPT_BKPT;
+     }else{
+-      rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
++      rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
+     }
+ 
+     /* If no error occurred, set the output variables. */
+@@ -52045,6 +62451,57 @@
+   return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
+ }
+ 
++#ifdef SQLITE_ENABLE_SNAPSHOT
++/* Create a snapshot object.  The content of a snapshot is opaque to
++** every other subsystem, so the WAL module can put whatever it needs
++** in the object.
++*/
++SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){
++  int rc = SQLITE_OK;
++  WalIndexHdr *pRet;
++  static const u32 aZero[4] = { 0, 0, 0, 0 };
++
++  assert( pWal->readLock>=0 && pWal->writeLock==0 );
++
++  if( memcmp(&pWal->hdr.aFrameCksum[0],aZero,16)==0 ){
++    *ppSnapshot = 0;
++    return SQLITE_ERROR;
++  }
++  pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr));
++  if( pRet==0 ){
++    rc = SQLITE_NOMEM_BKPT;
++  }else{
++    memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr));
++    *ppSnapshot = (sqlite3_snapshot*)pRet;
++  }
++
++  return rc;
++}
++
++/* Try to open on pSnapshot when the next read-transaction starts
++*/
++SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){
++  pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
++}
++
++/* 
++** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
++** p1 is older than p2 and zero if p1 and p2 are the same snapshot.
++*/
++SQLITE_API int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){
++  WalIndexHdr *pHdr1 = (WalIndexHdr*)p1;
++  WalIndexHdr *pHdr2 = (WalIndexHdr*)p2;
++
++  /* aSalt[0] is a copy of the value stored in the wal file header. It
++  ** is incremented each time the wal file is restarted.  */
++  if( pHdr1->aSalt[0]<pHdr2->aSalt[0] ) return -1;
++  if( pHdr1->aSalt[0]>pHdr2->aSalt[0] ) return +1;
++  if( pHdr1->mxFrame<pHdr2->mxFrame ) return -1;
++  if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1;
++  return 0;
++}
++#endif /* SQLITE_ENABLE_SNAPSHOT */
++
+ #ifdef SQLITE_ENABLE_ZIPVFS
+ /*
+ ** If the argument is not NULL, it points to a Wal object that holds a
+@@ -52057,6 +62514,12 @@
+ }
+ #endif
+ 
++/* Return the sqlite3_file object for the WAL file
++*/
++SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){
++  return pWal->pWalFd;
++}
++
+ #endif /* #ifndef SQLITE_OMIT_WAL */
+ 
+ /************** End of wal.c *************************************************/
+@@ -52078,692 +62541,7 @@
+ ** big and we want to break it down some.  This packaged seemed like
+ ** a good breakout.
+ */
+-/************** Include btreeInt.h in the middle of btmutex.c ****************/
+-/************** Begin file btreeInt.h ****************************************/
+-/*
+-** 2004 April 6
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
+-**
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-*************************************************************************
+-** This file implements an external (disk-based) database using BTrees.
+-** For a detailed discussion of BTrees, refer to
+-**
+-**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
+-**     "Sorting And Searching", pages 473-480. Addison-Wesley
+-**     Publishing Company, Reading, Massachusetts.
+-**
+-** The basic idea is that each page of the file contains N database
+-** entries and N+1 pointers to subpages.
+-**
+-**   ----------------------------------------------------------------
+-**   |  Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) |
+-**   ----------------------------------------------------------------
+-**
+-** All of the keys on the page that Ptr(0) points to have values less
+-** than Key(0).  All of the keys on page Ptr(1) and its subpages have
+-** values greater than Key(0) and less than Key(1).  All of the keys
+-** on Ptr(N) and its subpages have values greater than Key(N-1).  And
+-** so forth.
+-**
+-** Finding a particular key requires reading O(log(M)) pages from the 
+-** disk where M is the number of entries in the tree.
+-**
+-** In this implementation, a single file can hold one or more separate 
+-** BTrees.  Each BTree is identified by the index of its root page.  The
+-** key and data for any entry are combined to form the "payload".  A
+-** fixed amount of payload can be carried directly on the database
+-** page.  If the payload is larger than the preset amount then surplus
+-** bytes are stored on overflow pages.  The payload for an entry
+-** and the preceding pointer are combined to form a "Cell".  Each 
+-** page has a small header which contains the Ptr(N) pointer and other
+-** information such as the size of key and data.
+-**
+-** FORMAT DETAILS
+-**
+-** The file is divided into pages.  The first page is called page 1,
+-** the second is page 2, and so forth.  A page number of zero indicates
+-** "no such page".  The page size can be any power of 2 between 512 and 65536.
+-** Each page can be either a btree page, a freelist page, an overflow
+-** page, or a pointer-map page.
+-**
+-** The first page is always a btree page.  The first 100 bytes of the first
+-** page contain a special header (the "file header") that describes the file.
+-** The format of the file header is as follows:
+-**
+-**   OFFSET   SIZE    DESCRIPTION
+-**      0      16     Header string: "SQLite format 3\000"
+-**     16       2     Page size in bytes.  (1 means 65536)
+-**     18       1     File format write version
+-**     19       1     File format read version
+-**     20       1     Bytes of unused space at the end of each page
+-**     21       1     Max embedded payload fraction (must be 64)
+-**     22       1     Min embedded payload fraction (must be 32)
+-**     23       1     Min leaf payload fraction (must be 32)
+-**     24       4     File change counter
+-**     28       4     Reserved for future use
+-**     32       4     First freelist page
+-**     36       4     Number of freelist pages in the file
+-**     40      60     15 4-byte meta values passed to higher layers
+-**
+-**     40       4     Schema cookie
+-**     44       4     File format of schema layer
+-**     48       4     Size of page cache
+-**     52       4     Largest root-page (auto/incr_vacuum)
+-**     56       4     1=UTF-8 2=UTF16le 3=UTF16be
+-**     60       4     User version
+-**     64       4     Incremental vacuum mode
+-**     68       4     Application-ID
+-**     72      20     unused
+-**     92       4     The version-valid-for number
+-**     96       4     SQLITE_VERSION_NUMBER
+-**
+-** All of the integer values are big-endian (most significant byte first).
+-**
+-** The file change counter is incremented when the database is changed
+-** This counter allows other processes to know when the file has changed
+-** and thus when they need to flush their cache.
+-**
+-** The max embedded payload fraction is the amount of the total usable
+-** space in a page that can be consumed by a single cell for standard
+-** B-tree (non-LEAFDATA) tables.  A value of 255 means 100%.  The default
+-** is to limit the maximum cell size so that at least 4 cells will fit
+-** on one page.  Thus the default max embedded payload fraction is 64.
+-**
+-** If the payload for a cell is larger than the max payload, then extra
+-** payload is spilled to overflow pages.  Once an overflow page is allocated,
+-** as many bytes as possible are moved into the overflow pages without letting
+-** the cell size drop below the min embedded payload fraction.
+-**
+-** The min leaf payload fraction is like the min embedded payload fraction
+-** except that it applies to leaf nodes in a LEAFDATA tree.  The maximum
+-** payload fraction for a LEAFDATA tree is always 100% (or 255) and it
+-** not specified in the header.
+-**
+-** Each btree pages is divided into three sections:  The header, the
+-** cell pointer array, and the cell content area.  Page 1 also has a 100-byte
+-** file header that occurs before the page header.
+-**
+-**      |----------------|
+-**      | file header    |   100 bytes.  Page 1 only.
+-**      |----------------|
+-**      | page header    |   8 bytes for leaves.  12 bytes for interior nodes
+-**      |----------------|
+-**      | cell pointer   |   |  2 bytes per cell.  Sorted order.
+-**      | array          |   |  Grows downward
+-**      |                |   v
+-**      |----------------|
+-**      | unallocated    |
+-**      | space          |
+-**      |----------------|   ^  Grows upwards
+-**      | cell content   |   |  Arbitrary order interspersed with freeblocks.
+-**      | area           |   |  and free space fragments.
+-**      |----------------|
+-**
+-** The page headers looks like this:
+-**
+-**   OFFSET   SIZE     DESCRIPTION
+-**      0       1      Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf
+-**      1       2      byte offset to the first freeblock
+-**      3       2      number of cells on this page
+-**      5       2      first byte of the cell content area
+-**      7       1      number of fragmented free bytes
+-**      8       4      Right child (the Ptr(N) value).  Omitted on leaves.
+-**
+-** The flags define the format of this btree page.  The leaf flag means that
+-** this page has no children.  The zerodata flag means that this page carries
+-** only keys and no data.  The intkey flag means that the key is an integer
+-** which is stored in the key size entry of the cell header rather than in
+-** the payload area.
+-**
+-** The cell pointer array begins on the first byte after the page header.
+-** The cell pointer array contains zero or more 2-byte numbers which are
+-** offsets from the beginning of the page to the cell content in the cell
+-** content area.  The cell pointers occur in sorted order.  The system strives
+-** to keep free space after the last cell pointer so that new cells can
+-** be easily added without having to defragment the page.
+-**
+-** Cell content is stored at the very end of the page and grows toward the
+-** beginning of the page.
+-**
+-** Unused space within the cell content area is collected into a linked list of
+-** freeblocks.  Each freeblock is at least 4 bytes in size.  The byte offset
+-** to the first freeblock is given in the header.  Freeblocks occur in
+-** increasing order.  Because a freeblock must be at least 4 bytes in size,
+-** any group of 3 or fewer unused bytes in the cell content area cannot
+-** exist on the freeblock chain.  A group of 3 or fewer free bytes is called
+-** a fragment.  The total number of bytes in all fragments is recorded.
+-** in the page header at offset 7.
+-**
+-**    SIZE    DESCRIPTION
+-**      2     Byte offset of the next freeblock
+-**      2     Bytes in this freeblock
+-**
+-** Cells are of variable length.  Cells are stored in the cell content area at
+-** the end of the page.  Pointers to the cells are in the cell pointer array
+-** that immediately follows the page header.  Cells is not necessarily
+-** contiguous or in order, but cell pointers are contiguous and in order.
+-**
+-** Cell content makes use of variable length integers.  A variable
+-** length integer is 1 to 9 bytes where the lower 7 bits of each 
+-** byte are used.  The integer consists of all bytes that have bit 8 set and
+-** the first byte with bit 8 clear.  The most significant byte of the integer
+-** appears first.  A variable-length integer may not be more than 9 bytes long.
+-** As a special case, all 8 bytes of the 9th byte are used as data.  This
+-** allows a 64-bit integer to be encoded in 9 bytes.
+-**
+-**    0x00                      becomes  0x00000000
+-**    0x7f                      becomes  0x0000007f
+-**    0x81 0x00                 becomes  0x00000080
+-**    0x82 0x00                 becomes  0x00000100
+-**    0x80 0x7f                 becomes  0x0000007f
+-**    0x8a 0x91 0xd1 0xac 0x78  becomes  0x12345678
+-**    0x81 0x81 0x81 0x81 0x01  becomes  0x10204081
+-**
+-** Variable length integers are used for rowids and to hold the number of
+-** bytes of key and data in a btree cell.
+-**
+-** The content of a cell looks like this:
+-**
+-**    SIZE    DESCRIPTION
+-**      4     Page number of the left child. Omitted if leaf flag is set.
+-**     var    Number of bytes of data. Omitted if the zerodata flag is set.
+-**     var    Number of bytes of key. Or the key itself if intkey flag is set.
+-**      *     Payload
+-**      4     First page of the overflow chain.  Omitted if no overflow
+-**
+-** Overflow pages form a linked list.  Each page except the last is completely
+-** filled with data (pagesize - 4 bytes).  The last page can have as little
+-** as 1 byte of data.
+-**
+-**    SIZE    DESCRIPTION
+-**      4     Page number of next overflow page
+-**      *     Data
+-**
+-** Freelist pages come in two subtypes: trunk pages and leaf pages.  The
+-** file header points to the first in a linked list of trunk page.  Each trunk
+-** page points to multiple leaf pages.  The content of a leaf page is
+-** unspecified.  A trunk page looks like this:
+-**
+-**    SIZE    DESCRIPTION
+-**      4     Page number of next trunk page
+-**      4     Number of leaf pointers on this page
+-**      *     zero or more pages numbers of leaves
+-*/
+-
+-
+-/* The following value is the maximum cell size assuming a maximum page
+-** size give above.
+-*/
+-#define MX_CELL_SIZE(pBt)  ((int)(pBt->pageSize-8))
+-
+-/* The maximum number of cells on a single page of the database.  This
+-** assumes a minimum cell size of 6 bytes  (4 bytes for the cell itself
+-** plus 2 bytes for the index to the cell in the page header).  Such
+-** small cells will be rare, but they are possible.
+-*/
+-#define MX_CELL(pBt) ((pBt->pageSize-8)/6)
+-
+-/* Forward declarations */
+-typedef struct MemPage MemPage;
+-typedef struct BtLock BtLock;
+-
+-/*
+-** This is a magic string that appears at the beginning of every
+-** SQLite database in order to identify the file as a real database.
+-**
+-** You can change this value at compile-time by specifying a
+-** -DSQLITE_FILE_HEADER="..." on the compiler command-line.  The
+-** header must be exactly 16 bytes including the zero-terminator so
+-** the string itself should be 15 characters long.  If you change
+-** the header, then your custom library will not be able to read 
+-** databases generated by the standard tools and the standard tools
+-** will not be able to read databases created by your custom library.
+-*/
+-#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */
+-#  define SQLITE_FILE_HEADER "SQLite format 3"
+-#endif
+-
+-/*
+-** Page type flags.  An ORed combination of these flags appear as the
+-** first byte of on-disk image of every BTree page.
+-*/
+-#define PTF_INTKEY    0x01
+-#define PTF_ZERODATA  0x02
+-#define PTF_LEAFDATA  0x04
+-#define PTF_LEAF      0x08
+-
+-/*
+-** As each page of the file is loaded into memory, an instance of the following
+-** structure is appended and initialized to zero.  This structure stores
+-** information about the page that is decoded from the raw file page.
+-**
+-** The pParent field points back to the parent page.  This allows us to
+-** walk up the BTree from any leaf to the root.  Care must be taken to
+-** unref() the parent page pointer when this page is no longer referenced.
+-** The pageDestructor() routine handles that chore.
+-**
+-** Access to all fields of this structure is controlled by the mutex
+-** stored in MemPage.pBt->mutex.
+-*/
+-struct MemPage {
+-  u8 isInit;           /* True if previously initialized. MUST BE FIRST! */
+-  u8 nOverflow;        /* Number of overflow cell bodies in aCell[] */
+-  u8 intKey;           /* True if table b-trees.  False for index b-trees */
+-  u8 intKeyLeaf;       /* True if the leaf of an intKey table */
+-  u8 noPayload;        /* True if internal intKey page (thus w/o data) */
+-  u8 leaf;             /* True if a leaf page */
+-  u8 hdrOffset;        /* 100 for page 1.  0 otherwise */
+-  u8 childPtrSize;     /* 0 if leaf==1.  4 if leaf==0 */
+-  u8 max1bytePayload;  /* min(maxLocal,127) */
+-  u8 bBusy;            /* Prevent endless loops on corrupt database files */
+-  u16 maxLocal;        /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
+-  u16 minLocal;        /* Copy of BtShared.minLocal or BtShared.minLeaf */
+-  u16 cellOffset;      /* Index in aData of first cell pointer */
+-  u16 nFree;           /* Number of free bytes on the page */
+-  u16 nCell;           /* Number of cells on this page, local and ovfl */
+-  u16 maskPage;        /* Mask for page offset */
+-  u16 aiOvfl[5];       /* Insert the i-th overflow cell before the aiOvfl-th
+-                       ** non-overflow cell */
+-  u8 *apOvfl[5];       /* Pointers to the body of overflow cells */
+-  BtShared *pBt;       /* Pointer to BtShared that this page is part of */
+-  u8 *aData;           /* Pointer to disk image of the page data */
+-  u8 *aDataEnd;        /* One byte past the end of usable data */
+-  u8 *aCellIdx;        /* The cell index area */
+-  DbPage *pDbPage;     /* Pager page handle */
+-  Pgno pgno;           /* Page number for this page */
+-};
+-
+-/*
+-** The in-memory image of a disk page has the auxiliary information appended
+-** to the end.  EXTRA_SIZE is the number of bytes of space needed to hold
+-** that extra information.
+-*/
+-#define EXTRA_SIZE sizeof(MemPage)
+-
+-/*
+-** A linked list of the following structures is stored at BtShared.pLock.
+-** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor 
+-** is opened on the table with root page BtShared.iTable. Locks are removed
+-** from this list when a transaction is committed or rolled back, or when
+-** a btree handle is closed.
+-*/
+-struct BtLock {
+-  Btree *pBtree;        /* Btree handle holding this lock */
+-  Pgno iTable;          /* Root page of table */
+-  u8 eLock;             /* READ_LOCK or WRITE_LOCK */
+-  BtLock *pNext;        /* Next in BtShared.pLock list */
+-};
+-
+-/* Candidate values for BtLock.eLock */
+-#define READ_LOCK     1
+-#define WRITE_LOCK    2
+-
+-/* A Btree handle
+-**
+-** A database connection contains a pointer to an instance of
+-** this object for every database file that it has open.  This structure
+-** is opaque to the database connection.  The database connection cannot
+-** see the internals of this structure and only deals with pointers to
+-** this structure.
+-**
+-** For some database files, the same underlying database cache might be 
+-** shared between multiple connections.  In that case, each connection
+-** has it own instance of this object.  But each instance of this object
+-** points to the same BtShared object.  The database cache and the
+-** schema associated with the database file are all contained within
+-** the BtShared object.
+-**
+-** All fields in this structure are accessed under sqlite3.mutex.
+-** The pBt pointer itself may not be changed while there exists cursors 
+-** in the referenced BtShared that point back to this Btree since those
+-** cursors have to go through this Btree to find their BtShared and
+-** they often do so without holding sqlite3.mutex.
+-*/
+-struct Btree {
+-  sqlite3 *db;       /* The database connection holding this btree */
+-  BtShared *pBt;     /* Sharable content of this btree */
+-  u8 inTrans;        /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
+-  u8 sharable;       /* True if we can share pBt with another db */
+-  u8 locked;         /* True if db currently has pBt locked */
+-  int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
+-  int nBackup;       /* Number of backup operations reading this btree */
+-  u32 iDataVersion;  /* Combines with pBt->pPager->iDataVersion */
+-  Btree *pNext;      /* List of other sharable Btrees from the same db */
+-  Btree *pPrev;      /* Back pointer of the same list */
+-#ifndef SQLITE_OMIT_SHARED_CACHE
+-  BtLock lock;       /* Object used to lock page 1 */
+-#endif
+-};
+-
+-/*
+-** Btree.inTrans may take one of the following values.
+-**
+-** If the shared-data extension is enabled, there may be multiple users
+-** of the Btree structure. At most one of these may open a write transaction,
+-** but any number may have active read transactions.
+-*/
+-#define TRANS_NONE  0
+-#define TRANS_READ  1
+-#define TRANS_WRITE 2
+-
+-/*
+-** An instance of this object represents a single database file.
+-** 
+-** A single database file can be in use at the same time by two
+-** or more database connections.  When two or more connections are
+-** sharing the same database file, each connection has it own
+-** private Btree object for the file and each of those Btrees points
+-** to this one BtShared object.  BtShared.nRef is the number of
+-** connections currently sharing this database file.
+-**
+-** Fields in this structure are accessed under the BtShared.mutex
+-** mutex, except for nRef and pNext which are accessed under the
+-** global SQLITE_MUTEX_STATIC_MASTER mutex.  The pPager field
+-** may not be modified once it is initially set as long as nRef>0.
+-** The pSchema field may be set once under BtShared.mutex and
+-** thereafter is unchanged as long as nRef>0.
+-**
+-** isPending:
+-**
+-**   If a BtShared client fails to obtain a write-lock on a database
+-**   table (because there exists one or more read-locks on the table),
+-**   the shared-cache enters 'pending-lock' state and isPending is
+-**   set to true.
+-**
+-**   The shared-cache leaves the 'pending lock' state when either of
+-**   the following occur:
+-**
+-**     1) The current writer (BtShared.pWriter) concludes its transaction, OR
+-**     2) The number of locks held by other connections drops to zero.
+-**
+-**   while in the 'pending-lock' state, no connection may start a new
+-**   transaction.
+-**
+-**   This feature is included to help prevent writer-starvation.
+-*/
+-struct BtShared {
+-  Pager *pPager;        /* The page cache */
+-  sqlite3 *db;          /* Database connection currently using this Btree */
+-  BtCursor *pCursor;    /* A list of all open cursors */
+-  MemPage *pPage1;      /* First page of the database */
+-  u8 openFlags;         /* Flags to sqlite3BtreeOpen() */
+-#ifndef SQLITE_OMIT_AUTOVACUUM
+-  u8 autoVacuum;        /* True if auto-vacuum is enabled */
+-  u8 incrVacuum;        /* True if incr-vacuum is enabled */
+-  u8 bDoTruncate;       /* True to truncate db on commit */
+-#endif
+-  u8 inTransaction;     /* Transaction state */
+-  u8 max1bytePayload;   /* Maximum first byte of cell for a 1-byte payload */
+-#ifdef SQLITE_HAS_CODEC
+-  u8 optimalReserve;    /* Desired amount of reserved space per page */
+-#endif
+-  u16 btsFlags;         /* Boolean parameters.  See BTS_* macros below */
+-  u16 maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
+-  u16 minLocal;         /* Minimum local payload in non-LEAFDATA tables */
+-  u16 maxLeaf;          /* Maximum local payload in a LEAFDATA table */
+-  u16 minLeaf;          /* Minimum local payload in a LEAFDATA table */
+-  u32 pageSize;         /* Total number of bytes on a page */
+-  u32 usableSize;       /* Number of usable bytes on each page */
+-  int nTransaction;     /* Number of open transactions (read + write) */
+-  u32 nPage;            /* Number of pages in the database */
+-  void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
+-  void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
+-  sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */
+-  Bitvec *pHasContent;  /* Set of pages moved to free-list this transaction */
+-#ifndef SQLITE_OMIT_SHARED_CACHE
+-  int nRef;             /* Number of references to this structure */
+-  BtShared *pNext;      /* Next on a list of sharable BtShared structs */
+-  BtLock *pLock;        /* List of locks held on this shared-btree struct */
+-  Btree *pWriter;       /* Btree with currently open write transaction */
+-#endif
+-  u8 *pTmpSpace;        /* Temp space sufficient to hold a single cell */
+-};
+-
+-/*
+-** Allowed values for BtShared.btsFlags
+-*/
+-#define BTS_READ_ONLY        0x0001   /* Underlying file is readonly */
+-#define BTS_PAGESIZE_FIXED   0x0002   /* Page size can no longer be changed */
+-#define BTS_SECURE_DELETE    0x0004   /* PRAGMA secure_delete is enabled */
+-#define BTS_INITIALLY_EMPTY  0x0008   /* Database was empty at trans start */
+-#define BTS_NO_WAL           0x0010   /* Do not open write-ahead-log files */
+-#define BTS_EXCLUSIVE        0x0020   /* pWriter has an exclusive lock */
+-#define BTS_PENDING          0x0040   /* Waiting for read-locks to clear */
+-
+-/*
+-** An instance of the following structure is used to hold information
+-** about a cell.  The parseCellPtr() function fills in this structure
+-** based on information extract from the raw disk page.
+-*/
+-typedef struct CellInfo CellInfo;
+-struct CellInfo {
+-  i64 nKey;      /* The key for INTKEY tables, or nPayload otherwise */
+-  u8 *pPayload;  /* Pointer to the start of payload */
+-  u32 nPayload;  /* Bytes of payload */
+-  u16 nLocal;    /* Amount of payload held locally, not on overflow */
+-  u16 iOverflow; /* Offset to overflow page number.  Zero if no overflow */
+-  u16 nSize;     /* Size of the cell content on the main b-tree page */
+-};
+-
+-/*
+-** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than
+-** this will be declared corrupt. This value is calculated based on a
+-** maximum database size of 2^31 pages a minimum fanout of 2 for a
+-** root-node and 3 for all other internal nodes.
+-**
+-** If a tree that appears to be taller than this is encountered, it is
+-** assumed that the database is corrupt.
+-*/
+-#define BTCURSOR_MAX_DEPTH 20
+-
+-/*
+-** A cursor is a pointer to a particular entry within a particular
+-** b-tree within a database file.
+-**
+-** The entry is identified by its MemPage and the index in
+-** MemPage.aCell[] of the entry.
+-**
+-** A single database file can be shared by two more database connections,
+-** but cursors cannot be shared.  Each cursor is associated with a
+-** particular database connection identified BtCursor.pBtree.db.
+-**
+-** Fields in this structure are accessed under the BtShared.mutex
+-** found at self->pBt->mutex. 
+-**
+-** skipNext meaning:
+-**    eState==SKIPNEXT && skipNext>0:  Next sqlite3BtreeNext() is no-op.
+-**    eState==SKIPNEXT && skipNext<0:  Next sqlite3BtreePrevious() is no-op.
+-**    eState==FAULT:                   Cursor fault with skipNext as error code.
+-*/
+-struct BtCursor {
+-  Btree *pBtree;            /* The Btree to which this cursor belongs */
+-  BtShared *pBt;            /* The BtShared this cursor points to */
+-  BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
+-  struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
+-  Pgno *aOverflow;          /* Cache of overflow page locations */
+-  CellInfo info;            /* A parse of the cell we are pointing at */
+-  i64 nKey;                 /* Size of pKey, or last integer key */
+-  void *pKey;               /* Saved key that was cursor last known position */
+-  Pgno pgnoRoot;            /* The root page of this tree */
+-  int nOvflAlloc;           /* Allocated size of aOverflow[] array */
+-  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive.
+-                   ** Error code if eState==CURSOR_FAULT */
+-  u8 curFlags;              /* zero or more BTCF_* flags defined below */
+-  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
+-  u8 hints;                             /* As configured by CursorSetHints() */
+-  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 */
+-};
+-
+-/*
+-** Legal values for BtCursor.curFlags
+-*/
+-#define BTCF_WriteFlag    0x01   /* True if a write cursor */
+-#define BTCF_ValidNKey    0x02   /* True if info.nKey is valid */
+-#define BTCF_ValidOvfl    0x04   /* True if aOverflow is valid */
+-#define BTCF_AtLast       0x08   /* Cursor is pointing ot the last entry */
+-#define BTCF_Incrblob     0x10   /* True if an incremental I/O handle */
+-
+-/*
+-** Potential values for BtCursor.eState.
+-**
+-** CURSOR_INVALID:
+-**   Cursor does not point to a valid entry. This can happen (for example) 
+-**   because the table is empty or because BtreeCursorFirst() has not been
+-**   called.
+-**
+-** CURSOR_VALID:
+-**   Cursor points to a valid entry. getPayload() etc. may be called.
+-**
+-** CURSOR_SKIPNEXT:
+-**   Cursor is valid except that the Cursor.skipNext field is non-zero
+-**   indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
+-**   operation should be a no-op.
+-**
+-** CURSOR_REQUIRESEEK:
+-**   The table that this cursor was opened on still exists, but has been 
+-**   modified since the cursor was last used. The cursor position is saved
+-**   in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in 
+-**   this state, restoreCursorPosition() can be called to attempt to
+-**   seek the cursor to the saved position.
+-**
+-** CURSOR_FAULT:
+-**   An unrecoverable error (an I/O error or a malloc failure) has occurred
+-**   on a different connection that shares the BtShared cache with this
+-**   cursor.  The error has left the cache in an inconsistent state.
+-**   Do nothing else with this cursor.  Any attempt to use the cursor
+-**   should return the error code stored in BtCursor.skipNext
+-*/
+-#define CURSOR_INVALID           0
+-#define CURSOR_VALID             1
+-#define CURSOR_SKIPNEXT          2
+-#define CURSOR_REQUIRESEEK       3
+-#define CURSOR_FAULT             4
+-
+-/* 
+-** The database page the PENDING_BYTE occupies. This page is never used.
+-*/
+-# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
+-
+-/*
+-** These macros define the location of the pointer-map entry for a 
+-** database page. The first argument to each is the number of usable
+-** bytes on each page of the database (often 1024). The second is the
+-** page number to look up in the pointer map.
+-**
+-** PTRMAP_PAGENO returns the database page number of the pointer-map
+-** page that stores the required pointer. PTRMAP_PTROFFSET returns
+-** the offset of the requested map entry.
+-**
+-** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page,
+-** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be
+-** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
+-** this test.
+-*/
+-#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)
+-#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1))
+-#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
+-
+-/*
+-** The pointer map is a lookup table that identifies the parent page for
+-** each child page in the database file.  The parent page is the page that
+-** contains a pointer to the child.  Every page in the database contains
+-** 0 or 1 parent pages.  (In this context 'database page' refers
+-** to any page that is not part of the pointer map itself.)  Each pointer map
+-** entry consists of a single byte 'type' and a 4 byte parent page number.
+-** The PTRMAP_XXX identifiers below are the valid types.
+-**
+-** The purpose of the pointer map is to facility moving pages from one
+-** position in the file to another as part of autovacuum.  When a page
+-** is moved, the pointer in its parent must be updated to point to the
+-** new location.  The pointer map is used to locate the parent page quickly.
+-**
+-** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not
+-**                  used in this case.
+-**
+-** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number 
+-**                  is not used in this case.
+-**
+-** PTRMAP_OVERFLOW1: The database page is the first page in a list of 
+-**                   overflow pages. The page number identifies the page that
+-**                   contains the cell with a pointer to this overflow page.
+-**
+-** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of
+-**                   overflow pages. The page-number identifies the previous
+-**                   page in the overflow page list.
+-**
+-** PTRMAP_BTREE: The database page is a non-root btree page. The page number
+-**               identifies the parent page in the btree.
+-*/
+-#define PTRMAP_ROOTPAGE 1
+-#define PTRMAP_FREEPAGE 2
+-#define PTRMAP_OVERFLOW1 3
+-#define PTRMAP_OVERFLOW2 4
+-#define PTRMAP_BTREE 5
+-
+-/* A bunch of assert() statements to check the transaction state variables
+-** of handle p (type Btree*) are internally consistent.
+-*/
+-#define btreeIntegrity(p) \
+-  assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \
+-  assert( p->pBt->inTransaction>=p->inTrans ); 
+-
+-
+-/*
+-** The ISAUTOVACUUM macro is used within balance_nonroot() to determine
+-** if the database supports auto-vacuum or not. Because it is used
+-** within an expression that is an argument to another macro 
+-** (sqliteMallocRaw), it is not possible to use conditional compilation.
+-** So, this macro is defined instead.
+-*/
+-#ifndef SQLITE_OMIT_AUTOVACUUM
+-#define ISAUTOVACUUM (pBt->autoVacuum)
+-#else
+-#define ISAUTOVACUUM 0
+-#endif
+-
+-
+-/*
+-** This structure is passed around through all the sanity checking routines
+-** in order to keep track of some global state information.
+-**
+-** The aRef[] array is allocated so that there is 1 bit for each page in
+-** the database. As the integrity-check proceeds, for each page used in
+-** the database the corresponding bit is set. This allows integrity-check to 
+-** detect pages that are used twice and orphaned pages (both of which 
+-** indicate corruption).
+-*/
+-typedef struct IntegrityCk IntegrityCk;
+-struct IntegrityCk {
+-  BtShared *pBt;    /* The tree being checked out */
+-  Pager *pPager;    /* The associated pager.  Also accessible by pBt->pPager */
+-  u8 *aPgRef;       /* 1 bit per page in the db (see above) */
+-  Pgno nPage;       /* Number of pages in the database */
+-  int mxErr;        /* Stop accumulating errors when this reaches zero */
+-  int nErr;         /* Number of messages written to zErrMsg so far */
+-  int mallocFailed; /* A memory allocation error has occurred */
+-  const char *zPfx; /* Error message prefix */
+-  int v1, v2;       /* Values for up to two %d fields in zPfx */
+-  StrAccum errMsg;  /* Accumulate the error message text here */
+-};
+-
+-/*
+-** Routines to read or write a two- and four-byte big-endian integer values.
+-*/
+-#define get2byte(x)   ((x)[0]<<8 | (x)[1])
+-#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v))
+-#define get4byte sqlite3Get4byte
+-#define put4byte sqlite3Put4byte
+-
+-/************** End of btreeInt.h ********************************************/
+-/************** Continuing where we left off in btmutex.c ********************/
++/* #include "btreeInt.h" */
+ #ifndef SQLITE_OMIT_SHARED_CACHE
+ #if SQLITE_THREADSAFE
+ 
+@@ -52917,21 +62695,6 @@
+ #endif
+ 
+ 
+-#ifndef SQLITE_OMIT_INCRBLOB
+-/*
+-** Enter and leave a mutex on a Btree given a cursor owned by that
+-** Btree.  These entry points are used by incremental I/O and can be
+-** omitted if that module is not used.
+-*/
+-SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor *pCur){
+-  sqlite3BtreeEnter(pCur->pBtree);
+-}
+-SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){
+-  sqlite3BtreeLeave(pCur->pBtree);
+-}
+-#endif /* SQLITE_OMIT_INCRBLOB */
+-
+-
+ /*
+ ** Enter the mutex on every Btree associated with a database
+ ** connection.  This is needed (for example) prior to parsing
+@@ -52946,16 +62709,24 @@
+ ** two or more btrees in common both try to lock all their btrees
+ ** at the same instant.
+ */
+-SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
++static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){
+   int i;
++  int skipOk = 1;
+   Btree *p;
+   assert( sqlite3_mutex_held(db->mutex) );
+   for(i=0; i<db->nDb; i++){
+     p = db->aDb[i].pBt;
+-    if( p ) sqlite3BtreeEnter(p);
++    if( p && p->sharable ){
++      sqlite3BtreeEnter(p);
++      skipOk = 0;
++    }
+   }
++  db->skipBtreeMutex = skipOk;
+ }
+-SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
++SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
++  if( db->skipBtreeMutex==0 ) btreeEnterAll(db);
++}
++static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){
+   int i;
+   Btree *p;
+   assert( sqlite3_mutex_held(db->mutex) );
+@@ -52964,13 +62735,8 @@
+     if( p ) sqlite3BtreeLeave(p);
+   }
+ }
+-
+-/*
+-** Return true if a particular Btree requires a lock.  Return FALSE if
+-** no lock is ever required since it is not sharable.
+-*/
+-SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){
+-  return p->sharable;
++SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
++  if( db->skipBtreeMutex==0 ) btreeLeaveAll(db);
+ }
+ 
+ #ifndef NDEBUG
+@@ -53046,6 +62812,25 @@
+   }
+ }
+ #endif /* if SQLITE_THREADSAFE */
++
++#ifndef SQLITE_OMIT_INCRBLOB
++/*
++** Enter a mutex on a Btree given a cursor owned by that Btree. 
++**
++** These entry points are used by incremental I/O only. Enter() is required 
++** any time OMIT_SHARED_CACHE is not defined, regardless of whether or not 
++** the build is threadsafe. Leave() is only required by threadsafe builds.
++*/
++SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor *pCur){
++  sqlite3BtreeEnter(pCur->pBtree);
++}
++# if SQLITE_THREADSAFE
++SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){
++  sqlite3BtreeLeave(pCur->pBtree);
++}
++# endif
++#endif /* ifndef SQLITE_OMIT_INCRBLOB */
++
+ #endif /* ifndef SQLITE_OMIT_SHARED_CACHE */
+ 
+ /************** End of btmutex.c *********************************************/
+@@ -53065,6 +62850,7 @@
+ ** See the header comment on "btreeInt.h" for additional information.
+ ** Including a description of file format and an overview of operation.
+ */
++/* #include "btreeInt.h" */
+ 
+ /*
+ ** The header string that appears at the beginning of every
+@@ -53137,7 +62923,7 @@
+ ** The shared cache setting effects only future calls to
+ ** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int enable){
++SQLITE_API int sqlite3_enable_shared_cache(int enable){
+   sqlite3GlobalConfig.sharedCacheEnabled = enable;
+   return SQLITE_OK;
+ }
+@@ -53203,7 +62989,7 @@
+   ** Return true immediately.
+   */
+   if( (pBtree->sharable==0)
+-   || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommitted))
++   || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommit))
+   ){
+     return 1;
+   }
+@@ -53280,7 +63066,7 @@
+   for(p=pBtree->pBt->pCursor; p; p=p->pNext){
+     if( p->pgnoRoot==iRoot 
+      && p->pBtree!=pBtree
+-     && 0==(p->pBtree->db->flags & SQLITE_ReadUncommitted)
++     && 0==(p->pBtree->db->flags & SQLITE_ReadUncommit)
+     ){
+       return 1;
+     }
+@@ -53302,7 +63088,7 @@
+   assert( sqlite3BtreeHoldsMutex(p) );
+   assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
+   assert( p->db!=0 );
+-  assert( !(p->db->flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 );
++  assert( !(p->db->flags&SQLITE_ReadUncommit)||eLock==WRITE_LOCK||iTab==1 );
+   
+   /* If requesting a write-lock, then the Btree must have an open write
+   ** transaction on this file. And, obviously, for this to be so there 
+@@ -53380,7 +63166,7 @@
+   ** obtain a read-lock using this function. The only read-lock obtained
+   ** by a connection in read-uncommitted mode is on the sqlite_master 
+   ** table, and that lock is obtained in BtreeBeginTrans().  */
+-  assert( 0==(p->db->flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK );
++  assert( 0==(p->db->flags&SQLITE_ReadUncommit) || eLock==WRITE_LOCK );
+ 
+   /* This function should only be called on a sharable b-tree after it 
+   ** has been determined that no other b-tree holds a conflicting lock.  */
+@@ -53401,7 +63187,7 @@
+   if( !pLock ){
+     pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock));
+     if( !pLock ){
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     pLock->iTable = iTable;
+     pLock->pBtree = p;
+@@ -53501,6 +63287,19 @@
+ static int cursorHoldsMutex(BtCursor *p){
+   return sqlite3_mutex_held(p->pBt->mutex);
+ }
++
++/* Verify that the cursor and the BtShared agree about what is the current
++** database connetion. This is important in shared-cache mode. If the database 
++** connection pointers get out-of-sync, it is possible for routines like
++** btreeInitPage() to reference an stale connection pointer that references a
++** a connection that has already closed.  This routine is used inside assert()
++** statements only and for the purpose of double-checking that the btree code
++** does keep the database connection pointers up-to-date.
++*/
++static int cursorOwnsBtShared(BtCursor *p){
++  assert( cursorHoldsMutex(p) );
++  return (p->pBtree->db==p->pBt->db);
++}
+ #endif
+ 
+ /*
+@@ -53537,24 +63336,27 @@
+ */
+ static void invalidateIncrblobCursors(
+   Btree *pBtree,          /* The database file to check */
++  Pgno pgnoRoot,          /* The table that might be changing */
+   i64 iRow,               /* The rowid that might be changing */
+   int isClearTable        /* True if all rows are being deleted */
+ ){
+   BtCursor *p;
+-  BtShared *pBt = pBtree->pBt;
++  if( pBtree->hasIncrblobCur==0 ) return;
+   assert( sqlite3BtreeHoldsMutex(pBtree) );
+-  for(p=pBt->pCursor; p; p=p->pNext){
+-    if( (p->curFlags & BTCF_Incrblob)!=0
+-     && (isClearTable || p->info.nKey==iRow)
+-    ){
+-      p->eState = CURSOR_INVALID;
++  pBtree->hasIncrblobCur = 0;
++  for(p=pBtree->pBt->pCursor; p; p=p->pNext){
++    if( (p->curFlags & BTCF_Incrblob)!=0 ){
++      pBtree->hasIncrblobCur = 1;
++      if( p->pgnoRoot==pgnoRoot && (isClearTable || p->info.nKey==iRow) ){
++        p->eState = CURSOR_INVALID;
++      }
+     }
+   }
+ }
+ 
+ #else
+   /* Stub function when INCRBLOB is omitted */
+-  #define invalidateIncrblobCursors(x,y,z)
++  #define invalidateIncrblobCursors(w,x,y,z)
+ #endif /* SQLITE_OMIT_INCRBLOB */
+ 
+ /*
+@@ -53598,7 +63400,7 @@
+     assert( pgno<=pBt->nPage );
+     pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage);
+     if( !pBt->pHasContent ){
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+     }
+   }
+   if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){
+@@ -53640,6 +63442,47 @@
+   pCur->iPage = -1;
+ }
+ 
++/*
++** The cursor passed as the only argument must point to a valid entry
++** when this function is called (i.e. have eState==CURSOR_VALID). This
++** function saves the current cursor key in variables pCur->nKey and
++** pCur->pKey. SQLITE_OK is returned if successful or an SQLite error 
++** code otherwise.
++**
++** If the cursor is open on an intkey table, then the integer key
++** (the rowid) is stored in pCur->nKey and pCur->pKey is left set to
++** NULL. If the cursor is open on a non-intkey table, then pCur->pKey is 
++** set to point to a malloced buffer pCur->nKey bytes in size containing 
++** the key.
++*/
++static int saveCursorKey(BtCursor *pCur){
++  int rc = SQLITE_OK;
++  assert( CURSOR_VALID==pCur->eState );
++  assert( 0==pCur->pKey );
++  assert( cursorHoldsMutex(pCur) );
++
++  if( pCur->curIntKey ){
++    /* Only the rowid is required for a table btree */
++    pCur->nKey = sqlite3BtreeIntegerKey(pCur);
++  }else{
++    /* For an index btree, save the complete key content */
++    void *pKey;
++    pCur->nKey = sqlite3BtreePayloadSize(pCur);
++    pKey = sqlite3Malloc( pCur->nKey );
++    if( pKey ){
++      rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey);
++      if( rc==SQLITE_OK ){
++        pCur->pKey = pKey;
++      }else{
++        sqlite3_free(pKey);
++      }
++    }else{
++      rc = SQLITE_NOMEM_BKPT;
++    }
++  }
++  assert( !pCur->curIntKey || !pCur->pKey );
++  return rc;
++}
+ 
+ /*
+ ** Save the current cursor position in the variables BtCursor.nKey 
+@@ -53660,36 +63503,14 @@
+   }else{
+     pCur->skipNext = 0;
+   }
+-  rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
+-  assert( rc==SQLITE_OK );  /* KeySize() cannot fail */
+-
+-  /* If this is an intKey table, then the above call to BtreeKeySize()
+-  ** stores the integer key in pCur->nKey. In this case this value is
+-  ** all that is required. Otherwise, if pCur is not open on an intKey
+-  ** table, then malloc space for and store the pCur->nKey bytes of key 
+-  ** data.
+-  */
+-  if( 0==pCur->apPage[0]->intKey ){
+-    void *pKey = sqlite3Malloc( pCur->nKey );
+-    if( pKey ){
+-      rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey);
+-      if( rc==SQLITE_OK ){
+-        pCur->pKey = pKey;
+-      }else{
+-        sqlite3_free(pKey);
+-      }
+-    }else{
+-      rc = SQLITE_NOMEM;
+-    }
+-  }
+-  assert( !pCur->apPage[0]->intKey || !pCur->pKey );
+ 
++  rc = saveCursorKey(pCur);
+   if( rc==SQLITE_OK ){
+     btreeReleaseAllCursorPages(pCur);
+     pCur->eState = CURSOR_REQUIRESEEK;
+   }
+ 
+-  invalidateOverflowCache(pCur);
++  pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl|BTCF_AtLast);
+   return rc;
+ }
+ 
+@@ -53704,6 +63525,15 @@
+ ** routine is called just before cursor pExcept is used to modify the
+ ** table, for example in BtreeDelete() or BtreeInsert().
+ **
++** If there are two or more cursors on the same btree, then all such 
++** cursors should have their BTCF_Multiple flag set.  The btreeCursor()
++** routine enforces that rule.  This routine only needs to be called in
++** the uncommon case when pExpect has the BTCF_Multiple flag set.
++**
++** If pExpect!=NULL and if no other cursors are found on the same root-page,
++** then the BTCF_Multiple flag on pExpect is cleared, to avoid another
++** pointless call to this routine.
++**
+ ** Implementation note:  This routine merely checks to see if any cursors
+ ** need to be saved.  It calls out to saveCursorsOnList() in the (unusual)
+ ** event that cursors are in need to being saved.
+@@ -53715,7 +63545,9 @@
+   for(p=pBt->pCursor; p; p=p->pNext){
+     if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ) break;
+   }
+-  return p ? saveCursorsOnList(p, iRoot, pExcept) : SQLITE_OK;
++  if( p ) return saveCursorsOnList(p, iRoot, pExcept);
++  if( pExcept ) pExcept->curFlags &= ~BTCF_Multiple;
++  return SQLITE_OK;
+ }
+ 
+ /* This helper routine to saveAllCursors does the actual work of saving
+@@ -53769,26 +63601,23 @@
+ ){
+   int rc;                    /* Status code */
+   UnpackedRecord *pIdxKey;   /* Unpacked index key */
+-  char aSpace[200];          /* Temp space for pIdxKey - to avoid a malloc */
+-  char *pFree = 0;
+ 
+   if( pKey ){
+     assert( nKey==(i64)(int)nKey );
+-    pIdxKey = sqlite3VdbeAllocUnpackedRecord(
+-        pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree
+-    );
+-    if( pIdxKey==0 ) return SQLITE_NOMEM;
++    pIdxKey = sqlite3VdbeAllocUnpackedRecord(pCur->pKeyInfo);
++    if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
+     sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
+     if( pIdxKey->nField==0 ){
+-      sqlite3DbFree(pCur->pKeyInfo->db, pFree);
+-      return SQLITE_CORRUPT_BKPT;
++      rc = SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno);
++      goto moveto_done;
+     }
+   }else{
+     pIdxKey = 0;
+   }
+   rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes);
+-  if( pFree ){
+-    sqlite3DbFree(pCur->pKeyInfo->db, pFree);
++moveto_done:
++  if( pIdxKey ){
++    sqlite3DbFree(pCur->pKeyInfo->db, pIdxKey);
+   }
+   return rc;
+ }
+@@ -53803,7 +63632,7 @@
+ static int btreeRestoreCursorPosition(BtCursor *pCur){
+   int rc;
+   int skipNext;
+-  assert( cursorHoldsMutex(pCur) );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( pCur->eState>=CURSOR_REQUIRESEEK );
+   if( pCur->eState==CURSOR_FAULT ){
+     return pCur->skipNext;
+@@ -53875,6 +63704,26 @@
+   return SQLITE_OK;
+ }
+ 
++#ifdef SQLITE_ENABLE_CURSOR_HINTS
++/*
++** Provide hints to the cursor.  The particular hint given (and the type
++** and number of the varargs parameters) is determined by the eHintType
++** parameter.  See the definitions of the BTREE_HINT_* macros for details.
++*/
++SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){
++  /* Used only by system that substitute their own storage engine */
++}
++#endif
++
++/*
++** Provide flag hints to the cursor.
++*/
++SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){
++  assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 );
++  pCur->hints = x;
++}
++
++
+ #ifndef SQLITE_OMIT_AUTOVACUUM
+ /*
+ ** Given a page number of a regular database page, return the page
+@@ -53928,7 +63777,7 @@
+     return;
+   }
+   iPtrmap = PTRMAP_PAGENO(pBt, key);
+-  rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
++  rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
+   if( rc!=SQLITE_OK ){
+     *pRC = rc;
+     return;
+@@ -53971,7 +63820,7 @@
+   assert( sqlite3_mutex_held(pBt->mutex) );
+ 
+   iPtrmap = PTRMAP_PAGENO(pBt, key);
+-  rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
++  rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
+   if( rc!=0 ){
+     return rc;
+   }
+@@ -53988,7 +63837,7 @@
+   if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
+ 
+   sqlite3PagerUnref(pDbPage);
+-  if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT;
++  if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_PGNO(iPtrmap);
+   return SQLITE_OK;
+ }
+ 
+@@ -54003,39 +63852,85 @@
+ ** the page, 1 means the second cell, and so forth) return a pointer
+ ** to the cell content.
+ **
++** findCellPastPtr() does the same except it skips past the initial
++** 4-byte child pointer found on interior pages, if there is one.
++**
+ ** This routine works only for pages that do not contain overflow cells.
+ */
+ #define findCell(P,I) \
+-  ((P)->aData + ((P)->maskPage & get2byte(&(P)->aCellIdx[2*(I)])))
+-#define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I)))))
++  ((P)->aData + ((P)->maskPage & get2byteAligned(&(P)->aCellIdx[2*(I)])))
++#define findCellPastPtr(P,I) \
++  ((P)->aDataOfst + ((P)->maskPage & get2byteAligned(&(P)->aCellIdx[2*(I)])))
+ 
+ 
+ /*
+-** This a more complex version of findCell() that works for
+-** pages that do contain overflow cells.
++** This is common tail processing for btreeParseCellPtr() and
++** btreeParseCellPtrIndex() for the case when the cell does not fit entirely
++** on a single B-tree page.  Make necessary adjustments to the CellInfo
++** structure.
+ */
+-static u8 *findOverflowCell(MemPage *pPage, int iCell){
+-  int i;
+-  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+-  for(i=pPage->nOverflow-1; i>=0; i--){
+-    int k;
+-    k = pPage->aiOvfl[i];
+-    if( k<=iCell ){
+-      if( k==iCell ){
+-        return pPage->apOvfl[i];
+-      }
+-      iCell--;
+-    }
++static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow(
++  MemPage *pPage,         /* Page containing the cell */
++  u8 *pCell,              /* Pointer to the cell text. */
++  CellInfo *pInfo         /* Fill in this structure */
++){
++  /* If the payload will not fit completely on the local page, we have
++  ** to decide how much to store locally and how much to spill onto
++  ** overflow pages.  The strategy is to minimize the amount of unused
++  ** space on overflow pages while keeping the amount of local storage
++  ** in between minLocal and maxLocal.
++  **
++  ** Warning:  changing the way overflow payload is distributed in any
++  ** way will result in an incompatible file format.
++  */
++  int minLocal;  /* Minimum amount of payload held locally */
++  int maxLocal;  /* Maximum amount of payload held locally */
++  int surplus;   /* Overflow payload available for local storage */
++
++  minLocal = pPage->minLocal;
++  maxLocal = pPage->maxLocal;
++  surplus = minLocal + (pInfo->nPayload - minLocal)%(pPage->pBt->usableSize-4);
++  testcase( surplus==maxLocal );
++  testcase( surplus==maxLocal+1 );
++  if( surplus <= maxLocal ){
++    pInfo->nLocal = (u16)surplus;
++  }else{
++    pInfo->nLocal = (u16)minLocal;
+   }
+-  return findCell(pPage, iCell);
++  pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4;
+ }
+ 
+ /*
+-** Parse a cell content block and fill in the CellInfo structure.  There
+-** are two versions of this function.  btreeParseCell() takes a 
+-** cell index as the second argument and btreeParseCellPtr() 
+-** takes a pointer to the body of the cell as its second argument.
++** The following routines are implementations of the MemPage.xParseCell()
++** method.
++**
++** Parse a cell content block and fill in the CellInfo structure.
++**
++** btreeParseCellPtr()        =>   table btree leaf nodes
++** btreeParseCellNoPayload()  =>   table btree internal nodes
++** btreeParseCellPtrIndex()   =>   index btree nodes
++**
++** There is also a wrapper function btreeParseCell() that works for
++** all MemPage types and that references the cell by index rather than
++** by pointer.
+ */
++static void btreeParseCellPtrNoPayload(
++  MemPage *pPage,         /* Page containing the cell */
++  u8 *pCell,              /* Pointer to the cell text. */
++  CellInfo *pInfo         /* Fill in this structure */
++){
++  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
++  assert( pPage->leaf==0 );
++  assert( pPage->childPtrSize==4 );
++#ifndef SQLITE_DEBUG
++  UNUSED_PARAMETER(pPage);
++#endif
++  pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
++  pInfo->nPayload = 0;
++  pInfo->nLocal = 0;
++  pInfo->pPayload = 0;
++  return;
++}
+ static void btreeParseCellPtr(
+   MemPage *pPage,         /* Page containing the cell */
+   u8 *pCell,              /* Pointer to the cell text. */
+@@ -54043,26 +63938,89 @@
+ ){
+   u8 *pIter;              /* For scanning through pCell */
+   u32 nPayload;           /* Number of bytes of cell payload */
++  u64 iKey;               /* Extracted Key value */
+ 
+   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+   assert( pPage->leaf==0 || pPage->leaf==1 );
+-  if( pPage->intKeyLeaf ){
+-    assert( pPage->childPtrSize==0 );
+-    pIter = pCell + getVarint32(pCell, nPayload);
+-    pIter += getVarint(pIter, (u64*)&pInfo->nKey);
+-  }else if( pPage->noPayload ){
+-    assert( pPage->childPtrSize==4 );
+-    pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
+-    pInfo->nPayload = 0;
+-    pInfo->nLocal = 0;
+-    pInfo->iOverflow = 0;
+-    pInfo->pPayload = 0;
+-    return;
++  assert( pPage->intKeyLeaf );
++  assert( pPage->childPtrSize==0 );
++  pIter = pCell;
++
++  /* The next block of code is equivalent to:
++  **
++  **     pIter += getVarint32(pIter, nPayload);
++  **
++  ** The code is inlined to avoid a function call.
++  */
++  nPayload = *pIter;
++  if( nPayload>=0x80 ){
++    u8 *pEnd = &pIter[8];
++    nPayload &= 0x7f;
++    do{
++      nPayload = (nPayload<<7) | (*++pIter & 0x7f);
++    }while( (*pIter)>=0x80 && pIter<pEnd );
++  }
++  pIter++;
++
++  /* The next block of code is equivalent to:
++  **
++  **     pIter += getVarint(pIter, (u64*)&pInfo->nKey);
++  **
++  ** The code is inlined to avoid a function call.
++  */
++  iKey = *pIter;
++  if( iKey>=0x80 ){
++    u8 *pEnd = &pIter[7];
++    iKey &= 0x7f;
++    while(1){
++      iKey = (iKey<<7) | (*++pIter & 0x7f);
++      if( (*pIter)<0x80 ) break;
++      if( pIter>=pEnd ){
++        iKey = (iKey<<8) | *++pIter;
++        break;
++      }
++    }
++  }
++  pIter++;
++
++  pInfo->nKey = *(i64*)&iKey;
++  pInfo->nPayload = nPayload;
++  pInfo->pPayload = pIter;
++  testcase( nPayload==pPage->maxLocal );
++  testcase( nPayload==pPage->maxLocal+1 );
++  if( nPayload<=pPage->maxLocal ){
++    /* This is the (easy) common case where the entire payload fits
++    ** on the local page.  No overflow is required.
++    */
++    pInfo->nSize = nPayload + (u16)(pIter - pCell);
++    if( pInfo->nSize<4 ) pInfo->nSize = 4;
++    pInfo->nLocal = (u16)nPayload;
+   }else{
+-    pIter = pCell + pPage->childPtrSize;
+-    pIter += getVarint32(pIter, nPayload);
+-    pInfo->nKey = nPayload;
++    btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo);
++  }
++}
++static void btreeParseCellPtrIndex(
++  MemPage *pPage,         /* Page containing the cell */
++  u8 *pCell,              /* Pointer to the cell text. */
++  CellInfo *pInfo         /* Fill in this structure */
++){
++  u8 *pIter;              /* For scanning through pCell */
++  u32 nPayload;           /* Number of bytes of cell payload */
++
++  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
++  assert( pPage->leaf==0 || pPage->leaf==1 );
++  assert( pPage->intKeyLeaf==0 );
++  pIter = pCell + pPage->childPtrSize;
++  nPayload = *pIter;
++  if( nPayload>=0x80 ){
++    u8 *pEnd = &pIter[8];
++    nPayload &= 0x7f;
++    do{
++      nPayload = (nPayload<<7) | (*++pIter & 0x7f);
++    }while( *(pIter)>=0x80 && pIter<pEnd );
+   }
++  pIter++;
++  pInfo->nKey = nPayload;
+   pInfo->nPayload = nPayload;
+   pInfo->pPayload = pIter;
+   testcase( nPayload==pPage->maxLocal );
+@@ -54074,33 +64032,8 @@
+     pInfo->nSize = nPayload + (u16)(pIter - pCell);
+     if( pInfo->nSize<4 ) pInfo->nSize = 4;
+     pInfo->nLocal = (u16)nPayload;
+-    pInfo->iOverflow = 0;
+   }else{
+-    /* If the payload will not fit completely on the local page, we have
+-    ** to decide how much to store locally and how much to spill onto
+-    ** overflow pages.  The strategy is to minimize the amount of unused
+-    ** space on overflow pages while keeping the amount of local storage
+-    ** in between minLocal and maxLocal.
+-    **
+-    ** Warning:  changing the way overflow payload is distributed in any
+-    ** way will result in an incompatible file format.
+-    */
+-    int minLocal;  /* Minimum amount of payload held locally */
+-    int maxLocal;  /* Maximum amount of payload held locally */
+-    int surplus;   /* Overflow payload available for local storage */
+-
+-    minLocal = pPage->minLocal;
+-    maxLocal = pPage->maxLocal;
+-    surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4);
+-    testcase( surplus==maxLocal );
+-    testcase( surplus==maxLocal+1 );
+-    if( surplus <= maxLocal ){
+-      pInfo->nLocal = (u16)surplus;
+-    }else{
+-      pInfo->nLocal = (u16)minLocal;
+-    }
+-    pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell);
+-    pInfo->nSize = pInfo->iOverflow + 4;
++    btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo);
+   }
+ }
+ static void btreeParseCell(
+@@ -54108,14 +64041,20 @@
+   int iCell,              /* The cell index.  First cell is 0 */
+   CellInfo *pInfo         /* Fill in this structure */
+ ){
+-  btreeParseCellPtr(pPage, findCell(pPage, iCell), pInfo);
++  pPage->xParseCell(pPage, findCell(pPage, iCell), pInfo);
+ }
+ 
+ /*
++** The following routines are implementations of the MemPage.xCellSize
++** method.
++**
+ ** Compute the total number of bytes that a Cell needs in the cell
+ ** data area of the btree-page.  The return number includes the cell
+ ** data header and the local payload, but not any overflow page or
+ ** the space used by the cell pointer.
++**
++** cellSizePtrNoPayload()    =>   table internal nodes
++** cellSizePtr()             =>   all index nodes & table leaf nodes
+ */
+ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
+   u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
+@@ -54128,18 +64067,12 @@
+   ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
+   ** this function verifies that this invariant is not violated. */
+   CellInfo debuginfo;
+-  btreeParseCellPtr(pPage, pCell, &debuginfo);
++  pPage->xParseCell(pPage, pCell, &debuginfo);
+ #endif
+ 
+-  if( pPage->noPayload ){
+-    pEnd = &pIter[9];
+-    while( (*pIter++)&0x80 && pIter<pEnd );
+-    assert( pPage->childPtrSize==4 );
+-    return (u16)(pIter - pCell);
+-  }
+   nSize = *pIter;
+   if( nSize>=0x80 ){
+-    pEnd = &pIter[9];
++    pEnd = &pIter[8];
+     nSize &= 0x7f;
+     do{
+       nSize = (nSize<<7) | (*++pIter & 0x7f);
+@@ -54171,12 +64104,34 @@
+   assert( nSize==debuginfo.nSize || CORRUPT_DB );
+   return (u16)nSize;
+ }
++static u16 cellSizePtrNoPayload(MemPage *pPage, u8 *pCell){
++  u8 *pIter = pCell + 4; /* For looping over bytes of pCell */
++  u8 *pEnd;              /* End mark for a varint */
++
++#ifdef SQLITE_DEBUG
++  /* The value returned by this function should always be the same as
++  ** the (CellInfo.nSize) value found by doing a full parse of the
++  ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
++  ** this function verifies that this invariant is not violated. */
++  CellInfo debuginfo;
++  pPage->xParseCell(pPage, pCell, &debuginfo);
++#else
++  UNUSED_PARAMETER(pPage);
++#endif
++
++  assert( pPage->childPtrSize==4 );
++  pEnd = pIter + 9;
++  while( (*pIter++)&0x80 && pIter<pEnd );
++  assert( debuginfo.nSize==(u16)(pIter - pCell) || CORRUPT_DB );
++  return (u16)(pIter - pCell);
++}
++
+ 
+ #ifdef SQLITE_DEBUG
+ /* This variation on cellSizePtr() is used inside of assert() statements
+ ** only. */
+ static u16 cellSize(MemPage *pPage, int iCell){
+-  return cellSizePtr(pPage, findCell(pPage, iCell));
++  return pPage->xCellSize(pPage, findCell(pPage, iCell));
+ }
+ #endif
+ 
+@@ -54190,9 +64145,9 @@
+   CellInfo info;
+   if( *pRC ) return;
+   assert( pCell!=0 );
+-  btreeParseCellPtr(pPage, pCell, &info);
+-  if( info.iOverflow ){
+-    Pgno ovfl = get4byte(&pCell[info.iOverflow]);
++  pPage->xParseCell(pPage, pCell, &info);
++  if( info.nLocal<info.nPayload ){
++    Pgno ovfl = get4byte(&pCell[info.nSize-4]);
+     ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
+   }
+ }
+@@ -54200,17 +64155,18 @@
+ 
+ 
+ /*
+-** Defragment the page given.  All Cells are moved to the
+-** end of the page and all free space is collected into one
+-** big FreeBlk that occurs in between the header and cell
+-** pointer array and the cell content area.
++** Defragment the page given. This routine reorganizes cells within the
++** page so that there are no free-blocks on the free-block list.
++**
++** Parameter nMaxFrag is the maximum amount of fragmented space that may be
++** present in the page after this routine returns.
+ **
+ ** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a
+ ** b-tree page so that there are no freeblocks or fragment bytes, all
+ ** unused bytes are contained in the unallocated space region, and all
+ ** cells are packed tightly at the end of the page.
+ */
+-static int defragmentPage(MemPage *pPage){
++static int defragmentPage(MemPage *pPage, int nMaxFrag){
+   int i;                     /* Loop counter */
+   int pc;                    /* Address of the i-th cell */
+   int hdr;                   /* Offset to the page header */
+@@ -54225,7 +64181,6 @@
+   int iCellFirst;            /* First allowable cell index */
+   int iCellLast;             /* Last possible cell index */
+ 
+-
+   assert( sqlite3PagerIswriteable(pPage->pDbPage) );
+   assert( pPage->pBt!=0 );
+   assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
+@@ -54237,9 +64192,56 @@
+   cellOffset = pPage->cellOffset;
+   nCell = pPage->nCell;
+   assert( nCell==get2byte(&data[hdr+3]) );
++  iCellFirst = cellOffset + 2*nCell;
+   usableSize = pPage->pBt->usableSize;
++
++  /* This block handles pages with two or fewer free blocks and nMaxFrag
++  ** or fewer fragmented bytes. In this case it is faster to move the
++  ** two (or one) blocks of cells using memmove() and add the required
++  ** offsets to each pointer in the cell-pointer array than it is to 
++  ** reconstruct the entire page.  */
++  if( (int)data[hdr+7]<=nMaxFrag ){
++    int iFree = get2byte(&data[hdr+1]);
++    if( iFree ){
++      int iFree2 = get2byte(&data[iFree]);
++
++      /* pageFindSlot() has already verified that free blocks are sorted
++      ** in order of offset within the page, and that no block extends
++      ** past the end of the page. Provided the two free slots do not 
++      ** overlap, this guarantees that the memmove() calls below will not
++      ** overwrite the usableSize byte buffer, even if the database page
++      ** is corrupt.  */
++      assert( iFree2==0 || iFree2>iFree );
++      assert( iFree+get2byte(&data[iFree+2]) <= usableSize );
++      assert( iFree2==0 || iFree2+get2byte(&data[iFree2+2]) <= usableSize );
++
++      if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
++        u8 *pEnd = &data[cellOffset + nCell*2];
++        u8 *pAddr;
++        int sz2 = 0;
++        int sz = get2byte(&data[iFree+2]);
++        int top = get2byte(&data[hdr+5]);
++        if( iFree2 ){
++          if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
++          sz2 = get2byte(&data[iFree2+2]);
++          assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize );
++          memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
++          sz += sz2;
++        }
++        cbrk = top+sz;
++        assert( cbrk+(iFree-top) <= usableSize );
++        memmove(&data[cbrk], &data[top], iFree-top);
++        for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){
++          pc = get2byte(pAddr);
++          if( pc<iFree ){ put2byte(pAddr, pc+sz); }
++          else if( pc<iFree2 ){ put2byte(pAddr, pc+sz2); }
++        }
++        goto defragment_out;
++      }
++    }
++  }
++
+   cbrk = usableSize;
+-  iCellFirst = cellOffset + 2*nCell;
+   iCellLast = usableSize - 4;
+   for(i=0; i<nCell; i++){
+     u8 *pAddr;     /* The i-th cell pointer */
+@@ -54247,26 +64249,18 @@
+     pc = get2byte(pAddr);
+     testcase( pc==iCellFirst );
+     testcase( pc==iCellLast );
+-#if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
+     /* These conditions have already been verified in btreeInitPage()
+-    ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined 
++    ** if PRAGMA cell_size_check=ON.
+     */
+     if( pc<iCellFirst || pc>iCellLast ){
+-      return SQLITE_CORRUPT_BKPT;
++      return SQLITE_CORRUPT_PGNO(pPage->pgno);
+     }
+-#endif
+     assert( pc>=iCellFirst && pc<=iCellLast );
+-    size = cellSizePtr(pPage, &src[pc]);
++    size = pPage->xCellSize(pPage, &src[pc]);
+     cbrk -= size;
+-#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
+-    if( cbrk<iCellFirst ){
+-      return SQLITE_CORRUPT_BKPT;
+-    }
+-#else
+     if( cbrk<iCellFirst || pc+size>usableSize ){
+-      return SQLITE_CORRUPT_BKPT;
++      return SQLITE_CORRUPT_PGNO(pPage->pgno);
+     }
+-#endif
+     assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
+     testcase( cbrk+size==usableSize );
+     testcase( pc+size==usableSize );
+@@ -54281,16 +64275,18 @@
+     }
+     memcpy(&data[cbrk], &src[pc], size);
+   }
++  data[hdr+7] = 0;
++
++ defragment_out:
++  if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
++    return SQLITE_CORRUPT_PGNO(pPage->pgno);
++  }
+   assert( cbrk>=iCellFirst );
+   put2byte(&data[hdr+5], cbrk);
+   data[hdr+1] = 0;
+   data[hdr+2] = 0;
+-  data[hdr+7] = 0;
+   memset(&data[iCellFirst], 0, cbrk-iCellFirst);
+   assert( sqlite3PagerIswriteable(pPage->pDbPage) );
+-  if( cbrk-iCellFirst!=pPage->nFree ){
+-    return SQLITE_CORRUPT_BKPT;
+-  }
+   return SQLITE_OK;
+ }
+ 
+@@ -54304,47 +64300,46 @@
+ ** This function may detect corruption within pPg.  If corruption is
+ ** detected then *pRc is set to SQLITE_CORRUPT and NULL is returned.
+ **
+-** If a slot of at least nByte bytes is found but cannot be used because 
+-** there are already at least 60 fragmented bytes on the page, return NULL.
+-** In this case, if pbDefrag parameter is not NULL, set *pbDefrag to true.
++** Slots on the free list that are between 1 and 3 bytes larger than nByte
++** will be ignored if adding the extra space to the fragmentation count
++** causes the fragmentation count to exceed 60.
+ */
+-static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){
++static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
+   const int hdr = pPg->hdrOffset;
+   u8 * const aData = pPg->aData;
+-  int iAddr;
+-  int pc;
++  int iAddr = hdr + 1;
++  int pc = get2byte(&aData[iAddr]);
++  int x;
+   int usableSize = pPg->pBt->usableSize;
+ 
+-  for(iAddr=hdr+1; (pc = get2byte(&aData[iAddr]))>0; iAddr=pc){
++  assert( pc>0 );
++  do{
+     int size;            /* Size of the free slot */
+     /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
+     ** increasing offset. */
+     if( pc>usableSize-4 || pc<iAddr+4 ){
+-      *pRc = SQLITE_CORRUPT_BKPT;
++      *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno);
+       return 0;
+     }
+     /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
+     ** freeblock form a big-endian integer which is the size of the freeblock
+     ** in bytes, including the 4-byte header. */
+     size = get2byte(&aData[pc+2]);
+-    if( size>=nByte ){
+-      int x = size - nByte;
++    if( (x = size - nByte)>=0 ){
+       testcase( x==4 );
+       testcase( x==3 );
+-      if( x<4 ){
++      if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){
++        *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno);
++        return 0;
++      }else if( x<4 ){
+         /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
+         ** number of bytes in fragments may not exceed 60. */
+-        if( aData[hdr+7]>=60 ){
+-          if( pbDefrag ) *pbDefrag = 1;
+-          return 0;
+-        }
++        if( aData[hdr+7]>57 ) return 0;
++
+         /* Remove the slot from the free-list. Update the number of
+         ** fragmented bytes within the page. */
+         memcpy(&aData[iAddr], &aData[pc], 2);
+         aData[hdr+7] += (u8)x;
+-      }else if( size+pc > usableSize ){
+-        *pRc = SQLITE_CORRUPT_BKPT;
+-        return 0;
+       }else{
+         /* The slot remains on the free-list. Reduce its size to account
+          ** for the portion used by the new allocation. */
+@@ -54352,7 +64347,9 @@
+       }
+       return &aData[pc + x];
+     }
+-  }
++    iAddr = pc;
++    pc = get2byte(&aData[pc]);
++  }while( pc );
+ 
+   return 0;
+ }
+@@ -54393,8 +64390,15 @@
+   ** then the cell content offset of an empty page wants to be 65536.
+   ** However, that integer is too large to be stored in a 2-byte unsigned
+   ** integer, so a value of 0 is used in its place. */
+-  top = get2byteNotZero(&data[hdr+5]);
+-  if( gap>top ) return SQLITE_CORRUPT_BKPT;
++  top = get2byte(&data[hdr+5]);
++  assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */
++  if( gap>top ){
++    if( top==0 && pPage->pBt->usableSize==65536 ){
++      top = 65536;
++    }else{
++      return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    }
++  }
+ 
+   /* If there is enough space between gap and top for one more cell pointer
+   ** array entry offset, and if the freelist is not empty, then search the
+@@ -54403,15 +64407,14 @@
+   testcase( gap+2==top );
+   testcase( gap+1==top );
+   testcase( gap==top );
+-  if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){
+-    int bDefrag = 0;
+-    u8 *pSpace = pageFindSlot(pPage, nByte, &rc, &bDefrag);
+-    if( rc ) return rc;
+-    if( bDefrag ) goto defragment_page;
++  if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){
++    u8 *pSpace = pageFindSlot(pPage, nByte, &rc);
+     if( pSpace ){
+       assert( pSpace>=data && (pSpace - data)<65536 );
+       *pIdx = (int)(pSpace - data);
+       return SQLITE_OK;
++    }else if( rc ){
++      return rc;
+     }
+   }
+ 
+@@ -54420,12 +64423,11 @@
+   */
+   testcase( gap+2+nByte==top );
+   if( gap+2+nByte>top ){
+- defragment_page:
+     assert( pPage->nCell>0 || CORRUPT_DB );
+-    rc = defragmentPage(pPage);
++    rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte)));
+     if( rc ) return rc;
+     top = get2byteNotZero(&data[hdr+5]);
+-    assert( gap+nByte<=top );
++    assert( gap+2+nByte<=top );
+   }
+ 
+ 
+@@ -54467,7 +64469,7 @@
+ 
+   assert( pPage->pBt!=0 );
+   assert( sqlite3PagerIswriteable(pPage->pDbPage) );
+-  assert( iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
++  assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
+   assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
+   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+   assert( iSize>=4 );   /* Minimum cell size is 4 */
+@@ -54475,7 +64477,7 @@
+ 
+   /* Overwrite deleted information with zeros when the secure_delete
+   ** option is enabled */
+-  if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){
++  if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){
+     memset(&data[iStart], 0, iSize);
+   }
+ 
+@@ -54487,23 +64489,29 @@
+   if( data[iPtr+1]==0 && data[iPtr]==0 ){
+     iFreeBlk = 0;  /* Shortcut for the case when the freelist is empty */
+   }else{
+-    while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlk<iStart ){
+-      if( iFreeBlk<iPtr+4 ) return SQLITE_CORRUPT_BKPT;
++    while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){
++      if( iFreeBlk<iPtr+4 ){
++        if( iFreeBlk==0 ) break;
++        return SQLITE_CORRUPT_PGNO(pPage->pgno);
++      }
+       iPtr = iFreeBlk;
+     }
+-    if( iFreeBlk>iLast ) return SQLITE_CORRUPT_BKPT;
++    if( iFreeBlk>iLast ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+     assert( iFreeBlk>iPtr || iFreeBlk==0 );
+   
+     /* At this point:
+     **    iFreeBlk:   First freeblock after iStart, or zero if none
+-    **    iPtr:       The address of a pointer iFreeBlk
++    **    iPtr:       The address of a pointer to iFreeBlk
+     **
+     ** Check to see if iFreeBlk should be coalesced onto the end of iStart.
+     */
+     if( iFreeBlk && iEnd+3>=iFreeBlk ){
+       nFrag = iFreeBlk - iEnd;
+-      if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT;
++      if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+       iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
++      if( iEnd > pPage->pBt->usableSize ){
++        return SQLITE_CORRUPT_PGNO(pPage->pgno);
++      }
+       iSize = iEnd - iStart;
+       iFreeBlk = get2byte(&data[iFreeBlk]);
+     }
+@@ -54515,20 +64523,20 @@
+     if( iPtr>hdr+1 ){
+       int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
+       if( iPtrEnd+3>=iStart ){
+-        if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT;
++        if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+         nFrag += iStart - iPtrEnd;
+         iSize = iEnd - iPtr;
+         iStart = iPtr;
+       }
+     }
+-    if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT;
++    if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+     data[hdr+7] -= nFrag;
+   }
+   if( iStart==get2byte(&data[hdr+5]) ){
+     /* The new freeblock is at the beginning of the cell content area,
+     ** so just extend the cell content area rather than create another
+     ** freelist entry */
+-    if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_BKPT;
++    if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+     put2byte(&data[hdr+1], iFreeBlk);
+     put2byte(&data[hdr+5], iEnd);
+   }else{
+@@ -54561,35 +64569,42 @@
+   pPage->leaf = (u8)(flagByte>>3);  assert( PTF_LEAF == 1<<3 );
+   flagByte &= ~PTF_LEAF;
+   pPage->childPtrSize = 4-4*pPage->leaf;
++  pPage->xCellSize = cellSizePtr;
+   pBt = pPage->pBt;
+   if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
+-    /* EVIDENCE-OF: R-03640-13415 A value of 5 means the page is an interior
+-    ** table b-tree page. */
++    /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an
++    ** interior table b-tree page. */
+     assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
+-    /* EVIDENCE-OF: R-20501-61796 A value of 13 means the page is a leaf
+-    ** table b-tree page. */
++    /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a
++    ** leaf table b-tree page. */
+     assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
+     pPage->intKey = 1;
+-    pPage->intKeyLeaf = pPage->leaf;
+-    pPage->noPayload = !pPage->leaf;
++    if( pPage->leaf ){
++      pPage->intKeyLeaf = 1;
++      pPage->xParseCell = btreeParseCellPtr;
++    }else{
++      pPage->intKeyLeaf = 0;
++      pPage->xCellSize = cellSizePtrNoPayload;
++      pPage->xParseCell = btreeParseCellPtrNoPayload;
++    }
+     pPage->maxLocal = pBt->maxLeaf;
+     pPage->minLocal = pBt->minLeaf;
+   }else if( flagByte==PTF_ZERODATA ){
+-    /* EVIDENCE-OF: R-27225-53936 A value of 2 means the page is an interior
+-    ** index b-tree page. */
++    /* EVIDENCE-OF: R-43316-37308 A value of 2 (0x02) means the page is an
++    ** interior index b-tree page. */
+     assert( (PTF_ZERODATA)==2 );
+-    /* EVIDENCE-OF: R-16571-11615 A value of 10 means the page is a leaf
+-    ** index b-tree page. */
++    /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a
++    ** leaf index b-tree page. */
+     assert( (PTF_ZERODATA|PTF_LEAF)==10 );
+     pPage->intKey = 0;
+     pPage->intKeyLeaf = 0;
+-    pPage->noPayload = 0;
++    pPage->xParseCell = btreeParseCellPtrIndex;
+     pPage->maxLocal = pBt->maxLocal;
+     pPage->minLocal = pBt->minLocal;
+   }else{
+     /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
+     ** an error. */
+-    return SQLITE_CORRUPT_BKPT;
++    return SQLITE_CORRUPT_PGNO(pPage->pgno);
+   }
+   pPage->max1bytePayload = pBt->max1bytePayload;
+   return SQLITE_OK;
+@@ -54605,129 +64620,136 @@
+ ** we failed to detect any corruption.
+ */
+ static int btreeInitPage(MemPage *pPage){
++  int pc;            /* Address of a freeblock within pPage->aData[] */
++  u8 hdr;            /* Offset to beginning of page header */
++  u8 *data;          /* Equal to pPage->aData */
++  BtShared *pBt;        /* The main btree structure */
++  int usableSize;    /* Amount of usable space on each page */
++  u16 cellOffset;    /* Offset from start of page to first cell pointer */
++  int nFree;         /* Number of unused bytes on the page */
++  int top;           /* First byte of the cell content area */
++  int iCellFirst;    /* First allowable cell or freeblock offset */
++  int iCellLast;     /* Last possible cell or freeblock offset */
+ 
+   assert( pPage->pBt!=0 );
++  assert( pPage->pBt->db!=0 );
+   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+   assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
+   assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
+   assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
++  assert( pPage->isInit==0 );
+ 
+-  if( !pPage->isInit ){
+-    u16 pc;            /* Address of a freeblock within pPage->aData[] */
+-    u8 hdr;            /* Offset to beginning of page header */
+-    u8 *data;          /* Equal to pPage->aData */
+-    BtShared *pBt;        /* The main btree structure */
+-    int usableSize;    /* Amount of usable space on each page */
+-    u16 cellOffset;    /* Offset from start of page to first cell pointer */
+-    int nFree;         /* Number of unused bytes on the page */
+-    int top;           /* First byte of the cell content area */
+-    int iCellFirst;    /* First allowable cell or freeblock offset */
+-    int iCellLast;     /* Last possible cell or freeblock offset */
+-
+-    pBt = pPage->pBt;
+-
+-    hdr = pPage->hdrOffset;
+-    data = pPage->aData;
+-    /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
+-    ** the b-tree page type. */
+-    if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT;
+-    assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
+-    pPage->maskPage = (u16)(pBt->pageSize - 1);
+-    pPage->nOverflow = 0;
+-    usableSize = pBt->usableSize;
+-    pPage->cellOffset = cellOffset = hdr + 8 + pPage->childPtrSize;
+-    pPage->aDataEnd = &data[usableSize];
+-    pPage->aCellIdx = &data[cellOffset];
+-    /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates
+-    ** the start of the cell content area. A zero value for this integer is
+-    ** interpreted as 65536. */
+-    top = get2byteNotZero(&data[hdr+5]);
+-    /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
+-    ** number of cells on the page. */
+-    pPage->nCell = get2byte(&data[hdr+3]);
+-    if( pPage->nCell>MX_CELL(pBt) ){
+-      /* To many cells for a single page.  The page must be corrupt */
+-      return SQLITE_CORRUPT_BKPT;
+-    }
+-    testcase( pPage->nCell==MX_CELL(pBt) );
+-    /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
+-    ** possible for a root page of a table that contains no rows) then the
+-    ** offset to the cell content area will equal the page size minus the
+-    ** bytes of reserved space. */
+-    assert( pPage->nCell>0 || top==usableSize || CORRUPT_DB );
+-
+-    /* A malformed database page might cause us to read past the end
+-    ** of page when parsing a cell.  
+-    **
+-    ** The following block of code checks early to see if a cell extends
+-    ** past the end of a page boundary and causes SQLITE_CORRUPT to be 
+-    ** returned if it does.
+-    */
+-    iCellFirst = cellOffset + 2*pPage->nCell;
+-    iCellLast = usableSize - 4;
+-#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
+-    {
+-      int i;            /* Index into the cell pointer array */
+-      int sz;           /* Size of a cell */
+-
+-      if( !pPage->leaf ) iCellLast--;
+-      for(i=0; i<pPage->nCell; i++){
+-        pc = get2byte(&data[cellOffset+i*2]);
+-        testcase( pc==iCellFirst );
+-        testcase( pc==iCellLast );
+-        if( pc<iCellFirst || pc>iCellLast ){
+-          return SQLITE_CORRUPT_BKPT;
+-        }
+-        sz = cellSizePtr(pPage, &data[pc]);
+-        testcase( pc+sz==usableSize );
+-        if( pc+sz>usableSize ){
+-          return SQLITE_CORRUPT_BKPT;
+-        }
++  pBt = pPage->pBt;
++  hdr = pPage->hdrOffset;
++  data = pPage->aData;
++  /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
++  ** the b-tree page type. */
++  if( decodeFlags(pPage, data[hdr]) ){
++    return SQLITE_CORRUPT_PGNO(pPage->pgno);
++  }
++  assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
++  pPage->maskPage = (u16)(pBt->pageSize - 1);
++  pPage->nOverflow = 0;
++  usableSize = pBt->usableSize;
++  pPage->cellOffset = cellOffset = hdr + 8 + pPage->childPtrSize;
++  pPage->aDataEnd = &data[usableSize];
++  pPage->aCellIdx = &data[cellOffset];
++  pPage->aDataOfst = &data[pPage->childPtrSize];
++  /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates
++  ** the start of the cell content area. A zero value for this integer is
++  ** interpreted as 65536. */
++  top = get2byteNotZero(&data[hdr+5]);
++  /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
++  ** number of cells on the page. */
++  pPage->nCell = get2byte(&data[hdr+3]);
++  if( pPage->nCell>MX_CELL(pBt) ){
++    /* To many cells for a single page.  The page must be corrupt */
++    return SQLITE_CORRUPT_PGNO(pPage->pgno);
++  }
++  testcase( pPage->nCell==MX_CELL(pBt) );
++  /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
++  ** possible for a root page of a table that contains no rows) then the
++  ** offset to the cell content area will equal the page size minus the
++  ** bytes of reserved space. */
++  assert( pPage->nCell>0 || top==usableSize || CORRUPT_DB );
++
++  /* A malformed database page might cause us to read past the end
++  ** of page when parsing a cell.  
++  **
++  ** The following block of code checks early to see if a cell extends
++  ** past the end of a page boundary and causes SQLITE_CORRUPT to be 
++  ** returned if it does.
++  */
++  iCellFirst = cellOffset + 2*pPage->nCell;
++  iCellLast = usableSize - 4;
++  if( pBt->db->flags & SQLITE_CellSizeCk ){
++    int i;            /* Index into the cell pointer array */
++    int sz;           /* Size of a cell */
++
++    if( !pPage->leaf ) iCellLast--;
++    for(i=0; i<pPage->nCell; i++){
++      pc = get2byteAligned(&data[cellOffset+i*2]);
++      testcase( pc==iCellFirst );
++      testcase( pc==iCellLast );
++      if( pc<iCellFirst || pc>iCellLast ){
++        return SQLITE_CORRUPT_PGNO(pPage->pgno);
+       }
+-      if( !pPage->leaf ) iCellLast++;
+-    }  
+-#endif
++      sz = pPage->xCellSize(pPage, &data[pc]);
++      testcase( pc+sz==usableSize );
++      if( pc+sz>usableSize ){
++        return SQLITE_CORRUPT_PGNO(pPage->pgno);
++      }
++    }
++    if( !pPage->leaf ) iCellLast++;
++  }  
+ 
+-    /* Compute the total free space on the page
+-    ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
+-    ** start of the first freeblock on the page, or is zero if there are no
+-    ** freeblocks. */
+-    pc = get2byte(&data[hdr+1]);
+-    nFree = data[hdr+7] + top;  /* Init nFree to non-freeblock free space */
+-    while( pc>0 ){
+-      u16 next, size;
+-      if( pc<iCellFirst || pc>iCellLast ){
+-        /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
+-        ** always be at least one cell before the first freeblock.
+-        **
+-        ** Or, the freeblock is off the end of the page
+-        */
+-        return SQLITE_CORRUPT_BKPT; 
++  /* Compute the total free space on the page
++  ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
++  ** start of the first freeblock on the page, or is zero if there are no
++  ** freeblocks. */
++  pc = get2byte(&data[hdr+1]);
++  nFree = data[hdr+7] + top;  /* Init nFree to non-freeblock free space */
++  if( pc>0 ){
++    u32 next, size;
++    if( pc<iCellFirst ){
++      /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
++      ** always be at least one cell before the first freeblock.
++      */
++      return SQLITE_CORRUPT_PGNO(pPage->pgno); 
++    }
++    while( 1 ){
++      if( pc>iCellLast ){
++        /* Freeblock off the end of the page */
++        return SQLITE_CORRUPT_PGNO(pPage->pgno);
+       }
+       next = get2byte(&data[pc]);
+       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.  */
+-        return SQLITE_CORRUPT_BKPT; 
+-      }
+       nFree = nFree + size;
++      if( next<=pc+size+3 ) break;
+       pc = next;
+     }
+-
+-    /* At this point, nFree contains the sum of the offset to the start
+-    ** of the cell-content area plus the number of free bytes within
+-    ** the cell-content area. If this is greater than the usable-size
+-    ** of the page, then the page must be corrupted. This check also
+-    ** serves to verify that the offset to the start of the cell-content
+-    ** area, according to the page header, lies within the page.
+-    */
+-    if( nFree>usableSize ){
+-      return SQLITE_CORRUPT_BKPT; 
++    if( next>0 ){
++      /* Freeblock not in ascending order */
++      return SQLITE_CORRUPT_PGNO(pPage->pgno);
+     }
+-    pPage->nFree = (u16)(nFree - iCellFirst);
+-    pPage->isInit = 1;
++    if( pc+size>(unsigned int)usableSize ){
++      /* Last freeblock extends past page end */
++      return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    }
++  }
++
++  /* At this point, nFree contains the sum of the offset to the start
++  ** of the cell-content area plus the number of free bytes within
++  ** the cell-content area. If this is greater than the usable-size
++  ** of the page, then the page must be corrupted. This check also
++  ** serves to verify that the offset to the start of the cell-content
++  ** area, according to the page header, lies within the page.
++  */
++  if( nFree>usableSize ){
++    return SQLITE_CORRUPT_PGNO(pPage->pgno);
+   }
++  pPage->nFree = (u16)(nFree - iCellFirst);
++  pPage->isInit = 1;
+   return SQLITE_OK;
+ }
+ 
+@@ -54746,7 +64768,7 @@
+   assert( sqlite3PagerGetData(pPage->pDbPage) == data );
+   assert( sqlite3PagerIswriteable(pPage->pDbPage) );
+   assert( sqlite3_mutex_held(pBt->mutex) );
+-  if( pBt->btsFlags & BTS_SECURE_DELETE ){
++  if( pBt->btsFlags & BTS_FAST_SECURE ){
+     memset(&data[hdr], 0, pBt->usableSize - hdr);
+   }
+   data[hdr] = (char)flags;
+@@ -54759,6 +64781,7 @@
+   pPage->cellOffset = first;
+   pPage->aDataEnd = &data[pBt->usableSize];
+   pPage->aCellIdx = &data[first];
++  pPage->aDataOfst = &data[pPage->childPtrSize];
+   pPage->nOverflow = 0;
+   assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
+   pPage->maskPage = (u16)(pBt->pageSize - 1);
+@@ -54773,20 +64796,23 @@
+ */
+ static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){
+   MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
+-  pPage->aData = sqlite3PagerGetData(pDbPage);
+-  pPage->pDbPage = pDbPage;
+-  pPage->pBt = pBt;
+-  pPage->pgno = pgno;
+-  pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
++  if( pgno!=pPage->pgno ){
++    pPage->aData = sqlite3PagerGetData(pDbPage);
++    pPage->pDbPage = pDbPage;
++    pPage->pBt = pBt;
++    pPage->pgno = pgno;
++    pPage->hdrOffset = pgno==1 ? 100 : 0;
++  }
++  assert( pPage->aData==sqlite3PagerGetData(pDbPage) );
+   return pPage; 
+ }
+ 
+ /*
+ ** Get a page from the pager.  Initialize the MemPage.pBt and
+-** MemPage.aData elements if needed.
++** MemPage.aData elements if needed.  See also: btreeGetUnusedPage().
+ **
+-** If the noContent flag is set, it means that we do not care about
+-** the content of the page at this time.  So do not go to the disk
++** If the PAGER_GET_NOCONTENT flag is set, it means that we do not care
++** about the content of the page at this time.  So do not go to the disk
+ ** to fetch the content.  Just fill in the content with zeros for now.
+ ** If in the future we call sqlite3PagerWrite() on this page, that
+ ** means we have started to be concerned about content and the disk
+@@ -54803,7 +64829,7 @@
+ 
+   assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY );
+   assert( sqlite3_mutex_held(pBt->mutex) );
+-  rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
++  rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
+   if( rc ) return rc;
+   *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
+   return SQLITE_OK;
+@@ -54838,35 +64864,63 @@
+ }
+ 
+ /*
+-** Get a page from the pager and initialize it.  This routine is just a
+-** convenience wrapper around separate calls to btreeGetPage() and 
+-** btreeInitPage().
++** Get a page from the pager and initialize it.
++**
++** If pCur!=0 then the page is being fetched as part of a moveToChild()
++** call.  Do additional sanity checking on the page in this case.
++** And if the fetch fails, this routine must decrement pCur->iPage.
++**
++** The page is fetched as read-write unless pCur is not NULL and is
++** a read-only cursor.
+ **
+-** If an error occurs, then the value *ppPage is set to is undefined. It
++** If an error occurs, then *ppPage is undefined. It
+ ** may remain unchanged, or it may be set to an invalid value.
+ */
+ static int getAndInitPage(
+   BtShared *pBt,                  /* The database file */
+   Pgno pgno,                      /* Number of the page to get */
+   MemPage **ppPage,               /* Write the page pointer here */
+-  int bReadonly                   /* PAGER_GET_READONLY or 0 */
++  BtCursor *pCur,                 /* Cursor to receive the page, or NULL */
++  int bReadOnly                   /* True for a read-only page */
+ ){
+   int rc;
++  DbPage *pDbPage;
+   assert( sqlite3_mutex_held(pBt->mutex) );
+-  assert( bReadonly==PAGER_GET_READONLY || bReadonly==0 );
++  assert( pCur==0 || ppPage==&pCur->apPage[pCur->iPage] );
++  assert( pCur==0 || bReadOnly==pCur->curPagerFlags );
++  assert( pCur==0 || pCur->iPage>0 );
+ 
+   if( pgno>btreePagecount(pBt) ){
+     rc = SQLITE_CORRUPT_BKPT;
+-  }else{
+-    rc = btreeGetPage(pBt, pgno, ppPage, bReadonly);
+-    if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
+-      rc = btreeInitPage(*ppPage);
+-      if( rc!=SQLITE_OK ){
+-        releasePage(*ppPage);
+-      }
++    goto getAndInitPage_error;
++  }
++  rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly);
++  if( rc ){
++    goto getAndInitPage_error;
++  }
++  *ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
++  if( (*ppPage)->isInit==0 ){
++    btreePageFromDbPage(pDbPage, pgno, pBt);
++    rc = btreeInitPage(*ppPage);
++    if( rc!=SQLITE_OK ){
++      releasePage(*ppPage);
++      goto getAndInitPage_error;
+     }
+   }
++  assert( (*ppPage)->pgno==pgno );
++  assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
++
++  /* If obtaining a child page for a cursor, we must verify that the page is
++  ** compatible with the root page. */
++  if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
++    rc = SQLITE_CORRUPT_PGNO(pgno);
++    releasePage(*ppPage);
++    goto getAndInitPage_error;
++  }
++  return SQLITE_OK;
+ 
++getAndInitPage_error:
++  if( pCur ) pCur->iPage--;
+   testcase( pgno==0 );
+   assert( pgno!=0 || rc==SQLITE_CORRUPT );
+   return rc;
+@@ -54876,18 +64930,49 @@
+ ** Release a MemPage.  This should be called once for each prior
+ ** call to btreeGetPage.
+ */
++static void releasePageNotNull(MemPage *pPage){
++  assert( pPage->aData );
++  assert( pPage->pBt );
++  assert( pPage->pDbPage!=0 );
++  assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
++  assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
++  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
++  sqlite3PagerUnrefNotNull(pPage->pDbPage);
++}
+ static void releasePage(MemPage *pPage){
+-  if( pPage ){
+-    assert( pPage->aData );
+-    assert( pPage->pBt );
+-    assert( pPage->pDbPage!=0 );
+-    assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
+-    assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
+-    assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+-    sqlite3PagerUnrefNotNull(pPage->pDbPage);
++  if( pPage ) releasePageNotNull(pPage);
++}
++
++/*
++** Get an unused page.
++**
++** This works just like btreeGetPage() with the addition:
++**
++**   *  If the page is already in use for some other purpose, immediately
++**      release it and return an SQLITE_CURRUPT error.
++**   *  Make sure the isInit flag is clear
++*/
++static int btreeGetUnusedPage(
++  BtShared *pBt,       /* The btree */
++  Pgno pgno,           /* Number of the page to fetch */
++  MemPage **ppPage,    /* Return the page in this parameter */
++  int flags            /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */
++){
++  int rc = btreeGetPage(pBt, pgno, ppPage, flags);
++  if( rc==SQLITE_OK ){
++    if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
++      releasePage(*ppPage);
++      *ppPage = 0;
++      return SQLITE_CORRUPT_BKPT;
++    }
++    (*ppPage)->isInit = 0;
++  }else{
++    *ppPage = 0;
+   }
++  return rc;
+ }
+ 
++
+ /*
+ ** During a rollback, when the pager reloads information into the cache
+ ** so that the cache is restored to its original state at the start of
+@@ -54994,7 +65079,7 @@
+   }
+   p = sqlite3MallocZero(sizeof(Btree));
+   if( !p ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   p->inTrans = TRANS_NONE;
+   p->db = db;
+@@ -55018,7 +65103,7 @@
+       p->sharable = 1;
+       if( !zFullPathname ){
+         sqlite3_free(p);
+-        return SQLITE_NOMEM;
++        return SQLITE_NOMEM_BKPT;
+       }
+       if( isMemdb ){
+         memcpy(zFullPathname, zFilename, nFilename);
+@@ -55086,11 +65171,11 @@
+   
+     pBt = sqlite3MallocZero( sizeof(*pBt) );
+     if( pBt==0 ){
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+       goto btree_open_out;
+     }
+     rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
+-                          EXTRA_SIZE, flags, vfsFlags, pageReinit);
++                          sizeof(MemPage), flags, vfsFlags, pageReinit);
+     if( rc==SQLITE_OK ){
+       sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap);
+       rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
+@@ -55106,8 +65191,10 @@
+     pBt->pCursor = 0;
+     pBt->pPage1 = 0;
+     if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY;
+-#ifdef SQLITE_SECURE_DELETE
++#if defined(SQLITE_SECURE_DELETE)
+     pBt->btsFlags |= BTS_SECURE_DELETE;
++#elif defined(SQLITE_FAST_SECURE_DELETE)
++    pBt->btsFlags |= BTS_OVERWRITE;
+ #endif
+     /* EVIDENCE-OF: R-51873-39618 The page size for a database file is
+     ** determined by the 2-byte integer located at an offset of 16 bytes from
+@@ -55148,15 +65235,14 @@
+ #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
+     /* Add the new BtShared object to the linked list sharable BtShareds.
+     */
++    pBt->nRef = 1;
+     if( p->sharable ){
+       MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
+-      pBt->nRef = 1;
+       MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);)
+       if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
+         pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
+         if( pBt->mutex==0 ){
+-          rc = SQLITE_NOMEM;
+-          db->mallocFailed = 0;
++          rc = SQLITE_NOMEM_BKPT;
+           goto btree_open_out;
+         }
+       }
+@@ -55179,12 +65265,12 @@
+     for(i=0; i<db->nDb; i++){
+       if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){
+         while( pSib->pPrev ){ pSib = pSib->pPrev; }
+-        if( p->pBt<pSib->pBt ){
++        if( (uptr)p->pBt<(uptr)pSib->pBt ){
+           p->pNext = pSib;
+           p->pPrev = 0;
+           pSib->pPrev = p;
+         }else{
+-          while( pSib->pNext && pSib->pNext->pBt<p->pBt ){
++          while( pSib->pNext && (uptr)pSib->pNext->pBt<(uptr)p->pBt ){
+             pSib = pSib->pNext;
+           }
+           p->pNext = pSib->pNext;
+@@ -55204,12 +65290,14 @@
+ btree_open_out:
+   if( rc!=SQLITE_OK ){
+     if( pBt && pBt->pPager ){
+-      sqlite3PagerClose(pBt->pPager);
++      sqlite3PagerClose(pBt->pPager, 0);
+     }
+     sqlite3_free(pBt);
+     sqlite3_free(p);
+     *ppBtree = 0;
+   }else{
++    sqlite3_file *pFile;
++
+     /* If the B-Tree was successfully opened, set the pager-cache size to the
+     ** default value. Except, when opening on an existing shared pager-cache,
+     ** do not change the pager-cache size.
+@@ -55217,11 +65305,17 @@
+     if( sqlite3BtreeSchema(p, 0, 0)==0 ){
+       sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE);
+     }
++
++    pFile = sqlite3PagerFile(pBt->pPager);
++    if( pFile->pMethods ){
++      sqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db);
++    }
+   }
+   if( mutexOpen ){
+     assert( sqlite3_mutex_held(mutexOpen) );
+     sqlite3_mutex_leave(mutexOpen);
+   }
++  assert( rc!=SQLITE_OK || sqlite3BtreeConnectionCount(*ppBtree)>0 );
+   return rc;
+ }
+ 
+@@ -55345,7 +65439,7 @@
+     ** Clean out and delete the BtShared object.
+     */
+     assert( !pBt->pCursor );
+-    sqlite3PagerClose(pBt->pPager);
++    sqlite3PagerClose(pBt->pPager, p->db);
+     if( pBt->xFreeSchema && pBt->pSchema ){
+       pBt->xFreeSchema(pBt->pSchema);
+     }
+@@ -55366,19 +65460,11 @@
+ }
+ 
+ /*
+-** Change the limit on the number of pages allowed in the cache.
+-**
+-** The maximum number of cache pages is set to the absolute
+-** value of mxPage.  If mxPage is negative, the pager will
+-** operate asynchronously - it will not stop to do fsync()s
+-** to insure data is written to the disk surface before
+-** continuing.  Transactions still work if synchronous is off,
+-** and the database cannot be corrupted if this program
+-** crashes.  But if the operating system crashes or there is
+-** an abrupt power failure when synchronous is off, the database
+-** could be left in an inconsistent and unrecoverable state.
+-** Synchronous is on by default so database corruption is not
+-** normally a worry.
++** Change the "soft" limit on the number of pages in the cache.
++** Unused and unmodified pages will be recycled when the number of
++** pages in the cache exceeds this soft limit.  But the size of the
++** cache is allowed to grow larger than this limit if it contains
++** dirty pages or pages still in active use.
+ */
+ SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
+   BtShared *pBt = p->pBt;
+@@ -55389,6 +65475,26 @@
+   return SQLITE_OK;
+ }
+ 
++/*
++** Change the "spill" limit on the number of pages in the cache.
++** If the number of pages exceeds this limit during a write transaction,
++** the pager might attempt to "spill" pages to the journal early in
++** order to free up memory.
++**
++** The value returned is the current spill size.  If zero is passed
++** as an argument, no changes are made to the spill size setting, so
++** using mxPage of 0 is a way to query the current spill size.
++*/
++SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree *p, int mxPage){
++  BtShared *pBt = p->pBt;
++  int res;
++  assert( sqlite3_mutex_held(p->db->mutex) );
++  sqlite3BtreeEnter(p);
++  res = sqlite3PagerSetSpillsize(pBt->pPager, mxPage);
++  sqlite3BtreeLeave(p);
++  return res;
++}
++
+ #if SQLITE_MAX_MMAP_SIZE>0
+ /*
+ ** Change the limit on the amount of the database file that may be
+@@ -55427,21 +65533,6 @@
+ #endif
+ 
+ /*
+-** Return TRUE if the given btree is set to safety level 1.  In other
+-** words, return TRUE if no sync() occurs on the disk files.
+-*/
+-SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree *p){
+-  BtShared *pBt = p->pBt;
+-  int rc;
+-  assert( sqlite3_mutex_held(p->db->mutex) );  
+-  sqlite3BtreeEnter(p);
+-  assert( pBt && pBt->pPager );
+-  rc = sqlite3PagerNosync(pBt->pPager);
+-  sqlite3BtreeLeave(p);
+-  return rc;
+-}
+-
+-/*
+ ** Change the default pages size and the number of reserved bytes per page.
+ ** Or, if the page size has already been fixed, return SQLITE_READONLY 
+ ** without changing anything.
+@@ -55551,19 +65642,34 @@
+ }
+ 
+ /*
+-** Set the BTS_SECURE_DELETE flag if newFlag is 0 or 1.  If newFlag is -1,
+-** then make no changes.  Always return the value of the BTS_SECURE_DELETE
+-** setting after the change.
++** Change the values for the BTS_SECURE_DELETE and BTS_OVERWRITE flags:
++**
++**    newFlag==0       Both BTS_SECURE_DELETE and BTS_OVERWRITE are cleared
++**    newFlag==1       BTS_SECURE_DELETE set and BTS_OVERWRITE is cleared
++**    newFlag==2       BTS_SECURE_DELETE cleared and BTS_OVERWRITE is set
++**    newFlag==(-1)    No changes
++**
++** This routine acts as a query if newFlag is less than zero
++**
++** With BTS_OVERWRITE set, deleted content is overwritten by zeros, but
++** freelist leaf pages are not written back to the database.  Thus in-page
++** deleted content is cleared, but freelist deleted content is not.
++**
++** With BTS_SECURE_DELETE, operation is like BTS_OVERWRITE with the addition
++** that freelist leaf pages are written back into the database, increasing
++** the amount of disk I/O.
+ */
+ SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){
+   int b;
+   if( p==0 ) return 0;
+   sqlite3BtreeEnter(p);
++  assert( BTS_OVERWRITE==BTS_SECURE_DELETE*2 );
++  assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) );
+   if( newFlag>=0 ){
+-    p->pBt->btsFlags &= ~BTS_SECURE_DELETE;
+-    if( newFlag ) p->pBt->btsFlags |= BTS_SECURE_DELETE;
+-  } 
+-  b = (p->pBt->btsFlags & BTS_SECURE_DELETE)!=0;
++    p->pBt->btsFlags &= ~BTS_FAST_SECURE;
++    p->pBt->btsFlags |= BTS_SECURE_DELETE*newFlag;
++  }
++  b = (p->pBt->btsFlags & BTS_FAST_SECURE)/BTS_SECURE_DELETE;
+   sqlite3BtreeLeave(p);
+   return b;
+ }
+@@ -55614,6 +65720,31 @@
+ #endif
+ }
+ 
++/*
++** If the user has not set the safety-level for this database connection
++** using "PRAGMA synchronous", and if the safety-level is not already
++** set to the value passed to this function as the second parameter,
++** set it so.
++*/
++#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS
++static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){
++  sqlite3 *db;
++  Db *pDb;
++  if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){
++    while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; }
++    if( pDb->bSyncSet==0 
++     && pDb->safety_level!=safety_level 
++     && pDb!=&db->aDb[1] 
++    ){
++      pDb->safety_level = safety_level;
++      sqlite3PagerSetFlags(pBt->pPager,
++          pDb->safety_level | (db->flags & PAGER_FLAGS_MASK));
++    }
++  }
++}
++#else
++# define setDefaultSyncFlag(pBt,safety_level)
++#endif
+ 
+ /*
+ ** Get a reference to pPage1 of the database file.  This will
+@@ -55686,11 +65817,16 @@
+       rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen);
+       if( rc!=SQLITE_OK ){
+         goto page1_init_failed;
+-      }else if( isOpen==0 ){
+-        releasePage(pPage1);
+-        return SQLITE_OK;
++      }else{
++        setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1);
++        if( isOpen==0 ){
++          releasePage(pPage1);
++          return SQLITE_OK;
++        }
+       }
+       rc = SQLITE_NOTADB;
++    }else{
++      setDefaultSyncFlag(pBt, SQLITE_DEFAULT_SYNCHRONOUS+1);
+     }
+ #endif
+ 
+@@ -55739,7 +65875,7 @@
+                                    pageSize-usableSize);
+       return rc;
+     }
+-    if( (pBt->db->flags & SQLITE_RecoveryMode)==0 && nPage>nPageFile ){
++    if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){
+       rc = SQLITE_CORRUPT_BKPT;
+       goto page1_init_failed;
+     }
+@@ -55830,7 +65966,7 @@
+     assert( pPage1->aData );
+     assert( sqlite3PagerRefcount(pBt->pPager)==1 );
+     pBt->pPage1 = 0;
+-    releasePage(pPage1);
++    releasePageNotNull(pPage1);
+   }
+ }
+ 
+@@ -55928,7 +66064,6 @@
+ ** proceed.
+ */
+ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
+-  sqlite3 *pBlock = 0;
+   BtShared *pBt = p->pBt;
+   int rc = SQLITE_OK;
+ 
+@@ -55951,27 +66086,30 @@
+   }
+ 
+ #ifndef SQLITE_OMIT_SHARED_CACHE
+-  /* If another database handle has already opened a write transaction 
+-  ** on this shared-btree structure and a second write transaction is
+-  ** requested, return SQLITE_LOCKED.
+-  */
+-  if( (wrflag && pBt->inTransaction==TRANS_WRITE)
+-   || (pBt->btsFlags & BTS_PENDING)!=0
+-  ){
+-    pBlock = pBt->pWriter->db;
+-  }else if( wrflag>1 ){
+-    BtLock *pIter;
+-    for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
+-      if( pIter->pBtree!=p ){
+-        pBlock = pIter->pBtree->db;
+-        break;
++  {
++    sqlite3 *pBlock = 0;
++    /* If another database handle has already opened a write transaction 
++    ** on this shared-btree structure and a second write transaction is
++    ** requested, return SQLITE_LOCKED.
++    */
++    if( (wrflag && pBt->inTransaction==TRANS_WRITE)
++     || (pBt->btsFlags & BTS_PENDING)!=0
++    ){
++      pBlock = pBt->pWriter->db;
++    }else if( wrflag>1 ){
++      BtLock *pIter;
++      for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
++        if( pIter->pBtree!=p ){
++          pBlock = pIter->pBtree->db;
++          break;
++        }
+       }
+     }
+-  }
+-  if( pBlock ){
+-    sqlite3ConnectionBlocked(p->db, pBlock);
+-    rc = SQLITE_LOCKED_SHAREDCACHE;
+-    goto trans_begun;
++    if( pBlock ){
++      sqlite3ConnectionBlocked(p->db, pBlock);
++      rc = SQLITE_LOCKED_SHAREDCACHE;
++      goto trans_begun;
++    }
+   }
+ #endif
+ 
+@@ -56077,14 +66215,11 @@
+   int nCell;                         /* Number of cells in page pPage */
+   int rc;                            /* Return code */
+   BtShared *pBt = pPage->pBt;
+-  u8 isInitOrig = pPage->isInit;
+   Pgno pgno = pPage->pgno;
+ 
+   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+-  rc = btreeInitPage(pPage);
+-  if( rc!=SQLITE_OK ){
+-    goto set_child_ptrmaps_out;
+-  }
++  rc = pPage->isInit ? SQLITE_OK : btreeInitPage(pPage);
++  if( rc!=SQLITE_OK ) return rc;
+   nCell = pPage->nCell;
+ 
+   for(i=0; i<nCell; i++){
+@@ -56103,8 +66238,6 @@
+     ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc);
+   }
+ 
+-set_child_ptrmaps_out:
+-  pPage->isInit = isInitOrig;
+   return rc;
+ }
+ 
+@@ -56128,28 +66261,31 @@
+   if( eType==PTRMAP_OVERFLOW2 ){
+     /* The pointer is always the first 4 bytes of the page in this case.  */
+     if( get4byte(pPage->aData)!=iFrom ){
+-      return SQLITE_CORRUPT_BKPT;
++      return SQLITE_CORRUPT_PGNO(pPage->pgno);
+     }
+     put4byte(pPage->aData, iTo);
+   }else{
+-    u8 isInitOrig = pPage->isInit;
+     int i;
+     int nCell;
++    int rc;
+ 
+-    btreeInitPage(pPage);
++    rc = pPage->isInit ? SQLITE_OK : btreeInitPage(pPage);
++    if( rc ) return rc;
+     nCell = pPage->nCell;
+ 
+     for(i=0; i<nCell; i++){
+       u8 *pCell = findCell(pPage, i);
+       if( eType==PTRMAP_OVERFLOW1 ){
+         CellInfo info;
+-        btreeParseCellPtr(pPage, pCell, &info);
+-        if( info.iOverflow
+-         && pCell+info.iOverflow+3<=pPage->aData+pPage->maskPage
+-         && iFrom==get4byte(&pCell[info.iOverflow])
+-        ){
+-          put4byte(&pCell[info.iOverflow], iTo);
+-          break;
++        pPage->xParseCell(pPage, pCell, &info);
++        if( info.nLocal<info.nPayload ){
++          if( pCell+info.nSize > pPage->aData+pPage->pBt->usableSize ){
++            return SQLITE_CORRUPT_PGNO(pPage->pgno);
++          }
++          if( iFrom==get4byte(pCell+info.nSize-4) ){
++            put4byte(pCell+info.nSize-4, iTo);
++            break;
++          }
+         }
+       }else{
+         if( get4byte(pCell)==iFrom ){
+@@ -56162,12 +66298,10 @@
+     if( i==nCell ){
+       if( eType!=PTRMAP_BTREE || 
+           get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
+-        return SQLITE_CORRUPT_BKPT;
++        return SQLITE_CORRUPT_PGNO(pPage->pgno);
+       }
+       put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
+     }
+-
+-    pPage->isInit = isInitOrig;
+   }
+   return SQLITE_OK;
+ }
+@@ -56442,7 +66576,7 @@
+ static int autoVacuumCommit(BtShared *pBt){
+   int rc = SQLITE_OK;
+   Pager *pPager = pBt->pPager;
+-  VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager) );
++  VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager); )
+ 
+   assert( sqlite3_mutex_held(pBt->mutex) );
+   invalidateAllOverflowCache(pBt);
+@@ -56826,7 +66960,12 @@
+     assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
+     assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) );
+     sqlite3BtreeEnter(p);
+-    rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint);
++    if( op==SAVEPOINT_ROLLBACK ){
++      rc = saveAllCursors(pBt, 0, 0);
++    }
++    if( rc==SQLITE_OK ){
++      rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint);
++    }
+     if( rc==SQLITE_OK ){
+       if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){
+         pBt->nPage = 0;
+@@ -56851,13 +66990,13 @@
+ ** on the database already. If a write-cursor is requested, then
+ ** the caller is assumed to have an open write transaction.
+ **
+-** If wrFlag==0, then the cursor can only be used for reading.
+-** If wrFlag==1, then the cursor can be used for reading or for
+-** writing if other conditions for writing are also met.  These
+-** are the conditions that must be met in order for writing to
+-** be allowed:
++** If the BTREE_WRCSR bit of wrFlag is clear, then the cursor can only
++** be used for reading.  If the BTREE_WRCSR bit is set, then the cursor
++** can be used for reading or for writing if other conditions for writing
++** are also met.  These are the conditions that must be met in order
++** for writing to be allowed:
+ **
+-** 1:  The cursor must have been opened with wrFlag==1
++** 1:  The cursor must have been opened with wrFlag containing BTREE_WRCSR
+ **
+ ** 2:  Other database connections that share the same pager cache
+ **     but which are not in the READ_UNCOMMITTED state may not have
+@@ -56869,6 +67008,16 @@
+ **
+ ** 4:  There must be an active transaction.
+ **
++** The BTREE_FORDELETE bit of wrFlag may optionally be set if BTREE_WRCSR
++** is set.  If FORDELETE is set, that is a hint to the implementation that
++** this cursor will only be used to seek to and delete entries of an index
++** as part of a larger DELETE statement.  The FORDELETE hint is not used by
++** this implementation.  But in a hypothetical alternative storage engine 
++** in which index entries are automatically deleted when corresponding table
++** rows are deleted, the FORDELETE flag is a hint that all SEEK and DELETE
++** operations on this cursor can be no-ops and all READ operations can 
++** return a null row (2-bytes: 0x01 0x00).
++**
+ ** No checking is done to make sure that page iTable really is the
+ ** root page of a b-tree.  If it is not, then the cursor acquired
+ ** will not work correctly.
+@@ -56884,28 +67033,30 @@
+   BtCursor *pCur                         /* Space for new cursor */
+ ){
+   BtShared *pBt = p->pBt;                /* Shared b-tree handle */
++  BtCursor *pX;                          /* Looping over other all cursors */
+ 
+   assert( sqlite3BtreeHoldsMutex(p) );
+-  assert( wrFlag==0 || wrFlag==1 );
++  assert( wrFlag==0 
++       || wrFlag==BTREE_WRCSR 
++       || wrFlag==(BTREE_WRCSR|BTREE_FORDELETE) 
++  );
+ 
+   /* The following assert statements verify that if this is a sharable 
+   ** b-tree database, the connection is holding the required table locks, 
+   ** and that no other connection has any open cursor that conflicts with 
+   ** this lock.  */
+-  assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1) );
++  assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) );
+   assert( wrFlag==0 || !hasReadConflicts(p, iTable) );
+ 
+   /* Assert that the caller has opened the required transaction. */
+   assert( p->inTrans>TRANS_NONE );
+   assert( wrFlag==0 || p->inTrans==TRANS_WRITE );
+   assert( pBt->pPage1 && pBt->pPage1->aData );
++  assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 );
+ 
+-  if( NEVER(wrFlag && (pBt->btsFlags & BTS_READ_ONLY)!=0) ){
+-    return SQLITE_READONLY;
+-  }
+   if( wrFlag ){
+     allocateTempSpace(pBt);
+-    if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM;
++    if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT;
+   }
+   if( iTable==1 && btreePagecount(pBt)==0 ){
+     assert( wrFlag==0 );
+@@ -56919,12 +67070,17 @@
+   pCur->pKeyInfo = pKeyInfo;
+   pCur->pBtree = p;
+   pCur->pBt = pBt;
+-  assert( wrFlag==0 || wrFlag==BTCF_WriteFlag );
+-  pCur->curFlags = wrFlag;
+-  pCur->pNext = pBt->pCursor;
+-  if( pCur->pNext ){
+-    pCur->pNext->pPrev = pCur;
++  pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0;
++  pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY;
++  /* If there are two or more cursors on the same btree, then all such
++  ** cursors *must* have the BTCF_Multiple flag set. */
++  for(pX=pBt->pCursor; pX; pX=pX->pNext){
++    if( pX->pgnoRoot==(Pgno)iTable ){
++      pX->curFlags |= BTCF_Multiple;
++      pCur->curFlags |= BTCF_Multiple;
++    }
+   }
++  pCur->pNext = pBt->pCursor;
+   pBt->pCursor = pCur;
+   pCur->eState = CURSOR_INVALID;
+   return SQLITE_OK;
+@@ -56937,9 +67093,13 @@
+   BtCursor *pCur                              /* Write new cursor here */
+ ){
+   int rc;
+-  sqlite3BtreeEnter(p);
+-  rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
+-  sqlite3BtreeLeave(p);
++  if( iTable<1 ){
++    rc = SQLITE_CORRUPT_BKPT;
++  }else{
++    sqlite3BtreeEnter(p);
++    rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
++    sqlite3BtreeLeave(p);
++  }
+   return rc;
+ }
+ 
+@@ -56978,13 +67138,18 @@
+     BtShared *pBt = pCur->pBt;
+     sqlite3BtreeEnter(pBtree);
+     sqlite3BtreeClearCursor(pCur);
+-    if( pCur->pPrev ){
+-      pCur->pPrev->pNext = pCur->pNext;
+-    }else{
++    assert( pBt->pCursor!=0 );
++    if( pBt->pCursor==pCur ){
+       pBt->pCursor = pCur->pNext;
+-    }
+-    if( pCur->pNext ){
+-      pCur->pNext->pPrev = pCur->pPrev;
++    }else{
++      BtCursor *pPrev = pBt->pCursor;
++      do{
++        if( pPrev->pNext==pCur ){
++          pPrev->pNext = pCur->pNext;
++          break;
++        }
++        pPrev = pPrev->pNext;
++      }while( ALWAYS(pPrev) );
+     }
+     for(i=0; i<=pCur->iPage; i++){
+       releasePage(pCur->apPage[i]);
+@@ -57004,47 +67169,27 @@
+ **
+ ** BtCursor.info is a cache of the information in the current cell.
+ ** Using this cache reduces the number of calls to btreeParseCell().
+-**
+-** 2007-06-25:  There is a bug in some versions of MSVC that cause the
+-** compiler to crash when getCellInfo() is implemented as a macro.
+-** But there is a measureable speed advantage to using the macro on gcc
+-** (when less compiler optimizations like -Os or -O0 are used and the
+-** compiler is not doing aggressive inlining.)  So we use a real function
+-** for MSVC and a macro for everything else.  Ticket #2457.
+ */
+ #ifndef NDEBUG
+   static void assertCellInfo(BtCursor *pCur){
+     CellInfo info;
+     int iPage = pCur->iPage;
+     memset(&info, 0, sizeof(info));
+-    btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
++    btreeParseCell(pCur->apPage[iPage], pCur->ix, &info);
+     assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
+   }
+ #else
+   #define assertCellInfo(x)
+ #endif
+-#ifdef _MSC_VER
+-  /* Use a real function in MSVC to work around bugs in that compiler. */
+-  static void getCellInfo(BtCursor *pCur){
+-    if( pCur->info.nSize==0 ){
+-      int iPage = pCur->iPage;
+-      btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
+-      pCur->curFlags |= BTCF_ValidNKey;
+-    }else{
+-      assertCellInfo(pCur);
+-    }
+-  }
+-#else /* if not _MSC_VER */
+-  /* Use a macro in all other compilers so that the function is inlined */
+-#define getCellInfo(pCur)                                                      \
+-  if( pCur->info.nSize==0 ){                                                   \
+-    int iPage = pCur->iPage;                                                   \
+-    btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);        \
+-    pCur->curFlags |= BTCF_ValidNKey;                                          \
+-  }else{                                                                       \
+-    assertCellInfo(pCur);                                                      \
++static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){
++  if( pCur->info.nSize==0 ){
++    int iPage = pCur->iPage;
++    pCur->curFlags |= BTCF_ValidNKey;
++    btreeParseCell(pCur->apPage[iPage],pCur->ix,&pCur->info);
++  }else{
++    assertCellInfo(pCur);
+   }
+-#endif /* _MSC_VER */
++}
+ 
+ #ifndef NDEBUG  /* The next routine used only within assert() statements */
+ /*
+@@ -57056,48 +67201,39 @@
+   return pCur && pCur->eState==CURSOR_VALID;
+ }
+ #endif /* NDEBUG */
++SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor *pCur){
++  assert( pCur!=0 );
++  return pCur->eState==CURSOR_VALID;
++}
+ 
+ /*
+-** Set *pSize to the size of the buffer needed to hold the value of
+-** the key for the current entry.  If the cursor is not pointing
+-** to a valid entry, *pSize is set to 0. 
+-**
+-** For a table with the INTKEY flag set, this routine returns the key
+-** itself, not the number of bytes in the key.
+-**
+-** The caller must position the cursor prior to invoking this routine.
+-** 
+-** This routine cannot fail.  It always returns SQLITE_OK.  
++** Return the value of the integer key or "rowid" for a table btree.
++** This routine is only valid for a cursor that is pointing into a
++** ordinary table btree.  If the cursor points to an index btree or
++** is invalid, the result of this routine is undefined.
+ */
+-SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
++SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor *pCur){
+   assert( cursorHoldsMutex(pCur) );
+   assert( pCur->eState==CURSOR_VALID );
++  assert( pCur->curIntKey );
+   getCellInfo(pCur);
+-  *pSize = pCur->info.nKey;
+-  return SQLITE_OK;
++  return pCur->info.nKey;
+ }
+ 
+ /*
+-** Set *pSize to the number of bytes of data in the entry the
+-** cursor currently points to.
++** Return the number of bytes of payload for the entry that pCur is
++** currently pointing to.  For table btrees, this will be the amount
++** of data.  For index btrees, this will be the size of the key.
+ **
+ ** The caller must guarantee that the cursor is pointing to a non-NULL
+ ** valid entry.  In other words, the calling procedure must guarantee
+ ** that the cursor has Cursor.eState==CURSOR_VALID.
+-**
+-** Failure is not possible.  This function always returns SQLITE_OK.
+-** It might just as well be a procedure (returning void) but we continue
+-** to return an integer result code for historical reasons.
+ */
+-SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
++SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){
+   assert( cursorHoldsMutex(pCur) );
+   assert( pCur->eState==CURSOR_VALID );
+-  assert( pCur->iPage>=0 );
+-  assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
+-  assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
+   getCellInfo(pCur);
+-  *pSize = pCur->info.nPayload;
+-  return SQLITE_OK;
++  return pCur->info.nPayload;
+ }
+ 
+ /*
+@@ -57215,7 +67351,6 @@
+ **
+ **   0: The operation is a read. Populate the overflow cache.
+ **   1: The operation is a write. Populate the overflow cache.
+-**   2: The operation is a read. Do not populate the overflow cache.
+ **
+ ** A total of "amt" bytes are read or written beginning at "offset".
+ ** Data is read to or from the buffer pBuf.
+@@ -57223,13 +67358,13 @@
+ ** The content being read or written might appear on the main page
+ ** or be scattered out on multiple overflow pages.
+ **
+-** If the current cursor entry uses one or more overflow pages and the
+-** eOp argument is not 2, this function may allocate space for and lazily 
+-** populates the overflow page-list cache array (BtCursor.aOverflow). 
++** If the current cursor entry uses one or more overflow pages
++** this function may allocate space for and lazily populate
++** the overflow page-list cache array (BtCursor.aOverflow). 
+ ** Subsequent calls use this cache to make seeking to the supplied offset 
+ ** more efficient.
+ **
+-** Once an overflow page-list cache has been allocated, it may be
++** Once an overflow page-list cache has been allocated, it must be
+ ** invalidated if some other cursor writes to the same table, or if
+ ** the cursor is moved to a different row. Additionally, in auto-vacuum
+ ** mode, the following events may invalidate an overflow page-list cache.
+@@ -57251,26 +67386,27 @@
+   MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
+   BtShared *pBt = pCur->pBt;                  /* Btree this cursor belongs to */
+ #ifdef SQLITE_DIRECT_OVERFLOW_READ
+-  unsigned char * const pBufStart = pBuf;
+-  int bEnd;                                 /* True if reading to end of data */
++  unsigned char * const pBufStart = pBuf;     /* Start of original out buffer */
+ #endif
+ 
+   assert( pPage );
++  assert( eOp==0 || eOp==1 );
+   assert( pCur->eState==CURSOR_VALID );
+-  assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
++  assert( pCur->ix<pPage->nCell );
+   assert( cursorHoldsMutex(pCur) );
+-  assert( eOp!=2 || offset==0 );    /* Always start from beginning for eOp==2 */
+ 
+   getCellInfo(pCur);
+   aPayload = pCur->info.pPayload;
+-#ifdef SQLITE_DIRECT_OVERFLOW_READ
+-  bEnd = offset+amt==pCur->info.nPayload;
+-#endif
+   assert( offset+amt <= pCur->info.nPayload );
+ 
+-  if( &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ){
+-    /* Trying to read or write past the end of the data is an error */
+-    return SQLITE_CORRUPT_BKPT;
++  assert( aPayload > pPage->aData );
++  if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){
++    /* Trying to read or write past the end of the data is an error.  The
++    ** conditional above is really:
++    **    &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
++    ** but is recast into its current form to avoid integer overflow problems
++    */
++    return SQLITE_CORRUPT_PGNO(pPage->pgno);
+   }
+ 
+   /* Check if data must be read/written to/from the btree page itself. */
+@@ -57279,7 +67415,7 @@
+     if( a+offset>pCur->info.nLocal ){
+       a = pCur->info.nLocal - offset;
+     }
+-    rc = copyPayload(&aPayload[offset], pBuf, a, (eOp & 0x01), pPage->pDbPage);
++    rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage);
+     offset = 0;
+     pBuf += a;
+     amt -= a;
+@@ -57295,51 +67431,46 @@
+     nextPage = get4byte(&aPayload[pCur->info.nLocal]);
+ 
+     /* If the BtCursor.aOverflow[] has not been allocated, allocate it now.
+-    ** Except, do not allocate aOverflow[] for eOp==2.
+     **
+     ** The aOverflow[] array is sized at one entry for each overflow page
+     ** in the overflow chain. The page number of the first overflow page is
+     ** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array
+     ** means "not yet known" (the cache is lazily populated).
+     */
+-    if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){
++    if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){
+       int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
+       if( nOvfl>pCur->nOvflAlloc ){
+         Pgno *aNew = (Pgno*)sqlite3Realloc(
+             pCur->aOverflow, nOvfl*2*sizeof(Pgno)
+         );
+         if( aNew==0 ){
+-          rc = SQLITE_NOMEM;
++          return SQLITE_NOMEM_BKPT;
+         }else{
+           pCur->nOvflAlloc = nOvfl*2;
+           pCur->aOverflow = aNew;
+         }
+       }
+-      if( rc==SQLITE_OK ){
+-        memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
+-        pCur->curFlags |= BTCF_ValidOvfl;
++      memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
++      pCur->curFlags |= BTCF_ValidOvfl;
++    }else{
++      /* If the overflow page-list cache has been allocated and the
++      ** entry for the first required overflow page is valid, skip
++      ** directly to it.
++      */
++      if( pCur->aOverflow[offset/ovflSize] ){
++        iIdx = (offset/ovflSize);
++        nextPage = pCur->aOverflow[iIdx];
++        offset = (offset%ovflSize);
+       }
+     }
+ 
+-    /* If the overflow page-list cache has been allocated and the
+-    ** entry for the first required overflow page is valid, skip
+-    ** directly to it.
+-    */
+-    if( (pCur->curFlags & BTCF_ValidOvfl)!=0
+-     && pCur->aOverflow[offset/ovflSize]
+-    ){
+-      iIdx = (offset/ovflSize);
+-      nextPage = pCur->aOverflow[iIdx];
+-      offset = (offset%ovflSize);
+-    }
+-
+-    for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){
+-
++    assert( rc==SQLITE_OK && amt>0 );
++    while( nextPage ){
+       /* If required, populate the overflow page-list cache. */
+-      if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){
+-        assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
+-        pCur->aOverflow[iIdx] = nextPage;
+-      }
++      assert( pCur->aOverflow[iIdx]==0
++              || pCur->aOverflow[iIdx]==nextPage
++              || CORRUPT_DB );
++      pCur->aOverflow[iIdx] = nextPage;
+ 
+       if( offset>=ovflSize ){
+         /* The only reason to read this page is to obtain the page
+@@ -57347,11 +67478,7 @@
+         ** data is not required. So first try to lookup the overflow
+         ** page-list cache, if any, then fall back to the getOverflowPage()
+         ** function.
+-        **
+-        ** Note that the aOverflow[] array must be allocated because eOp!=2
+-        ** here.  If eOp==2, then offset==0 and this branch is never taken.
+         */
+-        assert( eOp!=2 );
+         assert( pCur->curFlags & BTCF_ValidOvfl );
+         assert( pCur->pBtree->db==pBt->db );
+         if( pCur->aOverflow[iIdx+1] ){
+@@ -57365,7 +67492,7 @@
+         ** range of data that is being read (eOp==0) or written (eOp!=0).
+         */
+ #ifdef SQLITE_DIRECT_OVERFLOW_READ
+-        sqlite3_file *fd;
++        sqlite3_file *fd;      /* File from which to do direct overflow read */
+ #endif
+         int a = amt;
+         if( a + offset > ovflSize ){
+@@ -57377,27 +67504,25 @@
+         **
+         **   1) this is a read operation, and 
+         **   2) data is required from the start of this overflow page, and
+-        **   3) the database is file-backed, and
+-        **   4) there is no open write-transaction, and
+-        **   5) the database is not a WAL database,
+-        **   6) all data from the page is being read.
+-        **   7) at least 4 bytes have already been read into the output buffer 
++        **   3) there is no open write-transaction, and
++        **   4) the database is file-backed, and
++        **   5) the page is not in the WAL file
++        **   6) at least 4 bytes have already been read into the output buffer 
+         **
+         ** then data can be read directly from the database file into the
+         ** output buffer, bypassing the page-cache altogether. This speeds
+         ** up loading large records that span many overflow pages.
+         */
+-        if( (eOp&0x01)==0                                      /* (1) */
++        if( eOp==0                                             /* (1) */
+          && offset==0                                          /* (2) */
+-         && (bEnd || a==ovflSize)                              /* (6) */
+-         && pBt->inTransaction==TRANS_READ                     /* (4) */
+-         && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (3) */
+-         && pBt->pPage1->aData[19]==0x01                       /* (5) */
+-         && &pBuf[-4]>=pBufStart                               /* (7) */
++         && pBt->inTransaction==TRANS_READ                     /* (3) */
++         && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (4) */
++         && 0==sqlite3PagerUseWal(pBt->pPager, nextPage)       /* (5) */
++         && &pBuf[-4]>=pBufStart                               /* (6) */
+         ){
+           u8 aSave[4];
+           u8 *aWrite = &pBuf[-4];
+-          assert( aWrite>=pBufStart );                         /* hence (7) */
++          assert( aWrite>=pBufStart );                         /* due to (6) */
+           memcpy(aSave, aWrite, 4);
+           rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
+           nextPage = get4byte(aWrite);
+@@ -57407,77 +67532,87 @@
+ 
+         {
+           DbPage *pDbPage;
+-          rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage,
+-              ((eOp&0x01)==0 ? PAGER_GET_READONLY : 0)
++          rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage,
++              (eOp==0 ? PAGER_GET_READONLY : 0)
+           );
+           if( rc==SQLITE_OK ){
+             aPayload = sqlite3PagerGetData(pDbPage);
+             nextPage = get4byte(aPayload);
+-            rc = copyPayload(&aPayload[offset+4], pBuf, a, (eOp&0x01), pDbPage);
++            rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
+             sqlite3PagerUnref(pDbPage);
+             offset = 0;
+           }
+         }
+         amt -= a;
++        if( amt==0 ) return rc;
+         pBuf += a;
+       }
++      if( rc ) break;
++      iIdx++;
+     }
+   }
+ 
+   if( rc==SQLITE_OK && amt>0 ){
+-    return SQLITE_CORRUPT_BKPT;
++    /* Overflow chain ends prematurely */
++    return SQLITE_CORRUPT_PGNO(pPage->pgno);
+   }
+   return rc;
+ }
+ 
+ /*
+-** Read part of the key associated with cursor pCur.  Exactly
+-** "amt" bytes will be transferred into pBuf[].  The transfer
++** Read part of the payload for the row at which that cursor pCur is currently
++** pointing.  "amt" bytes will be transferred into pBuf[].  The transfer
+ ** begins at "offset".
+ **
+-** The caller must ensure that pCur is pointing to a valid row
+-** in the table.
++** pCur can be pointing to either a table or an index b-tree.
++** If pointing to a table btree, then the content section is read.  If
++** pCur is pointing to an index b-tree then the key section is read.
++**
++** For sqlite3BtreePayload(), the caller must ensure that pCur is pointing
++** to a valid row in the table.  For sqlite3BtreePayloadChecked(), the
++** cursor might be invalid or might need to be restored before being read.
+ **
+ ** Return SQLITE_OK on success or an error code if anything goes
+ ** wrong.  An error is returned if "offset+amt" is larger than
+ ** the available payload.
+ */
+-SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
++SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
+   assert( cursorHoldsMutex(pCur) );
+   assert( pCur->eState==CURSOR_VALID );
+   assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
+-  assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
++  assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
+   return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
+ }
+ 
+ /*
+-** Read part of the data associated with cursor pCur.  Exactly
+-** "amt" bytes will be transfered into pBuf[].  The transfer
+-** begins at "offset".
+-**
+-** Return SQLITE_OK on success or an error code if anything goes
+-** wrong.  An error is returned if "offset+amt" is larger than
+-** the available payload.
++** This variant of sqlite3BtreePayload() works even if the cursor has not
++** in the CURSOR_VALID state.  It is only used by the sqlite3_blob_read()
++** interface.
+ */
+-SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
+-  int rc;
+-
+ #ifndef SQLITE_OMIT_INCRBLOB
++static SQLITE_NOINLINE int accessPayloadChecked(
++  BtCursor *pCur,
++  u32 offset,
++  u32 amt,
++  void *pBuf
++){
++  int rc;
+   if ( pCur->eState==CURSOR_INVALID ){
+     return SQLITE_ABORT;
+   }
+-#endif
+-
+-  assert( cursorHoldsMutex(pCur) );
+-  rc = restoreCursorPosition(pCur);
+-  if( rc==SQLITE_OK ){
+-    assert( pCur->eState==CURSOR_VALID );
+-    assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
+-    assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
+-    rc = accessPayload(pCur, offset, amt, pBuf, 0);
++  assert( cursorOwnsBtShared(pCur) );
++  rc = btreeRestoreCursorPosition(pCur);
++  return rc ? rc : accessPayload(pCur, offset, amt, pBuf, 0);
++}
++SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
++  if( pCur->eState==CURSOR_VALID ){
++    assert( cursorOwnsBtShared(pCur) );
++    return accessPayload(pCur, offset, amt, pBuf, 0);
++  }else{
++    return accessPayloadChecked(pCur, offset, amt, pBuf);
+   }
+-  return rc;
+ }
++#endif /* SQLITE_OMIT_INCRBLOB */
+ 
+ /*
+ ** Return a pointer to payload information from the entry that the 
+@@ -57506,8 +67641,8 @@
+   assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
+   assert( pCur->eState==CURSOR_VALID );
+   assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
+-  assert( cursorHoldsMutex(pCur) );
+-  assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
++  assert( cursorOwnsBtShared(pCur) );
++  assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
+   assert( pCur->info.nSize>0 );
+   assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
+   assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
+@@ -57532,10 +67667,7 @@
+ ** These routines is used to get quick access to key and data
+ ** in the common case where no overflow pages are used.
+ */
+-SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, u32 *pAmt){
+-  return fetchPayload(pCur, pAmt);
+-}
+-SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){
++SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){
+   return fetchPayload(pCur, pAmt);
+ }
+ 
+@@ -57550,34 +67682,24 @@
+ ** vice-versa).
+ */
+ static int moveToChild(BtCursor *pCur, u32 newPgno){
+-  int rc;
+-  int i = pCur->iPage;
+-  MemPage *pNewPage;
+   BtShared *pBt = pCur->pBt;
+ 
+-  assert( cursorHoldsMutex(pCur) );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( pCur->eState==CURSOR_VALID );
+   assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
+   assert( pCur->iPage>=0 );
+   if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
+     return SQLITE_CORRUPT_BKPT;
+   }
+-  rc = getAndInitPage(pBt, newPgno, &pNewPage,
+-               (pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0);
+-  if( rc ) return rc;
+-  pCur->apPage[i+1] = pNewPage;
+-  pCur->aiIdx[i+1] = 0;
+-  pCur->iPage++;
+-
+   pCur->info.nSize = 0;
+   pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
+-  if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){
+-    return SQLITE_CORRUPT_BKPT;
+-  }
+-  return SQLITE_OK;
++  pCur->aiIdx[pCur->iPage++] = pCur->ix;
++  pCur->ix = 0;
++  return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage],
++                        pCur, pCur->curPagerFlags);
+ }
+ 
+-#if SQLITE_DEBUG
++#ifdef SQLITE_DEBUG
+ /*
+ ** Page pParent is an internal (non-leaf) tree page. This function 
+ ** asserts that page number iChild is the left-child if the iIdx'th
+@@ -57608,7 +67730,7 @@
+ ** the largest cell index.
+ */
+ static void moveToParent(BtCursor *pCur){
+-  assert( cursorHoldsMutex(pCur) );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( pCur->eState==CURSOR_VALID );
+   assert( pCur->iPage>0 );
+   assert( pCur->apPage[pCur->iPage] );
+@@ -57618,11 +67740,10 @@
+     pCur->apPage[pCur->iPage]->pgno
+   );
+   testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
+-
+-  releasePage(pCur->apPage[pCur->iPage]);
+-  pCur->iPage--;
+   pCur->info.nSize = 0;
+   pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
++  pCur->ix = pCur->aiIdx[pCur->iPage-1];
++  releasePageNotNull(pCur->apPage[pCur->iPage--]);
+ }
+ 
+ /*
+@@ -57650,7 +67771,7 @@
+   MemPage *pRoot;
+   int rc = SQLITE_OK;
+ 
+-  assert( cursorHoldsMutex(pCur) );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
+   assert( CURSOR_VALID   < CURSOR_REQUIRESEEK );
+   assert( CURSOR_FAULT   > CURSOR_REQUIRESEEK );
+@@ -57663,18 +67784,26 @@
+   }
+ 
+   if( pCur->iPage>=0 ){
+-    while( pCur->iPage ) releasePage(pCur->apPage[pCur->iPage--]);
++    if( pCur->iPage ){
++      do{
++        assert( pCur->apPage[pCur->iPage]!=0 );
++        releasePageNotNull(pCur->apPage[pCur->iPage--]);
++      }while( pCur->iPage);
++      goto skip_init;
++    }
+   }else if( pCur->pgnoRoot==0 ){
+     pCur->eState = CURSOR_INVALID;
+     return SQLITE_OK;
+   }else{
++    assert( pCur->iPage==(-1) );
+     rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0],
+-                 (pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0);
++                        0, pCur->curPagerFlags);
+     if( rc!=SQLITE_OK ){
+       pCur->eState = CURSOR_INVALID;
+-      return rc;
++       return rc;
+     }
+     pCur->iPage = 0;
++    pCur->curIntKey = pCur->apPage[0]->intKey;
+   }
+   pRoot = pCur->apPage[0];
+   assert( pRoot->pgno==pCur->pgnoRoot );
+@@ -57691,13 +67820,15 @@
+   ** (or the freelist).  */
+   assert( pRoot->intKey==1 || pRoot->intKey==0 );
+   if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
+-    return SQLITE_CORRUPT_BKPT;
++    return SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno);
+   }
+ 
+-  pCur->aiIdx[0] = 0;
++skip_init:  
++  pCur->ix = 0;
+   pCur->info.nSize = 0;
+   pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
+ 
++  pRoot = pCur->apPage[0];
+   if( pRoot->nCell>0 ){
+     pCur->eState = CURSOR_VALID;
+   }else if( !pRoot->leaf ){
+@@ -57724,11 +67855,11 @@
+   int rc = SQLITE_OK;
+   MemPage *pPage;
+ 
+-  assert( cursorHoldsMutex(pCur) );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( pCur->eState==CURSOR_VALID );
+   while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
+-    assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
+-    pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage]));
++    assert( pCur->ix<pPage->nCell );
++    pgno = get4byte(findCell(pPage, pCur->ix));
+     rc = moveToChild(pCur, pgno);
+   }
+   return rc;
+@@ -57749,15 +67880,15 @@
+   int rc = SQLITE_OK;
+   MemPage *pPage = 0;
+ 
+-  assert( cursorHoldsMutex(pCur) );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( pCur->eState==CURSOR_VALID );
+   while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
+     pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
+-    pCur->aiIdx[pCur->iPage] = pPage->nCell;
++    pCur->ix = pPage->nCell;
+     rc = moveToChild(pCur, pgno);
+     if( rc ) return rc;
+   }
+-  pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
++  pCur->ix = pPage->nCell-1;
+   assert( pCur->info.nSize==0 );
+   assert( (pCur->curFlags & BTCF_ValidNKey)==0 );
+   return SQLITE_OK;
+@@ -57770,7 +67901,7 @@
+ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
+   int rc;
+ 
+-  assert( cursorHoldsMutex(pCur) );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
+   rc = moveToRoot(pCur);
+   if( rc==SQLITE_OK ){
+@@ -57793,7 +67924,7 @@
+ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
+   int rc;
+  
+-  assert( cursorHoldsMutex(pCur) );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
+ 
+   /* If the cursor already points to the last entry, this is a no-op. */
+@@ -57805,7 +67936,7 @@
+     for(ii=0; ii<pCur->iPage; ii++){
+       assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
+     }
+-    assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 );
++    assert( pCur->ix==pCur->apPage[pCur->iPage]->nCell-1 );
+     assert( pCur->apPage[pCur->iPage]->leaf );
+ #endif
+     return SQLITE_OK;
+@@ -57858,6 +67989,8 @@
+ **     *pRes>0      The cursor is left pointing at an entry that
+ **                  is larger than intKey/pIdxKey.
+ **
++** For index tables, the pIdxKey->eqSeen field is set to 1 if there
++** exists an entry in the table that exactly matches pIdxKey.  
+ */
+ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
+   BtCursor *pCur,          /* The cursor to be moved */
+@@ -57869,23 +68002,44 @@
+   int rc;
+   RecordCompare xRecordCompare;
+ 
+-  assert( cursorHoldsMutex(pCur) );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
+   assert( pRes );
+   assert( (pIdxKey==0)==(pCur->pKeyInfo==0) );
++  assert( pCur->eState!=CURSOR_VALID || (pIdxKey==0)==(pCur->curIntKey!=0) );
+ 
+   /* If the cursor is already positioned at the point we are trying
+   ** to move to, then just return without doing any work */
+-  if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0
+-   && pCur->apPage[0]->intKey 
++  if( pIdxKey==0
++   && pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0
+   ){
+     if( pCur->info.nKey==intKey ){
+       *pRes = 0;
+       return SQLITE_OK;
+     }
+-    if( (pCur->curFlags & BTCF_AtLast)!=0 && pCur->info.nKey<intKey ){
+-      *pRes = -1;
+-      return SQLITE_OK;
++    if( pCur->info.nKey<intKey ){
++      if( (pCur->curFlags & BTCF_AtLast)!=0 ){
++        *pRes = -1;
++        return SQLITE_OK;
++      }
++      /* If the requested key is one more than the previous key, then
++      ** try to get there using sqlite3BtreeNext() rather than a full
++      ** binary search.  This is an optimization only.  The correct answer
++      ** is still obtained without this case, only a little more slowely */
++      if( pCur->info.nKey+1==intKey && !pCur->skipNext ){
++        *pRes = 0;
++        rc = sqlite3BtreeNext(pCur, 0);
++        if( rc==SQLITE_OK ){
++          getCellInfo(pCur);
++          if( pCur->info.nKey==intKey ){
++            return SQLITE_OK;
++          }
++        }else if( rc==SQLITE_DONE ){
++          rc = SQLITE_OK;
++        }else{
++          return rc;
++        }
++      }
+     }
+   }
+ 
+@@ -57912,7 +68066,8 @@
+     assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
+     return SQLITE_OK;
+   }
+-  assert( pCur->apPage[0]->intKey || pIdxKey );
++  assert( pCur->apPage[0]->intKey==pCur->curIntKey );
++  assert( pCur->curIntKey || pIdxKey );
+   for(;;){
+     int lwr, upr, idx, c;
+     Pgno chldPg;
+@@ -57931,14 +68086,16 @@
+     upr = pPage->nCell-1;
+     assert( biasRight==0 || biasRight==1 );
+     idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
+-    pCur->aiIdx[pCur->iPage] = (u16)idx;
++    pCur->ix = (u16)idx;
+     if( xRecordCompare==0 ){
+       for(;;){
+         i64 nCellKey;
+-        pCell = findCell(pPage, idx) + pPage->childPtrSize;
++        pCell = findCellPastPtr(pPage, idx);
+         if( pPage->intKeyLeaf ){
+           while( 0x80 <= *(pCell++) ){
+-            if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
++            if( pCell>=pPage->aDataEnd ){
++              return SQLITE_CORRUPT_PGNO(pPage->pgno);
++            }
+           }
+         }
+         getVarint(pCell, (u64*)&nCellKey);
+@@ -57950,16 +68107,16 @@
+           if( lwr>upr ){ c = +1; break; }
+         }else{
+           assert( nCellKey==intKey );
+-          pCur->curFlags |= BTCF_ValidNKey;
+-          pCur->info.nKey = nCellKey;
+-          pCur->aiIdx[pCur->iPage] = (u16)idx;
++          pCur->ix = (u16)idx;
+           if( !pPage->leaf ){
+             lwr = idx;
+             goto moveto_next_layer;
+           }else{
++            pCur->curFlags |= BTCF_ValidNKey;
++            pCur->info.nKey = nCellKey;
++            pCur->info.nSize = 0;
+             *pRes = 0;
+-            rc = SQLITE_OK;
+-            goto moveto_finish;
++            return SQLITE_OK;
+           }
+         }
+         assert( lwr+upr>=0 );
+@@ -57967,8 +68124,8 @@
+       }
+     }else{
+       for(;;){
+-        int nCell;
+-        pCell = findCell(pPage, idx) + pPage->childPtrSize;
++        int nCell;  /* Size of the pCell cell in bytes */
++        pCell = findCellPastPtr(pPage, idx);
+ 
+         /* The maximum supported page-size is 65536 bytes. This means that
+         ** the maximum number of record bytes stored on an index B-Tree
+@@ -57996,18 +68153,32 @@
+           /* The record flows over onto one or more overflow pages. In
+           ** this case the whole cell needs to be parsed, a buffer allocated
+           ** and accessPayload() used to retrieve the record into the
+-          ** buffer before VdbeRecordCompare() can be called. */
++          ** buffer before VdbeRecordCompare() can be called. 
++          **
++          ** If the record is corrupt, the xRecordCompare routine may read
++          ** up to two varints past the end of the buffer. An extra 18 
++          ** bytes of padding is allocated at the end of the buffer in
++          ** case this happens.  */
+           void *pCellKey;
+           u8 * const pCellBody = pCell - pPage->childPtrSize;
+-          btreeParseCellPtr(pPage, pCellBody, &pCur->info);
++          pPage->xParseCell(pPage, pCellBody, &pCur->info);
+           nCell = (int)pCur->info.nKey;
+-          pCellKey = sqlite3Malloc( nCell );
++          testcase( nCell<0 );   /* True if key size is 2^32 or more */
++          testcase( nCell==0 );  /* Invalid key size:  0x80 0x80 0x00 */
++          testcase( nCell==1 );  /* Invalid key size:  0x80 0x80 0x01 */
++          testcase( nCell==2 );  /* Minimum legal index key size */
++          if( nCell<2 ){
++            rc = SQLITE_CORRUPT_PGNO(pPage->pgno);
++            goto moveto_finish;
++          }
++          pCellKey = sqlite3Malloc( nCell+18 );
+           if( pCellKey==0 ){
+-            rc = SQLITE_NOMEM;
++            rc = SQLITE_NOMEM_BKPT;
+             goto moveto_finish;
+           }
+-          pCur->aiIdx[pCur->iPage] = (u16)idx;
+-          rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2);
++          pCur->ix = (u16)idx;
++          rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
++          pCur->curFlags &= ~BTCF_ValidOvfl;
+           if( rc ){
+             sqlite3_free(pCellKey);
+             goto moveto_finish;
+@@ -58027,7 +68198,7 @@
+           assert( c==0 );
+           *pRes = 0;
+           rc = SQLITE_OK;
+-          pCur->aiIdx[pCur->iPage] = (u16)idx;
++          pCur->ix = (u16)idx;
+           if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
+           goto moveto_finish;
+         }
+@@ -58039,8 +68210,8 @@
+     assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
+     assert( pPage->isInit );
+     if( pPage->leaf ){
+-      assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
+-      pCur->aiIdx[pCur->iPage] = (u16)idx;
++      assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
++      pCur->ix = (u16)idx;
+       *pRes = c;
+       rc = SQLITE_OK;
+       goto moveto_finish;
+@@ -58051,13 +68222,13 @@
+     }else{
+       chldPg = get4byte(findCell(pPage, lwr));
+     }
+-    pCur->aiIdx[pCur->iPage] = (u16)lwr;
++    pCur->ix = (u16)lwr;
+     rc = moveToChild(pCur, chldPg);
+     if( rc ) break;
+   }
+ moveto_finish:
+   pCur->info.nSize = 0;
+-  pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
++  assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
+   return rc;
+ }
+ 
+@@ -58078,10 +68249,36 @@
+ }
+ 
+ /*
+-** Advance the cursor to the next entry in the database.  If
+-** successful then set *pRes=0.  If the cursor
+-** was already pointing to the last entry in the database before
+-** this routine was called, then set *pRes=1.
++** Return an estimate for the number of rows in the table that pCur is
++** pointing to.  Return a negative number if no estimate is currently 
++** available.
++*/
++SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){
++  i64 n;
++  u8 i;
++
++  assert( cursorOwnsBtShared(pCur) );
++  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
++
++  /* Currently this interface is only called by the OP_IfSmaller
++  ** opcode, and it that case the cursor will always be valid and
++  ** will always point to a leaf node. */
++  if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1;
++  if( NEVER(pCur->apPage[pCur->iPage]->leaf==0) ) return -1;
++
++  for(n=1, i=0; i<=pCur->iPage; i++){
++    n *= pCur->apPage[i]->nCell;
++  }
++  return n;
++}
++
++/*
++** Advance the cursor to the next entry in the database. 
++** Return value:
++**
++**    SQLITE_OK        success
++**    SQLITE_DONE      cursor is already pointing at the last element
++**    otherwise        some kind of error occurred
+ **
+ ** The main entry point is sqlite3BtreeNext().  That routine is optimized
+ ** for the common case of merely incrementing the cell counter BtCursor.aiIdx
+@@ -58089,23 +68286,19 @@
+ ** routine is called when it is necessary to move to a different page or
+ ** to restore the cursor.
+ **
+-** The calling function will set *pRes to 0 or 1.  The initial *pRes value
+-** will be 1 if the cursor being stepped corresponds to an SQL index and
+-** if this routine could have been skipped if that SQL index had been
+-** a unique index.  Otherwise the caller will have set *pRes to zero.
+-** Zero is the common case. The btree implementation is free to use the
+-** initial *pRes value as a hint to improve performance, but the current
+-** SQLite btree implementation does not. (Note that the comdb2 btree
+-** implementation does use this hint, however.)
++** If bit 0x01 of the F argument in sqlite3BtreeNext(C,F) is 1, then the
++** cursor corresponds to an SQL index and this routine could have been
++** skipped if the SQL index had been a unique index.  The F argument
++** is a hint to the implement.  SQLite btree implementation does not use
++** this hint, but COMDB2 does.
+ */
+-static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
++static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
+   int rc;
+   int idx;
+   MemPage *pPage;
+ 
+-  assert( cursorHoldsMutex(pCur) );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+-  assert( *pRes==0 );
+   if( pCur->eState!=CURSOR_VALID ){
+     assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
+     rc = restoreCursorPosition(pCur);
+@@ -58113,8 +68306,7 @@
+       return rc;
+     }
+     if( CURSOR_INVALID==pCur->eState ){
+-      *pRes = 1;
+-      return SQLITE_OK;
++      return SQLITE_DONE;
+     }
+     if( pCur->skipNext ){
+       assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+@@ -58128,7 +68320,7 @@
+   }
+ 
+   pPage = pCur->apPage[pCur->iPage];
+-  idx = ++pCur->aiIdx[pCur->iPage];
++  idx = ++pCur->ix;
+   assert( pPage->isInit );
+ 
+   /* If the database file is corrupt, it is possible for the value of idx 
+@@ -58146,15 +68338,14 @@
+     }
+     do{
+       if( pCur->iPage==0 ){
+-        *pRes = 1;
+         pCur->eState = CURSOR_INVALID;
+-        return SQLITE_OK;
++        return SQLITE_DONE;
+       }
+       moveToParent(pCur);
+       pPage = pCur->apPage[pCur->iPage];
+-    }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
++    }while( pCur->ix>=pPage->nCell );
+     if( pPage->intKey ){
+-      return sqlite3BtreeNext(pCur, pRes);
++      return sqlite3BtreeNext(pCur, 0);
+     }else{
+       return SQLITE_OK;
+     }
+@@ -58165,20 +68356,19 @@
+     return moveToLeftmost(pCur);
+   }
+ }
+-SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
++SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int flags){
+   MemPage *pPage;
+-  assert( cursorHoldsMutex(pCur) );
+-  assert( pRes!=0 );
+-  assert( *pRes==0 || *pRes==1 );
++  UNUSED_PARAMETER( flags );  /* Used in COMDB2 but not native SQLite */
++  assert( cursorOwnsBtShared(pCur) );
++  assert( flags==0 || flags==1 );
+   assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+   pCur->info.nSize = 0;
+   pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
+-  *pRes = 0;
+-  if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes);
++  if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur);
+   pPage = pCur->apPage[pCur->iPage];
+-  if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){
+-    pCur->aiIdx[pCur->iPage]--;
+-    return btreeNext(pCur, pRes);
++  if( (++pCur->ix)>=pPage->nCell ){
++    pCur->ix--;
++    return btreeNext(pCur);
+   }
+   if( pPage->leaf ){
+     return SQLITE_OK;
+@@ -58188,10 +68378,12 @@
+ }
+ 
+ /*
+-** Step the cursor to the back to the previous entry in the database.  If
+-** successful then set *pRes=0.  If the cursor
+-** was already pointing to the first entry in the database before
+-** this routine was called, then set *pRes=1.
++** Step the cursor to the back to the previous entry in the database.
++** Return values:
++**
++**     SQLITE_OK     success
++**     SQLITE_DONE   the cursor is already on the first element of the table
++**     otherwise     some kind of error occurred
+ **
+ ** The main entry point is sqlite3BtreePrevious().  That routine is optimized
+ ** for the common case of merely decrementing the cell counter BtCursor.aiIdx
+@@ -58199,22 +68391,17 @@
+ ** helper routine is called when it is necessary to move to a different page
+ ** or to restore the cursor.
+ **
+-** The calling function will set *pRes to 0 or 1.  The initial *pRes value
+-** will be 1 if the cursor being stepped corresponds to an SQL index and
+-** if this routine could have been skipped if that SQL index had been
+-** a unique index.  Otherwise the caller will have set *pRes to zero.
+-** Zero is the common case. The btree implementation is free to use the
+-** initial *pRes value as a hint to improve performance, but the current
+-** SQLite btree implementation does not. (Note that the comdb2 btree
+-** implementation does use this hint, however.)
++** If bit 0x01 of the F argument to sqlite3BtreePrevious(C,F) is 1, then
++** the cursor corresponds to an SQL index and this routine could have been
++** skipped if the SQL index had been a unique index.  The F argument is a
++** hint to the implement.  The native SQLite btree implementation does not
++** use this hint, but COMDB2 does.
+ */
+-static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
++static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
+   int rc;
+   MemPage *pPage;
+ 
+-  assert( cursorHoldsMutex(pCur) );
+-  assert( pRes!=0 );
+-  assert( *pRes==0 );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+   assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
+   assert( pCur->info.nSize==0 );
+@@ -58224,8 +68411,7 @@
+       return rc;
+     }
+     if( CURSOR_INVALID==pCur->eState ){
+-      *pRes = 1;
+-      return SQLITE_OK;
++      return SQLITE_DONE;
+     }
+     if( pCur->skipNext ){
+       assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+@@ -58241,47 +68427,45 @@
+   pPage = pCur->apPage[pCur->iPage];
+   assert( pPage->isInit );
+   if( !pPage->leaf ){
+-    int idx = pCur->aiIdx[pCur->iPage];
++    int idx = pCur->ix;
+     rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
+     if( rc ) return rc;
+     rc = moveToRightmost(pCur);
+   }else{
+-    while( pCur->aiIdx[pCur->iPage]==0 ){
++    while( pCur->ix==0 ){
+       if( pCur->iPage==0 ){
+         pCur->eState = CURSOR_INVALID;
+-        *pRes = 1;
+-        return SQLITE_OK;
++        return SQLITE_DONE;
+       }
+       moveToParent(pCur);
+     }
+     assert( pCur->info.nSize==0 );
+-    assert( (pCur->curFlags & (BTCF_ValidNKey|BTCF_ValidOvfl))==0 );
++    assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 );
+ 
+-    pCur->aiIdx[pCur->iPage]--;
++    pCur->ix--;
+     pPage = pCur->apPage[pCur->iPage];
+     if( pPage->intKey && !pPage->leaf ){
+-      rc = sqlite3BtreePrevious(pCur, pRes);
++      rc = sqlite3BtreePrevious(pCur, 0);
+     }else{
+       rc = SQLITE_OK;
+     }
+   }
+   return rc;
+ }
+-SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
+-  assert( cursorHoldsMutex(pCur) );
+-  assert( pRes!=0 );
+-  assert( *pRes==0 || *pRes==1 );
++SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int flags){
++  assert( cursorOwnsBtShared(pCur) );
++  assert( flags==0 || flags==1 );
+   assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+-  *pRes = 0;
++  UNUSED_PARAMETER( flags );  /* Used in COMDB2 but not native SQLite */
+   pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
+   pCur->info.nSize = 0;
+   if( pCur->eState!=CURSOR_VALID
+-   || pCur->aiIdx[pCur->iPage]==0
++   || pCur->ix==0
+    || pCur->apPage[pCur->iPage]->leaf==0
+   ){
+-    return btreePrevious(pCur, pRes);
++    return btreePrevious(pCur);
+   }
+-  pCur->aiIdx[pCur->iPage]--;
++  pCur->ix--;
+   return SQLITE_OK;
+ }
+ 
+@@ -58294,8 +68478,7 @@
+ ** sqlite3PagerUnref() on the new page when it is done.
+ **
+ ** SQLITE_OK is returned on success.  Any other return value indicates
+-** an error.  *ppPage and *pPgno are undefined in the event of an error.
+-** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned.
++** an error.  *ppPage is set to NULL in the event of an error.
+ **
+ ** If the "nearby" parameter is not 0, then an effort is made to 
+ ** locate a page close to the page number "nearby".  This can be used in an
+@@ -58338,6 +68521,7 @@
+     /* There are pages on the freelist.  Reuse one of those pages. */
+     Pgno iTrunk;
+     u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
++    u32 nSearch = 0;   /* Count of the number of search attempts */
+     
+     /* If eMode==BTALLOC_EXACT and a query of the pointer-map
+     ** shows that the page 'nearby' is somewhere on the free-list, then
+@@ -58386,10 +68570,10 @@
+         iTrunk = get4byte(&pPage1->aData[32]);
+       }
+       testcase( iTrunk==mxPage );
+-      if( iTrunk>mxPage ){
+-        rc = SQLITE_CORRUPT_BKPT;
++      if( iTrunk>mxPage || nSearch++ > n ){
++        rc = SQLITE_CORRUPT_PGNO(pPrevTrunk ? pPrevTrunk->pgno : 1);
+       }else{
+-        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
++        rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0);
+       }
+       if( rc ){
+         pTrunk = 0;
+@@ -58416,7 +68600,7 @@
+         TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
+       }else if( k>(u32)(pBt->usableSize/4 - 2) ){
+         /* Value of k is out of range.  Database corruption */
+-        rc = SQLITE_CORRUPT_BKPT;
++        rc = SQLITE_CORRUPT_PGNO(iTrunk);
+         goto end_allocate_page;
+ #ifndef SQLITE_OMIT_AUTOVACUUM
+       }else if( searchList 
+@@ -58450,11 +68634,11 @@
+           MemPage *pNewTrunk;
+           Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
+           if( iNewTrunk>mxPage ){ 
+-            rc = SQLITE_CORRUPT_BKPT;
++            rc = SQLITE_CORRUPT_PGNO(iTrunk);
+             goto end_allocate_page;
+           }
+           testcase( iNewTrunk==mxPage );
+-          rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
++          rc = btreeGetUnusedPage(pBt, iNewTrunk, &pNewTrunk, 0);
+           if( rc!=SQLITE_OK ){
+             goto end_allocate_page;
+           }
+@@ -58515,7 +68699,7 @@
+         iPage = get4byte(&aData[8+closest*4]);
+         testcase( iPage==mxPage );
+         if( iPage>mxPage ){
+-          rc = SQLITE_CORRUPT_BKPT;
++          rc = SQLITE_CORRUPT_PGNO(iTrunk);
+           goto end_allocate_page;
+         }
+         testcase( iPage==mxPage );
+@@ -58534,11 +68718,12 @@
+           }
+           put4byte(&aData[4], k-1);
+           noContent = !btreeGetHasContent(pBt, *pPgno)? PAGER_GET_NOCONTENT : 0;
+-          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
++          rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, noContent);
+           if( rc==SQLITE_OK ){
+             rc = sqlite3PagerWrite((*ppPage)->pDbPage);
+             if( rc!=SQLITE_OK ){
+               releasePage(*ppPage);
++              *ppPage = 0;
+             }
+           }
+           searchList = 0;
+@@ -58582,7 +68767,7 @@
+       MemPage *pPg = 0;
+       TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
+       assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
+-      rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent);
++      rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent);
+       if( rc==SQLITE_OK ){
+         rc = sqlite3PagerWrite(pPg->pDbPage);
+         releasePage(pPg);
+@@ -58596,11 +68781,12 @@
+     *pPgno = pBt->nPage;
+ 
+     assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
+-    rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent);
++    rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, bNoContent);
+     if( rc ) return rc;
+     rc = sqlite3PagerWrite((*ppPage)->pDbPage);
+     if( rc!=SQLITE_OK ){
+       releasePage(*ppPage);
++      *ppPage = 0;
+     }
+     TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
+   }
+@@ -58610,17 +68796,8 @@
+ end_allocate_page:
+   releasePage(pTrunk);
+   releasePage(pPrevTrunk);
+-  if( rc==SQLITE_OK ){
+-    if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
+-      releasePage(*ppPage);
+-      *ppPage = 0;
+-      return SQLITE_CORRUPT_BKPT;
+-    }
+-    (*ppPage)->isInit = 0;
+-  }else{
+-    *ppPage = 0;
+-  }
+-  assert( rc!=SQLITE_OK || sqlite3PagerIswriteable((*ppPage)->pDbPage) );
++  assert( rc!=SQLITE_OK || sqlite3PagerPageRefcount((*ppPage)->pDbPage)<=1 );
++  assert( rc!=SQLITE_OK || (*ppPage)->isInit==0 );
+   return rc;
+ }
+ 
+@@ -58645,9 +68822,10 @@
+   int nFree;                          /* Initial number of pages on free-list */
+ 
+   assert( sqlite3_mutex_held(pBt->mutex) );
+-  assert( iPage>1 );
++  assert( CORRUPT_DB || iPage>1 );
+   assert( !pMemPage || pMemPage->pgno==iPage );
+ 
++  if( iPage<2 ) return SQLITE_CORRUPT_BKPT;
+   if( pMemPage ){
+     pPage = pMemPage;
+     sqlite3PagerRef(pPage->pDbPage);
+@@ -58777,29 +68955,30 @@
+ static int clearCell(
+   MemPage *pPage,          /* The page that contains the Cell */
+   unsigned char *pCell,    /* First byte of the Cell */
+-  u16 *pnSize              /* Write the size of the Cell here */
++  CellInfo *pInfo          /* Size information about the cell */
+ ){
+   BtShared *pBt = pPage->pBt;
+-  CellInfo info;
+   Pgno ovflPgno;
+   int rc;
+   int nOvfl;
+   u32 ovflPageSize;
+ 
+   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+-  btreeParseCellPtr(pPage, pCell, &info);
+-  *pnSize = info.nSize;
+-  if( info.iOverflow==0 ){
++  pPage->xParseCell(pPage, pCell, pInfo);
++  if( pInfo->nLocal==pInfo->nPayload ){
+     return SQLITE_OK;  /* No overflow pages. Return without doing anything */
+   }
+-  if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
+-    return SQLITE_CORRUPT_BKPT;  /* Cell extends past end of page */
++  if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){
++    /* Cell extends past end of page */
++    return SQLITE_CORRUPT_PGNO(pPage->pgno);
+   }
+-  ovflPgno = get4byte(&pCell[info.iOverflow]);
++  ovflPgno = get4byte(pCell + pInfo->nSize - 4);
+   assert( pBt->usableSize > 4 );
+   ovflPageSize = pBt->usableSize - 4;
+-  nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
+-  assert( ovflPgno==0 || nOvfl>0 );
++  nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize;
++  assert( nOvfl>0 || 
++    (CORRUPT_DB && (pInfo->nPayload + ovflPageSize)<ovflPageSize)
++  );
+   while( nOvfl-- ){
+     Pgno iNext = 0;
+     MemPage *pOvfl = 0;
+@@ -58856,9 +69035,7 @@
+ static int fillInCell(
+   MemPage *pPage,                /* The page that contains the cell */
+   unsigned char *pCell,          /* Complete text of the cell */
+-  const void *pKey, i64 nKey,    /* The key */
+-  const void *pData,int nData,   /* The data */
+-  int nZero,                     /* Extra zero bytes to append to pData */
++  const BtreePayload *pX,        /* Payload with which to construct the cell */
+   int *pnSize                    /* Write cell size here */
+ ){
+   int nPayload;
+@@ -58882,28 +69059,21 @@
+ 
+   /* Fill in the header. */
+   nHeader = pPage->childPtrSize;
+-  nPayload = nData + nZero;
+-  if( pPage->intKeyLeaf ){
++  if( pPage->intKey ){
++    nPayload = pX->nData + pX->nZero;
++    pSrc = pX->pData;
++    nSrc = pX->nData;
++    assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */
+     nHeader += putVarint32(&pCell[nHeader], nPayload);
++    nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey);
+   }else{
+-    assert( nData==0 );
+-    assert( nZero==0 );
++    assert( pX->nKey<=0x7fffffff && pX->pKey!=0 );
++    nSrc = nPayload = (int)pX->nKey;
++    pSrc = pX->pKey;
++    nHeader += putVarint32(&pCell[nHeader], nPayload);
+   }
+-  nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
+   
+-  /* Fill in the payload size */
+-  if( pPage->intKey ){
+-    pSrc = pData;
+-    nSrc = nData;
+-    nData = 0;
+-  }else{ 
+-    if( NEVER(nKey>0x7fffffff || pKey==0) ){
+-      return SQLITE_CORRUPT_BKPT;
+-    }
+-    nPayload = (int)nKey;
+-    pSrc = pKey;
+-    nSrc = (int)nKey;
+-  }
++  /* Fill in the payload */
+   if( nPayload<=pPage->maxLocal ){
+     n = nHeader + nPayload;
+     testcase( n==3 );
+@@ -58936,15 +69106,14 @@
+   ** Use a call to btreeParseCellPtr() to verify that the values above
+   ** were computed correctly.
+   */
+-#if SQLITE_DEBUG
++#ifdef SQLITE_DEBUG
+   {
+     CellInfo info;
+-    btreeParseCellPtr(pPage, pCell, &info);
+-    assert( nHeader=(int)(info.pPayload - pCell) );
+-    assert( info.nKey==nKey );
++    pPage->xParseCell(pPage, pCell, &info);
++    assert( nHeader==(int)(info.pPayload - pCell) );
++    assert( info.nKey==pX->nKey );
+     assert( *pnSize == info.nSize );
+     assert( spaceLeft == info.nLocal );
+-    assert( pPrior == &pCell[info.iOverflow] );
+   }
+ #endif
+ 
+@@ -59027,10 +69196,6 @@
+     pSrc += n;
+     nSrc -= n;
+     spaceLeft -= n;
+-    if( nSrc==0 ){
+-      nSrc = nData;
+-      pSrc = pData;
+-    }
+   }
+   releasePage(pToRelease);
+   return SQLITE_OK;
+@@ -59052,9 +69217,8 @@
+   int hdr;        /* Beginning of the header.  0 most pages.  100 page 1 */
+ 
+   if( *pRC ) return;
+-
+   assert( idx>=0 && idx<pPage->nCell );
+-  assert( sz==cellSize(pPage, idx) );
++  assert( CORRUPT_DB || sz==cellSize(pPage, idx) );
+   assert( sqlite3PagerIswriteable(pPage->pDbPage) );
+   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+   data = pPage->aData;
+@@ -59097,6 +69261,8 @@
+ ** in pTemp or the original pCell) and also record its index. 
+ ** Allocating a new entry in pPage->aCell[] implies that 
+ ** pPage->nOverflow is incremented.
++**
++** *pRC must be SQLITE_OK when this routine is called.
+ */
+ static void insertCell(
+   MemPage *pPage,   /* Page into which we are copying */
+@@ -59109,13 +69275,10 @@
+ ){
+   int idx = 0;      /* Where to write new cell content in data[] */
+   int j;            /* Loop counter */
+-  int end;          /* First byte past the last cell pointer in data[] */
+-  int ins;          /* Index in data[] where new cell pointer is inserted */
+-  int cellOffset;   /* Address of first cell pointer in data[] */
+   u8 *data;         /* The content of the whole page */
++  u8 *pIns;         /* The point in pPage->aCellIdx[] where no cell inserted */
+ 
+-  if( *pRC ) return;
+-
++  assert( *pRC==SQLITE_OK );
+   assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
+   assert( MX_CELL(pPage->pBt)<=10921 );
+   assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB );
+@@ -59127,7 +69290,7 @@
+   ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
+   ** might be less than 8 (leaf-size + pointer) on the interior node.  Hence
+   ** the term after the || in the following assert(). */
+-  assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
++  assert( sz==pPage->xCellSize(pPage, pCell) || (sz==8 && iChild>0) );
+   if( pPage->nOverflow || sz+2>pPage->nFree ){
+     if( pTemp ){
+       memcpy(pTemp, pCell, sz);
+@@ -59137,9 +69300,20 @@
+       put4byte(pCell, iChild);
+     }
+     j = pPage->nOverflow++;
+-    assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) );
++    /* Comparison against ArraySize-1 since we hold back one extra slot
++    ** as a contingency.  In other words, never need more than 3 overflow
++    ** slots but 4 are allocated, just to be safe. */
++    assert( j < ArraySize(pPage->apOvfl)-1 );
+     pPage->apOvfl[j] = pCell;
+     pPage->aiOvfl[j] = (u16)i;
++
++    /* When multiple overflows occur, they are always sequential and in
++    ** sorted order.  This invariants arise because multiple overflows can
++    ** only occur when inserting divider cells into the parent page during
++    ** balancing, and the dividers are adjacent and sorted.
++    */
++    assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */
++    assert( j==0 || i==pPage->aiOvfl[j-1]+1 );   /* Overflows are sequential */
+   }else{
+     int rc = sqlite3PagerWrite(pPage->pDbPage);
+     if( rc!=SQLITE_OK ){
+@@ -59148,24 +69322,26 @@
+     }
+     assert( sqlite3PagerIswriteable(pPage->pDbPage) );
+     data = pPage->aData;
+-    cellOffset = pPage->cellOffset;
+-    end = cellOffset + 2*pPage->nCell;
+-    ins = cellOffset + 2*i;
++    assert( &data[pPage->cellOffset]==pPage->aCellIdx );
+     rc = allocateSpace(pPage, sz, &idx);
+     if( rc ){ *pRC = rc; return; }
+-    /* The allocateSpace() routine guarantees the following two properties
+-    ** if it returns success */
+-    assert( idx >= end+2 );
++    /* The allocateSpace() routine guarantees the following properties
++    ** if it returns successfully */
++    assert( idx >= 0 );
++    assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB );
+     assert( idx+sz <= (int)pPage->pBt->usableSize );
+-    pPage->nCell++;
+     pPage->nFree -= (u16)(2 + sz);
+     memcpy(&data[idx], pCell, sz);
+     if( iChild ){
+       put4byte(&data[idx], iChild);
+     }
+-    memmove(&data[ins+2], &data[ins], end-ins);
+-    put2byte(&data[ins], idx);
+-    put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
++    pIns = pPage->aCellIdx + i*2;
++    memmove(pIns+2, pIns, 2*(pPage->nCell - i));
++    put2byte(pIns, idx);
++    pPage->nCell++;
++    /* increment the cell count */
++    if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++;
++    assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell );
+ #ifndef SQLITE_OMIT_AUTOVACUUM
+     if( pPage->pBt->autoVacuum ){
+       /* The cell may contain a pointer to an overflow page. If so, write
+@@ -59178,6 +69354,52 @@
+ }
+ 
+ /*
++** A CellArray object contains a cache of pointers and sizes for a
++** consecutive sequence of cells that might be held on multiple pages.
++*/
++typedef struct CellArray CellArray;
++struct CellArray {
++  int nCell;              /* Number of cells in apCell[] */
++  MemPage *pRef;          /* Reference page */
++  u8 **apCell;            /* All cells begin balanced */
++  u16 *szCell;            /* Local size of all cells in apCell[] */
++};
++
++/*
++** Make sure the cell sizes at idx, idx+1, ..., idx+N-1 have been
++** computed.
++*/
++static void populateCellCache(CellArray *p, int idx, int N){
++  assert( idx>=0 && idx+N<=p->nCell );
++  while( N>0 ){
++    assert( p->apCell[idx]!=0 );
++    if( p->szCell[idx]==0 ){
++      p->szCell[idx] = p->pRef->xCellSize(p->pRef, p->apCell[idx]);
++    }else{
++      assert( CORRUPT_DB ||
++              p->szCell[idx]==p->pRef->xCellSize(p->pRef, p->apCell[idx]) );
++    }
++    idx++;
++    N--;
++  }
++}
++
++/*
++** Return the size of the Nth element of the cell array
++*/
++static SQLITE_NOINLINE u16 computeCellSize(CellArray *p, int N){
++  assert( N>=0 && N<p->nCell );
++  assert( p->szCell[N]==0 );
++  p->szCell[N] = p->pRef->xCellSize(p->pRef, p->apCell[N]);
++  return p->szCell[N];
++}
++static u16 cachedCellSize(CellArray *p, int N){
++  assert( N>=0 && N<p->nCell );
++  if( p->szCell[N] ) return p->szCell[N];
++  return computeCellSize(p, N);
++}
++
++/*
+ ** Array apCell[] contains pointers to nCell b-tree page cells. The 
+ ** szCell[] array contains the size in bytes of each cell. This function
+ ** replaces the current contents of page pPg with the contents of the cell
+@@ -59190,7 +69412,7 @@
+ ** The MemPage.nFree field is invalidated by this function. It is the 
+ ** responsibility of the caller to set it correctly.
+ */
+-static void rebuildPage(
++static int rebuildPage(
+   MemPage *pPg,                   /* Edit this page */
+   int nCell,                      /* Final number of cells on page */
+   u8 **apCell,                    /* Array of cells */
+@@ -59211,14 +69433,16 @@
+   pData = pEnd;
+   for(i=0; i<nCell; i++){
+     u8 *pCell = apCell[i];
+-    if( pCell>aData && pCell<pEnd ){
++    if( SQLITE_WITHIN(pCell,aData,pEnd) ){
+       pCell = &pTmp[pCell - aData];
+     }
+     pData -= szCell[i];
+-    memcpy(pData, pCell, szCell[i]);
+     put2byte(pCellptr, (pData - aData));
+     pCellptr += 2;
+-    assert( szCell[i]==cellSizePtr(pPg, pCell) );
++    if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
++    memcpy(pData, pCell, szCell[i]);
++    assert( szCell[i]==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
++    testcase( szCell[i]!=pPg->xCellSize(pPg,pCell) );
+   }
+ 
+   /* The pPg->nFree field is now set incorrectly. The caller will fix it. */
+@@ -59229,6 +69453,7 @@
+   put2byte(&aData[hdr+3], pPg->nCell);
+   put2byte(&aData[hdr+5], pData - aData);
+   aData[hdr+7] = 0x00;
++  return SQLITE_OK;
+ }
+ 
+ /*
+@@ -59261,25 +69486,31 @@
+   u8 *pBegin,                     /* End of cell-pointer array */
+   u8 **ppData,                    /* IN/OUT: Page content -area pointer */
+   u8 *pCellptr,                   /* Pointer to cell-pointer area */
++  int iFirst,                     /* Index of first cell to add */
+   int nCell,                      /* Number of cells to add to pPg */
+-  u8 **apCell,                    /* Array of cells */
+-  u16 *szCell                     /* Array of cell sizes */
++  CellArray *pCArray              /* Array of cells */
+ ){
+   int i;
+   u8 *aData = pPg->aData;
+   u8 *pData = *ppData;
+-  const int bFreelist = aData[1] || aData[2];
++  int iEnd = iFirst + nCell;
+   assert( CORRUPT_DB || pPg->hdrOffset==0 );    /* Never called on page 1 */
+-  for(i=0; i<nCell; i++){
+-    int sz = szCell[i];
+-    int rc;
++  for(i=iFirst; i<iEnd; i++){
++    int sz, rc;
+     u8 *pSlot;
+-    if( bFreelist==0 || (pSlot = pageFindSlot(pPg, sz, &rc, 0))==0 ){
++    sz = cachedCellSize(pCArray, i);
++    if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
++      if( (pData - pBegin)<sz ) return 1;
+       pData -= sz;
+-      if( pData<pBegin ) return 1;
+       pSlot = pData;
+     }
+-    memcpy(pSlot, apCell[i], sz);
++    /* pSlot and pCArray->apCell[i] will never overlap on a well-formed
++    ** database.  But they might for a corrupt database.  Hence use memmove()
++    ** since memcpy() sends SIGABORT with overlapping buffers on OpenBSD */
++    assert( (pSlot+sz)<=pCArray->apCell[i]
++         || pSlot>=(pCArray->apCell[i]+sz)
++         || CORRUPT_DB );
++    memmove(pSlot, pCArray->apCell[i], sz);
+     put2byte(pCellptr, (pSlot - aData));
+     pCellptr += 2;
+   }
+@@ -59298,22 +69529,27 @@
+ */
+ static int pageFreeArray(
+   MemPage *pPg,                   /* Page to edit */
++  int iFirst,                     /* First cell to delete */
+   int nCell,                      /* Cells to delete */
+-  u8 **apCell,                    /* Array of cells */
+-  u16 *szCell                     /* Array of cell sizes */
++  CellArray *pCArray              /* Array of cells */
+ ){
+   u8 * const aData = pPg->aData;
+   u8 * const pEnd = &aData[pPg->pBt->usableSize];
+   u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize];
+   int nRet = 0;
+   int i;
++  int iEnd = iFirst + nCell;
+   u8 *pFree = 0;
+   int szFree = 0;
+ 
+-  for(i=0; i<nCell; i++){
+-    u8 *pCell = apCell[i];
+-    if( pCell>=pStart && pCell<pEnd ){
+-      int sz = szCell[i];
++  for(i=iFirst; i<iEnd; i++){
++    u8 *pCell = pCArray->apCell[i];
++    if( SQLITE_WITHIN(pCell, pStart, pEnd) ){
++      int sz;
++      /* No need to use cachedCellSize() here.  The sizes of all cells that
++      ** are to be freed have already been computing while deciding which
++      ** cells need freeing */
++      sz = pCArray->szCell[i];  assert( sz>0 );
+       if( pFree!=(pCell + sz) ){
+         if( pFree ){
+           assert( pFree>aData && (pFree - aData)<65536 );
+@@ -59348,13 +69584,12 @@
+ ** The pPg->nFree field is invalid when this function returns. It is the
+ ** responsibility of the caller to set it correctly.
+ */
+-static void editPage(
++static int editPage(
+   MemPage *pPg,                   /* Edit this page */
+   int iOld,                       /* Index of first cell currently on page */
+   int iNew,                       /* Index of new first cell on page */
+   int nNew,                       /* Final number of cells on page */
+-  u8 **apCell,                    /* Array of cells */
+-  u16 *szCell                     /* Array of cell sizes */
++  CellArray *pCArray              /* Array of cells and sizes */
+ ){
+   u8 * const aData = pPg->aData;
+   const int hdr = pPg->hdrOffset;
+@@ -59373,16 +69608,12 @@
+ 
+   /* Remove cells from the start and end of the page */
+   if( iOld<iNew ){
+-    int nShift = pageFreeArray(
+-        pPg, iNew-iOld, &apCell[iOld], &szCell[iOld]
+-    );
++    int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
+     memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
+     nCell -= nShift;
+   }
+   if( iNewEnd < iOldEnd ){
+-    nCell -= pageFreeArray(
+-        pPg, iOldEnd-iNewEnd, &apCell[iNewEnd], &szCell[iNewEnd]
+-    );
++    nCell -= pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
+   }
+ 
+   pData = &aData[get2byteNotZero(&aData[hdr+5])];
+@@ -59396,7 +69627,7 @@
+     memmove(&pCellptr[nAdd*2], pCellptr, nCell*2);
+     if( pageInsertArray(
+           pPg, pBegin, &pData, pCellptr,
+-          nAdd, &apCell[iNew], &szCell[iNew]
++          iNew, nAdd, pCArray
+     ) ) goto editpage_fail;
+     nCell += nAdd;
+   }
+@@ -59410,7 +69641,7 @@
+       nCell++;
+       if( pageInsertArray(
+             pPg, pBegin, &pData, pCellptr,
+-            1, &apCell[iCell + iNew], &szCell[iCell + iNew]
++            iCell+iNew, 1, pCArray
+       ) ) goto editpage_fail;
+     }
+   }
+@@ -59419,7 +69650,7 @@
+   pCellptr = &pPg->aCellIdx[nCell*2];
+   if( pageInsertArray(
+         pPg, pBegin, &pData, pCellptr,
+-        nNew-nCell, &apCell[iNew+nCell], &szCell[iNew+nCell]
++        iNew+nCell, nNew-nCell, pCArray
+   ) ) goto editpage_fail;
+ 
+   pPg->nCell = nNew;
+@@ -59430,19 +69661,21 @@
+ 
+ #ifdef SQLITE_DEBUG
+   for(i=0; i<nNew && !CORRUPT_DB; i++){
+-    u8 *pCell = apCell[i+iNew];
+-    int iOff = get2byte(&pPg->aCellIdx[i*2]);
+-    if( pCell>=aData && pCell<&aData[pPg->pBt->usableSize] ){
++    u8 *pCell = pCArray->apCell[i+iNew];
++    int iOff = get2byteAligned(&pPg->aCellIdx[i*2]);
++    if( SQLITE_WITHIN(pCell, aData, &aData[pPg->pBt->usableSize]) ){
+       pCell = &pTmp[pCell - aData];
+     }
+-    assert( 0==memcmp(pCell, &aData[iOff], szCell[i+iNew]) );
++    assert( 0==memcmp(pCell, &aData[iOff],
++            pCArray->pRef->xCellSize(pCArray->pRef, pCArray->apCell[i+iNew])) );
+   }
+ #endif
+ 
+-  return;
++  return SQLITE_OK;
+  editpage_fail:
+   /* Unable to edit this page. Rebuild it from scratch instead. */
+-  rebuildPage(pPg, nNew, &apCell[iNew], &szCell[iNew]);
++  populateCellCache(pCArray, iNew, nNew);
++  return rebuildPage(pPg, nNew, &pCArray->apCell[iNew], &pCArray->szCell[iNew]);
+ }
+ 
+ /*
+@@ -59508,13 +69741,14 @@
+ 
+     u8 *pOut = &pSpace[4];
+     u8 *pCell = pPage->apOvfl[0];
+-    u16 szCell = cellSizePtr(pPage, pCell);
++    u16 szCell = pPage->xCellSize(pPage, pCell);
+     u8 *pStop;
+ 
+     assert( sqlite3PagerIswriteable(pNew->pDbPage) );
+     assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
+     zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
+-    rebuildPage(pNew, 1, &pCell, &szCell);
++    rc = rebuildPage(pNew, 1, &pCell, &szCell);
++    if( NEVER(rc) ) return rc;
+     pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell;
+ 
+     /* If this is an auto-vacuum database, update the pointer map
+@@ -59553,8 +69787,10 @@
+     while( ((*(pOut++) = *(pCell++))&0x80) && pCell<pStop );
+ 
+     /* Insert the new divider cell into pParent. */
+-    insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace),
+-               0, pPage->pgno, &rc);
++    if( rc==SQLITE_OK ){
++      insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace),
++                   0, pPage->pgno, &rc);
++    }
+ 
+     /* Set the right-child pointer of pParent to point to the new page. */
+     put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
+@@ -59587,9 +69823,9 @@
+       u8 *z;
+      
+       z = findCell(pPage, j);
+-      btreeParseCellPtr(pPage, z, &info);
+-      if( info.iOverflow ){
+-        Pgno ovfl = get4byte(&z[info.iOverflow]);
++      pPage->xParseCell(pPage, z, &info);
++      if( info.nLocal<info.nPayload ){
++        Pgno ovfl = get4byte(&z[info.nSize-4]);
+         ptrmapGet(pBt, ovfl, &e, &n);
+         assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 );
+       }
+@@ -59707,9 +69943,6 @@
+ ** 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 */
+@@ -59718,7 +69951,6 @@
+   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[] */
+   int nMaxCells = 0;           /* Allocated size of apCell, szCell, aFrom. */
+   int nNew = 0;                /* Number of pages in apNew[] */
+   int nOld;                    /* Number of pages in apOld[] */
+@@ -59729,7 +69961,6 @@
+   int leafData;                /* True if pPage is a leaf of a LEAFDATA tree */
+   int usableSpace;             /* Bytes in pPage beyond the header */
+   int pageFlags;               /* Value of pPage->aData[0] */
+-  int subtotal;                /* Subtotal of bytes in cells on one page */
+   int iSpace1 = 0;             /* First unused byte of aSpace1[] */
+   int iOvflSpace = 0;          /* First unused byte of aOvflSpace[] */
+   int szScratch;               /* Size of scratch memory requested */
+@@ -59737,19 +69968,20 @@
+   MemPage *apNew[NB+2];        /* pPage and up to NB siblings after balancing */
+   u8 *pRight;                  /* Location in parent of right-sibling pointer */
+   u8 *apDiv[NB-1];             /* Divider cells in pParent */
+-  int cntNew[NB+2];            /* Index in aCell[] of cell after i-th page */
+-  int cntOld[NB+2];            /* Old index in aCell[] after i-th page */
++  int cntNew[NB+2];            /* Index in b.paCell[] of cell after i-th page */
++  int cntOld[NB+2];            /* Old index in b.apCell[] */
+   int szNew[NB+2];             /* Combined size of cells placed on i-th page */
+-  u8 **apCell = 0;             /* All cells begin balanced */
+-  u16 *szCell;                 /* Local size of all cells in apCell[] */
+   u8 *aSpace1;                 /* Space for copies of dividers cells */
+   Pgno pgno;                   /* Temp var to store a page number in */
+   u8 abDone[NB+2];             /* True after i'th new page is populated */
+   Pgno aPgno[NB+2];            /* Page numbers of new pages before shuffling */
+   Pgno aPgOrder[NB+2];         /* Copy of aPgno[] used for sorting pages */
+   u16 aPgFlags[NB+2];          /* flags field of new pages before shuffling */
++  CellArray b;                  /* Parsed information on cells being balanced */
+ 
+   memset(abDone, 0, sizeof(abDone));
++  b.nCell = 0;
++  b.apCell = 0;
+   pBt = pParent->pBt;
+   assert( sqlite3_mutex_held(pBt->mutex) );
+   assert( sqlite3PagerIswriteable(pParent->pDbPage) );
+@@ -59767,7 +69999,7 @@
+   assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx );
+ 
+   if( !aOvflSpace ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+ 
+   /* Find the sibling pages to balance. Also locate the cells in pParent 
+@@ -59803,7 +70035,7 @@
+   }
+   pgno = get4byte(pRight);
+   while( 1 ){
+-    rc = getAndInitPage(pBt, pgno, &apOld[i], 0);
++    rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0);
+     if( rc ){
+       memset(apOld, 0, (i+1)*sizeof(MemPage*));
+       goto balance_cleanup;
+@@ -59811,15 +70043,15 @@
+     nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
+     if( (i--)==0 ) break;
+ 
+-    if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){
++    if( pParent->nOverflow && i+nxDiv==pParent->aiOvfl[0] ){
+       apDiv[i] = pParent->apOvfl[0];
+       pgno = get4byte(apDiv[i]);
+-      szNew[i] = cellSizePtr(pParent, apDiv[i]);
++      szNew[i] = pParent->xCellSize(pParent, apDiv[i]);
+       pParent->nOverflow = 0;
+     }else{
+       apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow);
+       pgno = get4byte(apDiv[i]);
+-      szNew[i] = cellSizePtr(pParent, apDiv[i]);
++      szNew[i] = pParent->xCellSize(pParent, apDiv[i]);
+ 
+       /* Drop the cell from the parent page. apDiv[i] still points to
+       ** the cell within the parent, even though it has been dropped.
+@@ -59833,7 +70065,7 @@
+       ** In this case, temporarily copy the cell into the aOvflSpace[]
+       ** buffer. It will be copied out again as soon as the aSpace[] buffer
+       ** is allocated.  */
+-      if( pBt->btsFlags & BTS_SECURE_DELETE ){
++      if( pBt->btsFlags & BTS_FAST_SECURE ){
+         int iOff;
+ 
+         iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
+@@ -59858,130 +70090,199 @@
+   ** Allocate space for memory structures
+   */
+   szScratch =
+-       nMaxCells*sizeof(u8*)                       /* apCell */
+-     + nMaxCells*sizeof(u16)                       /* szCell */
++       nMaxCells*sizeof(u8*)                       /* b.apCell */
++     + nMaxCells*sizeof(u16)                       /* b.szCell */
+      + pBt->pageSize;                              /* aSpace1 */
+ 
+   /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
+   ** that is more than 6 times the database page size. */
+   assert( szScratch<=6*(int)pBt->pageSize );
+-  apCell = sqlite3ScratchMalloc( szScratch ); 
+-  if( apCell==0 ){
+-    rc = SQLITE_NOMEM;
++  b.apCell = sqlite3ScratchMalloc( szScratch ); 
++  if( b.apCell==0 ){
++    rc = SQLITE_NOMEM_BKPT;
+     goto balance_cleanup;
+   }
+-  szCell = (u16*)&apCell[nMaxCells];
+-  aSpace1 = (u8*)&szCell[nMaxCells];
++  b.szCell = (u16*)&b.apCell[nMaxCells];
++  aSpace1 = (u8*)&b.szCell[nMaxCells];
+   assert( EIGHT_BYTE_ALIGNMENT(aSpace1) );
+ 
+   /*
+   ** Load pointers to all cells on sibling pages and the divider cells
+-  ** into the local apCell[] array.  Make copies of the divider cells
++  ** into the local b.apCell[] array.  Make copies of the divider cells
+   ** into space obtained from aSpace1[]. The divider cells have already
+   ** been removed from pParent.
+   **
+   ** If the siblings are on leaf pages, then the child pointers of the
+   ** divider cells are stripped from the cells before they are copied
+-  ** into aSpace1[].  In this way, all cells in apCell[] are without
++  ** into aSpace1[].  In this way, all cells in b.apCell[] are without
+   ** child pointers.  If siblings are not leaves, then all cell in
+-  ** apCell[] include child pointers.  Either way, all cells in apCell[]
++  ** b.apCell[] include child pointers.  Either way, all cells in b.apCell[]
+   ** are alike.
+   **
+   ** leafCorrection:  4 if pPage is a leaf.  0 if pPage is not a leaf.
+   **       leafData:  1 if pPage holds key+data and pParent holds only keys.
+   */
+-  leafCorrection = apOld[0]->leaf*4;
+-  leafData = apOld[0]->intKeyLeaf;
++  b.pRef = apOld[0];
++  leafCorrection = b.pRef->leaf*4;
++  leafData = b.pRef->intKeyLeaf;
+   for(i=0; i<nOld; i++){
+-    int limit;
+     MemPage *pOld = apOld[i];
++    int limit = pOld->nCell;
++    u8 *aData = pOld->aData;
++    u16 maskPage = pOld->maskPage;
++    u8 *piCell = aData + pOld->cellOffset;
++    u8 *piEnd;
++
++    /* Verify that all sibling pages are of the same "type" (table-leaf,
++    ** table-interior, index-leaf, or index-interior).
++    */
++    if( pOld->aData[0]!=apOld[0]->aData[0] ){
++      rc = SQLITE_CORRUPT_BKPT;
++      goto balance_cleanup;
++    }
+ 
+-    limit = pOld->nCell+pOld->nOverflow;
++    /* Load b.apCell[] with pointers to all cells in pOld.  If pOld
++    ** constains overflow cells, include them in the b.apCell[] array
++    ** in the correct spot.
++    **
++    ** Note that when there are multiple overflow cells, it is always the
++    ** case that they are sequential and adjacent.  This invariant arises
++    ** because multiple overflows can only occurs when inserting divider
++    ** cells into a parent on a prior balance, and divider cells are always
++    ** adjacent and are inserted in order.  There is an assert() tagged
++    ** with "NOTE 1" in the overflow cell insertion loop to prove this
++    ** invariant.
++    **
++    ** This must be done in advance.  Once the balance starts, the cell
++    ** offset section of the btree page will be overwritten and we will no
++    ** long be able to find the cells if a pointer to each cell is not saved
++    ** first.
++    */
++    memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
+     if( pOld->nOverflow>0 ){
++      limit = pOld->aiOvfl[0];
+       for(j=0; j<limit; j++){
+-        assert( nCell<nMaxCells );
+-        apCell[nCell] = findOverflowCell(pOld, j);
+-        szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
+-        nCell++;
++        b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
++        piCell += 2;
++        b.nCell++;
+       }
+-    }else{
+-      u8 *aData = pOld->aData;
+-      u16 maskPage = pOld->maskPage;
+-      u16 cellOffset = pOld->cellOffset;
+-      for(j=0; j<limit; j++){
+-        assert( nCell<nMaxCells );
+-        apCell[nCell] = findCellv2(aData, maskPage, cellOffset, j);
+-        szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
+-        nCell++;
++      for(k=0; k<pOld->nOverflow; k++){
++        assert( k==0 || pOld->aiOvfl[k-1]+1==pOld->aiOvfl[k] );/* NOTE 1 */
++        b.apCell[b.nCell] = pOld->apOvfl[k];
++        b.nCell++;
+       }
+-    }       
+-    cntOld[i] = nCell;
++    }
++    piEnd = aData + pOld->cellOffset + 2*pOld->nCell;
++    while( piCell<piEnd ){
++      assert( b.nCell<nMaxCells );
++      b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
++      piCell += 2;
++      b.nCell++;
++    }
++
++    cntOld[i] = b.nCell;
+     if( i<nOld-1 && !leafData){
+       u16 sz = (u16)szNew[i];
+       u8 *pTemp;
+-      assert( nCell<nMaxCells );
+-      szCell[nCell] = sz;
++      assert( b.nCell<nMaxCells );
++      b.szCell[b.nCell] = sz;
+       pTemp = &aSpace1[iSpace1];
+       iSpace1 += sz;
+       assert( sz<=pBt->maxLocal+23 );
+       assert( iSpace1 <= (int)pBt->pageSize );
+       memcpy(pTemp, apDiv[i], sz);
+-      apCell[nCell] = pTemp+leafCorrection;
++      b.apCell[b.nCell] = pTemp+leafCorrection;
+       assert( leafCorrection==0 || leafCorrection==4 );
+-      szCell[nCell] = szCell[nCell] - leafCorrection;
++      b.szCell[b.nCell] = b.szCell[b.nCell] - leafCorrection;
+       if( !pOld->leaf ){
+         assert( leafCorrection==0 );
+         assert( pOld->hdrOffset==0 );
+         /* The right pointer of the child page pOld becomes the left
+         ** pointer of the divider cell */
+-        memcpy(apCell[nCell], &pOld->aData[8], 4);
++        memcpy(b.apCell[b.nCell], &pOld->aData[8], 4);
+       }else{
+         assert( leafCorrection==4 );
+-        if( szCell[nCell]<4 ){
++        while( b.szCell[b.nCell]<4 ){
+           /* Do not allow any cells smaller than 4 bytes. If a smaller cell
+           ** does exist, pad it with 0x00 bytes. */
+-          assert( szCell[nCell]==3 );
+-          assert( apCell[nCell]==&aSpace1[iSpace1-3] );
++          assert( b.szCell[b.nCell]==3 || CORRUPT_DB );
++          assert( b.apCell[b.nCell]==&aSpace1[iSpace1-3] || CORRUPT_DB );
+           aSpace1[iSpace1++] = 0x00;
+-          szCell[nCell] = 4;
++          b.szCell[b.nCell]++;
+         }
+       }
+-      nCell++;
++      b.nCell++;
+     }
+   }
+ 
+   /*
+-  ** Figure out the number of pages needed to hold all nCell cells.
++  ** Figure out the number of pages needed to hold all b.nCell cells.
+   ** Store this number in "k".  Also compute szNew[] which is the total
+   ** size of all cells on the i-th page and cntNew[] which is the index
+-  ** in apCell[] of the cell that divides page i from page i+1.  
+-  ** cntNew[k] should equal nCell.
++  ** in b.apCell[] of the cell that divides page i from page i+1.  
++  ** cntNew[k] should equal b.nCell.
+   **
+   ** Values computed by this block:
+   **
+   **           k: The total number of sibling pages
+   **    szNew[i]: Spaced used on the i-th sibling page.
+-  **   cntNew[i]: Index in apCell[] and szCell[] for the first cell to
++  **   cntNew[i]: Index in b.apCell[] and b.szCell[] for the first cell to
+   **              the right of the i-th sibling page.
+   ** usableSpace: Number of bytes of space available on each sibling.
+   ** 
+   */
+   usableSpace = pBt->usableSize - 12 + leafCorrection;
+-  for(subtotal=k=i=0; i<nCell; i++){
+-    assert( i<nMaxCells );
+-    subtotal += szCell[i] + 2;
+-    if( subtotal > usableSpace ){
+-      szNew[k] = subtotal - szCell[i] - 2;
+-      cntNew[k] = i;
+-      if( leafData ){ i--; }
+-      subtotal = 0;
+-      k++;
+-      if( k>NB+1 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
++  for(i=0; i<nOld; i++){
++    MemPage *p = apOld[i];
++    szNew[i] = usableSpace - p->nFree;
++    for(j=0; j<p->nOverflow; j++){
++      szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]);
++    }
++    cntNew[i] = cntOld[i];
++  }
++  k = nOld;
++  for(i=0; i<k; i++){
++    int sz;
++    while( szNew[i]>usableSpace ){
++      if( i+1>=k ){
++        k = i+2;
++        if( k>NB+2 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
++        szNew[k-1] = 0;
++        cntNew[k-1] = b.nCell;
++      }
++      sz = 2 + cachedCellSize(&b, cntNew[i]-1);
++      szNew[i] -= sz;
++      if( !leafData ){
++        if( cntNew[i]<b.nCell ){
++          sz = 2 + cachedCellSize(&b, cntNew[i]);
++        }else{
++          sz = 0;
++        }
++      }
++      szNew[i+1] += sz;
++      cntNew[i]--;
++    }
++    while( cntNew[i]<b.nCell ){
++      sz = 2 + cachedCellSize(&b, cntNew[i]);
++      if( szNew[i]+sz>usableSpace ) break;
++      szNew[i] += sz;
++      cntNew[i]++;
++      if( !leafData ){
++        if( cntNew[i]<b.nCell ){
++          sz = 2 + cachedCellSize(&b, cntNew[i]);
++        }else{
++          sz = 0;
++        }
++      }
++      szNew[i+1] -= sz;
++    }
++    if( cntNew[i]>=b.nCell ){
++      k = i+1;
++    }else if( cntNew[i] <= (i>0 ? cntNew[i-1] : 0) ){
++      rc = SQLITE_CORRUPT_BKPT;
++      goto balance_cleanup;
+     }
+   }
+-  szNew[k] = subtotal;
+-  cntNew[k] = nCell;
+-  k++;
+ 
+   /*
+   ** The packing computed by the previous block is biased toward the siblings
+@@ -60002,19 +70303,27 @@
+ 
+     r = cntNew[i-1] - 1;
+     d = r + 1 - leafData;
+-    assert( d<nMaxCells );
+-    assert( r<nMaxCells );
+-    while( szRight==0 
+-       || (!bBulk && szRight+szCell[d]+2<=szLeft-(szCell[r]+2)) 
+-    ){
+-      szRight += szCell[d] + 2;
+-      szLeft -= szCell[r] + 2;
+-      cntNew[i-1]--;
+-      r = cntNew[i-1] - 1;
+-      d = r + 1 - leafData;
+-    }
++    (void)cachedCellSize(&b, d);
++    do{
++      assert( d<nMaxCells );
++      assert( r<nMaxCells );
++      (void)cachedCellSize(&b, r);
++      if( szRight!=0
++       && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+(i==k-1?0:2)))){
++        break;
++      }
++      szRight += b.szCell[d] + 2;
++      szLeft -= b.szCell[r] + 2;
++      cntNew[i-1] = r;
++      r--;
++      d--;
++    }while( r>=0 );
+     szNew[i] = szRight;
+     szNew[i-1] = szLeft;
++    if( cntNew[i-1] <= (i>1 ? cntNew[i-2] : 0) ){
++      rc = SQLITE_CORRUPT_BKPT;
++      goto balance_cleanup;
++    }
+   }
+ 
+   /* Sanity check:  For a non-corrupt database file one of the follwing
+@@ -60034,10 +70343,6 @@
+   /*
+   ** Allocate k new pages.  Reuse old pages where possible.
+   */
+-  if( apOld[0]->pgno<=1 ){
+-    rc = SQLITE_CORRUPT_BKPT;
+-    goto balance_cleanup;
+-  }
+   pageFlags = apOld[0]->aData[0];
+   for(i=0; i<k; i++){
+     MemPage *pNew;
+@@ -60054,7 +70359,7 @@
+       zeroPage(pNew, pageFlags);
+       apNew[i] = pNew;
+       nNew++;
+-      cntOld[i] = nCell;
++      cntOld[i] = b.nCell;
+ 
+       /* Set the pointer-map entry for the new sibling page. */
+       if( ISAUTOVACUUM ){
+@@ -60159,8 +70464,8 @@
+     int iNew = 0;
+     int iOld = 0;
+ 
+-    for(i=0; i<nCell; i++){
+-      u8 *pCell = apCell[i];
++    for(i=0; i<b.nCell; i++){
++      u8 *pCell = b.apCell[i];
+       if( i==cntOldNext ){
+         MemPage *pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld];
+         cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
+@@ -60179,15 +70484,15 @@
+       ** overflow cell), we can skip updating the pointer map entries.  */
+       if( iOld>=nNew
+        || pNew->pgno!=aPgno[iOld]
+-       || pCell<aOld
+-       || pCell>=&aOld[usableSize]
++       || !SQLITE_WITHIN(pCell,aOld,&aOld[usableSize])
+       ){
+         if( !leafCorrection ){
+           ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
+         }
+-        if( szCell[i]>pNew->minLocal ){
++        if( cachedCellSize(&b,i)>pNew->minLocal ){
+           ptrmapPutOvflPtr(pNew, pCell, &rc);
+         }
++        if( rc ) goto balance_cleanup;
+       }
+     }
+   }
+@@ -60201,20 +70506,21 @@
+     j = cntNew[i];
+ 
+     assert( j<nMaxCells );
+-    pCell = apCell[j];
+-    sz = szCell[j] + leafCorrection;
++    assert( b.apCell[j]!=0 );
++    pCell = b.apCell[j];
++    sz = b.szCell[j] + leafCorrection;
+     pTemp = &aOvflSpace[iOvflSpace];
+     if( !pNew->leaf ){
+       memcpy(&pNew->aData[8], pCell, 4);
+     }else if( leafData ){
+       /* If the tree is a leaf-data tree, and the siblings are leaves, 
+-      ** then there is no divider cell in apCell[]. Instead, the divider 
++      ** then there is no divider cell in b.apCell[]. Instead, the divider 
+       ** cell consists of the integer key for the right-most cell of 
+       ** the sibling-page assembled above only.
+       */
+       CellInfo info;
+       j--;
+-      btreeParseCellPtr(pNew, apCell[j], &info);
++      pNew->xParseCell(pNew, b.apCell[j], &info);
+       pCell = pTemp;
+       sz = 4 + putVarint(&pCell[4], info.nKey);
+       pTemp = 0;
+@@ -60227,13 +70533,13 @@
+       ** any cell). But it is important to pass the correct size to 
+       ** insertCell(), so reparse the cell now.
+       **
+-      ** Note that this can never happen in an SQLite data file, as all
+-      ** cells are at least 4 bytes. It only happens in b-trees used
+-      ** to evaluate "IN (SELECT ...)" and similar clauses.
++      ** This can only happen for b-trees used to evaluate "IN (SELECT ...)"
++      ** and WITHOUT ROWID tables with exactly one column which is the
++      ** primary key.
+       */
+-      if( szCell[j]==4 ){
++      if( b.szCell[j]==4 ){
+         assert(leafCorrection==4);
+-        sz = cellSizePtr(pParent, pCell);
++        sz = pParent->xCellSize(pParent, pCell);
+       }
+     }
+     iOvflSpace += sz;
+@@ -60289,12 +70595,13 @@
+         iNew = iOld = 0;
+         nNewCell = cntNew[0];
+       }else{
+-        iOld = iPg<nOld ? (cntOld[iPg-1] + !leafData) : nCell;
++        iOld = iPg<nOld ? (cntOld[iPg-1] + !leafData) : b.nCell;
+         iNew = cntNew[iPg-1] + !leafData;
+         nNewCell = cntNew[iPg] - iNew;
+       }
+ 
+-      editPage(apNew[iPg], iOld, iNew, nNewCell, apCell, szCell);
++      rc = editPage(apNew[iPg], iOld, iNew, nNewCell, &b);
++      if( rc ) goto balance_cleanup;
+       abDone[iPg]++;
+       apNew[iPg]->nFree = usableSpace-szNew[iPg];
+       assert( apNew[iPg]->nOverflow==0 );
+@@ -60324,8 +70631,8 @@
+     ** by smaller than the child due to the database header, and so all the
+     ** free space needs to be up front.
+     */
+-    assert( nNew==1 );
+-    rc = defragmentPage(apNew[0]);
++    assert( nNew==1 || CORRUPT_DB );
++    rc = defragmentPage(apNew[0], -1);
+     testcase( rc!=SQLITE_OK );
+     assert( apNew[0]->nFree == 
+         (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
+@@ -60345,7 +70652,7 @@
+ 
+   assert( pParent->isInit );
+   TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n",
+-          nOld, nNew, nCell));
++          nOld, nNew, b.nCell));
+ 
+   /* Free any old pages that were not reused as new pages.
+   */
+@@ -60368,7 +70675,7 @@
+   ** Cleanup before returning.
+   */
+ balance_cleanup:
+-  sqlite3ScratchFree(apCell);
++  sqlite3ScratchFree(b.apCell);
+   for(i=0; i<nOld; i++){
+     releasePage(apOld[i]);
+   }
+@@ -60378,9 +70685,6 @@
+ 
+   return rc;
+ }
+-#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
+-#pragma optimize("", on)
+-#endif
+ 
+ 
+ /*
+@@ -60465,8 +70769,8 @@
+   u8 aBalanceQuickSpace[13];
+   u8 *pFree = 0;
+ 
+-  TESTONLY( int balance_quick_called = 0 );
+-  TESTONLY( int balance_deeper_called = 0 );
++  VVA_ONLY( int balance_quick_called = 0 );
++  VVA_ONLY( int balance_deeper_called = 0 );
+ 
+   do {
+     int iPage = pCur->iPage;
+@@ -60479,12 +70783,13 @@
+         ** and copy the current contents of the root-page to it. The
+         ** next iteration of the do-loop will balance the child page.
+         */ 
+-        assert( (balance_deeper_called++)==0 );
++        assert( balance_deeper_called==0 );
++        VVA_ONLY( balance_deeper_called++ );
+         rc = balance_deeper(pPage, &pCur->apPage[1]);
+         if( rc==SQLITE_OK ){
+           pCur->iPage = 1;
++          pCur->ix = 0;
+           pCur->aiIdx[0] = 0;
+-          pCur->aiIdx[1] = 0;
+           assert( pCur->apPage[1]->nOverflow );
+         }
+       }else{
+@@ -60518,7 +70823,8 @@
+           ** function. If this were not verified, a subtle bug involving reuse
+           ** of the aBalanceQuickSpace[] might sneak in.
+           */
+-          assert( (balance_quick_called++)==0 );
++          assert( balance_quick_called==0 ); 
++          VVA_ONLY( balance_quick_called++ );
+           rc = balance_quick(pParent, pPage, aBalanceQuickSpace);
+         }else
+ #endif
+@@ -60575,33 +70881,39 @@
+ 
+ 
+ /*
+-** Insert a new record into the BTree.  The key is given by (pKey,nKey)
+-** and the data is given by (pData,nData).  The cursor is used only to
+-** define what table the record should be inserted into.  The cursor
+-** is left pointing at a random location.
+-**
+-** For an INTKEY table, only the nKey value of the key is used.  pKey is
+-** ignored.  For a ZERODATA table, the pData and nData are both ignored.
++** Insert a new record into the BTree.  The content of the new record
++** is described by the pX object.  The pCur cursor is used only to
++** define what table the record should be inserted into, and is left
++** pointing at a random location.
++**
++** For a table btree (used for rowid tables), only the pX.nKey value of
++** the key is used. The pX.pKey value must be NULL.  The pX.nKey is the
++** rowid or INTEGER PRIMARY KEY of the row.  The pX.nData,pData,nZero fields
++** hold the content of the row.
++**
++** For an index btree (used for indexes and WITHOUT ROWID tables), the
++** key is an arbitrary byte sequence stored in pX.pKey,nKey.  The 
++** pX.pData,nData,nZero fields must be zero.
+ **
+ ** If the seekResult parameter is non-zero, then a successful call to
+-** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already
+-** been performed. seekResult is the search result returned (a negative
+-** number if pCur points at an entry that is smaller than (pKey, nKey), or
+-** a positive value if pCur points at an entry that is larger than 
+-** (pKey, nKey)). 
+-**
+-** If the seekResult parameter is non-zero, then the caller guarantees that
+-** cursor pCur is pointing at the existing copy of a row that is to be
+-** overwritten.  If the seekResult parameter is 0, then cursor pCur may
+-** point to any entry or to no entry at all and so this function has to seek
+-** the cursor before the new key can be inserted.
++** MovetoUnpacked() to seek cursor pCur to (pKey,nKey) has already
++** been performed.  In other words, if seekResult!=0 then the cursor
++** is currently pointing to a cell that will be adjacent to the cell
++** to be inserted.  If seekResult<0 then pCur points to a cell that is
++** smaller then (pKey,nKey).  If seekResult>0 then pCur points to a cell
++** that is larger than (pKey,nKey).
++**
++** If seekResult==0, that means pCur is pointing at some unknown location.
++** In that case, this routine must seek the cursor to the correct insertion
++** point for (pKey,nKey) before doing the insertion.  For index btrees,
++** if pX->nMem is non-zero, then pX->aMem contains pointers to the unpacked
++** key values and pX->aMem can be used instead of pX->pKey to avoid having
++** to decode the key.
+ */
+ SQLITE_PRIVATE int sqlite3BtreeInsert(
+   BtCursor *pCur,                /* Insert data into the table of this cursor */
+-  const void *pKey, i64 nKey,    /* The key of the new record */
+-  const void *pData, int nData,  /* The data of the new record */
+-  int nZero,                     /* Number of extra 0 bytes to append to data */
+-  int appendBias,                /* True if this is likely an append */
++  const BtreePayload *pX,        /* Content of the row to be inserted */
++  int flags,                     /* True if this is likely an append */
+   int seekResult                 /* Result of prior MovetoUnpacked() call */
+ ){
+   int rc;
+@@ -60614,12 +70926,14 @@
+   unsigned char *oldCell;
+   unsigned char *newCell = 0;
+ 
++  assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND))==flags );
++
+   if( pCur->eState==CURSOR_FAULT ){
+     assert( pCur->skipNext!=SQLITE_OK );
+     return pCur->skipNext;
+   }
+ 
+-  assert( cursorHoldsMutex(pCur) );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( (pCur->curFlags & BTCF_WriteFlag)!=0
+               && pBt->inTransaction==TRANS_WRITE
+               && (pBt->btsFlags & BTS_READ_ONLY)==0 );
+@@ -60630,7 +70944,7 @@
+   ** keys with no associated data. If the cursor was opened expecting an
+   ** intkey table, the caller should be inserting integer keys with a
+   ** blob of associated data.  */
+-  assert( (pKey==0)==(pCur->pKeyInfo==0) );
++  assert( (pX->pKey==0)==(pCur->pKeyInfo==0) );
+ 
+   /* Save the positions of any other cursors open on this table.
+   **
+@@ -60643,46 +70957,67 @@
+   ** doing any work. To avoid thwarting these optimizations, it is important
+   ** not to clear the cursor here.
+   */
+-  rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
+-  if( rc ) return rc;
++  if( pCur->curFlags & BTCF_Multiple ){
++    rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
++    if( rc ) return rc;
++  }
+ 
+   if( pCur->pKeyInfo==0 ){
++    assert( pX->pKey==0 );
+     /* If this is an insert into a table b-tree, invalidate any incrblob 
+     ** cursors open on the row being replaced */
+-    invalidateIncrblobCursors(p, nKey, 0);
++    invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0);
++
++    /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing 
++    ** to a row with the same key as the new entry being inserted.  */
++    assert( (flags & BTREE_SAVEPOSITION)==0 || 
++            ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) );
+ 
+     /* If the cursor is currently on the last row and we are appending a
+-    ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto()
+-    ** call */
+-    if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0
+-      && pCur->info.nKey==nKey-1 ){
+-      loc = -1;
++    ** new row onto the end, set the "loc" to avoid an unnecessary
++    ** btreeMoveto() call */
++    if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){
++      loc = 0;
++    }else if( loc==0 ){
++      rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc);
++      if( rc ) return rc;
++    }
++  }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){
++    if( pX->nMem ){
++      UnpackedRecord r;
++      r.pKeyInfo = pCur->pKeyInfo;
++      r.aMem = pX->aMem;
++      r.nField = pX->nMem;
++      r.default_rc = 0;
++      r.errCode = 0;
++      r.r1 = 0;
++      r.r2 = 0;
++      r.eqSeen = 0;
++      rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc);
++    }else{
++      rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc);
+     }
+-  }
+-
+-  if( !loc ){
+-    rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc);
+     if( rc ) return rc;
+   }
+   assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
+ 
+   pPage = pCur->apPage[pCur->iPage];
+-  assert( pPage->intKey || nKey>=0 );
++  assert( pPage->intKey || pX->nKey>=0 );
+   assert( pPage->leaf || !pPage->intKey );
+ 
+   TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
+-          pCur->pgnoRoot, nKey, nData, pPage->pgno,
++          pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno,
+           loc==0 ? "overwrite" : "new entry"));
+   assert( pPage->isInit );
+   newCell = pBt->pTmpSpace;
+   assert( newCell!=0 );
+-  rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
++  rc = fillInCell(pPage, newCell, pX, &szNew);
+   if( rc ) goto end_insert;
+-  assert( szNew==cellSizePtr(pPage, newCell) );
++  assert( szNew==pPage->xCellSize(pPage, newCell) );
+   assert( szNew <= MX_CELL_SIZE(pBt) );
+-  idx = pCur->aiIdx[pCur->iPage];
++  idx = pCur->ix;
+   if( loc==0 ){
+-    u16 szOld;
++    CellInfo info;
+     assert( idx<pPage->nCell );
+     rc = sqlite3PagerWrite(pPage->pDbPage);
+     if( rc ){
+@@ -60692,16 +71027,35 @@
+     if( !pPage->leaf ){
+       memcpy(newCell, oldCell, 4);
+     }
+-    rc = clearCell(pPage, oldCell, &szOld);
+-    dropCell(pPage, idx, szOld, &rc);
++    rc = clearCell(pPage, oldCell, &info);
++    if( info.nSize==szNew && info.nLocal==info.nPayload 
++     && (!ISAUTOVACUUM || szNew<pPage->minLocal)
++    ){
++      /* Overwrite the old cell with the new if they are the same size.
++      ** We could also try to do this if the old cell is smaller, then add
++      ** the leftover space to the free list.  But experiments show that
++      ** doing that is no faster then skipping this optimization and just
++      ** calling dropCell() and insertCell(). 
++      **
++      ** This optimization cannot be used on an autovacuum database if the
++      ** new entry uses overflow pages, as the insertCell() call below is
++      ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry.  */
++      assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */
++      if( oldCell+szNew > pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
++      memcpy(oldCell, newCell, szNew);
++      return SQLITE_OK;
++    }
++    dropCell(pPage, idx, info.nSize, &rc);
+     if( rc ) goto end_insert;
+   }else if( loc<0 && pPage->nCell>0 ){
+     assert( pPage->leaf );
+-    idx = ++pCur->aiIdx[pCur->iPage];
++    idx = ++pCur->ix;
++    pCur->curFlags &= ~BTCF_ValidNKey;
+   }else{
+     assert( pPage->leaf );
+   }
+   insertCell(pPage, idx, newCell, szNew, 0, 0, &rc);
++  assert( pPage->nOverflow==0 || rc==SQLITE_OK );
+   assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );
+ 
+   /* If no error has occurred and pPage has an overflow cell, call balance() 
+@@ -60725,7 +71079,8 @@
+   ** row without seeking the cursor. This can be a big performance boost.
+   */
+   pCur->info.nSize = 0;
+-  if( rc==SQLITE_OK && pPage->nOverflow ){
++  if( pPage->nOverflow ){
++    assert( rc==SQLITE_OK );
+     pCur->curFlags &= ~(BTCF_ValidNKey);
+     rc = balance(pCur);
+ 
+@@ -60735,6 +71090,20 @@
+     ** from trying to save the current position of the cursor.  */
+     pCur->apPage[pCur->iPage]->nOverflow = 0;
+     pCur->eState = CURSOR_INVALID;
++    if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){
++      rc = moveToRoot(pCur);
++      if( pCur->pKeyInfo ){
++        assert( pCur->pKey==0 );
++        pCur->pKey = sqlite3Malloc( pX->nKey );
++        if( pCur->pKey==0 ){
++          rc = SQLITE_NOMEM;
++        }else{
++          memcpy(pCur->pKey, pX->pKey, pX->nKey);
++        }
++      }
++      pCur->eState = CURSOR_REQUIRESEEK;
++      pCur->nKey = pX->nKey;
++    }
+   }
+   assert( pCur->apPage[pCur->iPage]->nOverflow==0 );
+ 
+@@ -60743,10 +71112,23 @@
+ }
+ 
+ /*
+-** Delete the entry that the cursor is pointing to.  The cursor
+-** is left pointing at an arbitrary location.
++** Delete the entry that the cursor is pointing to. 
++**
++** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then
++** the cursor is left pointing at an arbitrary location after the delete.
++** But if that bit is set, then the cursor is left in a state such that
++** the next call to BtreeNext() or BtreePrev() moves it to the same row
++** as it would have been on if the call to BtreeDelete() had been omitted.
++**
++** The BTREE_AUXDELETE bit of flags indicates that is one of several deletes
++** associated with a single table entry and its indexes.  Only one of those
++** deletes is considered the "primary" delete.  The primary delete occurs
++** on a cursor that is not a BTREE_FORDELETE cursor.  All but one delete
++** operation on non-FORDELETE cursors is tagged with the AUXDELETE flag.
++** The BTREE_AUXDELETE bit is a hint that is not used by this implementation,
++** but which might be used by alternative storage engines.
+ */
+-SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
++SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
+   Btree *p = pCur->pBtree;
+   BtShared *pBt = p->pBt;              
+   int rc;                              /* Return code */
+@@ -60754,26 +71136,47 @@
+   unsigned char *pCell;                /* Pointer to cell to delete */
+   int iCellIdx;                        /* Index of cell to delete */
+   int iCellDepth;                      /* Depth of node containing pCell */ 
+-  u16 szCell;                          /* Size of the cell being deleted */
++  CellInfo info;                       /* Size of the cell being deleted */
++  int bSkipnext = 0;                   /* Leaf cursor in SKIPNEXT state */
++  u8 bPreserve = flags & BTREE_SAVEPOSITION;  /* Keep cursor valid */
+ 
+-  assert( cursorHoldsMutex(pCur) );
++  assert( cursorOwnsBtShared(pCur) );
+   assert( pBt->inTransaction==TRANS_WRITE );
+   assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
+   assert( pCur->curFlags & BTCF_WriteFlag );
+   assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
+   assert( !hasReadConflicts(p, pCur->pgnoRoot) );
+-
+-  if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) 
+-   || NEVER(pCur->eState!=CURSOR_VALID)
+-  ){
+-    return SQLITE_ERROR;  /* Something has gone awry. */
+-  }
++  assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
++  assert( pCur->eState==CURSOR_VALID );
++  assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
+ 
+   iCellDepth = pCur->iPage;
+-  iCellIdx = pCur->aiIdx[iCellDepth];
++  iCellIdx = pCur->ix;
+   pPage = pCur->apPage[iCellDepth];
+   pCell = findCell(pPage, iCellIdx);
+ 
++  /* If the bPreserve flag is set to true, then the cursor position must
++  ** be preserved following this delete operation. If the current delete
++  ** will cause a b-tree rebalance, then this is done by saving the cursor
++  ** key and leaving the cursor in CURSOR_REQUIRESEEK state before 
++  ** returning. 
++  **
++  ** Or, if the current delete will not cause a rebalance, then the cursor
++  ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
++  ** before or after the deleted entry. In this case set bSkipnext to true.  */
++  if( bPreserve ){
++    if( !pPage->leaf 
++     || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
++    ){
++      /* A b-tree rebalance will be required after deleting this entry.
++      ** Save the cursor key.  */
++      rc = saveCursorKey(pCur);
++      if( rc ) return rc;
++    }else{
++      bSkipnext = 1;
++    }
++  }
++
+   /* If the page containing the entry to delete is not a leaf page, move
+   ** the cursor to the largest entry in the tree that is smaller than
+   ** the entry being deleted. This cell will replace the cell being deleted
+@@ -60782,29 +71185,31 @@
+   ** sub-tree headed by the child page of the cell being deleted. This makes
+   ** balancing the tree following the delete operation easier.  */
+   if( !pPage->leaf ){
+-    int notUsed = 0;
+-    rc = sqlite3BtreePrevious(pCur, &notUsed);
++    rc = sqlite3BtreePrevious(pCur, 0);
++    assert( rc!=SQLITE_DONE );
+     if( rc ) return rc;
+   }
+ 
+   /* Save the positions of any other cursors open on this table before
+-  ** making any modifications. Make the page containing the entry to be 
+-  ** deleted writable. Then free any overflow pages associated with the 
+-  ** entry and finally remove the cell itself from within the page.  
+-  */
+-  rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
+-  if( rc ) return rc;
++  ** making any modifications.  */
++  if( pCur->curFlags & BTCF_Multiple ){
++    rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
++    if( rc ) return rc;
++  }
+ 
+   /* If this is a delete operation to remove a row from a table b-tree,
+   ** invalidate any incrblob cursors open on the row being deleted.  */
+   if( pCur->pKeyInfo==0 ){
+-    invalidateIncrblobCursors(p, pCur->info.nKey, 0);
++    invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0);
+   }
+ 
++  /* Make the page containing the entry to be deleted writable. Then free any
++  ** overflow pages associated with the entry and finally remove the cell
++  ** itself from within the page.  */
+   rc = sqlite3PagerWrite(pPage->pDbPage);
+   if( rc ) return rc;
+-  rc = clearCell(pPage, pCell, &szCell);
+-  dropCell(pPage, iCellIdx, szCell, &rc);
++  rc = clearCell(pPage, pCell, &info);
++  dropCell(pPage, iCellIdx, info.nSize, &rc);
+   if( rc ) return rc;
+ 
+   /* If the cell deleted was not located on a leaf page, then the cursor
+@@ -60819,12 +71224,15 @@
+     unsigned char *pTmp;
+ 
+     pCell = findCell(pLeaf, pLeaf->nCell-1);
+-    nCell = cellSizePtr(pLeaf, pCell);
++    if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT;
++    nCell = pLeaf->xCellSize(pLeaf, pCell);
+     assert( MX_CELL_SIZE(pBt) >= nCell );
+     pTmp = pBt->pTmpSpace;
+     assert( pTmp!=0 );
+     rc = sqlite3PagerWrite(pLeaf->pDbPage);
+-    insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
++    if( rc==SQLITE_OK ){
++      insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
++    }
+     dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
+     if( rc ) return rc;
+   }
+@@ -60853,7 +71261,23 @@
+   }
+ 
+   if( rc==SQLITE_OK ){
+-    moveToRoot(pCur);
++    if( bSkipnext ){
++      assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) );
++      assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB );
++      assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
++      pCur->eState = CURSOR_SKIPNEXT;
++      if( iCellIdx>=pPage->nCell ){
++        pCur->skipNext = -1;
++        pCur->ix = pPage->nCell-1;
++      }else{
++        pCur->skipNext = 1;
++      }
++    }else{
++      rc = moveToRoot(pCur);
++      if( bPreserve ){
++        pCur->eState = CURSOR_REQUIRESEEK;
++      }
++    }
+   }
+   return rc;
+ }
+@@ -60911,7 +71335,8 @@
+         pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
+       pgnoRoot++;
+     }
+-    assert( pgnoRoot>=3 );
++    assert( pgnoRoot>=3 || CORRUPT_DB );
++    testcase( pgnoRoot<3 );
+ 
+     /* Allocate a page. The page that currently resides at pgnoRoot will
+     ** be moved to the allocated page (unless the allocated page happens
+@@ -61034,13 +71459,13 @@
+   unsigned char *pCell;
+   int i;
+   int hdr;
+-  u16 szCell;
++  CellInfo info;
+ 
+   assert( sqlite3_mutex_held(pBt->mutex) );
+   if( pgno>btreePagecount(pBt) ){
+     return SQLITE_CORRUPT_BKPT;
+   }
+-  rc = getAndInitPage(pBt, pgno, &pPage, 0);
++  rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
+   if( rc ) return rc;
+   if( pPage->bBusy ){
+     rc = SQLITE_CORRUPT_BKPT;
+@@ -61054,14 +71479,15 @@
+       rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
+       if( rc ) goto cleardatabasepage_out;
+     }
+-    rc = clearCell(pPage, pCell, &szCell);
++    rc = clearCell(pPage, pCell, &info);
+     if( rc ) goto cleardatabasepage_out;
+   }
+   if( !pPage->leaf ){
+     rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
+     if( rc ) goto cleardatabasepage_out;
+   }else if( pnChange ){
+-    assert( pPage->intKey );
++    assert( pPage->intKey || CORRUPT_DB );
++    testcase( !pPage->intKey );
+     *pnChange += pPage->nCell;
+   }
+   if( freePageFlag ){
+@@ -61101,7 +71527,7 @@
+     /* Invalidate all incrblob cursors open on table iTable (assuming iTable
+     ** is the root of a table b-tree - if it is not, the following call is
+     ** a no-op).  */
+-    invalidateIncrblobCursors(p, 0, 1);
++    invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1);
+     rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange);
+   }
+   sqlite3BtreeLeave(p);
+@@ -61144,19 +71570,7 @@
+ 
+   assert( sqlite3BtreeHoldsMutex(p) );
+   assert( p->inTrans==TRANS_WRITE );
+-
+-  /* It is illegal to drop a table if any cursors are open on the
+-  ** database. This is because in auto-vacuum mode the backend may
+-  ** need to move another root-page to fill a gap left by the deleted
+-  ** root page. If an open cursor was using this page a problem would 
+-  ** occur.
+-  **
+-  ** This error is caught long before control reaches this point.
+-  */
+-  if( NEVER(pBt->pCursor) ){
+-    sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db);
+-    return SQLITE_LOCKED_SHAREDCACHE;
+-  }
++  assert( iTable>=2 );
+ 
+   rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
+   if( rc ) return rc;
+@@ -61168,76 +71582,67 @@
+ 
+   *piMoved = 0;
+ 
+-  if( iTable>1 ){
+ #ifdef SQLITE_OMIT_AUTOVACUUM
+-    freePage(pPage, &rc);
+-    releasePage(pPage);
++  freePage(pPage, &rc);
++  releasePage(pPage);
+ #else
+-    if( pBt->autoVacuum ){
+-      Pgno maxRootPgno;
+-      sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
+-
+-      if( iTable==maxRootPgno ){
+-        /* If the table being dropped is the table with the largest root-page
+-        ** number in the database, put the root page on the free list. 
+-        */
+-        freePage(pPage, &rc);
+-        releasePage(pPage);
+-        if( rc!=SQLITE_OK ){
+-          return rc;
+-        }
+-      }else{
+-        /* The table being dropped does not have the largest root-page
+-        ** number in the database. So move the page that does into the 
+-        ** gap left by the deleted root-page.
+-        */
+-        MemPage *pMove;
+-        releasePage(pPage);
+-        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
+-        if( rc!=SQLITE_OK ){
+-          return rc;
+-        }
+-        rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
+-        releasePage(pMove);
+-        if( rc!=SQLITE_OK ){
+-          return rc;
+-        }
+-        pMove = 0;
+-        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
+-        freePage(pMove, &rc);
+-        releasePage(pMove);
+-        if( rc!=SQLITE_OK ){
+-          return rc;
+-        }
+-        *piMoved = maxRootPgno;
+-      }
++  if( pBt->autoVacuum ){
++    Pgno maxRootPgno;
++    sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
+ 
+-      /* Set the new 'max-root-page' value in the database header. This
+-      ** is the old value less one, less one more if that happens to
+-      ** be a root-page number, less one again if that is the
+-      ** PENDING_BYTE_PAGE.
++    if( iTable==maxRootPgno ){
++      /* If the table being dropped is the table with the largest root-page
++      ** number in the database, put the root page on the free list. 
+       */
+-      maxRootPgno--;
+-      while( maxRootPgno==PENDING_BYTE_PAGE(pBt)
+-             || PTRMAP_ISPAGE(pBt, maxRootPgno) ){
+-        maxRootPgno--;
++      freePage(pPage, &rc);
++      releasePage(pPage);
++      if( rc!=SQLITE_OK ){
++        return rc;
+       }
+-      assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
+-
+-      rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
+     }else{
+-      freePage(pPage, &rc);
++      /* The table being dropped does not have the largest root-page
++      ** number in the database. So move the page that does into the 
++      ** gap left by the deleted root-page.
++      */
++      MemPage *pMove;
+       releasePage(pPage);
++      rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
++      if( rc!=SQLITE_OK ){
++        return rc;
++      }
++      rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
++      releasePage(pMove);
++      if( rc!=SQLITE_OK ){
++        return rc;
++      }
++      pMove = 0;
++      rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
++      freePage(pMove, &rc);
++      releasePage(pMove);
++      if( rc!=SQLITE_OK ){
++        return rc;
++      }
++      *piMoved = maxRootPgno;
+     }
+-#endif
+-  }else{
+-    /* If sqlite3BtreeDropTable was called on page 1.
+-    ** This really never should happen except in a corrupt
+-    ** database. 
++
++    /* Set the new 'max-root-page' value in the database header. This
++    ** is the old value less one, less one more if that happens to
++    ** be a root-page number, less one again if that is the
++    ** PENDING_BYTE_PAGE.
+     */
+-    zeroPage(pPage, PTF_INTKEY|PTF_LEAF );
++    maxRootPgno--;
++    while( maxRootPgno==PENDING_BYTE_PAGE(pBt)
++           || PTRMAP_ISPAGE(pBt, maxRootPgno) ){
++      maxRootPgno--;
++    }
++    assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
++
++    rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
++  }else{
++    freePage(pPage, &rc);
+     releasePage(pPage);
+   }
++#endif
+   return rc;  
+ }
+ SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
+@@ -61376,16 +71781,16 @@
+           return moveToRoot(pCur);
+         }
+         moveToParent(pCur);
+-      }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
++      }while ( pCur->ix>=pCur->apPage[pCur->iPage]->nCell );
+ 
+-      pCur->aiIdx[pCur->iPage]++;
++      pCur->ix++;
+       pPage = pCur->apPage[pCur->iPage];
+     }
+ 
+     /* Descend to the child node of the cell that the cursor currently 
+     ** points at. This is the right-child if (iIdx==pPage->nCell).
+     */
+-    iIdx = pCur->aiIdx[pCur->iPage];
++    iIdx = pCur->ix;
+     if( iIdx==pPage->nCell ){
+       rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
+     }else{
+@@ -61416,7 +71821,6 @@
+   ...
+ ){
+   va_list ap;
+-  char zBuf[200];
+   if( !pCheck->mxErr ) return;
+   pCheck->mxErr--;
+   pCheck->nErr++;
+@@ -61425,10 +71829,9 @@
+     sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
+   }
+   if( pCheck->zPfx ){
+-    sqlite3_snprintf(sizeof(zBuf), zBuf, pCheck->zPfx, pCheck->v1, pCheck->v2);
+-    sqlite3StrAccumAppendAll(&pCheck->errMsg, zBuf);
++    sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
+   }
+-  sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
++  sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap);
+   va_end(ap);
+   if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
+     pCheck->mallocFailed = 1;
+@@ -61532,7 +71935,7 @@
+       break;
+     }
+     if( checkRef(pCheck, iPage) ) break;
+-    if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
++    if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){
+       checkAppendMsg(pCheck, "failed to get page %d", iPage);
+       break;
+     }
+@@ -61575,6 +71978,10 @@
+ #endif
+     iPage = get4byte(pOvflData);
+     sqlite3PagerUnref(pOvflPage);
++
++    if( isFreeList && N<(iPage!=0) ){
++      checkAppendMsg(pCheck, "free-page count in header is too small");
++    }
+   }
+ }
+ #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+@@ -61640,35 +72047,42 @@
+ **
+ **      1.  Make sure that cells and freeblocks do not overlap
+ **          but combine to completely cover the page.
+-**  NO  2.  Make sure cell keys are in order.
+-**  NO  3.  Make sure no key is less than or equal to zLowerBound.
+-**  NO  4.  Make sure no key is greater than or equal to zUpperBound.
+-**      5.  Check the integrity of overflow pages.
+-**      6.  Recursively call checkTreePage on all children.
+-**      7.  Verify that the depth of all children is the same.
+-**      8.  Make sure this page is at least 33% full or else it is
+-**          the root of the tree.
++**      2.  Make sure integer cell keys are in order.
++**      3.  Check the integrity of overflow pages.
++**      4.  Recursively call checkTreePage on all children.
++**      5.  Verify that the depth of all children is the same.
+ */
+ static int checkTreePage(
+   IntegrityCk *pCheck,  /* Context for the sanity check */
+   int iPage,            /* Page number of the page to check */
+-  i64 *pnParentMinKey, 
+-  i64 *pnParentMaxKey
++  i64 *piMinKey,        /* Write minimum integer primary key here */
++  i64 maxKey            /* Error if integer primary key greater than this */
+ ){
+-  MemPage *pPage;
+-  int i, rc, depth, d2, pgno, cnt;
+-  int hdr, cellStart;
+-  int nCell;
+-  u8 *data;
+-  BtShared *pBt;
+-  int usableSize;
+-  u32 *heap = 0;
+-  u32 x, prev = 0;
+-  i64 nMinKey = 0;
+-  i64 nMaxKey = 0;
++  MemPage *pPage = 0;      /* The page being analyzed */
++  int i;                   /* Loop counter */
++  int rc;                  /* Result code from subroutine call */
++  int depth = -1, d2;      /* Depth of a subtree */
++  int pgno;                /* Page number */
++  int nFrag;               /* Number of fragmented bytes on the page */
++  int hdr;                 /* Offset to the page header */
++  int cellStart;           /* Offset to the start of the cell pointer array */
++  int nCell;               /* Number of cells */
++  int doCoverageCheck = 1; /* True if cell coverage checking should be done */
++  int keyCanBeEqual = 1;   /* True if IPK can be equal to maxKey
++                           ** False if IPK must be strictly less than maxKey */
++  u8 *data;                /* Page content */
++  u8 *pCell;               /* Cell content */
++  u8 *pCellIdx;            /* Next element of the cell pointer array */
++  BtShared *pBt;           /* The BtShared object that owns pPage */
++  u32 pc;                  /* Address of a cell */
++  u32 usableSize;          /* Usable size of the page */
++  u32 contentOffset;       /* Offset to the start of the cell content area */
++  u32 *heap = 0;           /* Min-heap used for checking cell coverage */
++  u32 x, prev = 0;         /* Next and previous entry on the min-heap */
+   const char *saved_zPfx = pCheck->zPfx;
+   int saved_v1 = pCheck->v1;
+   int saved_v2 = pCheck->v2;
++  u8 savedIsInit = 0;
+ 
+   /* Check that the page exists
+   */
+@@ -61681,54 +72095,96 @@
+   if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
+     checkAppendMsg(pCheck,
+        "unable to get the page. error code=%d", rc);
+-    depth = -1;
+     goto end_of_check;
+   }
+ 
+   /* Clear MemPage.isInit to make sure the corruption detection code in
+   ** btreeInitPage() is executed.  */
++  savedIsInit = pPage->isInit;
+   pPage->isInit = 0;
+   if( (rc = btreeInitPage(pPage))!=0 ){
+     assert( rc==SQLITE_CORRUPT );  /* The only possible error from InitPage */
+     checkAppendMsg(pCheck,
+                    "btreeInitPage() returns error code %d", rc);
+-    releasePage(pPage);
+-    depth = -1;
+     goto end_of_check;
+   }
++  data = pPage->aData;
++  hdr = pPage->hdrOffset;
+ 
+-  /* Check out all the cells.
+-  */
+-  depth = 0;
+-  for(i=0; i<pPage->nCell && pCheck->mxErr; i++){
+-    u8 *pCell;
+-    u32 sz;
++  /* Set up for cell analysis */
++  pCheck->zPfx = "On tree page %d cell %d: ";
++  contentOffset = get2byteNotZero(&data[hdr+5]);
++  assert( contentOffset<=usableSize );  /* Enforced by btreeInitPage() */
++
++  /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
++  ** number of cells on the page. */
++  nCell = get2byte(&data[hdr+3]);
++  assert( pPage->nCell==nCell );
++
++  /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page
++  ** immediately follows the b-tree page header. */
++  cellStart = hdr + 12 - 4*pPage->leaf;
++  assert( pPage->aCellIdx==&data[cellStart] );
++  pCellIdx = &data[cellStart + 2*(nCell-1)];
++
++  if( !pPage->leaf ){
++    /* Analyze the right-child page of internal pages */
++    pgno = get4byte(&data[hdr+8]);
++#ifndef SQLITE_OMIT_AUTOVACUUM
++    if( pBt->autoVacuum ){
++      pCheck->zPfx = "On page %d at right child: ";
++      checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
++    }
++#endif
++    depth = checkTreePage(pCheck, pgno, &maxKey, maxKey);
++    keyCanBeEqual = 0;
++  }else{
++    /* For leaf pages, the coverage check will occur in the same loop
++    ** as the other cell checks, so initialize the heap.  */
++    heap = pCheck->heap;
++    heap[0] = 0;
++  }
++
++  /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte
++  ** integer offsets to the cell contents. */
++  for(i=nCell-1; i>=0 && pCheck->mxErr; i--){
+     CellInfo info;
+ 
+-    /* Check payload overflow pages
+-    */
+-    pCheck->zPfx = "On tree page %d cell %d: ";
+-    pCheck->v1 = iPage;
++    /* Check cell size */
+     pCheck->v2 = i;
+-    pCell = findCell(pPage,i);
+-    btreeParseCellPtr(pPage, pCell, &info);
+-    sz = info.nPayload;
+-    /* For intKey pages, check that the keys are in order.
+-    */
++    assert( pCellIdx==&data[cellStart + i*2] );
++    pc = get2byteAligned(pCellIdx);
++    pCellIdx -= 2;
++    if( pc<contentOffset || pc>usableSize-4 ){
++      checkAppendMsg(pCheck, "Offset %d out of range %d..%d",
++                             pc, contentOffset, usableSize-4);
++      doCoverageCheck = 0;
++      continue;
++    }
++    pCell = &data[pc];
++    pPage->xParseCell(pPage, pCell, &info);
++    if( pc+info.nSize>usableSize ){
++      checkAppendMsg(pCheck, "Extends off end of page");
++      doCoverageCheck = 0;
++      continue;
++    }
++
++    /* Check for integer primary key out of range */
+     if( pPage->intKey ){
+-      if( i==0 ){
+-        nMinKey = nMaxKey = info.nKey;
+-      }else if( info.nKey <= nMaxKey ){
+-        checkAppendMsg(pCheck,
+-           "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey);
++      if( keyCanBeEqual ? (info.nKey > maxKey) : (info.nKey >= maxKey) ){
++        checkAppendMsg(pCheck, "Rowid %lld out of order", info.nKey);
+       }
+-      nMaxKey = info.nKey;
++      maxKey = info.nKey;
++      keyCanBeEqual = 0;     /* Only the first key on the page may ==maxKey */
+     }
+-    if( (sz>info.nLocal) 
+-     && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
+-    ){
+-      int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
+-      Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
++
++    /* Check the content overflow list */
++    if( info.nPayload>info.nLocal ){
++      int nPage;       /* Number of pages on the overflow chain */
++      Pgno pgnoOvfl;   /* First page of the overflow chain */
++      assert( pc + info.nSize - 4 <= usableSize );
++      nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4);
++      pgnoOvfl = get4byte(&pCell[info.nSize - 4]);
+ #ifndef SQLITE_OMIT_AUTOVACUUM
+       if( pBt->autoVacuum ){
+         checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage);
+@@ -61737,118 +72193,57 @@
+       checkList(pCheck, 0, pgnoOvfl, nPage);
+     }
+ 
+-    /* Check sanity of left child page.
+-    */
+     if( !pPage->leaf ){
++      /* Check sanity of left child page for internal pages */
+       pgno = get4byte(pCell);
+ #ifndef SQLITE_OMIT_AUTOVACUUM
+       if( pBt->autoVacuum ){
+         checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
+       }
+ #endif
+-      d2 = checkTreePage(pCheck, pgno, &nMinKey, i==0?NULL:&nMaxKey);
+-      if( i>0 && d2!=depth ){
++      d2 = checkTreePage(pCheck, pgno, &maxKey, maxKey);
++      keyCanBeEqual = 0;
++      if( d2!=depth ){
+         checkAppendMsg(pCheck, "Child page depth differs");
++        depth = d2;
+       }
+-      depth = d2;
+-    }
+-  }
+-
+-  if( !pPage->leaf ){
+-    pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
+-    pCheck->zPfx = "On page %d at right child: ";
+-    pCheck->v1 = iPage;
+-#ifndef SQLITE_OMIT_AUTOVACUUM
+-    if( pBt->autoVacuum ){
+-      checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
+-    }
+-#endif
+-    checkTreePage(pCheck, pgno, NULL, !pPage->nCell?NULL:&nMaxKey);
+-  }
+- 
+-  /* For intKey leaf pages, check that the min/max keys are in order
+-  ** with any left/parent/right pages.
+-  */
+-  pCheck->zPfx = "Page %d: ";
+-  pCheck->v1 = iPage;
+-  if( pPage->leaf && pPage->intKey ){
+-    /* if we are a left child page */
+-    if( pnParentMinKey ){
+-      /* if we are the left most child page */
+-      if( !pnParentMaxKey ){
+-        if( nMaxKey > *pnParentMinKey ){
+-          checkAppendMsg(pCheck,
+-              "Rowid %lld out of order (max larger than parent min of %lld)",
+-              nMaxKey, *pnParentMinKey);
+-        }
+-      }else{
+-        if( nMinKey <= *pnParentMinKey ){
+-          checkAppendMsg(pCheck,
+-              "Rowid %lld out of order (min less than parent min of %lld)",
+-              nMinKey, *pnParentMinKey);
+-        }
+-        if( nMaxKey > *pnParentMaxKey ){
+-          checkAppendMsg(pCheck,
+-              "Rowid %lld out of order (max larger than parent max of %lld)",
+-              nMaxKey, *pnParentMaxKey);
+-        }
+-        *pnParentMinKey = nMaxKey;
+-      }
+-    /* else if we're a right child page */
+-    } else if( pnParentMaxKey ){
+-      if( nMinKey <= *pnParentMaxKey ){
+-        checkAppendMsg(pCheck,
+-            "Rowid %lld out of order (min less than parent max of %lld)",
+-            nMinKey, *pnParentMaxKey);
+-      }
++    }else{
++      /* Populate the coverage-checking heap for leaf pages */
++      btreeHeapInsert(heap, (pc<<16)|(pc+info.nSize-1));
+     }
+   }
++  *piMinKey = maxKey;
+ 
+   /* Check for complete coverage of the page
+   */
+-  data = pPage->aData;
+-  hdr = pPage->hdrOffset;
+-  heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
+   pCheck->zPfx = 0;
+-  if( heap==0 ){
+-    pCheck->mallocFailed = 1;
+-  }else{
+-    int contentOffset = get2byteNotZero(&data[hdr+5]);
+-    assert( contentOffset<=usableSize );  /* Enforced by btreeInitPage() */
+-    heap[0] = 0;
+-    btreeHeapInsert(heap, contentOffset-1);
+-    /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
+-    ** number of cells on the page. */
+-    nCell = get2byte(&data[hdr+3]);
+-    /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page
+-    ** immediately follows the b-tree page header. */
+-    cellStart = hdr + 12 - 4*pPage->leaf;
+-    /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte
+-    ** integer offsets to the cell contents. */
+-    for(i=0; i<nCell; i++){
+-      int pc = get2byte(&data[cellStart+i*2]);
+-      u32 size = 65536;
+-      if( pc<=usableSize-4 ){
+-        size = cellSizePtr(pPage, &data[pc]);
+-      }
+-      if( (int)(pc+size-1)>=usableSize ){
+-        pCheck->zPfx = 0;
+-        checkAppendMsg(pCheck,
+-            "Corruption detected in cell %d on page %d",i,iPage);
+-      }else{
++  if( doCoverageCheck && pCheck->mxErr>0 ){
++    /* For leaf pages, the min-heap has already been initialized and the
++    ** cells have already been inserted.  But for internal pages, that has
++    ** not yet been done, so do it now */
++    if( !pPage->leaf ){
++      heap = pCheck->heap;
++      heap[0] = 0;
++      for(i=nCell-1; i>=0; i--){
++        u32 size;
++        pc = get2byteAligned(&data[cellStart+i*2]);
++        size = pPage->xCellSize(pPage, &data[pc]);
+         btreeHeapInsert(heap, (pc<<16)|(pc+size-1));
+       }
+     }
+-    /* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
++    /* Add the freeblocks to the min-heap
++    **
++    ** EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
+     ** is the offset of the first freeblock, or zero if there are no
+-    ** freeblocks on the page. */
++    ** freeblocks on the page. 
++    */
+     i = get2byte(&data[hdr+1]);
+     while( i>0 ){
+       int size, j;
+-      assert( i<=usableSize-4 );     /* Enforced by btreeInitPage() */
++      assert( (u32)i<=usableSize-4 );     /* Enforced by btreeInitPage() */
+       size = get2byte(&data[i+2]);
+-      assert( i+size<=usableSize );  /* Enforced by btreeInitPage() */
+-      btreeHeapInsert(heap, (i<<16)|(i+size-1));
++      assert( (u32)(i+size)<=usableSize );  /* Enforced by btreeInitPage() */
++      btreeHeapInsert(heap, (((u32)i)<<16)|(i+size-1));
+       /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
+       ** big-endian integer which is the offset in the b-tree page of the next
+       ** freeblock in the chain, or zero if the freeblock is the last on the
+@@ -61857,39 +72252,50 @@
+       /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
+       ** increasing offset. */
+       assert( j==0 || j>i+size );  /* Enforced by btreeInitPage() */
+-      assert( j<=usableSize-4 );   /* Enforced by btreeInitPage() */
++      assert( (u32)j<=usableSize-4 );   /* Enforced by btreeInitPage() */
+       i = j;
+     }
+-    cnt = 0;
+-    assert( heap[0]>0 );
+-    assert( (heap[1]>>16)==0 );
+-    btreeHeapPull(heap,&prev);
++    /* Analyze the min-heap looking for overlap between cells and/or 
++    ** freeblocks, and counting the number of untracked bytes in nFrag.
++    ** 
++    ** Each min-heap entry is of the form:    (start_address<<16)|end_address.
++    ** There is an implied first entry the covers the page header, the cell
++    ** pointer index, and the gap between the cell pointer index and the start
++    ** of cell content.  
++    **
++    ** The loop below pulls entries from the min-heap in order and compares
++    ** the start_address against the previous end_address.  If there is an
++    ** overlap, that means bytes are used multiple times.  If there is a gap,
++    ** that gap is added to the fragmentation count.
++    */
++    nFrag = 0;
++    prev = contentOffset - 1;   /* Implied first min-heap entry */
+     while( btreeHeapPull(heap,&x) ){
+-      if( (prev&0xffff)+1>(x>>16) ){
++      if( (prev&0xffff)>=(x>>16) ){
+         checkAppendMsg(pCheck,
+           "Multiple uses for byte %u of page %d", x>>16, iPage);
+         break;
+       }else{
+-        cnt += (x>>16) - (prev&0xffff) - 1;
++        nFrag += (x>>16) - (prev&0xffff) - 1;
+         prev = x;
+       }
+     }
+-    cnt += usableSize - (prev&0xffff) - 1;
++    nFrag += usableSize - (prev&0xffff) - 1;
+     /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments
+     ** is stored in the fifth field of the b-tree page header.
+     ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the
+     ** number of fragmented free bytes within the cell content area.
+     */
+-    if( heap[0]==0 && cnt!=data[hdr+7] ){
++    if( heap[0]==0 && nFrag!=data[hdr+7] ){
+       checkAppendMsg(pCheck,
+           "Fragmentation of %d bytes reported as %d on page %d",
+-          cnt, data[hdr+7], iPage);
++          nFrag, data[hdr+7], iPage);
+     }
+   }
+-  sqlite3PageFree(heap);
+-  releasePage(pPage);
+ 
+ end_of_check:
++  if( !doCoverageCheck ) pPage->isInit = savedIsInit;
++  releasePage(pPage);
+   pCheck->zPfx = saved_zPfx;
+   pCheck->v1 = saved_v1;
+   pCheck->v2 = saved_v2;
+@@ -61919,14 +72325,16 @@
+   int *pnErr    /* Write number of errors seen to this variable */
+ ){
+   Pgno i;
+-  int nRef;
+   IntegrityCk sCheck;
+   BtShared *pBt = p->pBt;
++  int savedDbFlags = pBt->db->flags;
+   char zErr[100];
++  VVA_ONLY( int nRef );
+ 
+   sqlite3BtreeEnter(p);
+   assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE );
+-  nRef = sqlite3PagerRefcount(pBt->pPager);
++  VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) );
++  assert( nRef>=0 );
+   sCheck.pBt = pBt;
+   sCheck.pPager = pBt->pPager;
+   sCheck.nPage = btreePagecount(sCheck.pBt);
+@@ -61936,21 +72344,27 @@
+   sCheck.zPfx = 0;
+   sCheck.v1 = 0;
+   sCheck.v2 = 0;
+-  *pnErr = 0;
++  sCheck.aPgRef = 0;
++  sCheck.heap = 0;
++  sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
++  sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL;
+   if( sCheck.nPage==0 ){
+-    sqlite3BtreeLeave(p);
+-    return 0;
++    goto integrity_ck_cleanup;
+   }
+ 
+   sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1);
+   if( !sCheck.aPgRef ){
+-    *pnErr = 1;
+-    sqlite3BtreeLeave(p);
+-    return 0;
++    sCheck.mallocFailed = 1;
++    goto integrity_ck_cleanup;
+   }
++  sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
++  if( sCheck.heap==0 ){
++    sCheck.mallocFailed = 1;
++    goto integrity_ck_cleanup;
++  }
++
+   i = PENDING_BYTE_PAGE(pBt);
+   if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
+-  sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
+ 
+   /* Check the integrity of the freelist
+   */
+@@ -61961,17 +72375,19 @@
+ 
+   /* Check all the tables.
+   */
++  testcase( pBt->db->flags & SQLITE_CellSizeCk );
++  pBt->db->flags &= ~SQLITE_CellSizeCk;
+   for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
++    i64 notUsed;
+     if( aRoot[i]==0 ) continue;
+ #ifndef SQLITE_OMIT_AUTOVACUUM
+     if( pBt->autoVacuum && aRoot[i]>1 ){
+       checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0);
+     }
+ #endif
+-    sCheck.zPfx = "List of tree roots: ";
+-    checkTreePage(&sCheck, aRoot[i], NULL, NULL);
+-    sCheck.zPfx = 0;
++    checkTreePage(&sCheck, aRoot[i], &notUsed, LARGEST_INT64);
+   }
++  pBt->db->flags = savedDbFlags;
+ 
+   /* Make sure every page in the file is referenced
+   */
+@@ -61995,28 +72411,20 @@
+ #endif
+   }
+ 
+-  /* Make sure this analysis did not leave any unref() pages.
+-  ** This is an internal consistency check; an integrity check
+-  ** of the integrity check.
+-  */
+-  if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){
+-    checkAppendMsg(&sCheck,
+-      "Outstanding page count goes from %d to %d during this analysis",
+-      nRef, sqlite3PagerRefcount(pBt->pPager)
+-    );
+-  }
+-
+   /* Clean  up and report errors.
+   */
+-  sqlite3BtreeLeave(p);
++integrity_ck_cleanup:
++  sqlite3PageFree(sCheck.heap);
+   sqlite3_free(sCheck.aPgRef);
+   if( sCheck.mallocFailed ){
+     sqlite3StrAccumReset(&sCheck.errMsg);
+-    *pnErr = sCheck.nErr+1;
+-    return 0;
++    sCheck.nErr++;
+   }
+   *pnErr = sCheck.nErr;
+   if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
++  /* Make sure this analysis did not leave any unref() pages. */
++  assert( nRef==sqlite3PagerRefcount(pBt->pPager) );
++  sqlite3BtreeLeave(p);
+   return sqlite3StrAccumFinish(&sCheck.errMsg);
+ }
+ #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+@@ -62071,7 +72479,7 @@
+     if( pBt->inTransaction!=TRANS_NONE ){
+       rc = SQLITE_LOCKED;
+     }else{
+-      rc = sqlite3PagerCheckpoint(pBt->pPager, eMode, pnLog, pnCkpt);
++      rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt);
+     }
+     sqlite3BtreeLeave(p);
+   }
+@@ -62179,7 +72587,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
+   int rc;
+-  assert( cursorHoldsMutex(pCsr) );
++  assert( cursorOwnsBtShared(pCsr) );
+   assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
+   assert( pCsr->curFlags & BTCF_Incrblob );
+ 
+@@ -62227,6 +72635,7 @@
+ */
+ SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *pCur){
+   pCur->curFlags |= BTCF_Incrblob;
++  pCur->pBtree->hasIncrblobCur = 1;
+ }
+ #endif
+ 
+@@ -62267,22 +72676,12 @@
+ }
+ 
+ /*
+-** set the mask of hint flags for cursor pCsr.
+-*/
+-SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
+-  assert( mask==BTREE_BULKLOAD || mask==BTREE_SEEK_EQ || mask==0 );
+-  pCsr->hints = mask;
+-}
+-
+-#ifdef SQLITE_DEBUG
+-/*
+ ** Return true if the cursor has a hint specified.  This routine is
+ ** only used from within assert() statements
+ */
+ SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){
+   return (pCsr->hints & mask)!=0;
+ }
+-#endif
+ 
+ /*
+ ** Return true if the given Btree is read-only.
+@@ -62296,6 +72695,25 @@
+ */
+ SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }
+ 
++#if !defined(SQLITE_OMIT_SHARED_CACHE)
++/*
++** Return true if the Btree passed as the only argument is sharable.
++*/
++SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){
++  return p->sharable;
++}
++
++/*
++** Return the number of connections to the BtShared object accessed by
++** the Btree handle passed as the only argument. For private caches 
++** this is always 1. For shared caches it may be 1 or greater.
++*/
++SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){
++  testcase( p->sharable );
++  return p->pBt->nRef;
++}
++#endif
++
+ /************** End of btree.c ***********************************************/
+ /************** Begin file backup.c ******************************************/
+ /*
+@@ -62312,6 +72730,8 @@
+ ** This file contains the implementation of the sqlite3_backup_XXX() 
+ ** API functions and the related features.
+ */
++/* #include "sqliteInt.h" */
++/* #include "btreeInt.h" */
+ 
+ /*
+ ** Structure allocated for each backup operation.
+@@ -62381,22 +72801,16 @@
+   int i = sqlite3FindDbName(pDb, zDb);
+ 
+   if( i==1 ){
+-    Parse *pParse;
++    Parse sParse;
+     int rc = 0;
+-    pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
+-    if( pParse==0 ){
+-      sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory");
+-      rc = SQLITE_NOMEM;
+-    }else{
+-      pParse->db = pDb;
+-      if( sqlite3OpenTempDatabase(pParse) ){
+-        sqlite3ErrorWithMsg(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
+-        rc = SQLITE_ERROR;
+-      }
+-      sqlite3DbFree(pErrorDb, pParse->zErrMsg);
+-      sqlite3ParserReset(pParse);
+-      sqlite3StackFree(pErrorDb, pParse);
++    memset(&sParse, 0, sizeof(sParse));
++    sParse.db = pDb;
++    if( sqlite3OpenTempDatabase(&sParse) ){
++      sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
++      rc = SQLITE_ERROR;
+     }
++    sqlite3DbFree(pErrorDb, sParse.zErrMsg);
++    sqlite3ParserReset(&sParse);
+     if( rc ){
+       return 0;
+     }
+@@ -62442,7 +72856,7 @@
+ ** If an error occurs, NULL is returned and an error code and error message
+ ** stored in database handle pDestDb.
+ */
+-SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
++SQLITE_API sqlite3_backup *sqlite3_backup_init(
+   sqlite3* pDestDb,                     /* Database to write to */
+   const char *zDestDb,                  /* Name of database within pDestDb */
+   sqlite3* pSrcDb,                      /* Database connection to read from */
+@@ -62480,7 +72894,7 @@
+     ** sqlite3_backup_finish(). */
+     p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
+     if( !p ){
+-      sqlite3Error(pDestDb, SQLITE_NOMEM);
++      sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT);
+     }
+   }
+ 
+@@ -62494,7 +72908,6 @@
+     p->isAttached = 0;
+ 
+     if( 0==p->pSrc || 0==p->pDest 
+-     || setDestPgsz(p)==SQLITE_NOMEM 
+      || checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK 
+      ){
+       /* One (or both) of the named databases did not exist or an OOM
+@@ -62591,7 +73004,7 @@
+     DbPage *pDestPg = 0;
+     Pgno iDest = (Pgno)(iOff/nDestPgsz)+1;
+     if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt) ) continue;
+-    if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg))
++    if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg, 0))
+      && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg))
+     ){
+       const u8 *zIn = &zSrcData[iOff%nSrcPgsz];
+@@ -62650,7 +73063,7 @@
+ /*
+ ** Copy nPage pages from the source b-tree to the destination.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage){
++SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
+   int rc;
+   int destMode;       /* Destination journal mode */
+   int pgszSrc = 0;    /* Source page size */
+@@ -62682,14 +73095,6 @@
+       rc = SQLITE_OK;
+     }
+ 
+-    /* Lock the destination database, if it is not locked already. */
+-    if( SQLITE_OK==rc && p->bDestLocked==0
+-     && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) 
+-    ){
+-      p->bDestLocked = 1;
+-      sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
+-    }
+-
+     /* If there is no open read-transaction on the source database, open
+     ** one now. If a transaction is opened here, then it will be closed
+     ** before this function exits.
+@@ -62699,6 +73104,24 @@
+       bCloseTrans = 1;
+     }
+ 
++    /* If the destination database has not yet been locked (i.e. if this
++    ** is the first call to backup_step() for the current backup operation),
++    ** try to set its page size to the same as the source database. This
++    ** is especially important on ZipVFS systems, as in that case it is
++    ** not possible to create a database file that uses one page size by
++    ** writing to it with another.  */
++    if( p->bDestLocked==0 && rc==SQLITE_OK && setDestPgsz(p)==SQLITE_NOMEM ){
++      rc = SQLITE_NOMEM;
++    }
++
++    /* Lock the destination database, if it is not locked already. */
++    if( SQLITE_OK==rc && p->bDestLocked==0
++     && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) 
++    ){
++      p->bDestLocked = 1;
++      sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
++    }
++
+     /* Do not allow backup if the destination database is in WAL mode
+     ** and the page sizes are different between source and destination */
+     pgszSrc = sqlite3BtreeGetPageSize(p->pSrc);
+@@ -62717,8 +73140,7 @@
+       const Pgno iSrcPg = p->iNext;                 /* Source page number */
+       if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
+         DbPage *pSrcPg;                             /* Source page object */
+-        rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
+-                                 PAGER_GET_READONLY);
++        rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY);
+         if( rc==SQLITE_OK ){
+           rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
+           sqlite3PagerUnref(pSrcPg);
+@@ -62818,7 +73240,7 @@
+           for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){
+             if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){
+               DbPage *pPg;
+-              rc = sqlite3PagerGet(pDestPager, iPg, &pPg);
++              rc = sqlite3PagerGet(pDestPager, iPg, &pPg, 0);
+               if( rc==SQLITE_OK ){
+                 rc = sqlite3PagerWrite(pPg);
+                 sqlite3PagerUnref(pPg);
+@@ -62838,7 +73260,7 @@
+           ){
+             PgHdr *pSrcPg = 0;
+             const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
+-            rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
++            rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg, 0);
+             if( rc==SQLITE_OK ){
+               u8 *zData = sqlite3PagerGetData(pSrcPg);
+               rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
+@@ -62880,7 +73302,7 @@
+     }
+   
+     if( rc==SQLITE_IOERR_NOMEM ){
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+     }
+     p->rc = rc;
+   }
+@@ -62895,7 +73317,7 @@
+ /*
+ ** Release all resources associated with an sqlite3_backup* handle.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p){
++SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
+   sqlite3_backup **pp;                 /* Ptr to head of pagers backup list */
+   sqlite3 *pSrcDb;                     /* Source database connection */
+   int rc;                              /* Value to return */
+@@ -62947,7 +73369,7 @@
+ ** Return the number of pages still to be backed up as of the most recent
+ ** call to sqlite3_backup_step().
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p){
++SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( p==0 ){
+     (void)SQLITE_MISUSE_BKPT;
+@@ -62961,7 +73383,7 @@
+ ** Return the total number of pages in the source database as of the most 
+ ** recent call to sqlite3_backup_step().
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p){
++SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( p==0 ){
+     (void)SQLITE_MISUSE_BKPT;
+@@ -62983,9 +73405,13 @@
+ ** corresponding to the source database is held when this function is
+ ** called.
+ */
+-SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){
+-  sqlite3_backup *p;                   /* Iterator variable */
+-  for(p=pBackup; p; p=p->pNext){
++static SQLITE_NOINLINE void backupUpdate(
++  sqlite3_backup *p,
++  Pgno iPage,
++  const u8 *aData
++){
++  assert( p!=0 );
++  do{
+     assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
+     if( !isFatalError(p->rc) && iPage<p->iNext ){
+       /* The backup process p has already copied page iPage. But now it
+@@ -63002,7 +73428,10 @@
+         p->rc = rc;
+       }
+     }
+-  }
++  }while( (p = p->pNext)!=0 );
++}
++SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){
++  if( pBackup ) backupUpdate(pBackup, iPage, aData);
+ }
+ 
+ /*
+@@ -63060,15 +73489,19 @@
+   b.pDest = pTo;
+   b.iNext = 1;
+ 
++#ifdef SQLITE_HAS_CODEC
++  sqlite3PagerAlignReserve(sqlite3BtreePager(pTo), sqlite3BtreePager(pFrom));
++#endif
++
+   /* 0x7FFFFFFF is the hard limit for the number of pages in a database
+   ** file. By passing this as the number of pages to copy to
+   ** sqlite3_backup_step(), we can guarantee that the copy finishes 
+   ** within a single call (unless an error occurs). The assert() statement
+   ** checks this assumption - (p->rc) should be set to either SQLITE_DONE 
+-  ** or an error code.
+-  */
++  ** or an error code.  */
+   sqlite3_backup_step(&b, 0x7FFFFFFF);
+   assert( b.rc!=SQLITE_OK );
++
+   rc = sqlite3_backup_finish(&b);
+   if( rc==SQLITE_OK ){
+     pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
+@@ -63103,6 +73536,8 @@
+ ** only within the VDBE.  Interface routines refer to a Mem using the
+ ** name sqlite_value
+ */
++/* #include "sqliteInt.h" */
++/* #include "vdbeInt.h" */
+ 
+ #ifdef SQLITE_DEBUG
+ /*
+@@ -63113,7 +73548,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
+   /* If MEM_Dyn is set then Mem.xDel!=0.  
+-  ** Mem.xDel is might not be initialized if MEM_Dyn is clear.
++  ** Mem.xDel might not be initialized if MEM_Dyn is clear.
+   */
+   assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
+ 
+@@ -63126,6 +73561,35 @@
+   /* Cannot be both MEM_Int and MEM_Real at the same time */
+   assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
+ 
++  if( p->flags & MEM_Null ){
++    /* Cannot be both MEM_Null and some other type */
++    assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
++                         |MEM_RowSet|MEM_Frame|MEM_Agg|MEM_Zero))==0 );
++
++    /* If MEM_Null is set, then either the value is a pure NULL (the usual
++    ** case) or it is a pointer set using sqlite3_bind_pointer() or
++    ** sqlite3_result_pointer().  If a pointer, then MEM_Term must also be
++    ** set.
++    */
++    if( (p->flags & (MEM_Term|MEM_Subtype))==(MEM_Term|MEM_Subtype) ){
++      /* This is a pointer type.  There may be a flag to indicate what to
++      ** do with the pointer. */
++      assert( ((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
++              ((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
++              ((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 );
++
++      /* No other bits set */
++      assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype
++                           |MEM_Dyn|MEM_Ephem|MEM_Static))==0 );
++    }else{
++      /* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn,
++      ** MEM_Ephem, MEM_Cleared, or MEM_Subtype */
++    }
++  }else{
++    /* The MEM_Cleared bit is only allowed on NULLs */
++    assert( (p->flags & MEM_Cleared)==0 );
++  }
++
+   /* The szMalloc field holds the correct memory allocation size */
+   assert( p->szMalloc==0
+        || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) );
+@@ -63202,6 +73666,7 @@
+ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
+   assert( sqlite3VdbeCheckMemInvariants(pMem) );
+   assert( (pMem->flags&MEM_RowSet)==0 );
++  testcase( pMem->db==0 );
+ 
+   /* If the bPreserve flag is set to true, then the memory cell must already
+   ** contain a valid string or blob value.  */
+@@ -63210,26 +73675,24 @@
+ 
+   assert( pMem->szMalloc==0
+        || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
+-  if( pMem->szMalloc<n ){
+-    if( n<32 ) n = 32;
+-    if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){
+-      pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
+-      bPreserve = 0;
+-    }else{
+-      if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
+-      pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
+-    }
+-    if( pMem->zMalloc==0 ){
+-      sqlite3VdbeMemSetNull(pMem);
+-      pMem->z = 0;
+-      pMem->szMalloc = 0;
+-      return SQLITE_NOMEM;
+-    }else{
+-      pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
+-    }
++  if( n<32 ) n = 32;
++  if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){
++    pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
++    bPreserve = 0;
++  }else{
++    if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
++    pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
++  }
++  if( pMem->zMalloc==0 ){
++    sqlite3VdbeMemSetNull(pMem);
++    pMem->z = 0;
++    pMem->szMalloc = 0;
++    return SQLITE_NOMEM_BKPT;
++  }else{
++    pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
+   }
+ 
+-  if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
++  if( bPreserve && pMem->z && ALWAYS(pMem->z!=pMem->zMalloc) ){
+     memcpy(pMem->zMalloc, pMem->z, pMem->n);
+   }
+   if( (pMem->flags&MEM_Dyn)!=0 ){
+@@ -63274,18 +73737,18 @@
+ ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
+ */
+ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
+-  int f;
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+   assert( (pMem->flags&MEM_RowSet)==0 );
+-  ExpandBlob(pMem);
+-  f = pMem->flags;
+-  if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){
+-    if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
+-      return SQLITE_NOMEM;
++  if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
++    if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
++    if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
++      if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
++        return SQLITE_NOMEM_BKPT;
++      }
++      pMem->z[pMem->n] = 0;
++      pMem->z[pMem->n+1] = 0;
++      pMem->flags |= MEM_Term;
+     }
+-    pMem->z[pMem->n] = 0;
+-    pMem->z[pMem->n+1] = 0;
+-    pMem->flags |= MEM_Term;
+   }
+   pMem->flags &= ~MEM_Ephem;
+ #ifdef SQLITE_DEBUG
+@@ -63301,25 +73764,24 @@
+ */
+ #ifndef SQLITE_OMIT_INCRBLOB
+ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
+-  if( pMem->flags & MEM_Zero ){
+-    int nByte;
+-    assert( pMem->flags&MEM_Blob );
+-    assert( (pMem->flags&MEM_RowSet)==0 );
+-    assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+-
+-    /* Set nByte to the number of bytes required to store the expanded blob. */
+-    nByte = pMem->n + pMem->u.nZero;
+-    if( nByte<=0 ){
+-      nByte = 1;
+-    }
+-    if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
+-      return SQLITE_NOMEM;
+-    }
++  int nByte;
++  assert( pMem->flags & MEM_Zero );
++  assert( pMem->flags&MEM_Blob );
++  assert( (pMem->flags&MEM_RowSet)==0 );
++  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+ 
+-    memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
+-    pMem->n += pMem->u.nZero;
+-    pMem->flags &= ~(MEM_Zero|MEM_Term);
++  /* Set nByte to the number of bytes required to store the expanded blob. */
++  nByte = pMem->n + pMem->u.nZero;
++  if( nByte<=0 ){
++    nByte = 1;
+   }
++  if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
++    return SQLITE_NOMEM_BKPT;
++  }
++
++  memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
++  pMem->n += pMem->u.nZero;
++  pMem->flags &= ~(MEM_Zero|MEM_Term);
+   return SQLITE_OK;
+ }
+ #endif
+@@ -63330,7 +73792,7 @@
+ */
+ static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
+   if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   pMem->z[pMem->n] = 0;
+   pMem->z[pMem->n+1] = 0;
+@@ -63379,7 +73841,8 @@
+ 
+ 
+   if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
+-    return SQLITE_NOMEM;
++    pMem->enc = 0;
++    return SQLITE_NOMEM_BKPT;
+   }
+ 
+   /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
+@@ -63426,7 +73889,7 @@
+     ctx.pFunc = pFunc;
+     pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
+     assert( (pMem->flags & MEM_Dyn)==0 );
+-    if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
++    if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
+     memcpy(pMem, &t, sizeof(t));
+     rc = ctx.isError;
+   }
+@@ -63477,7 +73940,7 @@
+     vdbeMemClearExternAndSetNull(p);
+   }
+   if( p->szMalloc ){
+-    sqlite3DbFree(p->db, p->zMalloc);
++    sqlite3DbFreeNN(p->db, p->zMalloc);
+     p->szMalloc = 0;
+   }
+   p->z = 0;
+@@ -63505,7 +73968,7 @@
+ ** If the double is out of range of a 64-bit signed integer then
+ ** return the closest available 64-bit signed integer.
+ */
+-static i64 doubleToInt64(double r){
++static SQLITE_NOINLINE i64 doubleToInt64(double r){
+ #ifdef SQLITE_OMIT_FLOATING_POINT
+   /* When floating-point is omitted, double and int64 are the same thing */
+   return r;
+@@ -63541,6 +74004,11 @@
+ **
+ ** If pMem represents a string value, its encoding might be changed.
+ */
++static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){
++  i64 value = 0;
++  sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
++  return value;
++}
+ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
+   int flags;
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+@@ -63551,10 +74019,8 @@
+   }else if( flags & MEM_Real ){
+     return doubleToInt64(pMem->u.r);
+   }else if( flags & (MEM_Str|MEM_Blob) ){
+-    i64 value = 0;
+     assert( pMem->z || pMem->n==0 );
+-    sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
+-    return value;
++    return memIntValue(pMem);
+   }else{
+     return 0;
+   }
+@@ -63566,6 +74032,12 @@
+ ** value.  If it is a string or blob, try to convert it to a double.
+ ** If it is a NULL, return 0.0.
+ */
++static SQLITE_NOINLINE double memRealValue(Mem *pMem){
++  /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
++  double val = (double)0;
++  sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
++  return val;
++}
+ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
+@@ -63574,10 +74046,7 @@
+   }else if( pMem->flags & MEM_Int ){
+     return (double)pMem->u.i;
+   }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
+-    /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+-    double val = (double)0;
+-    sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
+-    return val;
++    return memRealValue(pMem);
+   }else{
+     /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+     return (double)0;
+@@ -63660,7 +74129,7 @@
+     }
+   }
+   assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
+-  pMem->flags &= ~(MEM_Str|MEM_Blob);
++  pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
+   return SQLITE_OK;
+ }
+ 
+@@ -63674,11 +74143,11 @@
+ SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
+   if( pMem->flags & MEM_Null ) return;
+   switch( aff ){
+-    case SQLITE_AFF_NONE: {   /* Really a cast to BLOB */
++    case SQLITE_AFF_BLOB: {   /* Really a cast to BLOB */
+       if( (pMem->flags & MEM_Blob)==0 ){
+         sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
+         assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
+-        MemSetTypeFlag(pMem, MEM_Blob);
++        if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob);
+       }else{
+         pMem->flags &= ~(MEM_TypeMask&~MEM_Blob);
+       }
+@@ -63782,6 +74251,27 @@
+   }
+ }
+ 
++/* A no-op destructor */
++static void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
++
++/*
++** Set the value stored in *pMem should already be a NULL.
++** Also store a pointer to go with it.
++*/
++SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(
++  Mem *pMem,
++  void *pPtr,
++  const char *zPType,
++  void (*xDestructor)(void*)
++){
++  assert( pMem->flags==MEM_Null );
++  pMem->u.zPType = zPType ? zPType : "";
++  pMem->z = pPtr;
++  pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
++  pMem->eSubtype = 'p';
++  pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
++}
++
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+ /*
+ ** Delete any previous value and set the value stored in *pMem to val,
+@@ -63805,7 +74295,7 @@
+   assert( db!=0 );
+   assert( (pMem->flags & MEM_RowSet)==0 );
+   sqlite3VdbeMemRelease(pMem);
+-  pMem->zMalloc = sqlite3DbMallocRaw(db, 64);
++  pMem->zMalloc = sqlite3DbMallocRawNN(db, 64);
+   if( db->mallocFailed ){
+     pMem->flags = MEM_Null;
+     pMem->szMalloc = 0;
+@@ -63846,7 +74336,7 @@
+ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
+   int i;
+   Mem *pX;
+-  for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){
++  for(i=0, pX=pVdbe->aMem; i<pVdbe->nMem; i++, pX++){
+     if( pX->pScopyFrom==pMem ){
+       pX->flags |= MEM_Undefined;
+       pX->pScopyFrom = 0;
+@@ -63856,10 +74346,6 @@
+ }
+ #endif /* SQLITE_DEBUG */
+ 
+-/*
+-** Size of struct Mem not including the Mem.zMalloc member.
+-*/
+-#define MEMCELLSIZE offsetof(Mem,zMalloc)
+ 
+ /*
+ ** Make an shallow copy of pFrom into pTo.  Prior contents of
+@@ -63867,10 +74353,15 @@
+ ** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
+ ** and flags gets srcType (either MEM_Ephem or MEM_Static).
+ */
++static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){
++  vdbeMemClearExternAndSetNull(pTo);
++  assert( !VdbeMemDynamic(pTo) );
++  sqlite3VdbeMemShallowCopy(pTo, pFrom, eType);
++}
+ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
+   assert( (pFrom->flags & MEM_RowSet)==0 );
+   assert( pTo->db==pFrom->db );
+-  if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
++  if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; }
+   memcpy(pTo, pFrom, MEMCELLSIZE);
+   if( (pFrom->flags&MEM_Static)==0 ){
+     pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
+@@ -63886,7 +74377,6 @@
+ SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
+   int rc = SQLITE_OK;
+ 
+-  assert( pTo->db==pFrom->db );
+   assert( (pFrom->flags & MEM_RowSet)==0 );
+   if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
+   memcpy(pTo, pFrom, MEMCELLSIZE);
+@@ -63986,7 +74476,7 @@
+     testcase( nAlloc==31 );
+     testcase( nAlloc==32 );
+     if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     memcpy(pMem->z, z, nAlloc);
+   }else if( xDel==SQLITE_DYNAMIC ){
+@@ -64006,7 +74496,7 @@
+ 
+ #ifndef SQLITE_OMIT_UTF16
+   if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+ #endif
+ 
+@@ -64019,10 +74509,9 @@
+ 
+ /*
+ ** Move data out of a btree key or data field and into a Mem structure.
+-** The data or key is taken from the entry that pCur is currently pointing
++** The data is payload from the entry that pCur is currently pointing
+ ** to.  offset and amt determine what portion of the data or key to retrieve.
+-** key is true to get the key or false to get data.  The result is written
+-** into the pMem element.
++** The result is written into the pMem element.
+ **
+ ** The pMem object must have been initialized.  This routine will use
+ ** pMem->zMalloc to hold the content from the btree, if possible.  New
+@@ -64033,11 +74522,31 @@
+ ** If this routine fails for any reason (malloc returns NULL or unable
+ ** to read from the disk) then the pMem is left in an inconsistent state.
+ */
++static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
++  BtCursor *pCur,   /* Cursor pointing at record to retrieve. */
++  u32 offset,       /* Offset from the start of data to return bytes from. */
++  u32 amt,          /* Number of bytes to return. */
++  Mem *pMem         /* OUT: Return data in this Mem structure. */
++){
++  int rc;
++  pMem->flags = MEM_Null;
++  if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){
++    rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z);
++    if( rc==SQLITE_OK ){
++      pMem->z[amt] = 0;
++      pMem->z[amt+1] = 0;
++      pMem->flags = MEM_Blob|MEM_Term;
++      pMem->n = (int)amt;
++    }else{
++      sqlite3VdbeMemRelease(pMem);
++    }
++  }
++  return rc;
++}
+ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
+   BtCursor *pCur,   /* Cursor pointing at record to retrieve. */
+   u32 offset,       /* Offset from the start of data to return bytes from. */
+   u32 amt,          /* Number of bytes to return. */
+-  int key,          /* If true, retrieve from the btree key, not data. */
+   Mem *pMem         /* OUT: Return data in this Mem structure. */
+ ){
+   char *zData;        /* Data from the btree layer */
+@@ -64050,11 +74559,7 @@
+   /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() 
+   ** that both the BtShared and database handle mutexes are held. */
+   assert( (pMem->flags & MEM_RowSet)==0 );
+-  if( key ){
+-    zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
+-  }else{
+-    zData = (char *)sqlite3BtreeDataFetch(pCur, &available);
+-  }
++  zData = (char *)sqlite3BtreePayloadFetch(pCur, &available);
+   assert( zData!=0 );
+ 
+   if( offset+amt<=available ){
+@@ -64062,22 +74567,7 @@
+     pMem->flags = MEM_Blob|MEM_Ephem;
+     pMem->n = (int)amt;
+   }else{
+-    pMem->flags = MEM_Null;
+-    if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){
+-      if( key ){
+-        rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
+-      }else{
+-        rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
+-      }
+-      if( rc==SQLITE_OK ){
+-        pMem->z[amt] = 0;
+-        pMem->z[amt+1] = 0;
+-        pMem->flags = MEM_Blob|MEM_Term;
+-        pMem->n = (int)amt;
+-      }else{
+-        sqlite3VdbeMemRelease(pMem);
+-      }
+-    }
++    rc = vdbeMemFromBtreeResize(pCur, offset, amt, pMem);
+   }
+ 
+   return rc;
+@@ -64095,10 +74585,8 @@
+   assert( (pVal->flags & MEM_RowSet)==0 );
+   assert( (pVal->flags & (MEM_Null))==0 );
+   if( pVal->flags & (MEM_Blob|MEM_Str) ){
++    if( ExpandBlob(pVal) ) return 0;
+     pVal->flags |= MEM_Str;
+-    if( pVal->flags & MEM_Zero ){
+-      sqlite3VdbeMemExpandBlob(pVal);
+-    }
+     if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){
+       sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
+     }
+@@ -64204,7 +74692,7 @@
+             pRec->aMem[i].db = db;
+           }
+         }else{
+-          sqlite3DbFree(db, pRec);
++          sqlite3DbFreeNN(db, pRec);
+           pRec = 0;
+         }
+       }
+@@ -64226,7 +74714,7 @@
+ ** to be a scalar SQL function. If
+ **
+ **   * all function arguments are SQL literals,
+-**   * the SQLITE_FUNC_CONSTANT function flag is set, and
++**   * one of the SQLITE_FUNC_CONSTANT or _SLOCHNG function flags is set, and
+ **   * the SQLITE_FUNC_NEEDCOLL function flag is not set,
+ **
+ ** then this routine attempts to invoke the SQL function. Assuming no
+@@ -64256,7 +74744,6 @@
+   FuncDef *pFunc = 0;             /* Function definition */
+   sqlite3_value *pVal = 0;        /* New value */
+   int rc = SQLITE_OK;             /* Return code */
+-  int nName;                      /* Size of function name in bytes */
+   ExprList *pList = 0;            /* Function arguments */
+   int i;                          /* Iterator variable */
+ 
+@@ -64264,10 +74751,9 @@
+   assert( (p->flags & EP_TokenOnly)==0 );
+   pList = p->x.pList;
+   if( pList ) nVal = pList->nExpr;
+-  nName = sqlite3Strlen30(p->u.zToken);
+-  pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0);
++  pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0);
+   assert( pFunc );
+-  if( (pFunc->funcFlags & SQLITE_FUNC_CONSTANT)==0 
++  if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 
+    || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
+   ){
+     return SQLITE_OK;
+@@ -64276,7 +74762,7 @@
+   if( pList ){
+     apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
+     if( apVal==0 ){
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+       goto value_from_function_out;
+     }
+     for(i=0; i<nVal; i++){
+@@ -64287,7 +74773,7 @@
+ 
+   pVal = valueNew(db, pCtx);
+   if( pVal==0 ){
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+     goto value_from_function_out;
+   }
+ 
+@@ -64295,7 +74781,7 @@
+   memset(&ctx, 0, sizeof(ctx));
+   ctx.pOut = pVal;
+   ctx.pFunc = pFunc;
+-  pFunc->xFunc(&ctx, nVal, apVal);
++  pFunc->xSFunc(&ctx, nVal, apVal);
+   if( ctx.isError ){
+     rc = ctx.isError;
+     sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal));
+@@ -64318,7 +74804,7 @@
+     for(i=0; i<nVal; i++){
+       sqlite3ValueFree(apVal[i]);
+     }
+-    sqlite3DbFree(db, apVal);
++    sqlite3DbFreeNN(db, apVal);
+   }
+ 
+   *ppVal = pVal;
+@@ -64353,11 +74839,8 @@
+   const char *zNeg = "";
+   int rc = SQLITE_OK;
+ 
+-  if( !pExpr ){
+-    *ppVal = 0;
+-    return SQLITE_OK;
+-  }
+-  while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft;
++  assert( pExpr!=0 );
++  while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
+   if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
+ 
+   /* Compressed expressions only appear when parsing the DEFAULT clause
+@@ -64398,7 +74881,7 @@
+       if( zVal==0 ) goto no_mem;
+       sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
+     }
+-    if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
++    if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){
+       sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
+     }else{
+       sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
+@@ -64409,7 +74892,7 @@
+     }
+   }else if( op==TK_UMINUS ) {
+     /* This branch happens for multiple negative signs.  Ex: -(-5) */
+-    if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) 
++    if( SQLITE_OK==valueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal,pCtx) 
+      && pVal!=0
+     ){
+       sqlite3VdbeMemNumerify(pVal);
+@@ -64426,6 +74909,7 @@
+   }else if( op==TK_NULL ){
+     pVal = valueNew(db, pCtx);
+     if( pVal==0 ) goto no_mem;
++    sqlite3VdbeMemNumerify(pVal);
+   }
+ #ifndef SQLITE_OMIT_BLOB_LITERAL
+   else if( op==TK_BLOB ){
+@@ -64452,7 +74936,7 @@
+   return rc;
+ 
+ no_mem:
+-  db->mallocFailed = 1;
++  sqlite3OomFault(db);
+   sqlite3DbFree(db, zVal);
+   assert( *ppVal==0 );
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+@@ -64460,7 +74944,7 @@
+ #else
+   assert( pCtx==0 ); sqlite3ValueFree(pVal);
+ #endif
+-  return SQLITE_NOMEM;
++  return SQLITE_NOMEM_BKPT;
+ }
+ 
+ /*
+@@ -64480,7 +74964,7 @@
+   u8 affinity,              /* Affinity to use */
+   sqlite3_value **ppVal     /* Write the new value here */
+ ){
+-  return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0);
++  return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0;
+ }
+ 
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+@@ -64498,21 +74982,20 @@
+   sqlite3_value **argv
+ ){
+   const int file_format = 1;
+-  int iSerial;                    /* Serial type */
++  u32 iSerial;                    /* Serial type */
+   int nSerial;                    /* Bytes of space for iSerial as varint */
+-  int nVal;                       /* Bytes of space required for argv[0] */
++  u32 nVal;                       /* Bytes of space required for argv[0] */
+   int nRet;
+   sqlite3 *db;
+   u8 *aRet;
+ 
+   UNUSED_PARAMETER( argc );
+-  iSerial = sqlite3VdbeSerialType(argv[0], file_format);
++  iSerial = sqlite3VdbeSerialType(argv[0], file_format, &nVal);
+   nSerial = sqlite3VarintLen(iSerial);
+-  nVal = sqlite3VdbeSerialTypeLen(iSerial);
+   db = sqlite3_context_db_handle(context);
+ 
+   nRet = 1 + nSerial + nVal;
+-  aRet = sqlite3DbMallocRaw(db, nRet);
++  aRet = sqlite3DbMallocRawNN(db, nRet);
+   if( aRet==0 ){
+     sqlite3_result_error_nomem(context);
+   }else{
+@@ -64520,7 +75003,7 @@
+     putVarint32(&aRet[1], iSerial);
+     sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial);
+     sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
+-    sqlite3DbFree(db, aRet);
++    sqlite3DbFreeNN(db, aRet);
+   }
+ }
+ 
+@@ -64528,15 +75011,10 @@
+ ** Register built-in functions used to help read ANALYZE data.
+ */
+ SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void){
+-  static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = {
++  static FuncDef aAnalyzeTableFuncs[] = {
+     FUNCTION(sqlite_record,   1, 0, 0, recordFunc),
+   };
+-  int i;
+-  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
+-  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs);
+-  for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){
+-    sqlite3FuncDefInsert(pHash, &aFunc[i]);
+-  }
++  sqlite3InsertBuiltinFuncs(aAnalyzeTableFuncs, ArraySize(aAnalyzeTableFuncs));
+ }
+ 
+ /*
+@@ -64571,14 +75049,13 @@
+   /* Skip over any TK_COLLATE nodes */
+   pExpr = sqlite3ExprSkipCollate(pExpr);
+ 
++  assert( pExpr==0 || pExpr->op!=TK_REGISTER || pExpr->op2!=TK_VARIABLE );
+   if( !pExpr ){
+     pVal = valueNew(db, pAlloc);
+     if( pVal ){
+       sqlite3VdbeMemSetNull((Mem*)pVal);
+     }
+-  }else if( pExpr->op==TK_VARIABLE
+-        || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
+-  ){
++  }else if( pExpr->op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){
+     Vdbe *v;
+     int iBindVar = pExpr->iColumn;
+     sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar);
+@@ -64586,9 +75063,7 @@
+       pVal = valueNew(db, pAlloc);
+       if( pVal ){
+         rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]);
+-        if( rc==SQLITE_OK ){
+-          sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
+-        }
++        sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
+         pVal->db = pParse->db;
+       }
+     }
+@@ -64606,9 +75081,9 @@
+ ** structures intended to be compared against sample index keys stored 
+ ** in the sqlite_stat4 table.
+ **
+-** A single call to this function attempts to populates field iVal (leftmost 
+-** is 0 etc.) of the unpacked record with a value extracted from expression
+-** pExpr. Extraction of values is possible if:
++** A single call to this function populates zero or more fields of the
++** record starting with field iVal (fields are numbered from left to
++** right starting with 0). A single field is populated if:
+ **
+ **  * (pExpr==0). In this case the value is assumed to be an SQL NULL,
+ **
+@@ -64617,10 +75092,14 @@
+ **  * The sqlite3ValueFromExpr() function is able to extract a value 
+ **    from the expression (i.e. the expression is a literal value).
+ **
+-** If a value can be extracted, the affinity passed as the 5th argument
+-** is applied to it before it is copied into the UnpackedRecord. Output
+-** parameter *pbOk is set to true if a value is extracted, or false 
+-** otherwise.
++** Or, if pExpr is a TK_VECTOR, one field is populated for each of the
++** vector components that match either of the two latter criteria listed
++** above.
++**
++** Before any value is appended to the record, the affinity of the 
++** corresponding column within index pIdx is applied to it. Before
++** this function returns, output parameter *pnExtract is set to the
++** number of values appended to the record.
+ **
+ ** When this function is called, *ppRec must either point to an object
+ ** allocated by an earlier call to this function, or must be NULL. If it
+@@ -64636,22 +75115,33 @@
+   Index *pIdx,                    /* Index being probed */
+   UnpackedRecord **ppRec,         /* IN/OUT: Probe record */
+   Expr *pExpr,                    /* The expression to extract a value from */
+-  u8 affinity,                    /* Affinity to use */
++  int nElem,                      /* Maximum number of values to append */
+   int iVal,                       /* Array element to populate */
+-  int *pbOk                       /* OUT: True if value was extracted */
++  int *pnExtract                  /* OUT: Values appended to the record */
+ ){
+-  int rc;
+-  sqlite3_value *pVal = 0;
+-  struct ValueNewStat4Ctx alloc;
++  int rc = SQLITE_OK;
++  int nExtract = 0;
++
++  if( pExpr==0 || pExpr->op!=TK_SELECT ){
++    int i;
++    struct ValueNewStat4Ctx alloc;
++
++    alloc.pParse = pParse;
++    alloc.pIdx = pIdx;
++    alloc.ppRec = ppRec;
++
++    for(i=0; i<nElem; i++){
++      sqlite3_value *pVal = 0;
++      Expr *pElem = (pExpr ? sqlite3VectorFieldSubexpr(pExpr, i) : 0);
++      u8 aff = sqlite3IndexColumnAffinity(pParse->db, pIdx, iVal+i);
++      alloc.iVal = iVal+i;
++      rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal);
++      if( !pVal ) break;
++      nExtract++;
++    }
++  }
+ 
+-  alloc.pParse = pParse;
+-  alloc.pIdx = pIdx;
+-  alloc.ppRec = ppRec;
+-  alloc.iVal = iVal;
+-
+-  rc = stat4ValueFromExpr(pParse, pExpr, affinity, &alloc, &pVal);
+-  assert( pVal==0 || pVal->db==pParse->db );
+-  *pbOk = (pVal!=0);
++  *pnExtract = nExtract;
+   return rc;
+ }
+ 
+@@ -64715,7 +75205,7 @@
+   if( iField>nRec ) return SQLITE_CORRUPT_BKPT;
+   if( pMem==0 ){
+     pMem = *ppVal = sqlite3ValueNew(db);
+-    if( pMem==0 ) return SQLITE_NOMEM;
++    if( pMem==0 ) return SQLITE_NOMEM_BKPT;
+   }
+   sqlite3VdbeSerialGet(&a[iField-szField], t, pMem);
+   pMem->enc = ENC(db);
+@@ -64737,7 +75227,7 @@
+       sqlite3VdbeMemRelease(&aMem[i]);
+     }
+     sqlite3KeyInfoUnref(pRec->pKeyInfo);
+-    sqlite3DbFree(db, pRec);
++    sqlite3DbFreeNN(db, pRec);
+   }
+ }
+ #endif /* ifdef SQLITE_ENABLE_STAT4 */
+@@ -64761,23 +75251,32 @@
+ SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){
+   if( !v ) return;
+   sqlite3VdbeMemRelease((Mem *)v);
+-  sqlite3DbFree(((Mem*)v)->db, v);
++  sqlite3DbFreeNN(((Mem*)v)->db, v);
+ }
+ 
+ /*
+-** Return the number of bytes in the sqlite3_value object assuming
+-** that it uses the encoding "enc"
++** The sqlite3ValueBytes() routine returns the number of bytes in the
++** sqlite3_value object assuming that it uses the encoding "enc".
++** The valueBytes() routine is a helper function.
+ */
++static SQLITE_NOINLINE int valueBytes(sqlite3_value *pVal, u8 enc){
++  return valueToText(pVal, enc)!=0 ? pVal->n : 0;
++}
+ SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
+   Mem *p = (Mem*)pVal;
+-  if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
++  assert( (p->flags & MEM_Null)==0 || (p->flags & (MEM_Str|MEM_Blob))==0 );
++  if( (p->flags & MEM_Str)!=0 && pVal->enc==enc ){
++    return p->n;
++  }
++  if( (p->flags & MEM_Blob)!=0 ){
+     if( p->flags & MEM_Zero ){
+       return p->n + p->u.nZero;
+     }else{
+       return p->n;
+     }
+   }
+-  return 0;
++  if( p->flags & MEM_Null ) return 0;
++  return valueBytes(pVal, enc);
+ }
+ 
+ /************** End of vdbemem.c *********************************************/
+@@ -64796,6 +75295,8 @@
+ ** This file contains code used for creating, destroying, and populating
+ ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) 
+ */
++/* #include "sqliteInt.h" */
++/* #include "vdbeInt.h" */
+ 
+ /*
+ ** Create a new virtual database engine.
+@@ -64803,8 +75304,9 @@
+ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
+   sqlite3 *db = pParse->db;
+   Vdbe *p;
+-  p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
++  p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) );
+   if( p==0 ) return 0;
++  memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp));
+   p->db = db;
+   if( db->pVdbe ){
+     db->pVdbe->pPrev = p;
+@@ -64817,29 +75319,32 @@
+   assert( pParse->aLabel==0 );
+   assert( pParse->nLabel==0 );
+   assert( pParse->nOpAlloc==0 );
++  assert( pParse->szOpAlloc==0 );
+   return p;
+ }
+ 
+ /*
+-** Remember the SQL string for a prepared statement.
++** Change the error string stored in Vdbe.zErrMsg
+ */
+-SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
+-  assert( isPrepareV2==1 || isPrepareV2==0 );
+-  if( p==0 ) return;
+-#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG)
+-  if( !isPrepareV2 ) return;
+-#endif
+-  assert( p->zSql==0 );
+-  p->zSql = sqlite3DbStrNDup(p->db, z, n);
+-  p->isPrepareV2 = (u8)isPrepareV2;
++SQLITE_PRIVATE void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
++  va_list ap;
++  sqlite3DbFree(p->db, p->zErrMsg);
++  va_start(ap, zFormat);
++  p->zErrMsg = sqlite3VMPrintf(p->db, zFormat, ap);
++  va_end(ap);
+ }
+ 
+ /*
+-** Return the SQL associated with a prepared statement
++** Remember the SQL string for a prepared statement.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt){
+-  Vdbe *p = (Vdbe *)pStmt;
+-  return (p && p->isPrepareV2) ? p->zSql : 0;
++SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlags){
++  if( p==0 ) return;
++  p->prepFlags = prepFlags;
++  if( (prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){
++    p->expmask = 0;
++  }
++  assert( p->zSql==0 );
++  p->zSql = sqlite3DbStrNDup(p->db, z, n);
+ }
+ 
+ /*
+@@ -64848,6 +75353,7 @@
+ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
+   Vdbe tmp, *pTmp;
+   char *zTmp;
++  assert( pA->db==pB->db );
+   tmp = *pA;
+   *pA = *pB;
+   *pB = tmp;
+@@ -64860,7 +75366,10 @@
+   zTmp = pA->zSql;
+   pA->zSql = pB->zSql;
+   pB->zSql = zTmp;
+-  pB->isPrepareV2 = pA->isPrepareV2;
++  pB->expmask = pA->expmask;
++  pB->prepFlags = pA->prepFlags;
++  memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
++  pB->aCounter[SQLITE_STMTSTATUS_REPREPARE]++;
+ }
+ 
+ /*
+@@ -64891,14 +75400,21 @@
+   UNUSED_PARAMETER(nOp);
+ #endif
+ 
++  /* Ensure that the size of a VDBE does not grow too large */
++  if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
++    sqlite3OomFault(p->db);
++    return SQLITE_NOMEM;
++  }
++
+   assert( nOp<=(1024/sizeof(Op)) );
+   assert( nNew>=(p->nOpAlloc+nOp) );
+   pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
+   if( pNew ){
+-    p->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op);
++    p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
++    p->nOpAlloc = p->szOpAlloc/sizeof(Op);
+     v->aOp = pNew;
+   }
+-  return (pNew ? SQLITE_OK : SQLITE_NOMEM);
++  return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
+ }
+ 
+ #ifdef SQLITE_DEBUG
+@@ -64928,17 +75444,21 @@
+ ** the sqlite3VdbeChangeP4() function to change the value of the P4
+ ** operand.
+ */
++static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){
++  assert( p->pParse->nOpAlloc<=p->nOp );
++  if( growOpArray(p, 1) ) return 1;
++  assert( p->pParse->nOpAlloc>p->nOp );
++  return sqlite3VdbeAddOp3(p, op, p1, p2, p3);
++}
+ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
+   int i;
+   VdbeOp *pOp;
+ 
+   i = p->nOp;
+   assert( p->magic==VDBE_MAGIC_INIT );
+-  assert( op>0 && op<0xff );
++  assert( op>=0 && op<0xff );
+   if( p->pParse->nOpAlloc<=i ){
+-    if( growOpArray(p, 1) ){
+-      return 1;
+-    }
++    return growOp3(p, op, p1, p2, p3);
+   }
+   p->nOp++;
+   pOp = &p->aOp[i];
+@@ -64956,9 +75476,8 @@
+   if( p->db->flags & SQLITE_VdbeAddopTrace ){
+     int jj, kk;
+     Parse *pParse = p->pParse;
+-    for(jj=kk=0; jj<SQLITE_N_COLCACHE; jj++){
++    for(jj=kk=0; jj<pParse->nColCache; jj++){
+       struct yColCache *x = pParse->aColCache + jj;
+-      if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue;
+       printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
+       kk++;
+     }
+@@ -64986,6 +75505,49 @@
+   return sqlite3VdbeAddOp3(p, op, p1, p2, 0);
+ }
+ 
++/* Generate code for an unconditional jump to instruction iDest
++*/
++SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe *p, int iDest){
++  return sqlite3VdbeAddOp3(p, OP_Goto, 0, iDest, 0);
++}
++
++/* Generate code to cause the string zStr to be loaded into
++** register iDest
++*/
++SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){
++  return sqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0);
++}
++
++/*
++** Generate code that initializes multiple registers to string or integer
++** constants.  The registers begin with iDest and increase consecutively.
++** One register is initialized for each characgter in zTypes[].  For each
++** "s" character in zTypes[], the register is a string if the argument is
++** not NULL, or OP_Null if the value is a null pointer.  For each "i" character
++** in zTypes[], the register is initialized to an integer.
++**
++** If the input string does not end with "X" then an OP_ResultRow instruction
++** is generated for the values inserted.
++*/
++SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){
++  va_list ap;
++  int i;
++  char c;
++  va_start(ap, zTypes);
++  for(i=0; (c = zTypes[i])!=0; i++){
++    if( c=='s' ){
++      const char *z = va_arg(ap, const char*);
++      sqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest+i, 0, z, 0);
++    }else if( c=='i' ){
++      sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest+i);
++    }else{
++      goto skip_op_resultrow;
++    }
++  }
++  sqlite3VdbeAddOp2(p, OP_ResultRow, iDest, i);
++skip_op_resultrow:
++  va_end(ap);
++}
+ 
+ /*
+ ** Add an opcode that includes the p4 value as a pointer.
+@@ -65005,6 +75567,24 @@
+ }
+ 
+ /*
++** Add an opcode that includes the p4 value with a P4_INT64 or
++** P4_REAL type.
++*/
++SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(
++  Vdbe *p,            /* Add the opcode to this VM */
++  int op,             /* The new opcode */
++  int p1,             /* The P1 operand */
++  int p2,             /* The P2 operand */
++  int p3,             /* The P3 operand */
++  const u8 *zP4,      /* The P4 operand */
++  int p4type          /* P4 operand type */
++){
++  char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8);
++  if( p4copy ) memcpy(p4copy, zP4, 8);
++  return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type);
++}
++
++/*
+ ** Add an OP_ParseSchema opcode.  This routine is broken out from
+ ** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees
+ ** as having been used.
+@@ -65014,8 +75594,7 @@
+ */
+ SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){
+   int j;
+-  int addr = sqlite3VdbeAddOp3(p, OP_ParseSchema, iDb, 0, 0);
+-  sqlite3VdbeChangeP4(p, addr, zWhere, P4_DYNAMIC);
++  sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);
+   for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j);
+ }
+ 
+@@ -65031,10 +75610,29 @@
+   int p4              /* The P4 operand as an integer */
+ ){
+   int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3);
+-  sqlite3VdbeChangeP4(p, addr, SQLITE_INT_TO_PTR(p4), P4_INT32);
++  if( p->db->mallocFailed==0 ){
++    VdbeOp *pOp = &p->aOp[addr];
++    pOp->p4type = P4_INT32;
++    pOp->p4.i = p4;
++  }
+   return addr;
+ }
+ 
++/* Insert the end of a co-routine
++*/
++SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){
++  sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
++
++  /* Clear the temporary register cache, thereby ensuring that each
++  ** co-routine has its own independent set of registers, because co-routines
++  ** might expect their registers to be preserved across an OP_Yield, and
++  ** that could cause problems if two or more co-routines are using the same
++  ** temporary register.
++  */
++  v->pParse->nTempReg = 0;
++  v->pParse->nRangeReg = 0;
++}
++
+ /*
+ ** Create a new symbolic label for an instruction that has yet to be
+ ** coded.  The symbolic label is really just a negative number.  The
+@@ -65060,7 +75658,7 @@
+   if( p->aLabel ){
+     p->aLabel[i] = -1;
+   }
+-  return -1-i;
++  return ADDR(i);
+ }
+ 
+ /*
+@@ -65070,13 +75668,13 @@
+ */
+ SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
+   Parse *p = v->pParse;
+-  int j = -1-x;
++  int j = ADDR(x);
+   assert( v->magic==VDBE_MAGIC_INIT );
+   assert( j<p->nLabel );
+-  if( ALWAYS(j>=0) && p->aLabel ){
++  assert( j>=0 );
++  if( p->aLabel ){
+     p->aLabel[j] = v->nOp;
+   }
+-  p->iFixedOp = v->nOp - 1;
+ }
+ 
+ /*
+@@ -65086,6 +75684,13 @@
+   p->runOnlyOnce = 1;
+ }
+ 
++/*
++** Mark the VDBE as one that can only be run multiple times.
++*/
++SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){
++  p->runOnlyOnce = 0;
++}
++
+ #ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */
+ 
+ /*
+@@ -65168,6 +75773,7 @@
+ **   *  OP_VUpdate
+ **   *  OP_VRename
+ **   *  OP_FkCounter with P2==0 (immediate foreign key constraint)
++**   *  OP_CreateTable and OP_InitCoroutine (for CREATE TABLE AS SELECT ...)
+ **
+ ** Then check that the value of Parse.mayAbort is true if an
+ ** ABORT may be thrown, or false otherwise. Return true if it does
+@@ -65179,6 +75785,8 @@
+ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
+   int hasAbort = 0;
+   int hasFkCounter = 0;
++  int hasCreateTable = 0;
++  int hasInitCoroutine = 0;
+   Op *pOp;
+   VdbeOpIter sIter;
+   memset(&sIter, 0, sizeof(sIter));
+@@ -65193,6 +75801,8 @@
+       hasAbort = 1;
+       break;
+     }
++    if( opcode==OP_CreateTable ) hasCreateTable = 1;
++    if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1;
+ #ifndef SQLITE_OMIT_FOREIGN_KEY
+     if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
+       hasFkCounter = 1;
+@@ -65206,94 +75816,105 @@
+   ** through all opcodes and hasAbort may be set incorrectly. Return
+   ** true for this case to prevent the assert() in the callers frame
+   ** from failing.  */
+-  return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter );
++  return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter
++              || (hasCreateTable && hasInitCoroutine) );
+ }
+ #endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
+ 
+ /*
+-** Loop through the program looking for P2 values that are negative
+-** on jump instructions.  Each such value is a label.  Resolve the
+-** label by setting the P2 value to its correct non-zero value.
++** This routine is called after all opcodes have been inserted.  It loops
++** through all the opcodes and fixes up some details.
++**
++** (1) For each jump instruction with a negative P2 value (a label)
++**     resolve the P2 value to an actual address.
++**
++** (2) Compute the maximum number of arguments used by any SQL function
++**     and store that value in *pMaxFuncArgs.
+ **
+-** This routine is called once after all opcodes have been inserted.
++** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
++**     indicate what the prepared statement actually does.
+ **
+-** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument 
+-** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by 
+-** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array.
++** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
+ **
+-** The Op.opflags field is set on all opcodes.
++** (5) Reclaim the memory allocated for storing labels.
++**
++** This routine will only function correctly if the mkopcodeh.tcl generator
++** script numbers the opcodes correctly.  Changes to this routine must be
++** coordinated with changes to mkopcodeh.tcl.
+ */
+ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
+-  int i;
+   int nMaxArgs = *pMaxFuncArgs;
+   Op *pOp;
+   Parse *pParse = p->pParse;
+   int *aLabel = pParse->aLabel;
+   p->readOnly = 1;
+   p->bIsReader = 0;
+-  for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
+-    u8 opcode = pOp->opcode;
++  pOp = &p->aOp[p->nOp-1];
++  while(1){
+ 
+-    /* NOTE: Be sure to update mkopcodeh.awk when adding or removing
+-    ** cases from this switch! */
+-    switch( opcode ){
+-      case OP_Function:
+-      case OP_AggStep: {
+-        if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
+-        break;
+-      }
+-      case OP_Transaction: {
+-        if( pOp->p2!=0 ) p->readOnly = 0;
+-        /* fall thru */
+-      }
+-      case OP_AutoCommit:
+-      case OP_Savepoint: {
+-        p->bIsReader = 1;
+-        break;
+-      }
++    /* Only JUMP opcodes and the short list of special opcodes in the switch
++    ** below need to be considered.  The mkopcodeh.tcl generator script groups
++    ** all these opcodes together near the front of the opcode list.  Skip
++    ** any opcode that does not need processing by virtual of the fact that
++    ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization.
++    */
++    if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){
++      /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
++      ** cases from this switch! */
++      switch( pOp->opcode ){
++        case OP_Transaction: {
++          if( pOp->p2!=0 ) p->readOnly = 0;
++          /* fall thru */
++        }
++        case OP_AutoCommit:
++        case OP_Savepoint: {
++          p->bIsReader = 1;
++          break;
++        }
+ #ifndef SQLITE_OMIT_WAL
+-      case OP_Checkpoint:
++        case OP_Checkpoint:
+ #endif
+-      case OP_Vacuum:
+-      case OP_JournalMode: {
+-        p->readOnly = 0;
+-        p->bIsReader = 1;
+-        break;
+-      }
++        case OP_Vacuum:
++        case OP_JournalMode: {
++          p->readOnly = 0;
++          p->bIsReader = 1;
++          break;
++        }
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-      case OP_VUpdate: {
+-        if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
+-        break;
+-      }
+-      case OP_VFilter: {
+-        int n;
+-        assert( p->nOp - i >= 3 );
+-        assert( pOp[-1].opcode==OP_Integer );
+-        n = pOp[-1].p1;
+-        if( n>nMaxArgs ) nMaxArgs = n;
+-        break;
+-      }
++        case OP_VUpdate: {
++          if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
++          break;
++        }
++        case OP_VFilter: {
++          int n;
++          assert( (pOp - p->aOp) >= 3 );
++          assert( pOp[-1].opcode==OP_Integer );
++          n = pOp[-1].p1;
++          if( n>nMaxArgs ) nMaxArgs = n;
++          break;
++        }
+ #endif
+-      case OP_Next:
+-      case OP_NextIfOpen:
+-      case OP_SorterNext: {
+-        pOp->p4.xAdvance = sqlite3BtreeNext;
+-        pOp->p4type = P4_ADVANCE;
+-        break;
++        case OP_Next:
++        case OP_NextIfOpen:
++        case OP_SorterNext: {
++          pOp->p4.xAdvance = sqlite3BtreeNext;
++          pOp->p4type = P4_ADVANCE;
++          break;
++        }
++        case OP_Prev:
++        case OP_PrevIfOpen: {
++          pOp->p4.xAdvance = sqlite3BtreePrevious;
++          pOp->p4type = P4_ADVANCE;
++          break;
++        }
+       }
+-      case OP_Prev:
+-      case OP_PrevIfOpen: {
+-        pOp->p4.xAdvance = sqlite3BtreePrevious;
+-        pOp->p4type = P4_ADVANCE;
+-        break;
++      if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 && pOp->p2<0 ){
++        assert( ADDR(pOp->p2)<pParse->nLabel );
++        pOp->p2 = aLabel[ADDR(pOp->p2)];
+       }
+     }
+-
+-    pOp->opflags = sqlite3OpcodeProperty[opcode];
+-    if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
+-      assert( -1-pOp->p2<pParse->nLabel );
+-      pOp->p2 = aLabel[-1-pOp->p2];
+-    }
++    if( pOp==p->aOp ) break;
++    pOp--;
+   }
+   sqlite3DbFree(p->db, pParse->aLabel);
+   pParse->aLabel = 0;
+@@ -65311,6 +75932,36 @@
+ }
+ 
+ /*
++** Verify that at least N opcode slots are available in p without
++** having to malloc for more space (except when compiled using
++** SQLITE_TEST_REALLOC_STRESS).  This interface is used during testing
++** to verify that certain calls to sqlite3VdbeAddOpList() can never
++** fail due to a OOM fault and hence that the return value from
++** sqlite3VdbeAddOpList() will always be non-NULL.
++*/
++#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
++SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){
++  assert( p->nOp + N <= p->pParse->nOpAlloc );
++}
++#endif
++
++/*
++** Verify that the VM passed as the only argument does not contain
++** an OP_ResultRow opcode. Fail an assert() if it does. This is used
++** by code in pragma.c to ensure that the implementation of certain
++** pragmas comports with the flags specified in the mkpragmatab.tcl
++** script.
++*/
++#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
++SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p){
++  int i;
++  for(i=0; i<p->nOp; i++){
++    assert( p->aOp[i].opcode!=OP_ResultRow );
++  }
++}
++#endif
++
++/*
+ ** This function returns a pointer to the array of opcodes associated with
+ ** the Vdbe passed as the first argument. It is the callers responsibility
+ ** to arrange for the returned array to be eventually freed using the 
+@@ -65335,51 +75986,54 @@
+ }
+ 
+ /*
+-** Add a whole list of operations to the operation stack.  Return the
+-** address of the first operation added.
++** Add a whole list of operations to the operation stack.  Return a
++** pointer to the first operation inserted.
++**
++** Non-zero P2 arguments to jump instructions are automatically adjusted
++** so that the jump target is relative to the first operation inserted.
+ */
+-SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
+-  int addr;
++SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(
++  Vdbe *p,                     /* Add opcodes to the prepared statement */
++  int nOp,                     /* Number of opcodes to add */
++  VdbeOpList const *aOp,       /* The opcodes to be added */
++  int iLineno                  /* Source-file line number of first opcode */
++){
++  int i;
++  VdbeOp *pOut, *pFirst;
++  assert( nOp>0 );
+   assert( p->magic==VDBE_MAGIC_INIT );
+   if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){
+     return 0;
+   }
+-  addr = p->nOp;
+-  if( ALWAYS(nOp>0) ){
+-    int i;
+-    VdbeOpList const *pIn = aOp;
+-    for(i=0; i<nOp; i++, pIn++){
+-      int p2 = pIn->p2;
+-      VdbeOp *pOut = &p->aOp[i+addr];
+-      pOut->opcode = pIn->opcode;
+-      pOut->p1 = pIn->p1;
+-      if( p2<0 ){
+-        assert( sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP );
+-        pOut->p2 = addr + ADDR(p2);
+-      }else{
+-        pOut->p2 = p2;
+-      }
+-      pOut->p3 = pIn->p3;
+-      pOut->p4type = P4_NOTUSED;
+-      pOut->p4.p = 0;
+-      pOut->p5 = 0;
++  pFirst = pOut = &p->aOp[p->nOp];
++  for(i=0; i<nOp; i++, aOp++, pOut++){
++    pOut->opcode = aOp->opcode;
++    pOut->p1 = aOp->p1;
++    pOut->p2 = aOp->p2;
++    assert( aOp->p2>=0 );
++    if( (sqlite3OpcodeProperty[aOp->opcode] & OPFLG_JUMP)!=0 && aOp->p2>0 ){
++      pOut->p2 += p->nOp;
++    }
++    pOut->p3 = aOp->p3;
++    pOut->p4type = P4_NOTUSED;
++    pOut->p4.p = 0;
++    pOut->p5 = 0;
+ #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+-      pOut->zComment = 0;
++    pOut->zComment = 0;
+ #endif
+ #ifdef SQLITE_VDBE_COVERAGE
+-      pOut->iSrcLine = iLineno+i;
++    pOut->iSrcLine = iLineno+i;
+ #else
+-      (void)iLineno;
++    (void)iLineno;
+ #endif
+ #ifdef SQLITE_DEBUG
+-      if( p->db->flags & SQLITE_VdbeAddopTrace ){
+-        sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
+-      }
+-#endif
++    if( p->db->flags & SQLITE_VdbeAddopTrace ){
++      sqlite3VdbePrintOp(0, i+p->nOp, &p->aOp[i+p->nOp]);
+     }
+-    p->nOp += nOp;
++#endif
+   }
+-  return addr;
++  p->nOp += nOp;
++  return pFirst;
+ }
+ 
+ #if defined(SQLITE_ENABLE_STMT_SCANSTATUS)
+@@ -65411,49 +76065,24 @@
+ 
+ 
+ /*
+-** Change the value of the P1 operand for a specific instruction.
+-** This routine is useful when a large program is loaded from a
+-** static array using sqlite3VdbeAddOpList but we want to make a
+-** few minor changes to the program.
++** Change the value of the opcode, or P1, P2, P3, or P5 operands
++** for a specific instruction.
+ */
++SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe *p, u32 addr, u8 iNewOpcode){
++  sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode;
++}
+ SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){
+-  assert( p!=0 );
+-  if( ((u32)p->nOp)>addr ){
+-    p->aOp[addr].p1 = val;
+-  }
++  sqlite3VdbeGetOp(p,addr)->p1 = val;
+ }
+-
+-/*
+-** Change the value of the P2 operand for a specific instruction.
+-** This routine is useful for setting a jump destination.
+-*/
+ SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
+-  assert( p!=0 );
+-  if( ((u32)p->nOp)>addr ){
+-    p->aOp[addr].p2 = val;
+-  }
++  sqlite3VdbeGetOp(p,addr)->p2 = val;
+ }
+-
+-/*
+-** Change the value of the P3 operand for a specific instruction.
+-*/
+ SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
+-  assert( p!=0 );
+-  if( ((u32)p->nOp)>addr ){
+-    p->aOp[addr].p3 = val;
+-  }
++  sqlite3VdbeGetOp(p,addr)->p3 = val;
+ }
+-
+-/*
+-** Change the value of the P5 operand for the most recently
+-** added operation.
+-*/
+-SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
+-  assert( p!=0 );
+-  if( p->aOp ){
+-    assert( p->nOp>0 );
+-    p->aOp[p->nOp-1].p5 = val;
+-  }
++SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){
++  assert( p->nOp>0 || p->db->mallocFailed );
++  if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5;
+ }
+ 
+ /*
+@@ -65462,7 +76091,6 @@
+ */
+ SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
+   sqlite3VdbeChangeP2(p, addr, p->nOp);
+-  p->pParse->iFixedOp = p->nOp - 1;
+ }
+ 
+ 
+@@ -65471,8 +76099,8 @@
+ ** the FuncDef is not ephermal, then do nothing.
+ */
+ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
+-  if( ALWAYS(pDef) && (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){
+-    sqlite3DbFree(db, pDef);
++  if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){
++    sqlite3DbFreeNN(db, pDef);
+   }
+ }
+ 
+@@ -65481,43 +76109,53 @@
+ /*
+ ** Delete a P4 value if necessary.
+ */
++static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){
++  if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
++  sqlite3DbFreeNN(db, p);
++}
++static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){
++  freeEphemeralFunction(db, p->pFunc);
++ sqlite3DbFreeNN(db, p);
++}
+ static void freeP4(sqlite3 *db, int p4type, void *p4){
+-  if( p4 ){
+-    assert( db );
+-    switch( p4type ){
+-      case P4_REAL:
+-      case P4_INT64:
+-      case P4_DYNAMIC:
+-      case P4_INTARRAY: {
+-        sqlite3DbFree(db, p4);
+-        break;
+-      }
+-      case P4_KEYINFO: {
+-        if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
+-        break;
+-      }
+-      case P4_MPRINTF: {
+-        if( db->pnBytesFreed==0 ) sqlite3_free(p4);
+-        break;
+-      }
+-      case P4_FUNCDEF: {
+-        freeEphemeralFunction(db, (FuncDef*)p4);
+-        break;
+-      }
+-      case P4_MEM: {
+-        if( db->pnBytesFreed==0 ){
+-          sqlite3ValueFree((sqlite3_value*)p4);
+-        }else{
+-          Mem *p = (Mem*)p4;
+-          if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
+-          sqlite3DbFree(db, p);
+-        }
+-        break;
+-      }
+-      case P4_VTAB : {
+-        if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
+-        break;
++  assert( db );
++  switch( p4type ){
++    case P4_FUNCCTX: {
++      freeP4FuncCtx(db, (sqlite3_context*)p4);
++      break;
++    }
++    case P4_REAL:
++    case P4_INT64:
++    case P4_DYNAMIC:
++    case P4_INTARRAY: {
++      sqlite3DbFree(db, p4);
++      break;
++    }
++    case P4_KEYINFO: {
++      if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
++      break;
++    }
++#ifdef SQLITE_ENABLE_CURSOR_HINTS
++    case P4_EXPR: {
++      sqlite3ExprDelete(db, (Expr*)p4);
++      break;
++    }
++#endif
++    case P4_FUNCDEF: {
++      freeEphemeralFunction(db, (FuncDef*)p4);
++      break;
++    }
++    case P4_MEM: {
++      if( db->pnBytesFreed==0 ){
++        sqlite3ValueFree((sqlite3_value*)p4);
++      }else{
++        freeP4Mem(db, (Mem*)p4);
+       }
++      break;
++    }
++    case P4_VTAB : {
++      if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
++      break;
+     }
+   }
+ }
+@@ -65530,14 +76168,14 @@
+ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
+   if( aOp ){
+     Op *pOp;
+-    for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
+-      freeP4(db, pOp->p4type, pOp->p4.p);
++    for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){
++      if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p);
+ #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+       sqlite3DbFree(db, pOp->zComment);
+ #endif     
+     }
++    sqlite3DbFreeNN(db, aOp);
+   }
+-  sqlite3DbFree(db, aOp);
+ }
+ 
+ /*
+@@ -65553,15 +76191,16 @@
+ /*
+ ** Change the opcode at addr into OP_Noop
+ */
+-SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
+-  if( addr<p->nOp ){
+-    VdbeOp *pOp = &p->aOp[addr];
+-    sqlite3 *db = p->db;
+-    freeP4(db, pOp->p4type, pOp->p4.p);
+-    memset(pOp, 0, sizeof(pOp[0]));
+-    pOp->opcode = OP_Noop;
+-    if( addr==p->nOp-1 ) p->nOp--;
+-  }
++SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
++  VdbeOp *pOp;
++  if( p->db->mallocFailed ) return 0;
++  assert( addr>=0 && addr<p->nOp );
++  pOp = &p->aOp[addr];
++  freeP4(p->db, pOp->p4type, pOp->p4.p);
++  pOp->p4type = P4_NOTUSED;
++  pOp->p4.z = 0;
++  pOp->opcode = OP_Noop;
++  return 1;
+ }
+ 
+ /*
+@@ -65569,9 +76208,8 @@
+ ** then remove it.  Return true if and only if an opcode was removed.
+ */
+ SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
+-  if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
+-    sqlite3VdbeChangeToNoop(p, p->nOp-1);
+-    return 1;
++  if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){
++    return sqlite3VdbeChangeToNoop(p, p->nOp-1);
+   }else{
+     return 0;
+   }
+@@ -65594,16 +76232,34 @@
+ **
+ ** If addr<0 then change P4 on the most recently inserted instruction.
+ */
++static void SQLITE_NOINLINE vdbeChangeP4Full(
++  Vdbe *p,
++  Op *pOp,
++  const char *zP4,
++  int n
++){
++  if( pOp->p4type ){
++    freeP4(p->db, pOp->p4type, pOp->p4.p);
++    pOp->p4type = 0;
++    pOp->p4.p = 0;
++  }
++  if( n<0 ){
++    sqlite3VdbeChangeP4(p, (int)(pOp - p->aOp), zP4, n);
++  }else{
++    if( n==0 ) n = sqlite3Strlen30(zP4);
++    pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
++    pOp->p4type = P4_DYNAMIC;
++  }
++}
+ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
+   Op *pOp;
+   sqlite3 *db;
+   assert( p!=0 );
+   db = p->db;
+   assert( p->magic==VDBE_MAGIC_INIT );
+-  if( p->aOp==0 || db->mallocFailed ){
+-    if( n!=P4_VTAB ){
+-      freeP4(db, n, (void*)*(char**)&zP4);
+-    }
++  assert( p->aOp!=0 || db->mallocFailed );
++  if( db->mallocFailed ){
++    if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4);
+     return;
+   }
+   assert( p->nOp>0 );
+@@ -65612,34 +76268,45 @@
+     addr = p->nOp - 1;
+   }
+   pOp = &p->aOp[addr];
+-  assert( pOp->p4type==P4_NOTUSED
+-       || pOp->p4type==P4_INT32
+-       || pOp->p4type==P4_KEYINFO );
+-  freeP4(db, pOp->p4type, pOp->p4.p);
+-  pOp->p4.p = 0;
++  if( n>=0 || pOp->p4type ){
++    vdbeChangeP4Full(p, pOp, zP4, n);
++    return;
++  }
+   if( n==P4_INT32 ){
+     /* Note: this cast is safe, because the origin data point was an int
+     ** that was cast to a (const char *). */
+     pOp->p4.i = SQLITE_PTR_TO_INT(zP4);
+     pOp->p4type = P4_INT32;
+-  }else if( zP4==0 ){
+-    pOp->p4.p = 0;
+-    pOp->p4type = P4_NOTUSED;
+-  }else if( n==P4_KEYINFO ){
+-    pOp->p4.p = (void*)zP4;
+-    pOp->p4type = P4_KEYINFO;
+-  }else if( n==P4_VTAB ){
+-    pOp->p4.p = (void*)zP4;
+-    pOp->p4type = P4_VTAB;
+-    sqlite3VtabLock((VTable *)zP4);
+-    assert( ((VTable *)zP4)->db==p->db );
+-  }else if( n<0 ){
++  }else if( zP4!=0 ){
++    assert( n<0 );
+     pOp->p4.p = (void*)zP4;
+     pOp->p4type = (signed char)n;
++    if( n==P4_VTAB ) sqlite3VtabLock((VTable*)zP4);
++  }
++}
++
++/*
++** Change the P4 operand of the most recently coded instruction 
++** to the value defined by the arguments.  This is a high-speed
++** version of sqlite3VdbeChangeP4().
++**
++** The P4 operand must not have been previously defined.  And the new
++** P4 must not be P4_INT32.  Use sqlite3VdbeChangeP4() in either of
++** those cases.
++*/
++SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){
++  VdbeOp *pOp;
++  assert( n!=P4_INT32 && n!=P4_VTAB );
++  assert( n<=0 );
++  if( p->db->mallocFailed ){
++    freeP4(p->db, n, pP4);
+   }else{
+-    if( n==0 ) n = sqlite3Strlen30(zP4);
+-    pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
+-    pOp->p4type = P4_DYNAMIC;
++    assert( pP4!=0 );
++    assert( p->nOp>0 );
++    pOp = &p->aOp[p->nOp-1];
++    assert( pOp->p4type==P4_NOTUSED );
++    pOp->p4type = n;
++    pOp->p4.p = pP4;
+   }
+ }
+ 
+@@ -65649,10 +76316,11 @@
+ */
+ SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
+   Vdbe *v = pParse->pVdbe;
++  KeyInfo *pKeyInfo;
+   assert( v!=0 );
+   assert( pIdx!=0 );
+-  sqlite3VdbeChangeP4(v, -1, (char*)sqlite3KeyInfoOfIndex(pParse, pIdx),
+-                      P4_KEYINFO);
++  pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pIdx);
++  if( pKeyInfo ) sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
+ }
+ 
+ #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+@@ -65764,12 +76432,21 @@
+   const char *zSynopsis;
+   int nOpName;
+   int ii, jj;
++  char zAlt[50];
+   zOpName = sqlite3OpcodeName(pOp->opcode);
+   nOpName = sqlite3Strlen30(zOpName);
+   if( zOpName[nOpName+1] ){
+     int seenCom = 0;
+     char c;
+     zSynopsis = zOpName += nOpName + 1;
++    if( strncmp(zSynopsis,"IF ",3)==0 ){
++      if( pOp->p5 & SQLITE_STOREP2 ){
++        sqlite3_snprintf(sizeof(zAlt), zAlt, "r[P2] = (%s)", zSynopsis+3);
++      }else{
++        sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3);
++      }
++      zSynopsis = zAlt;
++    }
+     for(ii=jj=0; jj<nTemp-1 && (c = zSynopsis[ii])!=0; ii++){
+       if( c=='P' ){
+         c = zSynopsis[++ii];
+@@ -65818,67 +76495,138 @@
+ }
+ #endif /* SQLITE_DEBUG */
+ 
++#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
++/*
++** Translate the P4.pExpr value for an OP_CursorHint opcode into text
++** that can be displayed in the P4 column of EXPLAIN output.
++*/
++static void displayP4Expr(StrAccum *p, Expr *pExpr){
++  const char *zOp = 0;
++  switch( pExpr->op ){
++    case TK_STRING:
++      sqlite3XPrintf(p, "%Q", pExpr->u.zToken);
++      break;
++    case TK_INTEGER:
++      sqlite3XPrintf(p, "%d", pExpr->u.iValue);
++      break;
++    case TK_NULL:
++      sqlite3XPrintf(p, "NULL");
++      break;
++    case TK_REGISTER: {
++      sqlite3XPrintf(p, "r[%d]", pExpr->iTable);
++      break;
++    }
++    case TK_COLUMN: {
++      if( pExpr->iColumn<0 ){
++        sqlite3XPrintf(p, "rowid");
++      }else{
++        sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn);
++      }
++      break;
++    }
++    case TK_LT:      zOp = "LT";      break;
++    case TK_LE:      zOp = "LE";      break;
++    case TK_GT:      zOp = "GT";      break;
++    case TK_GE:      zOp = "GE";      break;
++    case TK_NE:      zOp = "NE";      break;
++    case TK_EQ:      zOp = "EQ";      break;
++    case TK_IS:      zOp = "IS";      break;
++    case TK_ISNOT:   zOp = "ISNOT";   break;
++    case TK_AND:     zOp = "AND";     break;
++    case TK_OR:      zOp = "OR";      break;
++    case TK_PLUS:    zOp = "ADD";     break;
++    case TK_STAR:    zOp = "MUL";     break;
++    case TK_MINUS:   zOp = "SUB";     break;
++    case TK_REM:     zOp = "REM";     break;
++    case TK_BITAND:  zOp = "BITAND";  break;
++    case TK_BITOR:   zOp = "BITOR";   break;
++    case TK_SLASH:   zOp = "DIV";     break;
++    case TK_LSHIFT:  zOp = "LSHIFT";  break;
++    case TK_RSHIFT:  zOp = "RSHIFT";  break;
++    case TK_CONCAT:  zOp = "CONCAT";  break;
++    case TK_UMINUS:  zOp = "MINUS";   break;
++    case TK_UPLUS:   zOp = "PLUS";    break;
++    case TK_BITNOT:  zOp = "BITNOT";  break;
++    case TK_NOT:     zOp = "NOT";     break;
++    case TK_ISNULL:  zOp = "ISNULL";  break;
++    case TK_NOTNULL: zOp = "NOTNULL"; break;
++
++    default:
++      sqlite3XPrintf(p, "%s", "expr");
++      break;
++  }
+ 
+-#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
+-     || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
++  if( zOp ){
++    sqlite3XPrintf(p, "%s(", zOp);
++    displayP4Expr(p, pExpr->pLeft);
++    if( pExpr->pRight ){
++      sqlite3StrAccumAppend(p, ",", 1);
++      displayP4Expr(p, pExpr->pRight);
++    }
++    sqlite3StrAccumAppend(p, ")", 1);
++  }
++}
++#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
++
++
++#if VDBE_DISPLAY_P4
+ /*
+ ** Compute a string that describes the P4 parameter for an opcode.
+ ** Use zTemp for any required temporary buffer space.
+ */
+ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
+   char *zP4 = zTemp;
++  StrAccum x;
+   assert( nTemp>=20 );
++  sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
+   switch( pOp->p4type ){
+     case P4_KEYINFO: {
+-      int i, j;
++      int j;
+       KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
+       assert( pKeyInfo->aSortOrder!=0 );
+-      sqlite3_snprintf(nTemp, zTemp, "k(%d", pKeyInfo->nField);
+-      i = sqlite3Strlen30(zTemp);
++      sqlite3XPrintf(&x, "k(%d", pKeyInfo->nField);
+       for(j=0; j<pKeyInfo->nField; j++){
+         CollSeq *pColl = pKeyInfo->aColl[j];
+-        const char *zColl = pColl ? pColl->zName : "nil";
+-        int n = sqlite3Strlen30(zColl);
+-        if( n==6 && memcmp(zColl,"BINARY",6)==0 ){
+-          zColl = "B";
+-          n = 1;
+-        }
+-        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;
+-      assert( i<nTemp );
++        const char *zColl = pColl ? pColl->zName : "";
++        if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
++        sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
++      }
++      sqlite3StrAccumAppend(&x, ")", 1);
++      break;
++    }
++#ifdef SQLITE_ENABLE_CURSOR_HINTS
++    case P4_EXPR: {
++      displayP4Expr(&x, pOp->p4.pExpr);
+       break;
+     }
++#endif
+     case P4_COLLSEQ: {
+       CollSeq *pColl = pOp->p4.pColl;
+-      sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName);
++      sqlite3XPrintf(&x, "(%.20s)", pColl->zName);
+       break;
+     }
+     case P4_FUNCDEF: {
+       FuncDef *pDef = pOp->p4.pFunc;
+-      sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
++      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
++      break;
++    }
++#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
++    case P4_FUNCCTX: {
++      FuncDef *pDef = pOp->p4.pCtx->pFunc;
++      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
+       break;
+     }
++#endif
+     case P4_INT64: {
+-      sqlite3_snprintf(nTemp, zTemp, "%lld", *pOp->p4.pI64);
++      sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64);
+       break;
+     }
+     case P4_INT32: {
+-      sqlite3_snprintf(nTemp, zTemp, "%d", pOp->p4.i);
++      sqlite3XPrintf(&x, "%d", pOp->p4.i);
+       break;
+     }
+     case P4_REAL: {
+-      sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal);
++      sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal);
+       break;
+     }
+     case P4_MEM: {
+@@ -65886,11 +76634,11 @@
+       if( pMem->flags & MEM_Str ){
+         zP4 = pMem->z;
+       }else if( pMem->flags & MEM_Int ){
+-        sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
++        sqlite3XPrintf(&x, "%lld", pMem->u.i);
+       }else if( pMem->flags & MEM_Real ){
+-        sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->u.r);
++        sqlite3XPrintf(&x, "%.16g", pMem->u.r);
+       }else if( pMem->flags & MEM_Null ){
+-        sqlite3_snprintf(nTemp, zTemp, "NULL");
++        zP4 = "NULL";
+       }else{
+         assert( pMem->flags & MEM_Blob );
+         zP4 = "(blob)";
+@@ -65900,22 +76648,34 @@
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+     case P4_VTAB: {
+       sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
+-      sqlite3_snprintf(nTemp, zTemp, "vtab:%p", pVtab);
++      sqlite3XPrintf(&x, "vtab:%p", pVtab);
+       break;
+     }
+ #endif
+     case P4_INTARRAY: {
+-      sqlite3_snprintf(nTemp, zTemp, "intarray");
++      int i;
++      int *ai = pOp->p4.ai;
++      int n = ai[0];   /* The first element of an INTARRAY is always the
++                       ** count of the number of elements to follow */
++      for(i=1; i<n; i++){
++        sqlite3XPrintf(&x, ",%d", ai[i]);
++      }
++      zTemp[0] = '[';
++      sqlite3StrAccumAppend(&x, "]", 1);
+       break;
+     }
+     case P4_SUBPROGRAM: {
+-      sqlite3_snprintf(nTemp, zTemp, "program");
++      sqlite3XPrintf(&x, "program");
+       break;
+     }
+     case P4_ADVANCE: {
+       zTemp[0] = 0;
+       break;
+     }
++    case P4_TABLE: {
++      sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName);
++      break;
++    }
+     default: {
+       zP4 = pOp->p4.z;
+       if( zP4==0 ){
+@@ -65924,10 +76684,11 @@
+       }
+     }
+   }
++  sqlite3StrAccumFinish(&x);
+   assert( zP4!=0 );
+   return zP4;
+ }
+-#endif
++#endif /* VDBE_DISPLAY_P4 */
+ 
+ /*
+ ** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
+@@ -65946,7 +76707,7 @@
+   }
+ }
+ 
+-#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
++#if !defined(SQLITE_OMIT_SHARED_CACHE)
+ /*
+ ** If SQLite is compiled to support shared-cache mode and to be threadsafe,
+ ** this routine obtains the mutex associated with each BtShared structure
+@@ -65989,12 +76750,11 @@
+ /*
+ ** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter().
+ */
+-SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){
++static SQLITE_NOINLINE void vdbeLeave(Vdbe *p){
+   int i;
+   sqlite3 *db;
+   Db *aDb;
+   int nDb;
+-  if( DbMaskAllZero(p->lockMask) ) return;  /* The common case */
+   db = p->db;
+   aDb = db->aDb;
+   nDb = db->nDb;
+@@ -66004,6 +76764,10 @@
+     }
+   }
+ }
++SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){
++  if( DbMaskAllZero(p->lockMask) ) return;  /* The common case */
++  vdbeLeave(p);
++}
+ #endif
+ 
+ #if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+@@ -66034,13 +76798,27 @@
+ #endif
+ 
+ /*
++** Initialize an array of N Mem element.
++*/
++static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
++  while( (N--)>0 ){
++    p->db = db;
++    p->flags = flags;
++    p->szMalloc = 0;
++#ifdef SQLITE_DEBUG
++    p->pScopyFrom = 0;
++#endif
++    p++;
++  }
++}
++
++/*
+ ** Release an array of N Mem elements
+ */
+ static void releaseMemArray(Mem *p, int N){
+   if( p && N ){
+     Mem *pEnd = &p[N];
+     sqlite3 *db = p->db;
+-    u8 malloc_failed = db->mallocFailed;
+     if( db->pnBytesFreed ){
+       do{
+         if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
+@@ -66070,13 +76848,12 @@
+       if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
+         sqlite3VdbeMemRelease(p);
+       }else if( p->szMalloc ){
+-        sqlite3DbFree(db, p->zMalloc);
++        sqlite3DbFreeNN(db, p->zMalloc);
+         p->szMalloc = 0;
+       }
+ 
+       p->flags = MEM_Undefined;
+     }while( (++p)<pEnd );
+-    db->mallocFailed = malloc_failed;
+   }
+ }
+ 
+@@ -66092,6 +76869,7 @@
+     sqlite3VdbeFreeCursor(p->v, apCsr[i]);
+   }
+   releaseMemArray(aMem, p->nChildMem);
++  sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
+   sqlite3DbFree(p->v->db, p);
+ }
+ 
+@@ -66134,10 +76912,10 @@
+   releaseMemArray(pMem, 8);
+   p->pResultSet = 0;
+ 
+-  if( p->rc==SQLITE_NOMEM ){
++  if( p->rc==SQLITE_NOMEM_BKPT ){
+     /* This happens if a malloc() inside a call to sqlite3_column_text() or
+     ** sqlite3_column_text16() failed.  */
+-    db->mallocFailed = 1;
++    sqlite3OomFault(db);
+     return SQLITE_ERROR;
+   }
+ 
+@@ -66176,7 +76954,7 @@
+   }else if( db->u1.isInterrupted ){
+     p->rc = SQLITE_INTERRUPT;
+     rc = SQLITE_ERROR;
+-    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc));
++    sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
+   }else{
+     char *zP4;
+     Op *pOp;
+@@ -66238,13 +77016,14 @@
+     pMem->u.i = pOp->p3;                          /* P3 */
+     pMem++;
+ 
+-    if( sqlite3VdbeMemClearAndResize(pMem, 32) ){ /* P4 */
++    if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
+       assert( p->db->mallocFailed );
+       return SQLITE_ERROR;
+     }
+     pMem->flags = MEM_Str|MEM_Term;
+-    zP4 = displayP4(pOp, pMem->z, 32);
++    zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
+     if( zP4!=pMem->z ){
++      pMem->n = 0;
+       sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
+     }else{
+       assert( pMem->z!=0 );
+@@ -66335,43 +77114,46 @@
+ }
+ #endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
+ 
+-/*
+-** Allocate space from a fixed size buffer and return a pointer to
+-** that space.  If insufficient space is available, return NULL.
+-**
+-** The pBuf parameter is the initial value of a pointer which will
+-** receive the new memory.  pBuf is normally NULL.  If pBuf is not
+-** NULL, it means that memory space has already been allocated and that
+-** this routine should not allocate any new memory.  When pBuf is not
+-** NULL simply return pBuf.  Only allocate new memory space when pBuf
+-** is NULL.
+-**
+-** nByte is the number of bytes of space needed.
+-**
+-** *ppFrom points to available space and pEnd points to the end of the
+-** available space.  When space is allocated, *ppFrom is advanced past
+-** the end of the allocated space.
+-**
+-** *pnByte is a counter of the number of bytes of space that have failed
+-** to allocate.  If there is insufficient space in *ppFrom to satisfy the
+-** request, then increment *pnByte by the amount of the request.
++/* An instance of this object describes bulk memory available for use
++** by subcomponents of a prepared statement.  Space is allocated out
++** of a ReusableSpace object by the allocSpace() routine below.
++*/
++struct ReusableSpace {
++  u8 *pSpace;          /* Available memory */
++  int nFree;           /* Bytes of available memory */
++  int nNeeded;         /* Total bytes that could not be allocated */
++};
++
++/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf
++** from the ReusableSpace object.  Return a pointer to the allocated
++** memory on success.  If insufficient memory is available in the
++** ReusableSpace object, increase the ReusableSpace.nNeeded
++** value by the amount needed and return NULL.
++**
++** If pBuf is not initially NULL, that means that the memory has already
++** been allocated by a prior call to this routine, so just return a copy
++** of pBuf and leave ReusableSpace unchanged.
++**
++** This allocator is employed to repurpose unused slots at the end of the
++** opcode array of prepared state for other memory needs of the prepared
++** statement.
+ */
+ static void *allocSpace(
+-  void *pBuf,          /* Where return pointer will be stored */
+-  int nByte,           /* Number of bytes to allocate */
+-  u8 **ppFrom,         /* IN/OUT: Allocate from *ppFrom */
+-  u8 *pEnd,            /* Pointer to 1 byte past the end of *ppFrom buffer */
+-  int *pnByte          /* If allocation cannot be made, increment *pnByte */
+-){
+-  assert( EIGHT_BYTE_ALIGNMENT(*ppFrom) );
+-  if( pBuf ) return pBuf;
+-  nByte = ROUND8(nByte);
+-  if( &(*ppFrom)[nByte] <= pEnd ){
+-    pBuf = (void*)*ppFrom;
+-    *ppFrom += nByte;
+-  }else{
+-    *pnByte += nByte;
++  struct ReusableSpace *p,  /* Bulk memory available for allocation */
++  void *pBuf,               /* Pointer to a prior allocation */
++  int nByte                 /* Bytes of memory needed */
++){
++  assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
++  if( pBuf==0 ){
++    nByte = ROUND8(nByte);
++    if( nByte <= p->nFree ){
++      p->nFree -= nByte;
++      pBuf = &p->pSpace[p->nFree];
++    }else{
++      p->nNeeded += nByte;
++    }
+   }
++  assert( EIGHT_BYTE_ALIGNMENT(pBuf) );
+   return pBuf;
+ }
+ 
+@@ -66384,7 +77166,7 @@
+   int i;
+ #endif
+   assert( p!=0 );
+-  assert( p->magic==VDBE_MAGIC_INIT );
++  assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET );
+ 
+   /* There should be at least one opcode.
+   */
+@@ -66394,14 +77176,13 @@
+   p->magic = VDBE_MAGIC_RUN;
+ 
+ #ifdef SQLITE_DEBUG
+-  for(i=1; i<p->nMem; i++){
++  for(i=0; i<p->nMem; i++){
+     assert( p->aMem[i].db==p->db );
+   }
+ #endif
+   p->pc = -1;
+   p->rc = SQLITE_OK;
+   p->errorAction = OE_Abort;
+-  p->magic = VDBE_MAGIC_RUN;
+   p->nChange = 0;
+   p->cacheCtr = 1;
+   p->minWriteFileFormat = 255;
+@@ -66442,11 +77223,8 @@
+   int nMem;                      /* Number of VM memory registers */
+   int nCursor;                   /* Number of cursors required */
+   int nArg;                      /* Number of arguments in subprograms */
+-  int nOnce;                     /* Number of OP_Once instructions */
+   int n;                         /* Loop counter */
+-  u8 *zCsr;                      /* Memory available for allocation */
+-  u8 *zEnd;                      /* First byte past allocated memory */
+-  int nByte;                     /* How much extra memory is needed */
++  struct ReusableSpace x;        /* Reusable bulk memory */
+ 
+   assert( p!=0 );
+   assert( p->nOp>0 );
+@@ -66459,88 +77237,75 @@
+   nMem = pParse->nMem;
+   nCursor = pParse->nTab;
+   nArg = pParse->nMaxArg;
+-  nOnce = pParse->nOnce;
+-  if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */
+   
+-  /* For each cursor required, also allocate a memory cell. Memory
+-  ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
+-  ** the vdbe program. Instead they are used to allocate space for
+-  ** VdbeCursor/BtCursor structures. The blob of memory associated with 
+-  ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
+-  ** stores the blob of memory associated with cursor 1, etc.
+-  **
++  /* Each cursor uses a memory cell.  The first cursor (cursor 0) can
++  ** use aMem[0] which is not otherwise used by the VDBE program.  Allocate
++  ** space at the end of aMem[] for cursors 1 and greater.
+   ** See also: allocateCursor().
+   */
+   nMem += nCursor;
++  if( nCursor==0 && nMem>0 ) nMem++;  /* Space for aMem[0] even if not used */
+ 
+-  /* Allocate space for memory registers, SQL variables, VDBE cursors and 
+-  ** an array to marshal SQL function arguments in.
+-  */
+-  zCsr = (u8*)&p->aOp[p->nOp];            /* Memory avaliable for allocation */
+-  zEnd = (u8*)&p->aOp[pParse->nOpAlloc];  /* First byte past end of zCsr[] */
++  /* Figure out how much reusable memory is available at the end of the
++  ** opcode array.  This extra memory will be reallocated for other elements
++  ** of the prepared statement.
++  */
++  n = ROUND8(sizeof(Op)*p->nOp);              /* Bytes of opcode memory used */
++  x.pSpace = &((u8*)p->aOp)[n];               /* Unused opcode memory */
++  assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
++  x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n);  /* Bytes of unused memory */
++  assert( x.nFree>=0 );
++  assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
+ 
+   resolveP2Values(p, &nArg);
+   p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
+   if( pParse->explain && nMem<10 ){
+     nMem = 10;
+   }
+-  memset(zCsr, 0, zEnd-zCsr);
+-  zCsr += (zCsr - (u8*)0)&7;
+-  assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
+   p->expired = 0;
+ 
+-  /* Memory for registers, parameters, cursor, etc, is allocated in two
+-  ** passes.  On the first pass, we try to reuse unused space at the 
++  /* Memory for registers, parameters, cursor, etc, is allocated in one or two
++  ** passes.  On the first pass, we try to reuse unused memory at the 
+   ** end of the opcode array.  If we are unable to satisfy all memory
+   ** requirements by reusing the opcode array tail, then the second
+-  ** pass will fill in the rest using a fresh allocation.  
++  ** pass will fill in the remainder using a fresh memory allocation.  
+   **
+   ** This two-pass approach that reuses as much memory as possible from
+-  ** the leftover space at the end of the opcode array can significantly
++  ** the leftover memory at the end of the opcode array.  This can significantly
+   ** reduce the amount of memory held by a prepared statement.
+   */
+   do {
+-    nByte = 0;
+-    p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
+-    p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
+-    p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
+-    p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
+-    p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
+-                          &zCsr, zEnd, &nByte);
+-    p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);
++    x.nNeeded = 0;
++    p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
++    p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
++    p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
++    p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+-    p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), &zCsr, zEnd, &nByte);
++    p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
+ #endif
+-    if( nByte ){
+-      p->pFree = sqlite3DbMallocZero(db, nByte);
+-    }
+-    zCsr = p->pFree;
+-    zEnd = &zCsr[nByte];
+-  }while( nByte && !db->mallocFailed );
+-
+-  p->nCursor = nCursor;
+-  p->nOnceFlag = nOnce;
+-  if( p->aVar ){
++    if( x.nNeeded==0 ) break;
++    x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
++    x.nFree = x.nNeeded;
++  }while( !db->mallocFailed );
++
++  p->pVList = pParse->pVList;
++  pParse->pVList =  0;
++  p->explain = pParse->explain;
++  if( db->mallocFailed ){
++    p->nVar = 0;
++    p->nCursor = 0;
++    p->nMem = 0;
++  }else{
++    p->nCursor = nCursor;
+     p->nVar = (ynVar)nVar;
+-    for(n=0; n<nVar; n++){
+-      p->aVar[n].flags = MEM_Null;
+-      p->aVar[n].db = db;
+-    }
+-  }
+-  if( p->azVar && pParse->nzVar>0 ){
+-    p->nzVar = pParse->nzVar;
+-    memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0]));
+-    memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0]));
+-  }
+-  if( p->aMem ){
+-    p->aMem--;                      /* aMem[] goes from 1..nMem */
+-    p->nMem = nMem;                 /*       not from 0..nMem-1 */
+-    for(n=1; n<=nMem; n++){
+-      p->aMem[n].flags = MEM_Undefined;
+-      p->aMem[n].db = db;
+-    }
++    initMemArray(p->aVar, nVar, db, MEM_Null);
++    p->nMem = nMem;
++    initMemArray(p->aMem, nMem, db, MEM_Undefined);
++    memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*));
++#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
++    memset(p->anExec, 0, p->nOp*sizeof(i64));
++#endif
+   }
+-  p->explain = pParse->explain;
+   sqlite3VdbeRewind(p);
+ }
+ 
+@@ -66552,23 +77317,34 @@
+   if( pCx==0 ){
+     return;
+   }
+-  sqlite3VdbeSorterClose(p->db, pCx);
+-  if( pCx->pBt ){
+-    sqlite3BtreeClose(pCx->pBt);
+-    /* The pCx->pCursor will be close automatically, if it exists, by
+-    ** the call above. */
+-  }else if( pCx->pCursor ){
+-    sqlite3BtreeCloseCursor(pCx->pCursor);
+-  }
++  assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE );
++  switch( pCx->eCurType ){
++    case CURTYPE_SORTER: {
++      sqlite3VdbeSorterClose(p->db, pCx);
++      break;
++    }
++    case CURTYPE_BTREE: {
++      if( pCx->isEphemeral ){
++        if( pCx->pBtx ) sqlite3BtreeClose(pCx->pBtx);
++        /* The pCx->pCursor will be close automatically, if it exists, by
++        ** the call above. */
++      }else{
++        assert( pCx->uc.pCursor!=0 );
++        sqlite3BtreeCloseCursor(pCx->uc.pCursor);
++      }
++      break;
++    }
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-  else if( pCx->pVtabCursor ){
+-    sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
+-    const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
+-    assert( pVtabCursor->pVtab->nRef>0 );
+-    pVtabCursor->pVtab->nRef--;
+-    pModule->xClose(pVtabCursor);
+-  }
++    case CURTYPE_VTAB: {
++      sqlite3_vtab_cursor *pVCur = pCx->uc.pVCur;
++      const sqlite3_module *pModule = pVCur->pVtab->pModule;
++      assert( pVCur->pVtab->nRef>0 );
++      pVCur->pVtab->nRef--;
++      pModule->xClose(pVCur);
++      break;
++    }
+ #endif
++  }
+ }
+ 
+ /*
+@@ -66598,8 +77374,6 @@
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+   v->anExec = pFrame->anExec;
+ #endif
+-  v->aOnceFlag = pFrame->aOnceFlag;
+-  v->nOnceFlag = pFrame->nOnceFlag;
+   v->aOp = pFrame->aOp;
+   v->nOp = pFrame->nOp;
+   v->aMem = pFrame->aMem;
+@@ -66609,6 +77383,9 @@
+   v->db->lastRowid = pFrame->lastRowid;
+   v->nChange = pFrame->nChange;
+   v->db->nChange = pFrame->nDbChange;
++  sqlite3VdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0);
++  v->pAuxData = pFrame->pAuxData;
++  pFrame->pAuxData = 0;
+   return pFrame->pc;
+ }
+ 
+@@ -66631,7 +77408,7 @@
+   assert( p->nFrame==0 );
+   closeCursorsInFrame(p);
+   if( p->aMem ){
+-    releaseMemArray(&p->aMem[1], p->nMem);
++    releaseMemArray(p->aMem, p->nMem);
+   }
+   while( p->pDelFrame ){
+     VdbeFrame *pDel = p->pDelFrame;
+@@ -66640,7 +77417,7 @@
+   }
+ 
+   /* Delete any auxdata allocations made by the VM */
+-  if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
++  if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0);
+   assert( p->pAuxData==0 );
+ }
+ 
+@@ -66656,7 +77433,7 @@
+   int i;
+   if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
+   if( p->aMem ){
+-    for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
++    for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
+   }
+ #endif
+ 
+@@ -66672,21 +77449,18 @@
+ ** be called on an SQL statement before sqlite3_step().
+ */
+ SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
+-  Mem *pColName;
+   int n;
+   sqlite3 *db = p->db;
+ 
+-  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
+-  sqlite3DbFree(db, p->aColName);
++  if( p->nResColumn ){
++    releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
++    sqlite3DbFree(db, p->aColName);
++  }
+   n = nResColumn*COLNAME_N;
+   p->nResColumn = (u16)nResColumn;
+-  p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n );
++  p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
+   if( p->aColName==0 ) return;
+-  while( n-- > 0 ){
+-    pColName->flags = MEM_Null;
+-    pColName->db = p->db;
+-    pColName++;
+-  }
++  initMemArray(p->aColName, n, db, MEM_Null);
+ }
+ 
+ /*
+@@ -66712,7 +77486,7 @@
+   assert( var<COLNAME_N );
+   if( p->db->mallocFailed ){
+     assert( !zName || xDel!=SQLITE_DYNAMIC );
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   assert( p->aColName!=0 );
+   pColName = &(p->aColName[idx+var*p->nResColumn]);
+@@ -66729,7 +77503,9 @@
+ */
+ static int vdbeCommit(sqlite3 *db, Vdbe *p){
+   int i;
+-  int nTrans = 0;  /* Number of databases with an active write-transaction */
++  int nTrans = 0;  /* Number of databases with an active write-transaction
++                   ** that are candidates for a two-phase commit using a
++                   ** master-journal */
+   int rc = SQLITE_OK;
+   int needXcommit = 0;
+ 
+@@ -66757,10 +77533,28 @@
+   for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
+     Btree *pBt = db->aDb[i].pBt;
+     if( sqlite3BtreeIsInTrans(pBt) ){
++      /* Whether or not a database might need a master journal depends upon
++      ** its journal mode (among other things).  This matrix determines which
++      ** journal modes use a master journal and which do not */
++      static const u8 aMJNeeded[] = {
++        /* DELETE   */  1,
++        /* PERSIST   */ 1,
++        /* OFF       */ 0,
++        /* TRUNCATE  */ 1,
++        /* MEMORY    */ 0,
++        /* WAL       */ 0
++      };
++      Pager *pPager;   /* Pager associated with pBt */
+       needXcommit = 1;
+-      if( i!=1 ) nTrans++;
+       sqlite3BtreeEnter(pBt);
+-      rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
++      pPager = sqlite3BtreePager(pBt);
++      if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF
++       && aMJNeeded[sqlite3PagerGetJournalMode(pPager)]
++      ){ 
++        assert( i!=1 );
++        nTrans++;
++      }
++      rc = sqlite3PagerExclusiveLock(pPager);
+       sqlite3BtreeLeave(pBt);
+     }
+   }
+@@ -66818,7 +77612,6 @@
+ #ifndef SQLITE_OMIT_DISKIO
+   else{
+     sqlite3_vfs *pVfs = db->pVfs;
+-    int needSync = 0;
+     char *zMaster = 0;   /* File-name for the master journal */
+     char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
+     sqlite3_file *pMaster = 0;
+@@ -66830,7 +77623,7 @@
+     /* Select a master journal file name */
+     nMainFile = sqlite3Strlen30(zMainFile);
+     zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile);
+-    if( zMaster==0 ) return SQLITE_NOMEM;
++    if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
+     do {
+       u32 iRandom;
+       if( retryCount ){
+@@ -66878,9 +77671,6 @@
+           continue;  /* Ignore TEMP and :memory: databases */
+         }
+         assert( zFile[0]!=0 );
+-        if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
+-          needSync = 1;
+-        }
+         rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
+         offset += sqlite3Strlen30(zFile)+1;
+         if( rc!=SQLITE_OK ){
+@@ -66895,8 +77685,7 @@
+     /* Sync the master journal file. If the IOCAP_SEQUENTIAL device
+     ** flag is set this is not required.
+     */
+-    if( needSync 
+-     && 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
++    if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
+      && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
+     ){
+       sqlite3OsCloseFree(pMaster);
+@@ -66932,7 +77721,7 @@
+     ** doing this the directory is synced again before any individual
+     ** transaction files are deleted.
+     */
+-    rc = sqlite3OsDelete(pVfs, zMaster, needSync);
++    rc = sqlite3OsDelete(pVfs, zMaster, 1);
+     sqlite3DbFree(db, zMaster);
+     zMaster = 0;
+     if( rc ){
+@@ -67006,60 +77795,59 @@
+ ** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. 
+ ** Otherwise SQLITE_OK.
+ */
+-SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
++static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){
+   sqlite3 *const db = p->db;
+   int rc = SQLITE_OK;
++  int i;
++  const int iSavepoint = p->iStatement-1;
+ 
+-  /* If p->iStatement is greater than zero, then this Vdbe opened a 
+-  ** statement transaction that should be closed here. The only exception
+-  ** is that an IO error may have occurred, causing an emergency rollback.
+-  ** In this case (db->nStatement==0), and there is nothing to do.
+-  */
+-  if( db->nStatement && p->iStatement ){
+-    int i;
+-    const int iSavepoint = p->iStatement-1;
+-
+-    assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
+-    assert( db->nStatement>0 );
+-    assert( p->iStatement==(db->nStatement+db->nSavepoint) );
+-
+-    for(i=0; i<db->nDb; i++){ 
+-      int rc2 = SQLITE_OK;
+-      Btree *pBt = db->aDb[i].pBt;
+-      if( pBt ){
+-        if( eOp==SAVEPOINT_ROLLBACK ){
+-          rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint);
+-        }
+-        if( rc2==SQLITE_OK ){
+-          rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint);
+-        }
+-        if( rc==SQLITE_OK ){
+-          rc = rc2;
+-        }
+-      }
+-    }
+-    db->nStatement--;
+-    p->iStatement = 0;
++  assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
++  assert( db->nStatement>0 );
++  assert( p->iStatement==(db->nStatement+db->nSavepoint) );
+ 
+-    if( rc==SQLITE_OK ){
++  for(i=0; i<db->nDb; i++){ 
++    int rc2 = SQLITE_OK;
++    Btree *pBt = db->aDb[i].pBt;
++    if( pBt ){
+       if( eOp==SAVEPOINT_ROLLBACK ){
+-        rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint);
++        rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint);
++      }
++      if( rc2==SQLITE_OK ){
++        rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint);
+       }
+       if( rc==SQLITE_OK ){
+-        rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint);
++        rc = rc2;
+       }
+     }
++  }
++  db->nStatement--;
++  p->iStatement = 0;
+ 
+-    /* If the statement transaction is being rolled back, also restore the 
+-    ** database handles deferred constraint counter to the value it had when 
+-    ** the statement transaction was opened.  */
++  if( rc==SQLITE_OK ){
+     if( eOp==SAVEPOINT_ROLLBACK ){
+-      db->nDeferredCons = p->nStmtDefCons;
+-      db->nDeferredImmCons = p->nStmtDefImmCons;
++      rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint);
++    }
++    if( rc==SQLITE_OK ){
++      rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint);
+     }
+   }
++
++  /* If the statement transaction is being rolled back, also restore the 
++  ** database handles deferred constraint counter to the value it had when 
++  ** the statement transaction was opened.  */
++  if( eOp==SAVEPOINT_ROLLBACK ){
++    db->nDeferredCons = p->nStmtDefCons;
++    db->nDeferredImmCons = p->nStmtDefImmCons;
++  }
+   return rc;
+ }
++SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
++  if( p->db->nStatement && p->iStatement ){
++    return vdbeCloseStatement(p, eOp);
++  }
++  return SQLITE_OK;
++}
++
+ 
+ /*
+ ** This function is called when a transaction opened by the database 
+@@ -67079,7 +77867,7 @@
+   ){
+     p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
+     p->errorAction = OE_Abort;
+-    sqlite3SetString(&p->zErrMsg, db, "FOREIGN KEY constraint failed");
++    sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
+     return SQLITE_ERROR;
+   }
+   return SQLITE_OK;
+@@ -67119,14 +77907,13 @@
+   ** one, or the complete transaction if there is no statement transaction.
+   */
+ 
+-  if( p->db->mallocFailed ){
+-    p->rc = SQLITE_NOMEM;
+-  }
+-  if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag);
+-  closeAllCursors(p);
+   if( p->magic!=VDBE_MAGIC_RUN ){
+     return SQLITE_OK;
+   }
++  if( db->mallocFailed ){
++    p->rc = SQLITE_NOMEM_BKPT;
++  }
++  closeAllCursors(p);
+   checkActiveVdbeCnt(db);
+ 
+   /* No commit or rollback needed if the program never started or if the
+@@ -67280,8 +78067,8 @@
+   }
+   p->magic = VDBE_MAGIC_HALT;
+   checkActiveVdbeCnt(db);
+-  if( p->db->mallocFailed ){
+-    p->rc = SQLITE_NOMEM;
++  if( db->mallocFailed ){
++    p->rc = SQLITE_NOMEM_BKPT;
+   }
+ 
+   /* If the auto-commit flag is set to true, then any locks that were held
+@@ -67317,16 +78104,16 @@
+   sqlite3 *db = p->db;
+   int rc = p->rc;
+   if( p->zErrMsg ){
+-    u8 mallocFailed = db->mallocFailed;
++    db->bBenignMalloc++;
+     sqlite3BeginBenignMalloc();
+     if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db);
+     sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
+     sqlite3EndBenignMalloc();
+-    db->mallocFailed = mallocFailed;
+-    db->errCode = rc;
+-  }else{
+-    sqlite3Error(db, rc);
++    db->bBenignMalloc--;
++  }else if( db->pErr ){
++    sqlite3ValueSetNull(db->pErr);
+   }
++  db->errCode = rc;
+   return rc;
+ }
+ 
+@@ -67433,8 +78220,7 @@
+     }
+   }
+ #endif
+-  p->iCurrentTime = 0;
+-  p->magic = VDBE_MAGIC_INIT;
++  p->magic = VDBE_MAGIC_RESET;
+   return p->rc & db->errMask;
+ }
+  
+@@ -67468,21 +78254,22 @@
+ **    * the corresponding bit in argument mask is clear (where the first
+ **      function parameter corresponds to bit 0 etc.).
+ */
+-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
+-  AuxData **pp = &pVdbe->pAuxData;
++SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
+   while( *pp ){
+     AuxData *pAux = *pp;
+     if( (iOp<0)
+-     || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & MASKBIT32(pAux->iArg))))
++     || (pAux->iAuxOp==iOp
++          && pAux->iAuxArg>=0
++          && (pAux->iAuxArg>31 || !(mask & MASKBIT32(pAux->iAuxArg))))
+     ){
+-      testcase( pAux->iArg==31 );
+-      if( pAux->xDelete ){
+-        pAux->xDelete(pAux->pAux);
++      testcase( pAux->iAuxArg==31 );
++      if( pAux->xDeleteAux ){
++        pAux->xDeleteAux(pAux->pAux);
+       }
+-      *pp = pAux->pNext;
+-      sqlite3DbFree(pVdbe->db, pAux);
++      *pp = pAux->pNextAux;
++      sqlite3DbFree(db, pAux);
+     }else{
+-      pp= &pAux->pNext;
++      pp= &pAux->pNextAux;
+     }
+   }
+ }
+@@ -67497,25 +78284,29 @@
+ */
+ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
+   SubProgram *pSub, *pNext;
+-  int i;
+   assert( p->db==0 || p->db==db );
+-  releaseMemArray(p->aVar, p->nVar);
+   releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
+   for(pSub=p->pProgram; pSub; pSub=pNext){
+     pNext = pSub->pNext;
+     vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
+     sqlite3DbFree(db, pSub);
+   }
+-  for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
++  if( p->magic!=VDBE_MAGIC_INIT ){
++    releaseMemArray(p->aVar, p->nVar);
++    sqlite3DbFree(db, p->pVList);
++    sqlite3DbFree(db, p->pFree);
++  }
+   vdbeFreeOpArray(db, p->aOp, p->nOp);
+   sqlite3DbFree(db, p->aColName);
+   sqlite3DbFree(db, p->zSql);
+-  sqlite3DbFree(db, p->pFree);
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+-  for(i=0; i<p->nScan; i++){
+-    sqlite3DbFree(db, p->aScan[i].zName);
++  {
++    int i;
++    for(i=0; i<p->nScan; i++){
++      sqlite3DbFree(db, p->aScan[i].zName);
++    }
++    sqlite3DbFree(db, p->aScan);
+   }
+-  sqlite3DbFree(db, p->aScan);
+ #endif
+ }
+ 
+@@ -67540,7 +78331,7 @@
+   }
+   p->magic = VDBE_MAGIC_DEAD;
+   p->db = 0;
+-  sqlite3DbFree(db, p);
++  sqlite3DbFreeNN(db, p);
+ }
+ 
+ /*
+@@ -67555,7 +78346,8 @@
+ #endif
+   assert( p->deferredMoveto );
+   assert( p->isTable );
+-  rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
++  assert( p->eCurType==CURTYPE_BTREE );
++  rc = sqlite3BtreeMovetoUnpacked(p->uc.pCursor, 0, p->movetoTarget, 0, &res);
+   if( rc ) return rc;
+   if( res!=0 ) return SQLITE_CORRUPT_BKPT;
+ #ifdef SQLITE_TEST
+@@ -67575,9 +78367,10 @@
+ */
+ static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
+   int isDifferentRow, rc;
+-  assert( p->pCursor!=0 );
+-  assert( sqlite3BtreeCursorHasMoved(p->pCursor) );
+-  rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
++  assert( p->eCurType==CURTYPE_BTREE );
++  assert( p->uc.pCursor!=0 );
++  assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) );
++  rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow);
+   p->cacheStatus = CACHE_STALE;
+   if( isDifferentRow ) p->nullRow = 1;
+   return rc;
+@@ -67588,7 +78381,8 @@
+ ** if need be.  Return any I/O error from the restore operation.
+ */
+ SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
+-  if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
++  assert( p->eCurType==CURTYPE_BTREE );
++  if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
+     return handleMovedCursor(p);
+   }
+   return SQLITE_OK;
+@@ -67607,12 +78401,21 @@
+ ** If the cursor is already pointing to the correct row and that row has
+ ** not been deleted out from under the cursor, then this routine is a no-op.
+ */
+-SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
+-  if( p->deferredMoveto ){
+-    return handleDeferredMoveto(p);
+-  }
+-  if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){
+-    return handleMovedCursor(p);
++SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
++  VdbeCursor *p = *pp;
++  if( p->eCurType==CURTYPE_BTREE ){
++    if( p->deferredMoveto ){
++      int iMap;
++      if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){
++        *pp = p->pAltCursor;
++        *piCol = iMap - 1;
++        return SQLITE_OK;
++      }
++      return handleDeferredMoveto(p);
++    }
++    if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
++      return handleMovedCursor(p);
++    }
+   }
+   return SQLITE_OK;
+ }
+@@ -67662,11 +78465,13 @@
+ /*
+ ** Return the serial-type for the value stored in pMem.
+ */
+-SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
++SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
+   int flags = pMem->flags;
+   u32 n;
+ 
++  assert( pLen!=0 );
+   if( flags&MEM_Null ){
++    *pLen = 0;
+     return 0;
+   }
+   if( flags&MEM_Int ){
+@@ -67680,15 +78485,23 @@
+       u = i;
+     }
+     if( u<=127 ){
+-      return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1;
++      if( (i&1)==i && file_format>=4 ){
++        *pLen = 0;
++        return 8+(u32)u;
++      }else{
++        *pLen = 1;
++        return 1;
++      }
+     }
+-    if( u<=32767 ) return 2;
+-    if( u<=8388607 ) return 3;
+-    if( u<=2147483647 ) return 4;
+-    if( u<=MAX_6BYTE ) return 5;
++    if( u<=32767 ){ *pLen = 2; return 2; }
++    if( u<=8388607 ){ *pLen = 3; return 3; }
++    if( u<=2147483647 ){ *pLen = 4; return 4; }
++    if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
++    *pLen = 8;
+     return 6;
+   }
+   if( flags&MEM_Real ){
++    *pLen = 8;
+     return 7;
+   }
+   assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
+@@ -67697,20 +78510,46 @@
+   if( flags & MEM_Zero ){
+     n += pMem->u.nZero;
+   }
++  *pLen = n;
+   return ((n*2) + 12 + ((flags&MEM_Str)!=0));
+ }
+ 
+ /*
++** The sizes for serial types less than 128
++*/
++static const u8 sqlite3SmallTypeSizes[] = {
++        /*  0   1   2   3   4   5   6   7   8   9 */   
++/*   0 */   0,  1,  2,  3,  4,  6,  8,  8,  0,  0,
++/*  10 */   0,  0,  0,  0,  1,  1,  2,  2,  3,  3,
++/*  20 */   4,  4,  5,  5,  6,  6,  7,  7,  8,  8,
++/*  30 */   9,  9, 10, 10, 11, 11, 12, 12, 13, 13,
++/*  40 */  14, 14, 15, 15, 16, 16, 17, 17, 18, 18,
++/*  50 */  19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
++/*  60 */  24, 24, 25, 25, 26, 26, 27, 27, 28, 28,
++/*  70 */  29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
++/*  80 */  34, 34, 35, 35, 36, 36, 37, 37, 38, 38,
++/*  90 */  39, 39, 40, 40, 41, 41, 42, 42, 43, 43,
++/* 100 */  44, 44, 45, 45, 46, 46, 47, 47, 48, 48,
++/* 110 */  49, 49, 50, 50, 51, 51, 52, 52, 53, 53,
++/* 120 */  54, 54, 55, 55, 56, 56, 57, 57
++};
++
++/*
+ ** Return the length of the data corresponding to the supplied serial-type.
+ */
+ SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){
+-  if( serial_type>=12 ){
++  if( serial_type>=128 ){
+     return (serial_type-12)/2;
+   }else{
+-    static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };
+-    return aSize[serial_type];
++    assert( serial_type<12 
++            || sqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 );
++    return sqlite3SmallTypeSizes[serial_type];
+   }
+ }
++SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){
++  assert( serial_type<128 );
++  return sqlite3SmallTypeSizes[serial_type];  
++}
+ 
+ /*
+ ** If we are on an architecture with mixed-endian floating 
+@@ -67792,7 +78631,7 @@
+     }else{
+       v = pMem->u.i;
+     }
+-    len = i = sqlite3VdbeSerialTypeLen(serial_type);
++    len = i = sqlite3SmallTypeSizes[serial_type];
+     assert( i>0 );
+     do{
+       buf[--i] = (u8)(v&0xFF);
+@@ -67806,7 +78645,7 @@
+     assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
+              == (int)sqlite3VdbeSerialTypeLen(serial_type) );
+     len = pMem->n;
+-    memcpy(buf, pMem->z, len);
++    if( len>0 ) memcpy(buf, pMem->z, len);
+     return len;
+   }
+ 
+@@ -67909,6 +78748,10 @@
+       /* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit
+       ** twos-complement integer. */
+       pMem->u.i = FOUR_BYTE_INT(buf);
++#ifdef __HP_cc 
++      /* Work around a sign-extension bug in the HP compiler for HP/UX */
++      if( buf[0]&0x80 ) pMem->u.i |= 0xffffffff80000000LL;
++#endif
+       pMem->flags = MEM_Int;
+       testcase( pMem->u.i<0 );
+       return 4;
+@@ -67964,30 +78807,13 @@
+ ** If an OOM error occurs, NULL is returned.
+ */
+ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
+-  KeyInfo *pKeyInfo,              /* Description of the record */
+-  char *pSpace,                   /* Unaligned space available */
+-  int szSpace,                    /* Size of pSpace[] in bytes */
+-  char **ppFree                   /* OUT: Caller should free this pointer */
++  KeyInfo *pKeyInfo               /* Description of the record */
+ ){
+   UnpackedRecord *p;              /* Unpacked record to return */
+-  int nOff;                       /* Increment pSpace by nOff to align it */
+   int nByte;                      /* Number of bytes required for *p */
+-
+-  /* We want to shift the pointer pSpace up such that it is 8-byte aligned.
+-  ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift 
+-  ** it by.  If pSpace is already 8-byte aligned, nOff should be zero.
+-  */
+-  nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7;
+   nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1);
+-  if( nByte>szSpace+nOff ){
+-    p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
+-    *ppFree = (char *)p;
+-    if( !p ) return 0;
+-  }else{
+-    p = (UnpackedRecord*)&pSpace[nOff];
+-    *ppFree = 0;
+-  }
+-
++  p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
++  if( !p ) return 0;
+   p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
+   assert( pKeyInfo->aSortOrder!=0 );
+   p->pKeyInfo = pKeyInfo;
+@@ -68026,6 +78852,7 @@
+     pMem->db = pKeyInfo->db;
+     /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */
+     pMem->szMalloc = 0;
++    pMem->z = 0;
+     d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
+     pMem++;
+     if( (++u)>=p->nField ) break;
+@@ -68034,7 +78861,7 @@
+   p->nField = u;
+ }
+ 
+-#if SQLITE_DEBUG
++#ifdef SQLITE_DEBUG
+ /*
+ ** This function compares two index or table record keys in the same way
+ ** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
+@@ -68077,6 +78904,7 @@
+   /*  mem1.u.i = 0;  // not needed, here to silence compiler warning */
+   
+   idx1 = getVarint32(aKey1, szHdr1);
++  if( szHdr1>98307 ) return SQLITE_CORRUPT;
+   d1 = szHdr1;
+   assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB );
+   assert( pKeyInfo->aSortOrder!=0 );
+@@ -68138,7 +78966,7 @@
+ }
+ #endif
+ 
+-#if SQLITE_DEBUG
++#ifdef SQLITE_DEBUG
+ /*
+ ** Count the number of fields (a.k.a. columns) in the record given by
+ ** pKey,nKey.  The verify that this count is less than or equal to the
+@@ -68193,7 +79021,6 @@
+   }else{
+     int rc;
+     const void *v1, *v2;
+-    int n1, n2;
+     Mem c1;
+     Mem c2;
+     sqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null);
+@@ -68201,28 +79028,92 @@
+     sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
+     sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
+     v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
+-    n1 = v1==0 ? 0 : c1.n;
+     v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
+-    n2 = v2==0 ? 0 : c2.n;
+-    rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
++    if( (v1==0 || v2==0) ){
++      if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
++      rc = 0;
++    }else{
++      rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2);
++    }
+     sqlite3VdbeMemRelease(&c1);
+     sqlite3VdbeMemRelease(&c2);
+-    if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM;
+     return rc;
+   }
+ }
+ 
+ /*
++** The input pBlob is guaranteed to be a Blob that is not marked
++** with MEM_Zero.  Return true if it could be a zero-blob.
++*/
++static int isAllZero(const char *z, int n){
++  int i;
++  for(i=0; i<n; i++){
++    if( z[i] ) return 0;
++  }
++  return 1;
++}
++
++/*
+ ** Compare two blobs.  Return negative, zero, or positive if the first
+ ** is less than, equal to, or greater than the second, respectively.
+ ** If one blob is a prefix of the other, then the shorter is the lessor.
+ */
+ static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
+-  int c = memcmp(pB1->z, pB2->z, pB1->n>pB2->n ? pB2->n : pB1->n);
++  int c;
++  int n1 = pB1->n;
++  int n2 = pB2->n;
++
++  /* It is possible to have a Blob value that has some non-zero content
++  ** followed by zero content.  But that only comes up for Blobs formed
++  ** by the OP_MakeRecord opcode, and such Blobs never get passed into
++  ** sqlite3MemCompare(). */
++  assert( (pB1->flags & MEM_Zero)==0 || n1==0 );
++  assert( (pB2->flags & MEM_Zero)==0 || n2==0 );
++
++  if( (pB1->flags|pB2->flags) & MEM_Zero ){
++    if( pB1->flags & pB2->flags & MEM_Zero ){
++      return pB1->u.nZero - pB2->u.nZero;
++    }else if( pB1->flags & MEM_Zero ){
++      if( !isAllZero(pB2->z, pB2->n) ) return -1;
++      return pB1->u.nZero - n2;
++    }else{
++      if( !isAllZero(pB1->z, pB1->n) ) return +1;
++      return n1 - pB2->u.nZero;
++    }
++  }
++  c = memcmp(pB1->z, pB2->z, n1>n2 ? n2 : n1);
+   if( c ) return c;
+-  return pB1->n - pB2->n;
++  return n1 - n2;
+ }
+ 
++/*
++** Do a comparison between a 64-bit signed integer and a 64-bit floating-point
++** number.  Return negative, zero, or positive if the first (i64) is less than,
++** equal to, or greater than the second (double).
++*/
++static int sqlite3IntFloatCompare(i64 i, double r){
++  if( sizeof(LONGDOUBLE_TYPE)>8 ){
++    LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i;
++    if( x<r ) return -1;
++    if( x>r ) return +1;
++    return 0;
++  }else{
++    i64 y;
++    double s;
++    if( r<-9223372036854775808.0 ) return +1;
++    if( r>9223372036854775807.0 ) return -1;
++    y = (i64)r;
++    if( i<y ) return -1;
++    if( i>y ){
++      if( y==SMALLEST_INT64 && r>0.0 ) return -1;
++      return +1;
++    }
++    s = (double)i;
++    if( s<r ) return -1;
++    if( s>r ) return +1;
++    return 0;
++  }
++}
+ 
+ /*
+ ** Compare the values contained by the two memory cells, returning
+@@ -68249,34 +79140,34 @@
+     return (f2&MEM_Null) - (f1&MEM_Null);
+   }
+ 
+-  /* If one value is a number and the other is not, the number is less.
+-  ** If both are numbers, compare as reals if one is a real, or as integers
+-  ** if both values are integers.
++  /* At least one of the two values is a number
+   */
+   if( combined_flags&(MEM_Int|MEM_Real) ){
+-    double r1, r2;
+     if( (f1 & f2 & MEM_Int)!=0 ){
+       if( pMem1->u.i < pMem2->u.i ) return -1;
+-      if( pMem1->u.i > pMem2->u.i ) return 1;
++      if( pMem1->u.i > pMem2->u.i ) return +1;
+       return 0;
+     }
+-    if( (f1&MEM_Real)!=0 ){
+-      r1 = pMem1->u.r;
+-    }else if( (f1&MEM_Int)!=0 ){
+-      r1 = (double)pMem1->u.i;
+-    }else{
+-      return 1;
++    if( (f1 & f2 & MEM_Real)!=0 ){
++      if( pMem1->u.r < pMem2->u.r ) return -1;
++      if( pMem1->u.r > pMem2->u.r ) return +1;
++      return 0;
+     }
+-    if( (f2&MEM_Real)!=0 ){
+-      r2 = pMem2->u.r;
+-    }else if( (f2&MEM_Int)!=0 ){
+-      r2 = (double)pMem2->u.i;
+-    }else{
+-      return -1;
++    if( (f1&MEM_Int)!=0 ){
++      if( (f2&MEM_Real)!=0 ){
++        return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
++      }else{
++        return -1;
++      }
+     }
+-    if( r1<r2 ) return -1;
+-    if( r1>r2 ) return 1;
+-    return 0;
++    if( (f1&MEM_Real)!=0 ){
++      if( (f2&MEM_Int)!=0 ){
++        return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
++      }else{
++        return -1;
++      }
++    }
++    return +1;
+   }
+ 
+   /* If one value is a string and the other is a blob, the string is less.
+@@ -68290,7 +79181,7 @@
+       return -1;
+     }
+ 
+-    assert( pMem1->enc==pMem2->enc );
++    assert( pMem1->enc==pMem2->enc || pMem1->db->mallocFailed );
+     assert( pMem1->enc==SQLITE_UTF8 || 
+             pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
+ 
+@@ -68422,18 +79313,13 @@
+     if( pRhs->flags & MEM_Int ){
+       serial_type = aKey1[idx1];
+       testcase( serial_type==12 );
+-      if( serial_type>=12 ){
++      if( serial_type>=10 ){
+         rc = +1;
+       }else if( serial_type==0 ){
+         rc = -1;
+       }else if( serial_type==7 ){
+-        double rhs = (double)pRhs->u.i;
+         sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
+-        if( mem1.u.r<rhs ){
+-          rc = -1;
+-        }else if( mem1.u.r>rhs ){
+-          rc = +1;
+-        }
++        rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r);
+       }else{
+         i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]);
+         i64 rhs = pRhs->u.i;
+@@ -68448,23 +79334,24 @@
+     /* RHS is real */
+     else if( pRhs->flags & MEM_Real ){
+       serial_type = aKey1[idx1];
+-      if( serial_type>=12 ){
++      if( serial_type>=10 ){
++        /* Serial types 12 or greater are strings and blobs (greater than
++        ** numbers). Types 10 and 11 are currently "reserved for future 
++        ** use", so it doesn't really matter what the results of comparing
++        ** them to numberic values are.  */
+         rc = +1;
+       }else if( serial_type==0 ){
+         rc = -1;
+       }else{
+-        double rhs = pRhs->u.r;
+-        double lhs;
+         sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
+         if( serial_type==7 ){
+-          lhs = mem1.u.r;
++          if( mem1.u.r<pRhs->u.r ){
++            rc = -1;
++          }else if( mem1.u.r>pRhs->u.r ){
++            rc = +1;
++          }
+         }else{
+-          lhs = (double)mem1.u.i;
+-        }
+-        if( lhs<rhs ){
+-          rc = -1;
+-        }else if( lhs>rhs ){
+-          rc = +1;
++          rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r);
+         }
+       }
+     }
+@@ -68502,6 +79389,7 @@
+ 
+     /* RHS is a blob */
+     else if( pRhs->flags & MEM_Blob ){
++      assert( (pRhs->flags & MEM_Zero)==0 || pRhs->n==0 );
+       getVarint32(&aKey1[idx1], serial_type);
+       testcase( serial_type==12 );
+       if( serial_type<12 || (serial_type & 0x01) ){
+@@ -68513,6 +79401,12 @@
+         if( (d1+nStr) > (unsigned)nKey1 ){
+           pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
+           return 0;                /* Corruption */
++        }else if( pRhs->flags & MEM_Zero ){
++          if( !isAllZero((const char*)&aKey1[d1],nStr) ){
++            rc = 1;
++          }else{
++            rc = nStr - pRhs->u.nZero;
++          }
+         }else{
+           int nCmp = MIN(nStr, pRhs->n);
+           rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
+@@ -68554,6 +79448,7 @@
+        || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) 
+        || pKeyInfo->db->mallocFailed
+   );
++  pPKey2->eqSeen = 1;
+   return pPKey2->default_rc;
+ }
+ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
+@@ -68582,7 +79477,7 @@
+   int res;
+   u32 y;
+   u64 x;
+-  i64 v = pPKey2->aMem[0].u.i;
++  i64 v;
+   i64 lhs;
+ 
+   vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
+@@ -68641,6 +79536,7 @@
+       return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
+   }
+ 
++  v = pPKey2->aMem[0].u.i;
+   if( v>lhs ){
+     res = pPKey2->r1;
+   }else if( v<lhs ){
+@@ -68653,6 +79549,7 @@
+     /* The first fields of the two keys are equal and there are no trailing
+     ** fields. Return pPKey2->default_rc in this case. */
+     res = pPKey2->default_rc;
++    pPKey2->eqSeen = 1;
+   }
+ 
+   assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) );
+@@ -68673,6 +79570,7 @@
+   int serial_type;
+   int res;
+ 
++  assert( pPKey2->aMem[0].flags & MEM_Str );
+   vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
+   getVarint32(&aKey1[1], serial_type);
+   if( serial_type<12 ){
+@@ -68699,6 +79597,7 @@
+           res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
+         }else{
+           res = pPKey2->default_rc;
++          pPKey2->eqSeen = 1;
+         }
+       }else if( res>0 ){
+         res = pPKey2->r2;
+@@ -68784,13 +79683,12 @@
+   ** this code can safely assume that nCellKey is 32-bits  
+   */
+   assert( sqlite3BtreeCursorIsValid(pCur) );
+-  VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
+-  assert( rc==SQLITE_OK );     /* pCur is always valid so KeySize cannot fail */
++  nCellKey = sqlite3BtreePayloadSize(pCur);
+   assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
+ 
+   /* Read in the complete content of the index entry */
+   sqlite3VdbeMemInit(&m, db, 0);
+-  rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m);
++  rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m);
+   if( rc ){
+     return rc;
+   }
+@@ -68817,7 +79715,7 @@
+   if( unlikely(typeRowid<1 || typeRowid>9 || typeRowid==7) ){
+     goto idx_rowid_corruption;
+   }
+-  lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
++  lenRowid = sqlite3SmallTypeSizes[typeRowid];
+   testcase( (u32)m.n==szHdr+lenRowid );
+   if( unlikely((u32)m.n<szHdr+lenRowid) ){
+     goto idx_rowid_corruption;
+@@ -68856,12 +79754,13 @@
+ ){
+   i64 nCellKey = 0;
+   int rc;
+-  BtCursor *pCur = pC->pCursor;
++  BtCursor *pCur;
+   Mem m;
+ 
++  assert( pC->eCurType==CURTYPE_BTREE );
++  pCur = pC->uc.pCursor;
+   assert( sqlite3BtreeCursorIsValid(pCur) );
+-  VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
+-  assert( rc==SQLITE_OK );    /* pCur is always valid so KeySize cannot fail */
++  nCellKey = sqlite3BtreePayloadSize(pCur);
+   /* nCellKey will always be between 0 and 0xffffffff because of the way
+   ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
+   if( nCellKey<=0 || nCellKey>0x7fffffff ){
+@@ -68869,7 +79768,7 @@
+     return SQLITE_CORRUPT_BKPT;
+   }
+   sqlite3VdbeMemInit(&m, db, 0);
+-  rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (u32)nCellKey, 1, &m);
++  rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m);
+   if( rc ){
+     return rc;
+   }
+@@ -68921,6 +79820,13 @@
+ }
+ 
+ /*
++** Return the SQLITE_PREPARE flags for a Vdbe.
++*/
++SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe *v){
++  return v->prepFlags;
++}
++
++/*
+ ** Return a pointer to an sqlite3_value structure containing the value bound
+ ** parameter iVar of VM v. Except, if the value is an SQL NULL, return 
+ ** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_*
+@@ -68932,6 +79838,7 @@
+   assert( iVar>0 );
+   if( v ){
+     Mem *pMem = &v->aVar[iVar-1];
++    assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
+     if( 0==(pMem->flags & MEM_Null) ){
+       sqlite3_value *pRet = sqlite3ValueNew(v->db);
+       if( pRet ){
+@@ -68951,13 +79858,36 @@
+ */
+ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
+   assert( iVar>0 );
+-  if( iVar>32 ){
+-    v->expmask = 0xffffffff;
++  assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
++  if( iVar>=32 ){
++    v->expmask |= 0x80000000;
+   }else{
+     v->expmask |= ((u32)1 << (iVar-1));
+   }
+ }
+ 
++/*
++** Cause a function to throw an error if it was call from OP_PureFunc
++** rather than OP_Function.
++**
++** OP_PureFunc means that the function must be deterministic, and should
++** throw an error if it is given inputs that would make it non-deterministic.
++** This routine is invoked by date/time functions that use non-deterministic
++** features such as 'now'.
++*/
++SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context *pCtx){
++#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
++  if( pCtx->pVdbe==0 ) return 1;
++#endif
++  if( pCtx->pVdbe->aOp[pCtx->iOp].opcode==OP_PureFunc ){
++    sqlite3_result_error(pCtx, 
++       "non-deterministic function in index expression or CHECK constraint",
++       -1);
++    return 0;
++  }
++  return 1;
++}
++
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+ /*
+ ** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
+@@ -68965,14 +79895,105 @@
+ ** in memory obtained from sqlite3DbMalloc).
+ */
+ SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){
+-  sqlite3 *db = p->db;
+-  sqlite3DbFree(db, p->zErrMsg);
+-  p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
+-  sqlite3_free(pVtab->zErrMsg);
+-  pVtab->zErrMsg = 0;
++  if( pVtab->zErrMsg ){
++    sqlite3 *db = p->db;
++    sqlite3DbFree(db, p->zErrMsg);
++    p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
++    sqlite3_free(pVtab->zErrMsg);
++    pVtab->zErrMsg = 0;
++  }
+ }
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+ 
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++
++/*
++** If the second argument is not NULL, release any allocations associated 
++** with the memory cells in the p->aMem[] array. Also free the UnpackedRecord
++** structure itself, using sqlite3DbFree().
++**
++** This function is used to free UnpackedRecord structures allocated by
++** the vdbeUnpackRecord() function found in vdbeapi.c.
++*/
++static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
++  if( p ){
++    int i;
++    for(i=0; i<nField; i++){
++      Mem *pMem = &p->aMem[i];
++      if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
++    }
++    sqlite3DbFreeNN(db, p);
++  }
++}
++#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
++
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++/*
++** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call,
++** then cursor passed as the second argument should point to the row about
++** to be update or deleted. If the application calls sqlite3_preupdate_old(),
++** the required value will be read from the row the cursor points to.
++*/
++SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
++  Vdbe *v,                        /* Vdbe pre-update hook is invoked by */
++  VdbeCursor *pCsr,               /* Cursor to grab old.* values from */
++  int op,                         /* SQLITE_INSERT, UPDATE or DELETE */
++  const char *zDb,                /* Database name */
++  Table *pTab,                    /* Modified table */
++  i64 iKey1,                      /* Initial key value */
++  int iReg                        /* Register for new.* record */
++){
++  sqlite3 *db = v->db;
++  i64 iKey2;
++  PreUpdate preupdate;
++  const char *zTbl = pTab->zName;
++  static const u8 fakeSortOrder = 0;
++
++  assert( db->pPreUpdate==0 );
++  memset(&preupdate, 0, sizeof(PreUpdate));
++  if( HasRowid(pTab)==0 ){
++    iKey1 = iKey2 = 0;
++    preupdate.pPk = sqlite3PrimaryKeyIndex(pTab);
++  }else{
++    if( op==SQLITE_UPDATE ){
++      iKey2 = v->aMem[iReg].u.i;
++    }else{
++      iKey2 = iKey1;
++    }
++  }
++
++  assert( pCsr->nField==pTab->nCol 
++       || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
++  );
++
++  preupdate.v = v;
++  preupdate.pCsr = pCsr;
++  preupdate.op = op;
++  preupdate.iNewReg = iReg;
++  preupdate.keyinfo.db = db;
++  preupdate.keyinfo.enc = ENC(db);
++  preupdate.keyinfo.nField = pTab->nCol;
++  preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
++  preupdate.iKey1 = iKey1;
++  preupdate.iKey2 = iKey2;
++  preupdate.pTab = pTab;
++
++  db->pPreUpdate = &preupdate;
++  db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
++  db->pPreUpdate = 0;
++  sqlite3DbFree(db, preupdate.aRecord);
++  vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pUnpacked);
++  vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pNewUnpacked);
++  if( preupdate.aNew ){
++    int i;
++    for(i=0; i<pCsr->nField; i++){
++      sqlite3VdbeMemRelease(&preupdate.aNew[i]);
++    }
++    sqlite3DbFreeNN(db, preupdate.aNew);
++  }
++}
++#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
++
+ /************** End of vdbeaux.c *********************************************/
+ /************** Begin file vdbeapi.c *****************************************/
+ /*
+@@ -68990,6 +80011,8 @@
+ ** This file contains code use to implement APIs that are part of the
+ ** VDBE.
+ */
++/* #include "sqliteInt.h" */
++/* #include "vdbeInt.h" */
+ 
+ #ifndef SQLITE_OMIT_DEPRECATED
+ /*
+@@ -69000,7 +80023,7 @@
+ ** collating sequences are registered or if an authorizer function is
+ ** added or changed.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt *pStmt){
++SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){
+   Vdbe *p = (Vdbe*)pStmt;
+   return p==0 || p->expired;
+ }
+@@ -69028,18 +80051,50 @@
+   }
+ }
+ 
++#ifndef SQLITE_OMIT_TRACE
+ /*
+-** The following routine destroys a virtual machine that is created by
+-** the sqlite3_compile() routine. The integer returned is an SQLITE_
+-** success/failure code that describes the result of executing the virtual
+-** machine.
+-**
+-** This routine sets the error code and string returned by
+-** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
++** Invoke the profile callback.  This routine is only called if we already
++** know that the profile callback is defined and needs to be invoked.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt){
+-  int rc;
+-  if( pStmt==0 ){
++static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){
++  sqlite3_int64 iNow;
++  sqlite3_int64 iElapse;
++  assert( p->startTime>0 );
++  assert( db->xProfile!=0 || (db->mTrace & SQLITE_TRACE_PROFILE)!=0 );
++  assert( db->init.busy==0 );
++  assert( p->zSql!=0 );
++  sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
++  iElapse = (iNow - p->startTime)*1000000;
++  if( db->xProfile ){
++    db->xProfile(db->pProfileArg, p->zSql, iElapse);
++  }
++  if( db->mTrace & SQLITE_TRACE_PROFILE ){
++    db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse);
++  }
++  p->startTime = 0;
++}
++/*
++** The checkProfileCallback(DB,P) macro checks to see if a profile callback
++** is needed, and it invokes the callback if it is needed.
++*/
++# define checkProfileCallback(DB,P) \
++   if( ((P)->startTime)>0 ){ invokeProfileCallback(DB,P); }
++#else
++# define checkProfileCallback(DB,P)  /*no-op*/
++#endif
++
++/*
++** The following routine destroys a virtual machine that is created by
++** the sqlite3_compile() routine. The integer returned is an SQLITE_
++** success/failure code that describes the result of executing the virtual
++** machine.
++**
++** This routine sets the error code and string returned by
++** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
++*/
++SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
++  int rc;
++  if( pStmt==0 ){
+     /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
+     ** pointer is a harmless no-op. */
+     rc = SQLITE_OK;
+@@ -69048,6 +80103,7 @@
+     sqlite3 *db = v->db;
+     if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
+     sqlite3_mutex_enter(db->mutex);
++    checkProfileCallback(db, v);
+     rc = sqlite3VdbeFinalize(v);
+     rc = sqlite3ApiExit(db, rc);
+     sqlite3LeaveMutexAndCloseZombie(db);
+@@ -69063,18 +80119,20 @@
+ ** This routine sets the error code and string returned by
+ ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt){
++SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){
+   int rc;
+   if( pStmt==0 ){
+     rc = SQLITE_OK;
+   }else{
+     Vdbe *v = (Vdbe*)pStmt;
+-    sqlite3_mutex_enter(v->db->mutex);
++    sqlite3 *db = v->db;
++    sqlite3_mutex_enter(db->mutex);
++    checkProfileCallback(db, v);
+     rc = sqlite3VdbeReset(v);
+     sqlite3VdbeRewind(v);
+-    assert( (rc & (v->db->errMask))==rc );
+-    rc = sqlite3ApiExit(v->db, rc);
+-    sqlite3_mutex_leave(v->db->mutex);
++    assert( (rc & (db->errMask))==rc );
++    rc = sqlite3ApiExit(db, rc);
++    sqlite3_mutex_leave(db->mutex);
+   }
+   return rc;
+ }
+@@ -69082,7 +80140,7 @@
+ /*
+ ** Set all the parameters in the compiled SQL statement to NULL.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt *pStmt){
++SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
+   int i;
+   int rc = SQLITE_OK;
+   Vdbe *p = (Vdbe*)pStmt;
+@@ -69094,7 +80152,8 @@
+     sqlite3VdbeMemRelease(&p->aVar[i]);
+     p->aVar[i].flags = MEM_Null;
+   }
+-  if( p->isPrepareV2 && p->expmask ){
++  assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 );
++  if( p->expmask ){
+     p->expired = 1;
+   }
+   sqlite3_mutex_leave(mutex);
+@@ -69106,42 +80165,62 @@
+ ** The following routines extract information from a Mem or sqlite3_value
+ ** structure.
+ */
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value *pVal){
++SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
+   Mem *p = (Mem*)pVal;
+   if( p->flags & (MEM_Blob|MEM_Str) ){
+-    sqlite3VdbeMemExpandBlob(p);
++    if( ExpandBlob(p)!=SQLITE_OK ){
++      assert( p->flags==MEM_Null && p->z==0 );
++      return 0;
++    }
+     p->flags |= MEM_Blob;
+     return p->n ? p->z : 0;
+   }else{
+     return sqlite3_value_text(pVal);
+   }
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value *pVal){
++SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){
+   return sqlite3ValueBytes(pVal, SQLITE_UTF8);
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value *pVal){
++SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){
+   return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
+ }
+-SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value *pVal){
++SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){
+   return sqlite3VdbeRealValue((Mem*)pVal);
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value *pVal){
++SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){
+   return (int)sqlite3VdbeIntValue((Mem*)pVal);
+ }
+-SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value *pVal){
++SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
+   return sqlite3VdbeIntValue((Mem*)pVal);
+ }
+-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value *pVal){
++SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value *pVal){
++  Mem *pMem = (Mem*)pVal;
++  return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0);
++}
++SQLITE_API void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){
++  Mem *p = (Mem*)pVal;
++  if( (p->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) ==
++                 (MEM_Null|MEM_Term|MEM_Subtype)
++   && zPType!=0
++   && p->eSubtype=='p'
++   && strcmp(p->u.zPType, zPType)==0
++  ){
++    return (void*)p->z;
++  }else{
++    return 0;
++  }
++}
++SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
+   return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
+ }
+ #ifndef SQLITE_OMIT_UTF16
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value* pVal){
++SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){
+   return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
+ }
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value *pVal){
++SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){
+   return sqlite3ValueText(pVal, SQLITE_UTF16BE);
+ }
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value *pVal){
++SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
+   return sqlite3ValueText(pVal, SQLITE_UTF16LE);
+ }
+ #endif /* SQLITE_OMIT_UTF16 */
+@@ -69149,7 +80228,7 @@
+ ** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
+ ** point number string BLOB NULL
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value* pVal){
++SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
+   static const u8 aType[] = {
+      SQLITE_BLOB,     /* 0x00 */
+      SQLITE_NULL,     /* 0x01 */
+@@ -69187,6 +80266,36 @@
+   return aType[pVal->flags&MEM_AffMask];
+ }
+ 
++/* Make a copy of an sqlite3_value object
++*/
++SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
++  sqlite3_value *pNew;
++  if( pOrig==0 ) return 0;
++  pNew = sqlite3_malloc( sizeof(*pNew) );
++  if( pNew==0 ) return 0;
++  memset(pNew, 0, sizeof(*pNew));
++  memcpy(pNew, pOrig, MEMCELLSIZE);
++  pNew->flags &= ~MEM_Dyn;
++  pNew->db = 0;
++  if( pNew->flags&(MEM_Str|MEM_Blob) ){
++    pNew->flags &= ~(MEM_Static|MEM_Dyn);
++    pNew->flags |= MEM_Ephem;
++    if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){
++      sqlite3ValueFree(pNew);
++      pNew = 0;
++    }
++  }
++  return pNew;
++}
++
++/* Destroy an sqlite3_value object previously obtained from
++** sqlite3_value_dup().
++*/
++SQLITE_API void sqlite3_value_free(sqlite3_value *pOld){
++  sqlite3ValueFree(pOld);
++}
++  
++
+ /**************************** sqlite3_result_  *******************************
+ ** The following routines are used by user-defined functions to specify
+ ** the function result.
+@@ -69225,7 +80334,7 @@
+   if( pCtx ) sqlite3_result_error_toobig(pCtx);
+   return SQLITE_TOOBIG;
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(
++SQLITE_API void sqlite3_result_blob(
+   sqlite3_context *pCtx, 
+   const void *z, 
+   int n, 
+@@ -69235,7 +80344,7 @@
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   setResultStrOrError(pCtx, z, n, 0, xDel);
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(
++SQLITE_API void sqlite3_result_blob64(
+   sqlite3_context *pCtx, 
+   const void *z, 
+   sqlite3_uint64 n,
+@@ -69249,37 +80358,55 @@
+     setResultStrOrError(pCtx, z, (int)n, 0, xDel);
+   }
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context *pCtx, double rVal){
++SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   sqlite3VdbeMemSetDouble(pCtx->pOut, rVal);
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
++SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   pCtx->isError = SQLITE_ERROR;
+   pCtx->fErrorOrAux = 1;
+   sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
+ }
+ #ifndef SQLITE_OMIT_UTF16
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
++SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   pCtx->isError = SQLITE_ERROR;
+   pCtx->fErrorOrAux = 1;
+   sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
+ }
+ #endif
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context *pCtx, int iVal){
++SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal);
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
++SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   sqlite3VdbeMemSetInt64(pCtx->pOut, iVal);
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context *pCtx){
++SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   sqlite3VdbeMemSetNull(pCtx->pOut);
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text(
++SQLITE_API void sqlite3_result_pointer(
++  sqlite3_context *pCtx,
++  void *pPtr,
++  const char *zPType,
++  void (*xDestructor)(void*)
++){
++  Mem *pOut = pCtx->pOut;
++  assert( sqlite3_mutex_held(pOut->db->mutex) );
++  sqlite3VdbeMemRelease(pOut);
++  pOut->flags = MEM_Null;
++  sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor);
++}
++SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
++  Mem *pOut = pCtx->pOut;
++  assert( sqlite3_mutex_held(pOut->db->mutex) );
++  pOut->eSubtype = eSubtype & 0xff;
++  pOut->flags |= MEM_Subtype;
++}
++SQLITE_API void sqlite3_result_text(
+   sqlite3_context *pCtx, 
+   const char *z, 
+   int n,
+@@ -69288,7 +80415,7 @@
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(
++SQLITE_API void sqlite3_result_text64(
+   sqlite3_context *pCtx, 
+   const char *z, 
+   sqlite3_uint64 n,
+@@ -69305,7 +80432,7 @@
+   }
+ }
+ #ifndef SQLITE_OMIT_UTF16
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(
++SQLITE_API void sqlite3_result_text16(
+   sqlite3_context *pCtx, 
+   const void *z, 
+   int n, 
+@@ -69314,7 +80441,7 @@
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(
++SQLITE_API void sqlite3_result_text16be(
+   sqlite3_context *pCtx, 
+   const void *z, 
+   int n, 
+@@ -69323,7 +80450,7 @@
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(
++SQLITE_API void sqlite3_result_text16le(
+   sqlite3_context *pCtx, 
+   const void *z, 
+   int n, 
+@@ -69333,15 +80460,24 @@
+   setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
+ }
+ #endif /* SQLITE_OMIT_UTF16 */
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
++SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   sqlite3VdbeMemCopy(pCtx->pOut, pValue);
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
++SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
+ }
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
++SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
++  Mem *pOut = pCtx->pOut;
++  assert( sqlite3_mutex_held(pOut->db->mutex) );
++  if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
++    return SQLITE_TOOBIG;
++  }
++  sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
++  return SQLITE_OK;
++}
++SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
+   pCtx->isError = errCode;
+   pCtx->fErrorOrAux = 1;
+ #ifdef SQLITE_DEBUG
+@@ -69354,7 +80490,7 @@
+ }
+ 
+ /* Force an SQLITE_TOOBIG error. */
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context *pCtx){
++SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   pCtx->isError = SQLITE_TOOBIG;
+   pCtx->fErrorOrAux = 1;
+@@ -69363,12 +80499,12 @@
+ }
+ 
+ /* An SQLITE_NOMEM error. */
+-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context *pCtx){
++SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   sqlite3VdbeMemSetNull(pCtx->pOut);
+-  pCtx->isError = SQLITE_NOMEM;
++  pCtx->isError = SQLITE_NOMEM_BKPT;
+   pCtx->fErrorOrAux = 1;
+-  pCtx->pOut->db->mallocFailed = 1;
++  sqlite3OomFault(pCtx->pOut->db);
+ }
+ 
+ /*
+@@ -69387,7 +80523,7 @@
+       nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
+       sqlite3BtreeLeave(pBt);
+       if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
+-        rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry);
++        rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
+       }
+     }
+   }
+@@ -69395,6 +80531,7 @@
+   return rc;
+ }
+ 
++
+ /*
+ ** Execute the statement pStmt, either until a row of data is ready, the
+ ** statement is completely executed or an error occurs.
+@@ -69441,7 +80578,7 @@
+   db = p->db;
+   if( db->mallocFailed ){
+     p->rc = SQLITE_NOMEM;
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+ 
+   if( p->pc<=0 && p->expired ){
+@@ -69463,8 +80600,11 @@
+     );
+ 
+ #ifndef SQLITE_OMIT_TRACE
+-    if( db->xProfile && !db->init.busy ){
++    if( (db->xProfile || (db->mTrace & SQLITE_TRACE_PROFILE)!=0)
++        && !db->init.busy && p->zSql ){
+       sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
++    }else{
++      assert( p->startTime==0 );
+     }
+ #endif
+ 
+@@ -69488,13 +80628,8 @@
+   }
+ 
+ #ifndef SQLITE_OMIT_TRACE
+-  /* Invoke the profile callback if there is one
+-  */
+-  if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy && p->zSql ){
+-    sqlite3_int64 iNow;
+-    sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
+-    db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000);
+-  }
++  /* If the statement completed successfully, invoke the profile callback */
++  if( rc!=SQLITE_ROW ) checkProfileCallback(db, p);
+ #endif
+ 
+   if( rc==SQLITE_DONE ){
+@@ -69507,7 +80642,7 @@
+ 
+   db->errCode = rc;
+   if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){
+-    p->rc = SQLITE_NOMEM;
++    p->rc = SQLITE_NOMEM_BKPT;
+   }
+ end_of_step:
+   /* At this point local variable rc holds the value that should be 
+@@ -69518,11 +80653,14 @@
+   ** were called on statement p.
+   */
+   assert( rc==SQLITE_ROW  || rc==SQLITE_DONE   || rc==SQLITE_ERROR 
+-       || rc==SQLITE_BUSY || rc==SQLITE_MISUSE
++       || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE
+   );
+   assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp );
+-  if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
+-    /* If this statement was prepared using sqlite3_prepare_v2(), and an
++  if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 
++   && rc!=SQLITE_ROW 
++   && rc!=SQLITE_DONE 
++  ){
++    /* If this statement was prepared using saved SQL and an 
+     ** error has occurred, then return the error code in p->rc to the
+     ** caller. Set the error code in the database handle to the same value.
+     */ 
+@@ -69536,7 +80674,7 @@
+ ** sqlite3Step() to do most of the work.  If a schema error occurs,
+ ** call sqlite3Reprepare() and try again.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt *pStmt){
++SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
+   int rc = SQLITE_OK;      /* Result from sqlite3Step() */
+   int rc2 = SQLITE_OK;     /* Result from sqlite3Reprepare() */
+   Vdbe *v = (Vdbe*)pStmt;  /* the prepared statement */
+@@ -69574,7 +80712,7 @@
+       v->rc = rc2;
+     } else {
+       v->zErrMsg = 0;
+-      v->rc = rc = SQLITE_NOMEM;
++      v->rc = rc = SQLITE_NOMEM_BKPT;
+     }
+   }
+   rc = sqlite3ApiExit(db, rc);
+@@ -69587,7 +80725,7 @@
+ ** Extract the user data from a sqlite3_context structure and return a
+ ** pointer to it.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context *p){
++SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
+   assert( p && p->pFunc );
+   return p->pFunc->pUserData;
+ }
+@@ -69602,8 +80740,8 @@
+ ** sqlite3_create_function16() routines that originally registered the
+ ** application defined function.
+ */
+-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context *p){
+-  assert( p && p->pFunc );
++SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
++  assert( p && p->pOut );
+   return p->pOut->db;
+ }
+ 
+@@ -69678,8 +80816,8 @@
+ ** context is allocated on the first call.  Subsequent calls return the
+ ** same context that was returned on prior calls.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context *p, int nByte){
+-  assert( p && p->pFunc && p->pFunc->xStep );
++SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
++  assert( p && p->pFunc && p->pFunc->xFinalize );
+   assert( sqlite3_mutex_held(p->pOut->db->mutex) );
+   testcase( nByte<0 );
+   if( (p->pMem->flags & MEM_Agg)==0 ){
+@@ -69692,8 +80830,14 @@
+ /*
+ ** Return the auxiliary data pointer, if any, for the iArg'th argument to
+ ** the user-function defined by pCtx.
++**
++** The left-most argument is 0.
++**
++** Undocumented behavior:  If iArg is negative then access a cache of
++** auxiliary data pointers that is available to all functions within a
++** single prepared statement.  The iArg values must match.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
++SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
+   AuxData *pAuxData;
+ 
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+@@ -69702,19 +80846,26 @@
+ #else
+   assert( pCtx->pVdbe!=0 );
+ #endif
+-  for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
+-    if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
++  for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
++    if(  pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
++      return pAuxData->pAux;
++    }
+   }
+-
+-  return (pAuxData ? pAuxData->pAux : 0);
++  return 0;
+ }
+ 
+ /*
+ ** Set the auxiliary data pointer and delete function, for the iArg'th
+ ** argument to the user-function defined by pCtx. Any previous value is
+ ** deleted by calling the delete function specified when it was set.
++**
++** The left-most argument is 0.
++**
++** Undocumented behavior:  If iArg is negative then make the data available
++** to all functions within the current prepared statement using iArg as an
++** access code.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(
++SQLITE_API void sqlite3_set_auxdata(
+   sqlite3_context *pCtx, 
+   int iArg, 
+   void *pAux, 
+@@ -69724,33 +80875,34 @@
+   Vdbe *pVdbe = pCtx->pVdbe;
+ 
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+-  if( iArg<0 ) goto failed;
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+   if( pVdbe==0 ) goto failed;
+ #else
+   assert( pVdbe!=0 );
+ #endif
+ 
+-  for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
+-    if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
++  for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
++    if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
++      break;
++    }
+   }
+   if( pAuxData==0 ){
+     pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
+     if( !pAuxData ) goto failed;
+-    pAuxData->iOp = pCtx->iOp;
+-    pAuxData->iArg = iArg;
+-    pAuxData->pNext = pVdbe->pAuxData;
++    pAuxData->iAuxOp = pCtx->iOp;
++    pAuxData->iAuxArg = iArg;
++    pAuxData->pNextAux = pVdbe->pAuxData;
+     pVdbe->pAuxData = pAuxData;
+     if( pCtx->fErrorOrAux==0 ){
+       pCtx->isError = 0;
+       pCtx->fErrorOrAux = 1;
+     }
+-  }else if( pAuxData->xDelete ){
+-    pAuxData->xDelete(pAuxData->pAux);
++  }else if( pAuxData->xDeleteAux ){
++    pAuxData->xDeleteAux(pAuxData->pAux);
+   }
+ 
+   pAuxData->pAux = pAux;
+-  pAuxData->xDelete = xDelete;
++  pAuxData->xDeleteAux = xDelete;
+   return;
+ 
+ failed:
+@@ -69769,8 +80921,8 @@
+ ** implementations should keep their own counts within their aggregate
+ ** context.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context *p){
+-  assert( p && p->pMem && p->pFunc && p->pFunc->xStep );
++SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
++  assert( p && p->pMem && p->pFunc && p->pFunc->xFinalize );
+   return p->pMem->n;
+ }
+ #endif
+@@ -69778,7 +80930,7 @@
+ /*
+ ** Return the number of columns in the result set for the statement pStmt.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt){
++SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
+   Vdbe *pVm = (Vdbe *)pStmt;
+   return pVm ? pVm->nResColumn : 0;
+ }
+@@ -69787,7 +80939,7 @@
+ ** Return the number of values available from the current row of the
+ ** currently executing statement pStmt.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt){
++SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){
+   Vdbe *pVm = (Vdbe *)pStmt;
+   if( pVm==0 || pVm->pResultSet==0 ) return 0;
+   return pVm->nResColumn;
+@@ -69812,18 +80964,19 @@
+ #endif
+     = {
+         /* .u          = */ {0},
+-        /* .flags      = */ MEM_Null,
+-        /* .enc        = */ 0,
+-        /* .n          = */ 0,
+-        /* .z          = */ 0,
+-        /* .zMalloc    = */ 0,
+-        /* .szMalloc   = */ 0,
+-        /* .iPadding1  = */ 0,
+-        /* .db         = */ 0,
+-        /* .xDel       = */ 0,
++        /* .flags      = */ (u16)MEM_Null,
++        /* .enc        = */ (u8)0,
++        /* .eSubtype   = */ (u8)0,
++        /* .n          = */ (int)0,
++        /* .z          = */ (char*)0,
++        /* .zMalloc    = */ (char*)0,
++        /* .szMalloc   = */ (int)0,
++        /* .uTemp      = */ (u32)0,
++        /* .db         = */ (sqlite3*)0,
++        /* .xDel       = */ (void(*)(void*))0,
+ #ifdef SQLITE_DEBUG
+-        /* .pScopyFrom = */ 0,
+-        /* .pFiller    = */ 0,
++        /* .pScopyFrom = */ (Mem*)0,
++        /* .pFiller    = */ (void*)0,
+ #endif
+       };
+   return &nullMem;
+@@ -69840,14 +80993,13 @@
+   Mem *pOut;
+ 
+   pVm = (Vdbe *)pStmt;
+-  if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
+-    sqlite3_mutex_enter(pVm->db->mutex);
++  if( pVm==0 ) return (Mem*)columnNullValue();
++  assert( pVm->db );
++  sqlite3_mutex_enter(pVm->db->mutex);
++  if( pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
+     pOut = &pVm->pResultSet[i];
+   }else{
+-    if( pVm && ALWAYS(pVm->db) ){
+-      sqlite3_mutex_enter(pVm->db->mutex);
+-      sqlite3Error(pVm->db, SQLITE_RANGE);
+-    }
++    sqlite3Error(pVm->db, SQLITE_RANGE);
+     pOut = (Mem*)columnNullValue();
+   }
+   return pOut;
+@@ -69880,6 +81032,8 @@
+   */
+   Vdbe *p = (Vdbe *)pStmt;
+   if( p ){
++    assert( p->db!=0 );
++    assert( sqlite3_mutex_held(p->db->mutex) );
+     p->rc = sqlite3ApiExit(p->db, p->rc);
+     sqlite3_mutex_leave(p->db->mutex);
+   }
+@@ -69889,7 +81043,7 @@
+ ** The following routines are used to access elements of the current row
+ ** in the result set.
+ */
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
++SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
+   const void *val;
+   val = sqlite3_value_blob( columnMem(pStmt,i) );
+   /* Even though there is no encoding conversion, value_blob() might
+@@ -69899,37 +81053,37 @@
+   columnMallocFailure(pStmt);
+   return val;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
++SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
+   int val = sqlite3_value_bytes( columnMem(pStmt,i) );
+   columnMallocFailure(pStmt);
+   return val;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
++SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
+   int val = sqlite3_value_bytes16( columnMem(pStmt,i) );
+   columnMallocFailure(pStmt);
+   return val;
+ }
+-SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt *pStmt, int i){
++SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
+   double val = sqlite3_value_double( columnMem(pStmt,i) );
+   columnMallocFailure(pStmt);
+   return val;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt *pStmt, int i){
++SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
+   int val = sqlite3_value_int( columnMem(pStmt,i) );
+   columnMallocFailure(pStmt);
+   return val;
+ }
+-SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
++SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
+   sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) );
+   columnMallocFailure(pStmt);
+   return val;
+ }
+-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt *pStmt, int i){
++SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
+   const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) );
+   columnMallocFailure(pStmt);
+   return val;
+ }
+-SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt *pStmt, int i){
++SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
+   Mem *pOut = columnMem(pStmt, i);
+   if( pOut->flags&MEM_Static ){
+     pOut->flags &= ~MEM_Static;
+@@ -69939,13 +81093,13 @@
+   return (sqlite3_value *)pOut;
+ }
+ #ifndef SQLITE_OMIT_UTF16
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
++SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
+   const void *val = sqlite3_value_text16( columnMem(pStmt,i) );
+   columnMallocFailure(pStmt);
+   return val;
+ }
+ #endif /* SQLITE_OMIT_UTF16 */
+-SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt *pStmt, int i){
++SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
+   int iType = sqlite3_value_type( columnMem(pStmt,i) );
+   columnMallocFailure(pStmt);
+   return iType;
+@@ -69997,7 +81151,7 @@
+     ** is the case, clear the mallocFailed flag and return NULL.
+     */
+     if( db->mallocFailed ){
+-      db->mallocFailed = 0;
++      sqlite3OomClear(db);
+       ret = 0;
+     }
+     sqlite3_mutex_leave(db->mutex);
+@@ -70009,12 +81163,12 @@
+ ** Return the name of the Nth column of the result set returned by SQL
+ ** statement pStmt.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt *pStmt, int N){
++SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
+   return columnName(
+       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME);
+ }
+ #ifndef SQLITE_OMIT_UTF16
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
++SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
+   return columnName(
+       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
+ }
+@@ -70034,12 +81188,12 @@
+ ** Return the column declaration type (if applicable) of the 'i'th column
+ ** of the result set of SQL statement pStmt.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
++SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
+   return columnName(
+       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE);
+ }
+ #ifndef SQLITE_OMIT_UTF16
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
++SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
+   return columnName(
+       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
+ }
+@@ -70052,12 +81206,12 @@
+ ** NULL is returned if the result column is an expression or constant or
+ ** anything else which is not an unambiguous reference to a database column.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
++SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
+   return columnName(
+       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE);
+ }
+ #ifndef SQLITE_OMIT_UTF16
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
++SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
+   return columnName(
+       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
+ }
+@@ -70068,12 +81222,12 @@
+ ** NULL is returned if the result column is an expression or constant or
+ ** anything else which is not an unambiguous reference to a database column.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
++SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
+   return columnName(
+       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE);
+ }
+ #ifndef SQLITE_OMIT_UTF16
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
++SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
+   return columnName(
+       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
+ }
+@@ -70084,12 +81238,12 @@
+ ** NULL is returned if the result column is an expression or constant or
+ ** anything else which is not an unambiguous reference to a database column.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
++SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
+   return columnName(
+       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN);
+ }
+ #ifndef SQLITE_OMIT_UTF16
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
++SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
+   return columnName(
+       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
+ }
+@@ -70145,9 +81299,8 @@
+   ** as if there had been a schema change, on the first sqlite3_step() call
+   ** following any change to the bindings of that parameter.
+   */
+-  if( p->isPrepareV2 &&
+-     ((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff)
+-  ){
++  assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 );
++  if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<<i))!=0 ){
+     p->expired = 1;
+   }
+   return SQLITE_OK;
+@@ -70176,8 +81329,10 @@
+       if( rc==SQLITE_OK && encoding!=0 ){
+         rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
+       }
+-      sqlite3Error(p->db, rc);
+-      rc = sqlite3ApiExit(p->db, rc);
++      if( rc ){
++        sqlite3Error(p->db, rc);
++        rc = sqlite3ApiExit(p->db, rc);
++      }
+     }
+     sqlite3_mutex_leave(p->db->mutex);
+   }else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){
+@@ -70190,16 +81345,19 @@
+ /*
+ ** Bind a blob value to an SQL statement variable.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(
++SQLITE_API int sqlite3_bind_blob(
+   sqlite3_stmt *pStmt, 
+   int i, 
+   const void *zData, 
+   int nData, 
+   void (*xDel)(void*)
+ ){
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( nData<0 ) return SQLITE_MISUSE_BKPT;
++#endif
+   return bindText(pStmt, i, zData, nData, xDel, 0);
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(
++SQLITE_API int sqlite3_bind_blob64(
+   sqlite3_stmt *pStmt, 
+   int i, 
+   const void *zData, 
+@@ -70213,7 +81371,7 @@
+     return bindText(pStmt, i, zData, (int)nData, xDel, 0);
+   }
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
++SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
+   int rc;
+   Vdbe *p = (Vdbe *)pStmt;
+   rc = vdbeUnbind(p, i);
+@@ -70223,10 +81381,10 @@
+   }
+   return rc;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
++SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
+   return sqlite3_bind_int64(p, i, (i64)iValue);
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
++SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
+   int rc;
+   Vdbe *p = (Vdbe *)pStmt;
+   rc = vdbeUnbind(p, i);
+@@ -70236,16 +81394,34 @@
+   }
+   return rc;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
++SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
++  int rc;
++  Vdbe *p = (Vdbe*)pStmt;
++  rc = vdbeUnbind(p, i);
++  if( rc==SQLITE_OK ){
++    sqlite3_mutex_leave(p->db->mutex);
++  }
++  return rc;
++}
++SQLITE_API int sqlite3_bind_pointer(
++  sqlite3_stmt *pStmt,
++  int i,
++  void *pPtr,
++  const char *zPTtype,
++  void (*xDestructor)(void*)
++){
+   int rc;
+   Vdbe *p = (Vdbe*)pStmt;
+   rc = vdbeUnbind(p, i);
+   if( rc==SQLITE_OK ){
++    sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor);
+     sqlite3_mutex_leave(p->db->mutex);
++  }else if( xDestructor ){
++    xDestructor(pPtr);
+   }
+   return rc;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text( 
++SQLITE_API int sqlite3_bind_text( 
+   sqlite3_stmt *pStmt, 
+   int i, 
+   const char *zData, 
+@@ -70254,7 +81430,7 @@
+ ){
+   return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64( 
++SQLITE_API int sqlite3_bind_text64( 
+   sqlite3_stmt *pStmt, 
+   int i, 
+   const char *zData, 
+@@ -70271,7 +81447,7 @@
+   }
+ }
+ #ifndef SQLITE_OMIT_UTF16
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(
++SQLITE_API int sqlite3_bind_text16(
+   sqlite3_stmt *pStmt, 
+   int i, 
+   const void *zData, 
+@@ -70281,7 +81457,7 @@
+   return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
+ }
+ #endif /* SQLITE_OMIT_UTF16 */
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
++SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
+   int rc;
+   switch( sqlite3_value_type((sqlite3_value*)pValue) ){
+     case SQLITE_INTEGER: {
+@@ -70312,7 +81488,7 @@
+   }
+   return rc;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
++SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
+   int rc;
+   Vdbe *p = (Vdbe *)pStmt;
+   rc = vdbeUnbind(p, i);
+@@ -70322,12 +81498,26 @@
+   }
+   return rc;
+ }
++SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
++  int rc;
++  Vdbe *p = (Vdbe *)pStmt;
++  sqlite3_mutex_enter(p->db->mutex);
++  if( n>(u64)p->db->aLimit[SQLITE_LIMIT_LENGTH] ){
++    rc = SQLITE_TOOBIG;
++  }else{
++    assert( (n & 0x7FFFFFFF)==n );
++    rc = sqlite3_bind_zeroblob(pStmt, i, n);
++  }
++  rc = sqlite3ApiExit(p->db, rc);
++  sqlite3_mutex_leave(p->db->mutex);
++  return rc;
++}
+ 
+ /*
+ ** Return the number of wildcards that can be potentially bound to.
+ ** This routine is added to support DBD::SQLite.  
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
++SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
+   Vdbe *p = (Vdbe*)pStmt;
+   return p ? p->nVar : 0;
+ }
+@@ -70338,12 +81528,10 @@
+ **
+ ** The result is always UTF-8.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
++SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
+   Vdbe *p = (Vdbe*)pStmt;
+-  if( p==0 || i<1 || i>p->nzVar ){
+-    return 0;
+-  }
+-  return p->azVar[i-1];
++  if( p==0 ) return 0;
++  return sqlite3VListNumToName(p->pVList, i);
+ }
+ 
+ /*
+@@ -70352,21 +81540,10 @@
+ ** return 0.
+ */
+ SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){
+-  int i;
+-  if( p==0 ){
+-    return 0;
+-  }
+-  if( zName ){
+-    for(i=0; i<p->nzVar; i++){
+-      const char *z = p->azVar[i];
+-      if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){
+-        return i+1;
+-      }
+-    }
+-  }
+-  return 0;
++  if( p==0 || zName==0 ) return 0;
++  return sqlite3VListNameToNum(p->pVList, zName, nName);
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
++SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
+   return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
+ }
+ 
+@@ -70400,16 +81577,18 @@
+ ** an SQLITE_ERROR is returned.  Nothing else can go wrong, so otherwise
+ ** SQLITE_OK is returned.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
++SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
+   Vdbe *pFrom = (Vdbe*)pFromStmt;
+   Vdbe *pTo = (Vdbe*)pToStmt;
+   if( pFrom->nVar!=pTo->nVar ){
+     return SQLITE_ERROR;
+   }
+-  if( pTo->isPrepareV2 && pTo->expmask ){
++  assert( (pTo->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || pTo->expmask==0 );
++  if( pTo->expmask ){
+     pTo->expired = 1;
+   }
+-  if( pFrom->isPrepareV2 && pFrom->expmask ){
++  assert( (pFrom->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || pFrom->expmask==0 );
++  if( pFrom->expmask ){
+     pFrom->expired = 1;
+   }
+   return sqlite3TransferBindings(pFromStmt, pToStmt);
+@@ -70422,7 +81601,7 @@
+ ** the first argument to the sqlite3_prepare() that was used to create
+ ** the statement in the first place.
+ */
+-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt *pStmt){
++SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
+   return pStmt ? ((Vdbe*)pStmt)->db : 0;
+ }
+ 
+@@ -70430,16 +81609,16 @@
+ ** Return true if the prepared statement is guaranteed to not modify the
+ ** database.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
++SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
+   return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
+ }
+ 
+ /*
+ ** Return true if the prepared statement is in need of being reset.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt *pStmt){
++SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
+   Vdbe *v = (Vdbe*)pStmt;
+-  return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN;
++  return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0;
+ }
+ 
+ /*
+@@ -70448,7 +81627,7 @@
+ ** prepared statement for the database connection.  Return NULL if there
+ ** are no more.
+ */
+-SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
++SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
+   sqlite3_stmt *pNext;
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(pDb) ){
+@@ -70469,7 +81648,7 @@
+ /*
+ ** Return the value of a status counter for a prepared statement
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
++SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
+   Vdbe *pVdbe = (Vdbe*)pStmt;
+   u32 v;
+ #ifdef SQLITE_ENABLE_API_ARMOR
+@@ -70478,16 +81657,246 @@
+     return 0;
+   }
+ #endif
+-  v = pVdbe->aCounter[op];
+-  if( resetFlag ) pVdbe->aCounter[op] = 0;
++  if( op==SQLITE_STMTSTATUS_MEMUSED ){
++    sqlite3 *db = pVdbe->db;
++    sqlite3_mutex_enter(db->mutex);
++    v = 0;
++    db->pnBytesFreed = (int*)&v;
++    sqlite3VdbeClearObject(db, pVdbe);
++    sqlite3DbFree(db, pVdbe);
++    db->pnBytesFreed = 0;
++    sqlite3_mutex_leave(db->mutex);
++  }else{
++    v = pVdbe->aCounter[op];
++    if( resetFlag ) pVdbe->aCounter[op] = 0;
++  }
+   return (int)v;
+ }
+ 
++/*
++** Return the SQL associated with a prepared statement
++*/
++SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){
++  Vdbe *p = (Vdbe *)pStmt;
++  return p ? p->zSql : 0;
++}
++
++/*
++** Return the SQL associated with a prepared statement with
++** bound parameters expanded.  Space to hold the returned string is
++** obtained from sqlite3_malloc().  The caller is responsible for
++** freeing the returned string by passing it to sqlite3_free().
++**
++** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of
++** expanded bound parameters.
++*/
++SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
++#ifdef SQLITE_OMIT_TRACE
++  return 0;
++#else
++  char *z = 0;
++  const char *zSql = sqlite3_sql(pStmt);
++  if( zSql ){
++    Vdbe *p = (Vdbe *)pStmt;
++    sqlite3_mutex_enter(p->db->mutex);
++    z = sqlite3VdbeExpandSql(p, zSql);
++    sqlite3_mutex_leave(p->db->mutex);
++  }
++  return z;
++#endif
++}
++
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++/*
++** Allocate and populate an UnpackedRecord structure based on the serialized
++** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure
++** if successful, or a NULL pointer if an OOM error is encountered.
++*/
++static UnpackedRecord *vdbeUnpackRecord(
++  KeyInfo *pKeyInfo, 
++  int nKey, 
++  const void *pKey
++){
++  UnpackedRecord *pRet;           /* Return value */
++
++  pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
++  if( pRet ){
++    memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nField+1));
++    sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet);
++  }
++  return pRet;
++}
++
++/*
++** This function is called from within a pre-update callback to retrieve
++** a field of the row currently being updated or deleted.
++*/
++SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
++  PreUpdate *p = db->pPreUpdate;
++  Mem *pMem;
++  int rc = SQLITE_OK;
++
++  /* Test that this call is being made from within an SQLITE_DELETE or
++  ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
++  if( !p || p->op==SQLITE_INSERT ){
++    rc = SQLITE_MISUSE_BKPT;
++    goto preupdate_old_out;
++  }
++  if( p->pPk ){
++    iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx);
++  }
++  if( iIdx>=p->pCsr->nField || iIdx<0 ){
++    rc = SQLITE_RANGE;
++    goto preupdate_old_out;
++  }
++
++  /* If the old.* record has not yet been loaded into memory, do so now. */
++  if( p->pUnpacked==0 ){
++    u32 nRec;
++    u8 *aRec;
++
++    nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
++    aRec = sqlite3DbMallocRaw(db, nRec);
++    if( !aRec ) goto preupdate_old_out;
++    rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
++    if( rc==SQLITE_OK ){
++      p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec);
++      if( !p->pUnpacked ) rc = SQLITE_NOMEM;
++    }
++    if( rc!=SQLITE_OK ){
++      sqlite3DbFree(db, aRec);
++      goto preupdate_old_out;
++    }
++    p->aRecord = aRec;
++  }
++
++  pMem = *ppValue = &p->pUnpacked->aMem[iIdx];
++  if( iIdx==p->pTab->iPKey ){
++    sqlite3VdbeMemSetInt64(pMem, p->iKey1);
++  }else if( iIdx>=p->pUnpacked->nField ){
++    *ppValue = (sqlite3_value *)columnNullValue();
++  }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
++    if( pMem->flags & MEM_Int ){
++      sqlite3VdbeMemRealify(pMem);
++    }
++  }
++
++ preupdate_old_out:
++  sqlite3Error(db, rc);
++  return sqlite3ApiExit(db, rc);
++}
++#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
++
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++/*
++** This function is called from within a pre-update callback to retrieve
++** the number of columns in the row being updated, deleted or inserted.
++*/
++SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){
++  PreUpdate *p = db->pPreUpdate;
++  return (p ? p->keyinfo.nField : 0);
++}
++#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
++
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++/*
++** This function is designed to be called from within a pre-update callback
++** only. It returns zero if the change that caused the callback was made
++** immediately by a user SQL statement. Or, if the change was made by a
++** trigger program, it returns the number of trigger programs currently
++** on the stack (1 for a top-level trigger, 2 for a trigger fired by a 
++** top-level trigger etc.).
++**
++** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL
++** or SET DEFAULT action is considered a trigger.
++*/
++SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){
++  PreUpdate *p = db->pPreUpdate;
++  return (p ? p->v->nFrame : 0);
++}
++#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
++
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++/*
++** This function is called from within a pre-update callback to retrieve
++** a field of the row currently being updated or inserted.
++*/
++SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
++  PreUpdate *p = db->pPreUpdate;
++  int rc = SQLITE_OK;
++  Mem *pMem;
++
++  if( !p || p->op==SQLITE_DELETE ){
++    rc = SQLITE_MISUSE_BKPT;
++    goto preupdate_new_out;
++  }
++  if( p->pPk && p->op!=SQLITE_UPDATE ){
++    iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx);
++  }
++  if( iIdx>=p->pCsr->nField || iIdx<0 ){
++    rc = SQLITE_RANGE;
++    goto preupdate_new_out;
++  }
++
++  if( p->op==SQLITE_INSERT ){
++    /* For an INSERT, memory cell p->iNewReg contains the serialized record
++    ** that is being inserted. Deserialize it. */
++    UnpackedRecord *pUnpack = p->pNewUnpacked;
++    if( !pUnpack ){
++      Mem *pData = &p->v->aMem[p->iNewReg];
++      rc = ExpandBlob(pData);
++      if( rc!=SQLITE_OK ) goto preupdate_new_out;
++      pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z);
++      if( !pUnpack ){
++        rc = SQLITE_NOMEM;
++        goto preupdate_new_out;
++      }
++      p->pNewUnpacked = pUnpack;
++    }
++    pMem = &pUnpack->aMem[iIdx];
++    if( iIdx==p->pTab->iPKey ){
++      sqlite3VdbeMemSetInt64(pMem, p->iKey2);
++    }else if( iIdx>=pUnpack->nField ){
++      pMem = (sqlite3_value *)columnNullValue();
++    }
++  }else{
++    /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
++    ** value. Make a copy of the cell contents and return a pointer to it.
++    ** It is not safe to return a pointer to the memory cell itself as the
++    ** caller may modify the value text encoding.
++    */
++    assert( p->op==SQLITE_UPDATE );
++    if( !p->aNew ){
++      p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField);
++      if( !p->aNew ){
++        rc = SQLITE_NOMEM;
++        goto preupdate_new_out;
++      }
++    }
++    assert( iIdx>=0 && iIdx<p->pCsr->nField );
++    pMem = &p->aNew[iIdx];
++    if( pMem->flags==0 ){
++      if( iIdx==p->pTab->iPKey ){
++        sqlite3VdbeMemSetInt64(pMem, p->iKey2);
++      }else{
++        rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
++        if( rc!=SQLITE_OK ) goto preupdate_new_out;
++      }
++    }
++  }
++  *ppValue = pMem;
++
++ preupdate_new_out:
++  sqlite3Error(db, rc);
++  return sqlite3ApiExit(db, rc);
++}
++#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
++
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ /*
+ ** Return status data for a single loop within query pStmt.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
++SQLITE_API int sqlite3_stmt_scanstatus(
+   sqlite3_stmt *pStmt,            /* Prepared statement being queried */
+   int idx,                        /* Index of loop to report on */
+   int iScanStatusOp,              /* Which metric to return */
+@@ -70546,7 +81955,7 @@
+ /*
+ ** Zero all counters associated with the sqlite3_stmt_scanstatus() data.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
++SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
+   Vdbe *p = (Vdbe*)pStmt;
+   memset(p->anExec, 0, p->nOp * sizeof(i64));
+ }
+@@ -70571,6 +81980,8 @@
+ **
+ ** The Vdbe parse-tree explainer is also found here.
+ */
++/* #include "sqliteInt.h" */
++/* #include "vdbeInt.h" */
+ 
+ #ifndef SQLITE_OMIT_TRACE
+ 
+@@ -70635,10 +82046,13 @@
+   int i;                   /* Loop counter */
+   Mem *pVar;               /* Value of a host parameter */
+   StrAccum out;            /* Accumulate the output here */
++#ifndef SQLITE_OMIT_UTF16
++  Mem utf8;                /* Used to convert UTF16 parameters into UTF8 for display */
++#endif
+   char zBase[100];         /* Initial working space */
+ 
+   db = p->db;
+-  sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase), 
++  sqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase), 
+                       db->aLimit[SQLITE_LIMIT_LENGTH]);
+   if( db->nVdbeExec>1 ){
+     while( *zRawSql ){
+@@ -70682,19 +82096,21 @@
+       if( pVar->flags & MEM_Null ){
+         sqlite3StrAccumAppend(&out, "NULL", 4);
+       }else if( pVar->flags & MEM_Int ){
+-        sqlite3XPrintf(&out, 0, "%lld", pVar->u.i);
++        sqlite3XPrintf(&out, "%lld", pVar->u.i);
+       }else if( pVar->flags & MEM_Real ){
+-        sqlite3XPrintf(&out, 0, "%!.15g", pVar->u.r);
++        sqlite3XPrintf(&out, "%!.15g", pVar->u.r);
+       }else if( pVar->flags & MEM_Str ){
+         int nOut;  /* Number of bytes of the string text to include in output */
+ #ifndef SQLITE_OMIT_UTF16
+         u8 enc = ENC(db);
+-        Mem utf8;
+         if( enc!=SQLITE_UTF8 ){
+           memset(&utf8, 0, sizeof(utf8));
+           utf8.db = db;
+           sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
+-          sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8);
++          if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){
++            out.accError = STRACCUM_NOMEM;
++            out.nAlloc = 0;
++          }
+           pVar = &utf8;
+         }
+ #endif
+@@ -70705,17 +82121,17 @@
+           while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
+         }
+ #endif    
+-        sqlite3XPrintf(&out, 0, "'%.*q'", nOut, pVar->z);
++        sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
+ #ifdef SQLITE_TRACE_SIZE_LIMIT
+         if( nOut<pVar->n ){
+-          sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
++          sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
+         }
+ #endif
+ #ifndef SQLITE_OMIT_UTF16
+         if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
+ #endif
+       }else if( pVar->flags & MEM_Zero ){
+-        sqlite3XPrintf(&out, 0, "zeroblob(%d)", pVar->u.nZero);
++        sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
+       }else{
+         int nOut;  /* Number of bytes of the blob to include in output */
+         assert( pVar->flags & MEM_Blob );
+@@ -70725,17 +82141,18 @@
+         if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
+ #endif
+         for(i=0; i<nOut; i++){
+-          sqlite3XPrintf(&out, 0, "%02x", pVar->z[i]&0xff);
++          sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
+         }
+         sqlite3StrAccumAppend(&out, "'", 1);
+ #ifdef SQLITE_TRACE_SIZE_LIMIT
+         if( nOut<pVar->n ){
+-          sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
++          sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
+         }
+ #endif
+       }
+     }
+   }
++  if( out.accError ) sqlite3StrAccumReset(&out);
+   return sqlite3StrAccumFinish(&out);
+ }
+ 
+@@ -70763,6 +82180,8 @@
+ ** in this file for details.  If in doubt, do not deviate from existing
+ ** commenting and indentation practices when changing or adding code.
+ */
++/* #include "sqliteInt.h" */
++/* #include "vdbeInt.h" */
+ 
+ /*
+ ** Invoke this macro on memory cells just prior to changing the
+@@ -70830,6 +82249,16 @@
+ #endif
+ 
+ /*
++** This macro evaluates to true if either the update hook or the preupdate
++** hook are enabled for database connect DB.
++*/
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++# define HAS_UPDATE_HOOK(DB) ((DB)->xPreUpdateCallback||(DB)->xUpdateCallback)
++#else
++# define HAS_UPDATE_HOOK(DB) ((DB)->xUpdateCallback)
++#endif
++
++/*
+ ** The next global variable is incremented each time the OP_Found opcode
+ ** is executed. This is used to test whether or not the foreign key
+ ** operation implemented using OP_FkIsZero is working. This variable
+@@ -70844,7 +82273,7 @@
+ ** Test a register to see if it exceeds the current maximum blob size.
+ ** If it does, record the new maximum blob size.
+ */
+-#if defined(SQLITE_TEST) && !defined(SQLITE_OMIT_BUILTIN_TEST)
++#if defined(SQLITE_TEST) && !defined(SQLITE_UNTESTABLE)
+ # define UPDATE_MAX_BLOBSIZE(P)  updateMaxBlobsize(P)
+ #else
+ # define UPDATE_MAX_BLOBSIZE(P)
+@@ -70908,7 +82337,7 @@
+        && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}
+ 
+ /* Return true if the cursor was opened using the OP_OpenSorter opcode. */
+-#define isSorter(x) ((x)->pSorter!=0)
++#define isSorter(x) ((x)->eCurType==CURTYPE_SORTER)
+ 
+ /*
+ ** Allocate VdbeCursor number iCur.  Return a pointer to it.  Return NULL
+@@ -70919,7 +82348,7 @@
+   int iCur,             /* Index of the new VdbeCursor */
+   int nField,           /* Number of fields in the table or index */
+   int iDb,              /* Database the cursor belongs to, or -1 */
+-  int isBtreeCursor     /* True for B-Tree.  False for pseudo-table or vtab */
++  u8 eCurType           /* Type of the new cursor */
+ ){
+   /* Find the memory cell that will be used to store the blob of memory
+   ** required for this VdbeCursor structure. It is convenient to use a 
+@@ -70935,33 +82364,34 @@
+   **     be freed lazily via the sqlite3_release_memory() API. This
+   **     minimizes the number of malloc calls made by the system.
+   **
+-  ** Memory cells for cursors are allocated at the top of the address
+-  ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for
+-  ** cursor 1 is managed by memory cell (p->nMem-1), etc.
++  ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from
++  ** the top of the register space.  Cursor 1 is at Mem[p->nMem-1].
++  ** Cursor 2 is at Mem[p->nMem-2]. And so forth.
+   */
+-  Mem *pMem = &p->aMem[p->nMem-iCur];
++  Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem;
+ 
+   int nByte;
+   VdbeCursor *pCx = 0;
+   nByte = 
+       ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + 
+-      (isBtreeCursor?sqlite3BtreeCursorSize():0);
++      (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);
+ 
+-  assert( iCur<p->nCursor );
+-  if( p->apCsr[iCur] ){
++  assert( iCur>=0 && iCur<p->nCursor );
++  if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
+     sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
+     p->apCsr[iCur] = 0;
+   }
+   if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
+     p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
+-    memset(pCx, 0, sizeof(VdbeCursor));
++    memset(pCx, 0, offsetof(VdbeCursor,pAltCursor));
++    pCx->eCurType = eCurType;
+     pCx->iDb = iDb;
+     pCx->nField = nField;
+     pCx->aOffset = &pCx->aType[nField];
+-    if( isBtreeCursor ){
+-      pCx->pCursor = (BtCursor*)
++    if( eCurType==CURTYPE_BTREE ){
++      pCx->uc.pCursor = (BtCursor*)
+           &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
+-      sqlite3BtreeCursorZero(pCx->pCursor);
++      sqlite3BtreeCursorZero(pCx->uc.pCursor);
+     }
+   }
+   return pCx;
+@@ -71013,7 +82443,7 @@
+ ** SQLITE_AFF_TEXT:
+ **    Convert pRec to a text representation.
+ **
+-** SQLITE_AFF_NONE:
++** SQLITE_AFF_BLOB:
+ **    No-op.  pRec is unchanged.
+ */
+ static void applyAffinity(
+@@ -71024,7 +82454,7 @@
+   if( affinity>=SQLITE_AFF_NUMERIC ){
+     assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
+              || affinity==SQLITE_AFF_NUMERIC );
+-    if( (pRec->flags & MEM_Int)==0 ){
++    if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/
+       if( (pRec->flags & MEM_Real)==0 ){
+         if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1);
+       }else{
+@@ -71034,10 +82464,13 @@
+   }else if( affinity==SQLITE_AFF_TEXT ){
+     /* Only attempt the conversion to TEXT if there is an integer or real
+     ** representation (blob and NULL do not get converted) but no string
+-    ** representation.
+-    */
+-    if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
+-      sqlite3VdbeMemStringify(pRec, enc, 1);
++    ** representation.  It would be harmless to repeat the conversion if 
++    ** there is already a string rep, but it is pointless to waste those
++    ** CPU cycles. */
++    if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
++      if( (pRec->flags&(MEM_Real|MEM_Int)) ){
++        sqlite3VdbeMemStringify(pRec, enc, 1);
++      }
+     }
+     pRec->flags &= ~(MEM_Real|MEM_Int);
+   }
+@@ -71049,7 +82482,7 @@
+ ** is appropriate.  But only do the conversion if it is possible without
+ ** loss of information and return the revised type of the argument.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value *pVal){
++SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){
+   int eType = sqlite3_value_type(pVal);
+   if( eType==SQLITE_TEXT ){
+     Mem *pMem = (Mem*)pVal;
+@@ -71132,9 +82565,7 @@
+     }else{
+       c = 's';
+     }
+-
+-    sqlite3_snprintf(100, zCsr, "%c", c);
+-    zCsr += sqlite3Strlen30(zCsr);
++    *(zCsr++) = c;
+     sqlite3_snprintf(100, zCsr, "%d[", pMem->n);
+     zCsr += sqlite3Strlen30(zCsr);
+     for(i=0; i<16 && i<pMem->n; i++){
+@@ -71146,9 +82577,7 @@
+       if( z<32 || z>126 ) *zCsr++ = '.';
+       else *zCsr++ = z;
+     }
+-
+-    sqlite3_snprintf(100, zCsr, "]%s", encnames[pMem->enc]);
+-    zCsr += sqlite3Strlen30(zCsr);
++    *(zCsr++) = ']';
+     if( f & MEM_Zero ){
+       sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero);
+       zCsr += sqlite3Strlen30(zCsr);
+@@ -71213,11 +82642,13 @@
+     sqlite3VdbeMemPrettyPrint(p, zBuf);
+     printf(" %s", zBuf);
+   }
++  if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype);
+ }
+ static void registerTrace(int iReg, Mem *p){
+   printf("REG[%d] = ", iReg);
+   memTracePrint(p);
+   printf("\n");
++  sqlite3VdbeCheckMemInvariants(p);
+ }
+ #endif
+ 
+@@ -71251,8 +82682,8 @@
+ ** This file contains inline asm code for retrieving "high-performance"
+ ** counters for x86 class CPUs.
+ */
+-#ifndef _HWTIME_H_
+-#define _HWTIME_H_
++#ifndef SQLITE_HWTIME_H
++#define SQLITE_HWTIME_H
+ 
+ /*
+ ** The following routine only works on pentium-class (or newer) processors.
+@@ -71320,7 +82751,7 @@
+ 
+ #endif
+ 
+-#endif /* !defined(_HWTIME_H_) */
++#endif /* !defined(SQLITE_HWTIME_H) */
+ 
+ /************** End of hwtime.h **********************************************/
+ /************** Continuing where we left off in vdbe.c ***********************/
+@@ -71350,16 +82781,24 @@
+ /*
+ ** Return the register of pOp->p2 after first preparing it to be
+ ** overwritten with an integer value.
+-*/ 
++*/
++static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){
++  sqlite3VdbeMemSetNull(pOut);
++  pOut->flags = MEM_Int;
++  return pOut;
++}
+ static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
+   Mem *pOut;
+   assert( pOp->p2>0 );
+-  assert( pOp->p2<=(p->nMem-p->nCursor) );
++  assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
+   pOut = &p->aMem[pOp->p2];
+   memAboutToChange(p, pOut);
+-  if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
+-  pOut->flags = MEM_Int;
+-  return pOut;
++  if( VdbeMemDynamic(pOut) ){ /*OPTIMIZATION-IF-FALSE*/
++    return out2PrereleaseWithClear(pOut);
++  }else{
++    pOut->flags = MEM_Int;
++    return pOut;
++  }
+ }
+ 
+ 
+@@ -71375,22 +82814,23 @@
+ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+   Op *pOrigOp;               /* Value of pOp at the top of the loop */
+ #endif
++#ifdef SQLITE_DEBUG
++  int nExtraDelete = 0;      /* Verifies FORDELETE and AUXDELETE flags */
++#endif
+   int rc = SQLITE_OK;        /* Value to return */
+   sqlite3 *db = p->db;       /* The database */
+   u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
+   u8 encoding = ENC(db);     /* The database encoding */
+-  int iCompare = 0;          /* Result of last OP_Compare operation */
++  int iCompare = 0;          /* Result of last comparison */
+   unsigned nVmStep = 0;      /* Number of virtual machine steps */
+ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+-  unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */
++  unsigned nProgressLimit;   /* Invoke xProgress() when nVmStep reaches this */
+ #endif
+   Mem *aMem = p->aMem;       /* Copy of p->aMem */
+   Mem *pIn1 = 0;             /* 1st input operand */
+   Mem *pIn2 = 0;             /* 2nd input operand */
+   Mem *pIn3 = 0;             /* 3rd input operand */
+   Mem *pOut = 0;             /* Output operand */
+-  int *aPermute = 0;         /* Permutation of columns for OP_Compare */
+-  i64 lastRowid = db->lastRowid;  /* Saved value of the last insert ROWID */
+ #ifdef VDBE_PROFILE
+   u64 start;                 /* CPU clock count at start of opcode */
+ #endif
+@@ -71403,9 +82843,8 @@
+     ** sqlite3_column_text16() failed.  */
+     goto no_mem;
+   }
+-  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
++  assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
+   assert( p->bIsReader || p->readOnly!=0 );
+-  p->rc = SQLITE_OK;
+   p->iCurrentTime = 0;
+   assert( p->explain==0 );
+   p->pResultSet = 0;
+@@ -71414,13 +82853,11 @@
+   sqlite3VdbeIOTraceSql(p);
+ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+   if( db->xProgress ){
++    u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
+     assert( 0 < db->nProgressOps );
+-    nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
+-    if( nProgressLimit==0 ){
+-      nProgressLimit = db->nProgressOps;
+-    }else{
+-      nProgressLimit %= (unsigned)db->nProgressOps;
+-    }
++    nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
++  }else{
++    nProgressLimit = 0xffffffff;
+   }
+ #endif
+ #ifdef SQLITE_DEBUG
+@@ -71450,9 +82887,12 @@
+   }
+   sqlite3EndBenignMalloc();
+ #endif
+-  for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
++  for(pOp=&aOp[p->pc]; 1; pOp++){
++    /* Errors are detected by individual opcodes, with an immediate
++    ** jumps to abort_due_to_error. */
++    assert( rc==SQLITE_OK );
++
+     assert( pOp>=aOp && pOp<&aOp[p->nOp]);
+-    if( db->mallocFailed ) goto no_mem;
+ #ifdef VDBE_PROFILE
+     start = sqlite3Hwtime();
+ #endif
+@@ -71484,37 +82924,39 @@
+ 
+     /* Sanity checking on other operands */
+ #ifdef SQLITE_DEBUG
+-    assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
+-    if( (pOp->opflags & OPFLG_IN1)!=0 ){
+-      assert( pOp->p1>0 );
+-      assert( pOp->p1<=(p->nMem-p->nCursor) );
+-      assert( memIsValid(&aMem[pOp->p1]) );
+-      assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
+-      REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
+-    }
+-    if( (pOp->opflags & OPFLG_IN2)!=0 ){
+-      assert( pOp->p2>0 );
+-      assert( pOp->p2<=(p->nMem-p->nCursor) );
+-      assert( memIsValid(&aMem[pOp->p2]) );
+-      assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
+-      REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
+-    }
+-    if( (pOp->opflags & OPFLG_IN3)!=0 ){
+-      assert( pOp->p3>0 );
+-      assert( pOp->p3<=(p->nMem-p->nCursor) );
+-      assert( memIsValid(&aMem[pOp->p3]) );
+-      assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
+-      REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
+-    }
+-    if( (pOp->opflags & OPFLG_OUT2)!=0 ){
+-      assert( pOp->p2>0 );
+-      assert( pOp->p2<=(p->nMem-p->nCursor) );
+-      memAboutToChange(p, &aMem[pOp->p2]);
+-    }
+-    if( (pOp->opflags & OPFLG_OUT3)!=0 ){
+-      assert( pOp->p3>0 );
+-      assert( pOp->p3<=(p->nMem-p->nCursor) );
+-      memAboutToChange(p, &aMem[pOp->p3]);
++    {
++      u8 opProperty = sqlite3OpcodeProperty[pOp->opcode];
++      if( (opProperty & OPFLG_IN1)!=0 ){
++        assert( pOp->p1>0 );
++        assert( pOp->p1<=(p->nMem+1 - p->nCursor) );
++        assert( memIsValid(&aMem[pOp->p1]) );
++        assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
++        REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
++      }
++      if( (opProperty & OPFLG_IN2)!=0 ){
++        assert( pOp->p2>0 );
++        assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
++        assert( memIsValid(&aMem[pOp->p2]) );
++        assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
++        REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
++      }
++      if( (opProperty & OPFLG_IN3)!=0 ){
++        assert( pOp->p3>0 );
++        assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
++        assert( memIsValid(&aMem[pOp->p3]) );
++        assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
++        REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
++      }
++      if( (opProperty & OPFLG_OUT2)!=0 ){
++        assert( pOp->p2>0 );
++        assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
++        memAboutToChange(p, &aMem[pOp->p2]);
++      }
++      if( (opProperty & OPFLG_OUT3)!=0 ){
++        assert( pOp->p3>0 );
++        assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
++        memAboutToChange(p, &aMem[pOp->p3]);
++      }
+     }
+ #endif
+ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+@@ -71575,7 +83017,7 @@
+   pOp = &aOp[pOp->p2 - 1];
+ 
+   /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
+-  ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
++  ** OP_VNext, or OP_SorterNext) all jump here upon
+   ** completion.  Check to see if sqlite3_interrupt() has been called
+   ** or if the progress callback needs to be invoked. 
+   **
+@@ -71593,12 +83035,12 @@
+   ** If the progress callback returns non-zero, exit the virtual machine with
+   ** a return code SQLITE_ABORT.
+   */
+-  if( db->xProgress!=0 && nVmStep>=nProgressLimit ){
++  if( nVmStep>=nProgressLimit && db->xProgress!=0 ){
+     assert( db->nProgressOps!=0 );
+     nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
+     if( db->xProgress(db->pProgressArg) ){
+       rc = SQLITE_INTERRUPT;
+-      goto vdbe_error_halt;
++      goto abort_due_to_error;
+     }
+   }
+ #endif
+@@ -71612,7 +83054,7 @@
+ ** and then jump to address P2.
+ */
+ case OP_Gosub: {            /* jump */
+-  assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
++  assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
+   pIn1 = &aMem[pOp->p1];
+   assert( VdbeMemDynamic(pIn1)==0 );
+   memAboutToChange(p, pIn1);
+@@ -71652,7 +83094,7 @@
+ ** See also: EndCoroutine
+ */
+ case OP_InitCoroutine: {     /* jump */
+-  assert( pOp->p1>0 &&  pOp->p1<=(p->nMem-p->nCursor) );
++  assert( pOp->p1>0 &&  pOp->p1<=(p->nMem+1 - p->nCursor) );
+   assert( pOp->p2>=0 && pOp->p2<p->nOp );
+   assert( pOp->p3>=0 && pOp->p3<p->nOp );
+   pOut = &aMem[pOp->p1];
+@@ -71710,7 +83152,7 @@
+ }
+ 
+ /* Opcode:  HaltIfNull  P1 P2 P3 P4 P5
+-** Synopsis:  if r[P3]=null halt
++** Synopsis: if r[P3]=null halt
+ **
+ ** Check the value in register P3.  If it is NULL then Halt using
+ ** parameter P1, P2, and P4 as if this were a Halt instruction.  If the
+@@ -71754,8 +83196,6 @@
+ ** is the same as executing Halt.
+ */
+ case OP_Halt: {
+-  const char *zType;
+-  const char *zLogFmt;
+   VdbeFrame *pFrame;
+   int pcx;
+ 
+@@ -71767,7 +83207,6 @@
+     p->nFrame--;
+     sqlite3VdbeSetChanges(db, p->nChange);
+     pcx = sqlite3VdbeFrameRestore(pFrame);
+-    lastRowid = db->lastRowid;
+     if( pOp->p2==OE_Ignore ){
+       /* Instruction pcx is the OP_Program that invoked the sub-program 
+       ** currently being halted. If the p2 instruction of this OP_Halt
+@@ -71784,35 +83223,28 @@
+   p->rc = pOp->p1;
+   p->errorAction = (u8)pOp->p2;
+   p->pc = pcx;
++  assert( pOp->p5<=4 );
+   if( p->rc ){
+     if( pOp->p5 ){
+       static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
+                                              "FOREIGN KEY" };
+-      assert( pOp->p5>=1 && pOp->p5<=4 );
+       testcase( pOp->p5==1 );
+       testcase( pOp->p5==2 );
+       testcase( pOp->p5==3 );
+       testcase( pOp->p5==4 );
+-      zType = azType[pOp->p5-1];
+-    }else{
+-      zType = 0;
+-    }
+-    assert( zType!=0 || pOp->p4.z!=0 );
+-    zLogFmt = "abort at %d in [%s]: %s";
+-    if( zType && pOp->p4.z ){
+-      sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s", 
+-                       zType, pOp->p4.z);
+-    }else if( pOp->p4.z ){
+-      sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
++      sqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]);
++      if( pOp->p4.z ){
++        p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z);
++      }
+     }else{
+-      sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
++      sqlite3VdbeError(p, "%s", pOp->p4.z);
+     }
+-    sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
++    sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg);
+   }
+   rc = sqlite3VdbeHalt(p);
+   assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
+   if( rc==SQLITE_BUSY ){
+-    p->rc = rc = SQLITE_BUSY;
++    p->rc = SQLITE_BUSY;
+   }else{
+     assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
+     assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 );
+@@ -71878,7 +83310,7 @@
+ #ifndef SQLITE_OMIT_UTF16
+   if( encoding!=SQLITE_UTF8 ){
+     rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
+-    if( rc==SQLITE_TOOBIG ) goto too_big;
++    assert( rc==SQLITE_OK || rc==SQLITE_TOOBIG );
+     if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
+     assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z );
+     assert( VdbeMemDynamic(pOut)==0 );
+@@ -71891,10 +83323,12 @@
+     pOp->p4.z = pOut->z;
+     pOp->p1 = pOut->n;
+   }
++  testcase( rc==SQLITE_TOOBIG );
+ #endif
+   if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+     goto too_big;
+   }
++  assert( rc==SQLITE_OK );
+   /* Fall through to the next case, OP_String */
+ }
+   
+@@ -71903,10 +83337,12 @@
+ **
+ ** The string value P4 of length P1 (bytes) is stored in register P2.
+ **
+-** If P5!=0 and the content of register P3 is greater than zero, then
++** If P3 is not zero and the content of register P3 is equal to P5, then
+ ** the datatype of the register P2 is converted to BLOB.  The content is
+ ** the same sequence of bytes, it is merely interpreted as a BLOB instead
+-** of a string, as if it had been CAST.
++** of a string, as if it had been CAST.  In other words:
++**
++** if( P3!=0 and reg[P3]==P5 ) reg[P2] := CAST(reg[P2] as BLOB)
+ */
+ case OP_String: {          /* out2 */
+   assert( pOp->p4.z!=0 );
+@@ -71916,18 +83352,19 @@
+   pOut->n = pOp->p1;
+   pOut->enc = encoding;
+   UPDATE_MAX_BLOBSIZE(pOut);
+-  if( pOp->p5 ){
+-    assert( pOp->p3>0 );
+-    assert( pOp->p3<=(p->nMem-p->nCursor) );
++#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
++  if( pOp->p3>0 ){
++    assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
+     pIn3 = &aMem[pOp->p3];
+     assert( pIn3->flags & MEM_Int );
+-    if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term;
++    if( pIn3->u.i==pOp->p5 ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term;
+   }
++#endif
+   break;
+ }
+ 
+ /* Opcode: Null P1 P2 P3 * *
+-** Synopsis:  r[P2..P3]=NULL
++** Synopsis: r[P2..P3]=NULL
+ **
+ ** Write a NULL into registers P2.  If P3 greater than P2, then also write
+ ** NULL into register P3 and every register in between P2 and P3.  If P3
+@@ -71943,20 +83380,22 @@
+   u16 nullFlag;
+   pOut = out2Prerelease(p, pOp);
+   cnt = pOp->p3-pOp->p2;
+-  assert( pOp->p3<=(p->nMem-p->nCursor) );
++  assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
+   pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
++  pOut->n = 0;
+   while( cnt>0 ){
+     pOut++;
+     memAboutToChange(p, pOut);
+     sqlite3VdbeMemSetNull(pOut);
+     pOut->flags = nullFlag;
++    pOut->n = 0;
+     cnt--;
+   }
+   break;
+ }
+ 
+ /* Opcode: SoftNull P1 * * * *
+-** Synopsis:  r[P1]=NULL
++** Synopsis: r[P1]=NULL
+ **
+ ** Set register P1 to have the value NULL as seen by the OP_MakeRecord
+ ** instruction, but do not free any string or blob memory associated with
+@@ -71964,9 +83403,9 @@
+ ** previously copied using OP_SCopy, the copies will continue to be valid.
+ */
+ case OP_SoftNull: {
+-  assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
++  assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
+   pOut = &aMem[pOp->p1];
+-  pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined;
++  pOut->flags = (pOut->flags&~(MEM_Undefined|MEM_AffMask))|MEM_Null;
+   break;
+ }
+ 
+@@ -71997,19 +83436,19 @@
+   Mem *pVar;       /* Value being transferred */
+ 
+   assert( pOp->p1>0 && pOp->p1<=p->nVar );
+-  assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] );
++  assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) );
+   pVar = &p->aVar[pOp->p1 - 1];
+   if( sqlite3VdbeMemTooBig(pVar) ){
+     goto too_big;
+   }
+-  pOut = out2Prerelease(p, pOp);
++  pOut = &aMem[pOp->p2];
+   sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
+   UPDATE_MAX_BLOBSIZE(pOut);
+   break;
+ }
+ 
+ /* Opcode: Move P1 P2 P3 * *
+-** Synopsis:  r[P2@P3]=r[P1@P3]
++** Synopsis: r[P2@P3]=r[P1@P3]
+ **
+ ** Move the P3 values in register P1..P1+P3-1 over into
+ ** registers P2..P2+P3-1.  Registers P1..P1+P3-1 are
+@@ -72031,8 +83470,8 @@
+   pIn1 = &aMem[p1];
+   pOut = &aMem[p2];
+   do{
+-    assert( pOut<=&aMem[(p->nMem-p->nCursor)] );
+-    assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
++    assert( pOut<=&aMem[(p->nMem+1 - p->nCursor)] );
++    assert( pIn1<=&aMem[(p->nMem+1 - p->nCursor)] );
+     assert( memIsValid(pIn1) );
+     memAboutToChange(p, pOut);
+     sqlite3VdbeMemMove(pOut, pIn1);
+@@ -72102,8 +83541,24 @@
+   break;
+ }
+ 
++/* Opcode: IntCopy P1 P2 * * *
++** Synopsis: r[P2]=r[P1]
++**
++** Transfer the integer value held in register P1 into register P2.
++**
++** This is an optimized version of SCopy that works only for integer
++** values.
++*/
++case OP_IntCopy: {            /* out2 */
++  pIn1 = &aMem[pOp->p1];
++  assert( (pIn1->flags & MEM_Int)!=0 );
++  pOut = &aMem[pOp->p2];
++  sqlite3VdbeMemSetInt64(pOut, pIn1->u.i);
++  break;
++}
++
+ /* Opcode: ResultRow P1 P2 * * *
+-** Synopsis:  output=r[P1@P2]
++** Synopsis: output=r[P1@P2]
+ **
+ ** The registers P1 through P1+P2-1 contain a single row of
+ ** results. This opcode causes the sqlite3_step() call to terminate
+@@ -72116,17 +83571,17 @@
+   int i;
+   assert( p->nResColumn==pOp->p2 );
+   assert( pOp->p1>0 );
+-  assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 );
++  assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
+ 
+ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+   /* Run the progress counter just before returning.
+   */
+   if( db->xProgress!=0
+-   && nVmStep>=nProgressLimit
++   && nVmStep>=nProgressLimit 
+    && db->xProgress(db->pProgressArg)!=0
+   ){
+     rc = SQLITE_INTERRUPT;
+-    goto vdbe_error_halt;
++    goto abort_due_to_error;
+   }
+ #endif
+ 
+@@ -72136,7 +83591,7 @@
+   if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){
+     assert( db->flags&SQLITE_CountRows );
+     assert( p->usesStmtJournal );
+-    break;
++    goto abort_due_to_error;
+   }
+ 
+   /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then 
+@@ -72156,9 +83611,7 @@
+   */
+   assert( p->iStatement==0 || db->flags&SQLITE_CountRows );
+   rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE);
+-  if( NEVER(rc!=SQLITE_OK) ){
+-    break;
+-  }
++  assert( rc==SQLITE_OK );
+ 
+   /* Invalidate all ephemeral cursor row caches */
+   p->cacheCtr = (p->cacheCtr + 2)|1;
+@@ -72178,6 +83631,10 @@
+   }
+   if( db->mallocFailed ) goto no_mem;
+ 
++  if( db->mTrace & SQLITE_TRACE_ROW ){
++    db->xTrace(SQLITE_TRACE_ROW, db->pTraceArg, p, 0);
++  }
++
+   /* Return SQLITE_ROW
+   */
+   p->pc = (int)(pOp - aOp) + 1;
+@@ -72234,14 +83691,14 @@
+ }
+ 
+ /* Opcode: Add P1 P2 P3 * *
+-** Synopsis:  r[P3]=r[P1]+r[P2]
++** Synopsis: r[P3]=r[P1]+r[P2]
+ **
+ ** Add the value in register P1 to the value in register P2
+ ** and store the result in register P3.
+ ** If either input is NULL, the result is NULL.
+ */
+ /* Opcode: Multiply P1 P2 P3 * *
+-** Synopsis:  r[P3]=r[P1]*r[P2]
++** Synopsis: r[P3]=r[P1]*r[P2]
+ **
+ **
+ ** Multiply the value in register P1 by the value in register P2
+@@ -72249,14 +83706,14 @@
+ ** If either input is NULL, the result is NULL.
+ */
+ /* Opcode: Subtract P1 P2 P3 * *
+-** Synopsis:  r[P3]=r[P2]-r[P1]
++** Synopsis: r[P3]=r[P2]-r[P1]
+ **
+ ** Subtract the value in register P1 from the value in register P2
+ ** and store the result in register P3.
+ ** If either input is NULL, the result is NULL.
+ */
+ /* Opcode: Divide P1 P2 P3 * *
+-** Synopsis:  r[P3]=r[P2]/r[P1]
++** Synopsis: r[P3]=r[P2]/r[P1]
+ **
+ ** Divide the value in register P1 by the value in register P2
+ ** and store the result in register P3 (P3=P2/P1). If the value in 
+@@ -72264,7 +83721,7 @@
+ ** NULL, the result is NULL.
+ */
+ /* Opcode: Remainder P1 P2 P3 * *
+-** Synopsis:  r[P3]=r[P2]%r[P1]
++** Synopsis: r[P3]=r[P2]%r[P1]
+ **
+ ** Compute the remainder after integer register P2 is divided by 
+ ** register P1 and store the result in register P3. 
+@@ -72291,7 +83748,6 @@
+   type2 = numericType(pIn2);
+   pOut = &aMem[pOp->p3];
+   flags = pIn1->flags | pIn2->flags;
+-  if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
+   if( (type1 & type2 & MEM_Int)!=0 ){
+     iA = pIn1->u.i;
+     iB = pIn2->u.i;
+@@ -72315,6 +83771,8 @@
+     }
+     pOut->u.i = iB;
+     MemSetTypeFlag(pOut, MEM_Int);
++  }else if( (flags & MEM_Null)!=0 ){
++    goto arithmetic_result_is_null;
+   }else{
+     bIntint = 0;
+ fp_math:
+@@ -72362,7 +83820,7 @@
+ 
+ /* Opcode: CollSeq P1 * * P4
+ **
+-** P4 is a pointer to a CollSeq struct. If the next call to a user function
++** P4 is a pointer to a CollSeq object. If the next call to a user function
+ ** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
+ ** be returned. This is used by the built-in min(), max() and nullif()
+ ** functions.
+@@ -72383,93 +83841,22 @@
+   break;
+ }
+ 
+-/* Opcode: Function P1 P2 P3 P4 P5
+-** Synopsis: r[P3]=func(r[P2@P5])
+-**
+-** Invoke a user function (P4 is a pointer to a Function structure that
+-** defines the function) with P5 arguments taken from register P2 and
+-** successors.  The result of the function is stored in register P3.
+-** Register P3 must not be one of the function inputs.
+-**
+-** P1 is a 32-bit bitmask indicating whether or not each argument to the 
+-** function was determined to be constant at compile time. If the first
+-** argument was constant then bit 0 of P1 is set. This is used to determine
+-** whether meta data associated with a user function argument using the
+-** sqlite3_set_auxdata() API may be safely retained until the next
+-** invocation of this opcode.
+-**
+-** See also: AggStep and AggFinal
+-*/
+-case OP_Function: {
+-  int i;
+-  Mem *pArg;
+-  sqlite3_context ctx;
+-  sqlite3_value **apVal;
+-  int n;
+-
+-  n = pOp->p5;
+-  apVal = p->apArg;
+-  assert( apVal || n==0 );
+-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+-  ctx.pOut = &aMem[pOp->p3];
+-  memAboutToChange(p, ctx.pOut);
+-
+-  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
+-  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
+-  pArg = &aMem[pOp->p2];
+-  for(i=0; i<n; i++, pArg++){
+-    assert( memIsValid(pArg) );
+-    apVal[i] = pArg;
+-    Deephemeralize(pArg);
+-    REGISTER_TRACE(pOp->p2+i, pArg);
+-  }
+-
+-  assert( pOp->p4type==P4_FUNCDEF );
+-  ctx.pFunc = pOp->p4.pFunc;
+-  ctx.iOp = (int)(pOp - aOp);
+-  ctx.pVdbe = p;
+-  MemSetTypeFlag(ctx.pOut, MEM_Null);
+-  ctx.fErrorOrAux = 0;
+-  db->lastRowid = lastRowid;
+-  (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
+-  lastRowid = db->lastRowid;  /* Remember rowid changes made by xFunc */
+-
+-  /* If the function returned an error, throw an exception */
+-  if( ctx.fErrorOrAux ){
+-    if( ctx.isError ){
+-      sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
+-      rc = ctx.isError;
+-    }
+-    sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1);
+-  }
+-
+-  /* Copy the result of the function into register P3 */
+-  sqlite3VdbeChangeEncoding(ctx.pOut, encoding);
+-  if( sqlite3VdbeMemTooBig(ctx.pOut) ){
+-    goto too_big;
+-  }
+-
+-  REGISTER_TRACE(pOp->p3, ctx.pOut);
+-  UPDATE_MAX_BLOBSIZE(ctx.pOut);
+-  break;
+-}
+-
+ /* Opcode: BitAnd P1 P2 P3 * *
+-** Synopsis:  r[P3]=r[P1]&r[P2]
++** Synopsis: r[P3]=r[P1]&r[P2]
+ **
+ ** Take the bit-wise AND of the values in register P1 and P2 and
+ ** store the result in register P3.
+ ** If either input is NULL, the result is NULL.
+ */
+ /* Opcode: BitOr P1 P2 P3 * *
+-** Synopsis:  r[P3]=r[P1]|r[P2]
++** Synopsis: r[P3]=r[P1]|r[P2]
+ **
+ ** Take the bit-wise OR of the values in register P1 and P2 and
+ ** store the result in register P3.
+ ** If either input is NULL, the result is NULL.
+ */
+ /* Opcode: ShiftLeft P1 P2 P3 * *
+-** Synopsis:  r[P3]=r[P2]<<r[P1]
++** Synopsis: r[P3]=r[P2]<<r[P1]
+ **
+ ** Shift the integer value in register P2 to the left by the
+ ** number of bits specified by the integer in register P1.
+@@ -72477,7 +83864,7 @@
+ ** If either input is NULL, the result is NULL.
+ */
+ /* Opcode: ShiftRight P1 P2 P3 * *
+-** Synopsis:  r[P3]=r[P2]>>r[P1]
++** Synopsis: r[P3]=r[P2]>>r[P1]
+ **
+ ** Shift the integer value in register P2 to the right by the
+ ** number of bits specified by the integer in register P1.
+@@ -72537,7 +83924,7 @@
+ }
+ 
+ /* Opcode: AddImm  P1 P2 * * *
+-** Synopsis:  r[P1]=r[P1]+P2
++** Synopsis: r[P1]=r[P1]+P2
+ ** 
+ ** Add the constant P2 to the value in register P1.
+ ** The result is always an integer.
+@@ -72603,19 +83990,19 @@
+ ** Force the value in register P1 to be the type defined by P2.
+ ** 
+ ** <ul>
+-** <li value="97"> TEXT
+-** <li value="98"> BLOB
+-** <li value="99"> NUMERIC
+-** <li value="100"> INTEGER
+-** <li value="101"> REAL
++** <li> P2=='A' &rarr; BLOB
++** <li> P2=='B' &rarr; TEXT
++** <li> P2=='C' &rarr; NUMERIC
++** <li> P2=='D' &rarr; INTEGER
++** <li> P2=='E' &rarr; REAL
+ ** </ul>
+ **
+ ** A NULL value is not changed by this routine.  It remains NULL.
+ */
+ case OP_Cast: {                  /* in1 */
+-  assert( pOp->p2>=SQLITE_AFF_NONE && pOp->p2<=SQLITE_AFF_REAL );
++  assert( pOp->p2>=SQLITE_AFF_BLOB && pOp->p2<=SQLITE_AFF_REAL );
+   testcase( pOp->p2==SQLITE_AFF_TEXT );
+-  testcase( pOp->p2==SQLITE_AFF_NONE );
++  testcase( pOp->p2==SQLITE_AFF_BLOB );
+   testcase( pOp->p2==SQLITE_AFF_NUMERIC );
+   testcase( pOp->p2==SQLITE_AFF_INTEGER );
+   testcase( pOp->p2==SQLITE_AFF_REAL );
+@@ -72624,19 +84011,17 @@
+   rc = ExpandBlob(pIn1);
+   sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
+   UPDATE_MAX_BLOBSIZE(pIn1);
++  if( rc ) goto abort_due_to_error;
+   break;
+ }
+ #endif /* SQLITE_OMIT_CAST */
+ 
+-/* Opcode: Lt P1 P2 P3 P4 P5
+-** Synopsis: if r[P1]<r[P3] goto P2
+-**
+-** Compare the values in register P1 and P3.  If reg(P3)<reg(P1) then
+-** jump to address P2.  
++/* Opcode: Eq P1 P2 P3 P4 P5
++** Synopsis: IF r[P3]==r[P1]
+ **
+-** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or
+-** reg(P3) is NULL then take the jump.  If the SQLITE_JUMPIFNULL 
+-** bit is clear then fall through if either operand is NULL.
++** Compare the values in register P1 and P3.  If reg(P3)==reg(P1) then
++** jump to address P2.  Or if the SQLITE_STOREP2 flag is set in P5, then
++** store the result of comparison in register P2.
+ **
+ ** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
+ ** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made 
+@@ -72650,61 +84035,78 @@
+ ** the values are compared. If both values are blobs then memcmp() is
+ ** used to determine the results of the comparison.  If both values
+ ** are text, then the appropriate collating function specified in
+-** P4 is  used to do the comparison.  If P4 is not specified then
++** P4 is used to do the comparison.  If P4 is not specified then
+ ** memcmp() is used to compare text string.  If both values are
+ ** numeric, then a numeric comparison is used. If the two values
+ ** are of different types, then numbers are considered less than
+ ** strings and strings are considered less than blobs.
+ **
+-** 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 SQLITE_NULLEQ is set in P5 then the result of comparison is always either
++** true or false and is never NULL.  If both operands are NULL then the result
++** of comparison is true.  If either operand is NULL then the result is false.
++** If neither operand is NULL the result is the same as it would be if
++** the SQLITE_NULLEQ flag were omitted from P5.
+ **
+-** 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.
++** If both SQLITE_STOREP2 and SQLITE_KEEPNULL flags are set then the
++** content of r[P2] is only changed if the new value is NULL or 0 (false).
++** In other words, a prior r[P2] value will not be overwritten by 1 (true).
+ */
+ /* Opcode: Ne P1 P2 P3 P4 P5
+-** Synopsis: if r[P1]!=r[P3] goto P2
++** Synopsis: IF r[P3]!=r[P1]
+ **
+-** This works just like the Lt opcode except that the jump is taken if
+-** the operands in registers P1 and P3 are not equal.  See the Lt opcode for
++** This works just like the Eq opcode except that the jump is taken if
++** the operands in registers P1 and P3 are not equal.  See the Eq opcode for
+ ** additional information.
+ **
+-** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
+-** true or false and is never NULL.  If both operands are NULL then the result
+-** of comparison is false.  If either operand is NULL then the result is true.
+-** If neither operand is NULL the result is the same as it would be if
+-** the SQLITE_NULLEQ flag were omitted from P5.
++** If both SQLITE_STOREP2 and SQLITE_KEEPNULL flags are set then the
++** content of r[P2] is only changed if the new value is NULL or 1 (true).
++** In other words, a prior r[P2] value will not be overwritten by 0 (false).
+ */
+-/* Opcode: Eq P1 P2 P3 P4 P5
+-** Synopsis: if r[P1]==r[P3] goto P2
++/* Opcode: Lt P1 P2 P3 P4 P5
++** Synopsis: IF r[P3]<r[P1]
+ **
+-** This works just like the Lt opcode except that the jump is taken if
+-** the operands in registers P1 and P3 are equal.
+-** See the Lt opcode for additional information.
++** Compare the values in register P1 and P3.  If reg(P3)<reg(P1) then
++** jump to address P2.  Or if the SQLITE_STOREP2 flag is set in P5 store
++** the result of comparison (0 or 1 or NULL) into register P2.
+ **
+-** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
+-** true or false and is never NULL.  If both operands are NULL then the result
+-** of comparison is true.  If either operand is NULL then the result is false.
+-** If neither operand is NULL the result is the same as it would be if
+-** the SQLITE_NULLEQ flag were omitted from P5.
++** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or
++** reg(P3) is NULL then the take the jump.  If the SQLITE_JUMPIFNULL 
++** bit is clear then fall through if either operand is NULL.
++**
++** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
++** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made 
++** to coerce both inputs according to this affinity before the
++** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric
++** affinity is used. Note that the affinity conversions are stored
++** back into the input registers P1 and P3.  So this opcode can cause
++** persistent changes to registers P1 and P3.
++**
++** Once any conversions have taken place, and neither value is NULL, 
++** the values are compared. If both values are blobs then memcmp() is
++** used to determine the results of the comparison.  If both values
++** are text, then the appropriate collating function specified in
++** P4 is  used to do the comparison.  If P4 is not specified then
++** memcmp() is used to compare text string.  If both values are
++** numeric, then a numeric comparison is used. If the two values
++** are of different types, then numbers are considered less than
++** strings and strings are considered less than blobs.
+ */
+ /* Opcode: Le P1 P2 P3 P4 P5
+-** Synopsis: if r[P1]<=r[P3] goto P2
++** Synopsis: IF r[P3]<=r[P1]
+ **
+ ** This works just like the Lt opcode except that the jump is taken if
+ ** the content of register P3 is less than or equal to the content of
+ ** register P1.  See the Lt opcode for additional information.
+ */
+ /* Opcode: Gt P1 P2 P3 P4 P5
+-** Synopsis: if r[P1]>r[P3] goto P2
++** Synopsis: IF r[P3]>r[P1]
+ **
+ ** This works just like the Lt opcode except that the jump is taken if
+ ** the content of register P3 is greater than the content of
+ ** register P1.  See the Lt opcode for additional information.
+ */
+ /* Opcode: Ge P1 P2 P3 P4 P5
+-** Synopsis: if r[P1]>=r[P3] goto P2
++** Synopsis: IF r[P3]>=r[P1]
+ **
+ ** This works just like the Lt opcode except that the jump is taken if
+ ** the content of register P3 is greater than or equal to the content of
+@@ -72716,7 +84118,7 @@
+ 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 */
+-  int res;            /* Result of the comparison of pIn1 against pIn3 */
++  int res, res2;      /* 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 */
+@@ -72735,13 +84137,12 @@
+       assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
+       assert( (flags1 & MEM_Cleared)==0 );
+       assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
+-      if( (flags1&MEM_Null)!=0
+-       && (flags3&MEM_Null)!=0
++      if( (flags1&flags3&MEM_Null)!=0
+        && (flags3&MEM_Cleared)==0
+       ){
+-        res = 0;  /* Results are equal */
++        res = 0;  /* Operands are equal */
+       }else{
+-        res = 1;  /* Results are not equal */
++        res = 1;  /* Operands are not equal */
+       }
+     }else{
+       /* SQLITE_NULLEQ is clear and at least one operand is NULL,
+@@ -72750,6 +84151,8 @@
+       */
+       if( pOp->p5 & SQLITE_STOREP2 ){
+         pOut = &aMem[pOp->p2];
++        iCompare = 1;    /* Operands are not equal */
++        memAboutToChange(p, pOut);
+         MemSetTypeFlag(pOut, MEM_Null);
+         REGISTER_TRACE(pOp->p2, pOut);
+       }else{
+@@ -72764,21 +84167,34 @@
+     /* Neither operand is NULL.  Do a comparison. */
+     affinity = pOp->p5 & SQLITE_AFF_MASK;
+     if( affinity>=SQLITE_AFF_NUMERIC ){
+-      if( (pIn1->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+-        applyNumericAffinity(pIn1,0);
++      if( (flags1 | flags3)&MEM_Str ){
++        if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
++          applyNumericAffinity(pIn1,0);
++          testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */
++          flags3 = pIn3->flags;
++        }
++        if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
++          applyNumericAffinity(pIn3,0);
++        }
+       }
+-      if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+-        applyNumericAffinity(pIn3,0);
++      /* Handle the common case of integer comparison here, as an
++      ** optimization, to avoid a call to sqlite3MemCompare() */
++      if( (pIn1->flags & pIn3->flags & MEM_Int)!=0 ){
++        if( pIn3->u.i > pIn1->u.i ){ res = +1; goto compare_op; }
++        if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; }
++        res = 0;
++        goto compare_op;
+       }
+     }else if( affinity==SQLITE_AFF_TEXT ){
+-      if( (pIn1->flags & MEM_Str)==0 && (pIn1->flags & (MEM_Int|MEM_Real))!=0 ){
++      if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
+         testcase( pIn1->flags & MEM_Int );
+         testcase( pIn1->flags & MEM_Real );
+         sqlite3VdbeMemStringify(pIn1, encoding, 1);
+         testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
+         flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
++        assert( pIn1!=pIn3 );
+       }
+-      if( (pIn3->flags & MEM_Str)==0 && (pIn3->flags & (MEM_Int|MEM_Real))!=0 ){
++      if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
+         testcase( pIn3->flags & MEM_Int );
+         testcase( pIn3->flags & MEM_Real );
+         sqlite3VdbeMemStringify(pIn3, encoding, 1);
+@@ -72787,24 +84203,16 @@
+       }
+     }
+     assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
+-    if( pIn1->flags & MEM_Zero ){
+-      sqlite3VdbeMemExpandBlob(pIn1);
+-      flags1 &= ~MEM_Zero;
+-    }
+-    if( pIn3->flags & MEM_Zero ){
+-      sqlite3VdbeMemExpandBlob(pIn3);
+-      flags3 &= ~MEM_Zero;
+-    }
+-    if( db->mallocFailed ) goto no_mem;
+     res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
+   }
++compare_op:
+   switch( pOp->opcode ){
+-    case OP_Eq:    res = res==0;     break;
+-    case OP_Ne:    res = res!=0;     break;
+-    case OP_Lt:    res = res<0;      break;
+-    case OP_Le:    res = res<=0;     break;
+-    case OP_Gt:    res = res>0;      break;
+-    default:       res = res>=0;     break;
++    case OP_Eq:    res2 = res==0;     break;
++    case OP_Ne:    res2 = res;        break;
++    case OP_Lt:    res2 = res<0;      break;
++    case OP_Le:    res2 = res<=0;     break;
++    case OP_Gt:    res2 = res>0;      break;
++    default:       res2 = res>=0;     break;
+   }
+ 
+   /* Undo any changes made by applyAffinity() to the input registers. */
+@@ -72815,32 +84223,72 @@
+ 
+   if( pOp->p5 & SQLITE_STOREP2 ){
+     pOut = &aMem[pOp->p2];
++    iCompare = res;
++    res2 = res2!=0;  /* For this path res2 must be exactly 0 or 1 */
++    if( (pOp->p5 & SQLITE_KEEPNULL)!=0 ){
++      /* The KEEPNULL flag prevents OP_Eq from overwriting a NULL with 1
++      ** and prevents OP_Ne from overwriting NULL with 0.  This flag
++      ** is only used in contexts where either:
++      **   (1) op==OP_Eq && (r[P2]==NULL || r[P2]==0)
++      **   (2) op==OP_Ne && (r[P2]==NULL || r[P2]==1)
++      ** Therefore it is not necessary to check the content of r[P2] for
++      ** NULL. */
++      assert( pOp->opcode==OP_Ne || pOp->opcode==OP_Eq );
++      assert( res2==0 || res2==1 );
++      testcase( res2==0 && pOp->opcode==OP_Eq );
++      testcase( res2==1 && pOp->opcode==OP_Eq );
++      testcase( res2==0 && pOp->opcode==OP_Ne );
++      testcase( res2==1 && pOp->opcode==OP_Ne );
++      if( (pOp->opcode==OP_Eq)==res2 ) break;
++    }
+     memAboutToChange(p, pOut);
+     MemSetTypeFlag(pOut, MEM_Int);
+-    pOut->u.i = res;
++    pOut->u.i = res2;
+     REGISTER_TRACE(pOp->p2, pOut);
+   }else{
+     VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
+-    if( res ){
++    if( res2 ){
+       goto jump_to_p2;
+     }
+   }
+   break;
+ }
+ 
++/* Opcode: ElseNotEq * P2 * * *
++**
++** This opcode must immediately follow an OP_Lt or OP_Gt comparison operator.
++** If result of an OP_Eq comparison on the same two operands
++** would have be NULL or false (0), then then jump to P2. 
++** If the result of an OP_Eq comparison on the two previous operands
++** would have been true (1), then fall through.
++*/
++case OP_ElseNotEq: {       /* same as TK_ESCAPE, jump */
++  assert( pOp>aOp );
++  assert( pOp[-1].opcode==OP_Lt || pOp[-1].opcode==OP_Gt );
++  assert( pOp[-1].p5 & SQLITE_STOREP2 );
++  VdbeBranchTaken(iCompare!=0, 2);
++  if( iCompare!=0 ) goto jump_to_p2;
++  break;
++}
++
++
+ /* Opcode: Permutation * * * P4 *
+ **
+-** Set the permutation used by the OP_Compare operator to be the array
+-** of integers in P4.
++** Set the permutation used by the OP_Compare operator in the next
++** instruction.  The permutation is stored in the P4 operand.
+ **
+ ** 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.
++**
++** The first integer in the P4 integer array is the length of the array
++** and does not become part of the permutation.
+ */
+ case OP_Permutation: {
+   assert( pOp->p4type==P4_INTARRAY );
+   assert( pOp->p4.ai );
+-  aPermute = pOp->p4.ai;
++  assert( pOp[1].opcode==OP_Compare );
++  assert( pOp[1].p5 & OPFLAG_PERMUTE );
+   break;
+ }
+ 
+@@ -72873,23 +84321,32 @@
+   int idx;
+   CollSeq *pColl;    /* Collating sequence to use on this term */
+   int bRev;          /* True for DESCENDING sort order */
++  int *aPermute;     /* The permutation */
+ 
+-  if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
++  if( (pOp->p5 & OPFLAG_PERMUTE)==0 ){
++    aPermute = 0;
++  }else{
++    assert( pOp>aOp );
++    assert( pOp[-1].opcode==OP_Permutation );
++    assert( pOp[-1].p4type==P4_INTARRAY );
++    aPermute = pOp[-1].p4.ai + 1;
++    assert( aPermute!=0 );
++  }
+   n = pOp->p3;
+   pKeyInfo = pOp->p4.pKeyInfo;
+   assert( n>0 );
+   assert( pKeyInfo!=0 );
+   p1 = pOp->p1;
+   p2 = pOp->p2;
+-#if SQLITE_DEBUG
++#ifdef SQLITE_DEBUG
+   if( aPermute ){
+     int k, mx = 0;
+     for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
+-    assert( p1>0 && p1+mx<=(p->nMem-p->nCursor)+1 );
+-    assert( p2>0 && p2+mx<=(p->nMem-p->nCursor)+1 );
++    assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 );
++    assert( p2>0 && p2+mx<=(p->nMem+1 - p->nCursor)+1 );
+   }else{
+-    assert( p1>0 && p1+n<=(p->nMem-p->nCursor)+1 );
+-    assert( p2>0 && p2+n<=(p->nMem-p->nCursor)+1 );
++    assert( p1>0 && p1+n<=(p->nMem+1 - p->nCursor)+1 );
++    assert( p2>0 && p2+n<=(p->nMem+1 - p->nCursor)+1 );
+   }
+ #endif /* SQLITE_DEBUG */
+   for(i=0; i<n; i++){
+@@ -72907,7 +84364,6 @@
+       break;
+     }
+   }
+-  aPermute = 0;
+   break;
+ }
+ 
+@@ -73020,23 +84476,39 @@
+ 
+ /* Opcode: Once P1 P2 * * *
+ **
+-** Check the "once" flag number P1. If it is set, jump to instruction P2. 
+-** Otherwise, set the flag and fall through to the next instruction.
+-** In other words, this opcode causes all following opcodes up through P2
+-** (but not including P2) to run just once and to be skipped on subsequent
+-** times through the loop.
+-**
+-** All "once" flags are initially cleared whenever a prepared statement
+-** first begins to run.
++** Fall through to the next instruction the first time this opcode is
++** encountered on each invocation of the byte-code program.  Jump to P2
++** on the second and all subsequent encounters during the same invocation.
++**
++** Top-level programs determine first invocation by comparing the P1
++** operand against the P1 operand on the OP_Init opcode at the beginning
++** of the program.  If the P1 values differ, then fall through and make
++** the P1 of this opcode equal to the P1 of OP_Init.  If P1 values are
++** the same then take the jump.
++**
++** For subprograms, there is a bitmask in the VdbeFrame that determines
++** whether or not the jump should be taken.  The bitmask is necessary
++** because the self-altering code trick does not work for recursive
++** triggers.
+ */
+ case OP_Once: {             /* jump */
+-  assert( pOp->p1<p->nOnceFlag );
+-  VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
+-  if( p->aOnceFlag[pOp->p1] ){
+-    goto jump_to_p2;
++  u32 iAddr;                /* Address of this instruction */
++  assert( p->aOp[0].opcode==OP_Init );
++  if( p->pFrame ){
++    iAddr = (int)(pOp - p->aOp);
++    if( (p->pFrame->aOnce[iAddr/8] & (1<<(iAddr & 7)))!=0 ){
++      VdbeBranchTaken(1, 2);
++      goto jump_to_p2;
++    }
++    p->pFrame->aOnce[iAddr/8] |= 1<<(iAddr & 7);
+   }else{
+-    p->aOnceFlag[pOp->p1] = 1;
++    if( p->aOp[0].p1==pOp->p1 ){
++      VdbeBranchTaken(1, 2);
++      goto jump_to_p2;
++    }
+   }
++  VdbeBranchTaken(0, 2);
++  pOp->p1 = p->aOp[0].p1;
+   break;
+ }
+ 
+@@ -73074,7 +84546,7 @@
+ }
+ 
+ /* Opcode: IsNull P1 P2 * * *
+-** Synopsis:  if r[P1]==NULL goto P2
++** Synopsis: if r[P1]==NULL goto P2
+ **
+ ** Jump to P2 if the value in register P1 is NULL.
+ */
+@@ -73101,8 +84573,26 @@
+   break;
+ }
+ 
++/* Opcode: IfNullRow P1 P2 P3 * *
++** Synopsis: if P1.nullRow then r[P3]=NULL, goto P2
++**
++** Check the cursor P1 to see if it is currently pointing at a NULL row.
++** If it is, then set register P3 to NULL and jump immediately to P2.
++** If P1 is not on a NULL row, then fall through without making any
++** changes.
++*/
++case OP_IfNullRow: {         /* jump */
++  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
++  assert( p->apCsr[pOp->p1]!=0 );
++  if( p->apCsr[pOp->p1]->nullRow ){
++    sqlite3VdbeMemSetNull(aMem + pOp->p3);
++    goto jump_to_p2;
++  }
++  break;
++}
++
+ /* Opcode: Column P1 P2 P3 P4 P5
+-** Synopsis:  r[P3]=PX
++** Synopsis: r[P3]=PX
+ **
+ ** Interpret the data that cursor P1 points to as a structure built using
+ ** the MakeRecord instruction.  (See the MakeRecord opcode for additional
+@@ -73112,7 +84602,7 @@
+ **
+ ** The value extracted is stored in register P3.
+ **
+-** If the column contains fewer than P2 fields, then extract a NULL.  Or,
++** If the record contains fewer than P2 fields, then extract a NULL.  Or,
+ ** if the P4 argument is a P4_MEM use the value of the P4 argument as
+ ** the result.
+ **
+@@ -73121,13 +84611,12 @@
+ ** The first OP_Column against a pseudo-table after the value of the content
+ ** register has changed should have this bit set.
+ **
+-** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when
++** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then
+ ** the result is guaranteed to only be used as the argument of a length()
+ ** or typeof() function, respectively.  The loading of large blobs can be
+ ** skipped for length() and all content loading can be skipped for typeof().
+ */
+ case OP_Column: {
+-  i64 payloadSize64; /* Number of bytes in the record */
+   int p2;            /* column number to retrieve */
+   VdbeCursor *pC;    /* The VDBE cursor */
+   BtCursor *pCrsr;   /* The BTree cursor */
+@@ -73140,36 +84629,36 @@
+   const u8 *zHdr;    /* Next unparsed byte of the header */
+   const u8 *zEndHdr; /* Pointer to first byte after the header */
+   u32 offset;        /* Offset into the data */
+-  u32 szField;       /* Number of bytes in the content of a field */
++  u64 offset64;      /* 64-bit offset */
+   u32 avail;         /* Number of bytes of available data */
+   u32 t;             /* A type code from the record header */
+-  u16 fx;            /* pDest->flags value */
+   Mem *pReg;         /* PseudoTable input register */
+ 
++  pC = p->apCsr[pOp->p1];
+   p2 = pOp->p2;
+-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
++
++  /* If the cursor cache is stale (meaning it is not currently point at
++  ** the correct row) then bring it up-to-date by doing the necessary 
++  ** B-Tree seek. */
++  rc = sqlite3VdbeCursorMoveto(&pC, &p2);
++  if( rc ) goto abort_due_to_error;
++
++  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+   pDest = &aMem[pOp->p3];
+   memAboutToChange(p, pDest);
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+-  pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+   assert( p2<pC->nField );
+   aOffset = pC->aOffset;
+-#ifndef SQLITE_OMIT_VIRTUALTABLE
+-  assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
+-#endif
+-  pCrsr = pC->pCursor;
+-  assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */
+-  assert( pCrsr!=0 || pC->nullRow );          /* pC->nullRow on PseudoTables */
++  assert( pC->eCurType!=CURTYPE_VTAB );
++  assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
++  assert( pC->eCurType!=CURTYPE_SORTER );
+ 
+-  /* If the cursor cache is stale, bring it up-to-date */
+-  rc = sqlite3VdbeCursorMoveto(pC);
+-  if( rc ) goto abort_due_to_error;
+-  if( pC->cacheStatus!=p->cacheCtr ){
++  if( pC->cacheStatus!=p->cacheCtr ){                /*OPTIMIZATION-IF-FALSE*/
+     if( pC->nullRow ){
+-      if( pCrsr==0 ){
+-        assert( pC->pseudoTableReg>0 );
+-        pReg = &aMem[pC->pseudoTableReg];
++      if( pC->eCurType==CURTYPE_PSEUDO ){
++        assert( pC->uc.pseudoTableReg>0 );
++        pReg = &aMem[pC->uc.pseudoTableReg];
+         assert( pReg->flags & MEM_Blob );
+         assert( memIsValid(pReg) );
+         pC->payloadSize = pC->szRow = avail = pReg->n;
+@@ -73179,67 +84668,57 @@
+         goto op_column_out;
+       }
+     }else{
++      pCrsr = pC->uc.pCursor;
++      assert( pC->eCurType==CURTYPE_BTREE );
+       assert( pCrsr );
+-      if( pC->isTable==0 ){
+-        assert( sqlite3BtreeCursorIsValid(pCrsr) );
+-        VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64);
+-        assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
+-        /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
+-        ** payload size, so it is impossible for payloadSize64 to be
+-        ** larger than 32 bits. */
+-        assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 );
+-        pC->aRow = sqlite3BtreeKeyFetch(pCrsr, &avail);
+-        pC->payloadSize = (u32)payloadSize64;
+-      }else{
+-        assert( sqlite3BtreeCursorIsValid(pCrsr) );
+-        VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &pC->payloadSize);
+-        assert( rc==SQLITE_OK );   /* DataSize() cannot fail */
+-        pC->aRow = sqlite3BtreeDataFetch(pCrsr, &avail);
+-      }
++      assert( sqlite3BtreeCursorIsValid(pCrsr) );
++      pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
++      pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &avail);
+       assert( avail<=65536 );  /* Maximum page size is 64KiB */
+       if( pC->payloadSize <= (u32)avail ){
+         pC->szRow = pC->payloadSize;
++      }else if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
++        goto too_big;
+       }else{
+         pC->szRow = avail;
+       }
+-      if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+-        goto too_big;
+-      }
+     }
+     pC->cacheStatus = p->cacheCtr;
+     pC->iHdrOffset = getVarint32(pC->aRow, offset);
+     pC->nHdrParsed = 0;
+     aOffset[0] = offset;
+ 
+-    /* Make sure a corrupt database has not given us an oversize header.
+-    ** Do this now to avoid an oversize memory allocation.
+-    **
+-    ** Type entries can be between 1 and 5 bytes each.  But 4 and 5 byte
+-    ** types use so much data space that there can only be 4096 and 32 of
+-    ** them, respectively.  So the maximum header length results from a
+-    ** 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( offset > 98307 || offset > pC->payloadSize ){
+-      rc = SQLITE_CORRUPT_BKPT;
+-      goto op_column_error;
+-    }
+ 
+-    if( avail<offset ){
++    if( avail<offset ){      /*OPTIMIZATION-IF-FALSE*/
+       /* pC->aRow does not have to hold the entire row, but it does at least
+       ** need to cover the header of the record.  If pC->aRow does not contain
+       ** the complete header, then set it to zero, forcing the header to be
+       ** dynamically allocated. */
+       pC->aRow = 0;
+       pC->szRow = 0;
+-    }
+ 
+-    /* The following goto is an optimization.  It can be omitted and
+-    ** everything will still work.  But OP_Column is measurably faster
+-    ** by skipping the subsequent conditional, which is always true.
+-    */
+-    assert( pC->nHdrParsed<=p2 );         /* Conditional skipped */
+-    goto op_column_read_header;
++      /* Make sure a corrupt database has not given us an oversize header.
++      ** Do this now to avoid an oversize memory allocation.
++      **
++      ** Type entries can be between 1 and 5 bytes each.  But 4 and 5 byte
++      ** types use so much data space that there can only be 4096 and 32 of
++      ** them, respectively.  So the maximum header length results from a
++      ** 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( offset > 98307 || offset > pC->payloadSize ){
++        rc = SQLITE_CORRUPT_BKPT;
++        goto abort_due_to_error;
++      }
++    }else if( offset>0 ){ /*OPTIMIZATION-IF-TRUE*/
++      /* The following goto is an optimization.  It can be omitted and
++      ** everything will still work.  But OP_Column is measurably faster
++      ** by skipping the subsequent conditional, which is always true.
++      */
++      zData = pC->aRow;
++      assert( pC->nHdrParsed<=p2 );         /* Conditional skipped */
++      goto op_column_read_header;
++    }
+   }
+ 
+   /* Make sure at least the first p2+1 entries of the header have been
+@@ -73249,65 +84728,53 @@
+     /* If there is more header available for parsing in the record, try
+     ** to extract additional fields up through the p2+1-th field 
+     */
+-    op_column_read_header:
+     if( pC->iHdrOffset<aOffset[0] ){
+       /* Make sure zData points to enough of the record to cover the header. */
+       if( pC->aRow==0 ){
+         memset(&sMem, 0, sizeof(sMem));
+-        rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], 
+-                                     !pC->isTable, &sMem);
+-        if( rc!=SQLITE_OK ){
+-          goto op_column_error;
+-        }
++        rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, 0, aOffset[0], &sMem);
++        if( rc!=SQLITE_OK ) goto abort_due_to_error;
+         zData = (u8*)sMem.z;
+       }else{
+         zData = pC->aRow;
+       }
+   
+       /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */
++    op_column_read_header:
+       i = pC->nHdrParsed;
+-      offset = aOffset[i];
++      offset64 = aOffset[i];
+       zHdr = zData + pC->iHdrOffset;
+       zEndHdr = zData + aOffset[0];
+-      assert( i<=p2 && zHdr<zEndHdr );
+       do{
+-        if( zHdr[0]<0x80 ){
+-          t = zHdr[0];
++        if( (t = zHdr[0])<0x80 ){
+           zHdr++;
++          offset64 += sqlite3VdbeOneByteSerialTypeLen(t);
+         }else{
+           zHdr += sqlite3GetVarint32(zHdr, &t);
++          offset64 += sqlite3VdbeSerialTypeLen(t);
+         }
+-        pC->aType[i] = t;
+-        szField = sqlite3VdbeSerialTypeLen(t);
+-        offset += szField;
+-        if( offset<szField ){  /* True if offset overflows */
+-          zHdr = &zEndHdr[1];  /* Forces SQLITE_CORRUPT return below */
+-          break;
+-        }
+-        i++;
+-        aOffset[i] = offset;
++        pC->aType[i++] = t;
++        aOffset[i] = (u32)(offset64 & 0xffffffff);
+       }while( i<=p2 && zHdr<zEndHdr );
+-      pC->nHdrParsed = i;
+-      pC->iHdrOffset = (u32)(zHdr - zData);
+-      if( pC->aRow==0 ){
+-        sqlite3VdbeMemRelease(&sMem);
+-        sMem.flags = MEM_Null;
+-      }
+-  
++
+       /* The record is corrupt if any of the following are true:
+       ** (1) the bytes of the header extend past the declared header size
+-      **          (zHdr>zEndHdr)
+       ** (2) the entire header was used but not all data was used
+-      **          (zHdr==zEndHdr && offset!=pC->payloadSize)
+       ** (3) the end of the data extends beyond the end of the record.
+-      **          (offset > pC->payloadSize)
+       */
+-      if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize))
+-       || (offset > pC->payloadSize)
++      if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize))
++       || (offset64 > pC->payloadSize)
+       ){
++        if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
+         rc = SQLITE_CORRUPT_BKPT;
+-        goto op_column_error;
++        goto abort_due_to_error;
+       }
++
++      pC->nHdrParsed = i;
++      pC->iHdrOffset = (u32)(zHdr - zData);
++      if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
++    }else{
++      t = 0;
+     }
+ 
+     /* If after trying to extract new entries from the header, nHdrParsed is
+@@ -73322,6 +84789,8 @@
+       }
+       goto op_column_out;
+     }
++  }else{
++    t = pC->aType[p2];
+   }
+ 
+   /* Extract the content for the p2+1-th column.  Control can only
+@@ -73331,13 +84800,37 @@
+   assert( p2<pC->nHdrParsed );
+   assert( rc==SQLITE_OK );
+   assert( sqlite3VdbeCheckMemInvariants(pDest) );
+-  if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest);
+-  t = pC->aType[p2];
++  if( VdbeMemDynamic(pDest) ){
++    sqlite3VdbeMemSetNull(pDest);
++  }
++  assert( t==pC->aType[p2] );
+   if( pC->szRow>=aOffset[p2+1] ){
+     /* This is the common case where the desired content fits on the original
+     ** page - where the content is not on an overflow page */
+-    sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], t, pDest);
++    zData = pC->aRow + aOffset[p2];
++    if( t<12 ){
++      sqlite3VdbeSerialGet(zData, t, pDest);
++    }else{
++      /* If the column value is a string, we need a persistent value, not
++      ** a MEM_Ephem value.  This branch is a fast short-cut that is equivalent
++      ** to calling sqlite3VdbeSerialGet() and sqlite3VdbeDeephemeralize().
++      */
++      static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term };
++      pDest->n = len = (t-12)/2;
++      pDest->enc = encoding;
++      if( pDest->szMalloc < len+2 ){
++        pDest->flags = MEM_Null;
++        if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem;
++      }else{
++        pDest->z = pDest->zMalloc;
++      }
++      memcpy(pDest->z, zData, len);
++      pDest->z[len] = 0;
++      pDest->z[len+1] = 0;
++      pDest->flags = aFlag[t&1];
++    }
+   }else{
++    pDest->enc = encoding;
+     /* This branch happens only when content is on overflow pages */
+     if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
+           && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
+@@ -73348,39 +84841,23 @@
+       **    2. the length(X) function if X is a blob, and
+       **    3. if the content length is zero.
+       ** So we might as well use bogus content rather than reading
+-      ** content from disk.  NULL will work for the value for strings
+-      ** and blobs and whatever is in the payloadSize64 variable
+-      ** will work for everything else. */
+-      sqlite3VdbeSerialGet(t<=13 ? (u8*)&payloadSize64 : 0, t, pDest);
++      ** content from disk. 
++      **
++      ** Although sqlite3VdbeSerialGet() may read at most 8 bytes from the
++      ** buffer passed to it, debugging function VdbeMemPrettyPrint() may
++      ** read up to 16. So 16 bytes of bogus content is supplied.
++      */
++      static u8 aZero[16];  /* This is the bogus content */
++      sqlite3VdbeSerialGet(aZero, t, pDest);
+     }else{
+-      rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable,
+-                                   pDest);
+-      if( rc!=SQLITE_OK ){
+-        goto op_column_error;
+-      }
++      rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
++      if( rc!=SQLITE_OK ) goto abort_due_to_error;
+       sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
+       pDest->flags &= ~MEM_Ephem;
+     }
+   }
+-  pDest->enc = encoding;
+ 
+ op_column_out:
+-  /* If the column value is an ephemeral string, go ahead and persist
+-  ** that string in case the cursor moves before the column value is
+-  ** used.  The following code does the equivalent of Deephemeralize()
+-  ** but does it faster. */
+-  if( (pDest->flags & MEM_Ephem)!=0 && pDest->z ){
+-    fx = pDest->flags & (MEM_Str|MEM_Blob);
+-    assert( fx!=0 );
+-    zData = (const u8*)pDest->z;
+-    len = pDest->n;
+-    if( sqlite3VdbeMemClearAndResize(pDest, len+2) ) goto no_mem;
+-    memcpy(pDest->z, zData, len);
+-    pDest->z[len] = 0;
+-    pDest->z[len+1] = 0;
+-    pDest->flags = fx|MEM_Term;
+-  }
+-op_column_error:
+   UPDATE_MAX_BLOBSIZE(pDest);
+   REGISTER_TRACE(pOp->p3, pDest);
+   break;
+@@ -73391,24 +84868,24 @@
+ **
+ ** Apply affinities to a range of P2 registers starting with P1.
+ **
+-** P4 is a string that is P2 characters long. The nth character of the
+-** string indicates the column affinity that should be used for the nth
++** P4 is a string that is P2 characters long. The N-th character of the
++** string indicates the column affinity that should be used for the N-th
+ ** memory cell in the range.
+ */
+ case OP_Affinity: {
+   const char *zAffinity;   /* The affinity to be applied */
+-  char cAff;               /* A single character of affinity */
+ 
+   zAffinity = pOp->p4.z;
+   assert( zAffinity!=0 );
++  assert( pOp->p2>0 );
+   assert( zAffinity[pOp->p2]==0 );
+   pIn1 = &aMem[pOp->p1];
+-  while( (cAff = *(zAffinity++))!=0 ){
+-    assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] );
++  do{
++    assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
+     assert( memIsValid(pIn1) );
+-    applyAffinity(pIn1, cAff, encoding);
++    applyAffinity(pIn1, *(zAffinity++), encoding);
+     pIn1++;
+-  }
++  }while( zAffinity[0] );
+   break;
+ }
+ 
+@@ -73419,14 +84896,14 @@
+ ** use as a data record in a database table or as a key
+ ** in an index.  The OP_Column opcode can decode the record later.
+ **
+-** P4 may be a string that is P2 characters long.  The nth character of the
+-** string indicates the column affinity that should be used for the nth
++** P4 may be a string that is P2 characters long.  The N-th character of the
++** string indicates the column affinity that should be used for the N-th
+ ** field of the index key.
+ **
+ ** The mapping from character to affinity is given by the SQLITE_AFF_
+ ** macros defined in sqliteInt.h.
+ **
+-** If P4 is NULL then all index fields have the affinity NONE.
++** If P4 is NULL then all index fields have the affinity BLOB.
+ */
+ case OP_MakeRecord: {
+   u8 *zNewRecord;        /* A buffer to hold the data for the new record */
+@@ -73444,7 +84921,7 @@
+   int file_format;       /* File format to use for encoding */
+   int i;                 /* Space used in zNewRecord[] header */
+   int j;                 /* Space used in zNewRecord[] content */
+-  int len;               /* Length of a field */
++  u32 len;               /* Length of a field */
+ 
+   /* Assuming the record contains N fields, the record format looks
+   ** like this:
+@@ -73466,7 +84943,7 @@
+   nZero = 0;         /* Number of zero bytes at the end of the record */
+   nField = pOp->p1;
+   zAffinity = pOp->p4.z;
+-  assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem-p->nCursor)+1 );
++  assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 );
+   pData0 = &aMem[nField];
+   nField = pOp->p2;
+   pLast = &pData0[nField-1];
+@@ -73488,17 +84965,30 @@
+     }while( zAffinity[0] );
+   }
+ 
++#ifdef SQLITE_ENABLE_NULL_TRIM
++  /* NULLs can be safely trimmed from the end of the record, as long as
++  ** as the schema format is 2 or more and none of the omitted columns
++  ** have a non-NULL default value.  Also, the record must be left with
++  ** at least one field.  If P5>0 then it will be one more than the
++  ** index of the right-most column with a non-NULL default value */
++  if( pOp->p5 ){
++    while( (pLast->flags & MEM_Null)!=0 && nField>pOp->p5 ){
++      pLast--;
++      nField--;
++    }
++  }
++#endif
++
+   /* Loop through the elements that will make up the record to figure
+   ** out how much space is required for the new record.
+   */
+   pRec = pLast;
+   do{
+     assert( memIsValid(pRec) );
+-    pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format);
+-    len = sqlite3VdbeSerialTypeLen(serial_type);
++    pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
+     if( pRec->flags & MEM_Zero ){
+       if( nData ){
+-        sqlite3VdbeMemExpandBlob(pRec);
++        if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
+       }else{
+         nZero += pRec->u.nZero;
+         len -= pRec->u.nZero;
+@@ -73508,7 +84998,9 @@
+     testcase( serial_type==127 );
+     testcase( serial_type==128 );
+     nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
+-  }while( (--pRec)>=pData0 );
++    if( pRec==pData0 ) break;
++    pRec--;
++  }while(1);
+ 
+   /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
+   ** which determines the total number of bytes in the header. The varint
+@@ -73557,14 +85049,13 @@
+   assert( i==nHdr );
+   assert( j==nByte );
+ 
+-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
++  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+   pOut->n = (int)nByte;
+   pOut->flags = MEM_Blob;
+   if( nZero ){
+     pOut->u.nZero = nZero;
+     pOut->flags |= MEM_Zero;
+   }
+-  pOut->enc = SQLITE_UTF8;  /* In case the blob is ever converted to text */
+   REGISTER_TRACE(pOp->p3, pOut);
+   UPDATE_MAX_BLOBSIZE(pOut);
+   break;
+@@ -73581,10 +85072,12 @@
+   i64 nEntry;
+   BtCursor *pCrsr;
+ 
+-  pCrsr = p->apCsr[pOp->p1]->pCursor;
++  assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
++  pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
+   assert( pCrsr );
+   nEntry = 0;  /* Not needed.  Only used to silence a warning. */
+   rc = sqlite3BtreeCount(pCrsr, &nEntry);
++  if( rc ) goto abort_due_to_error;
+   pOut = out2Prerelease(p, pOp);
+   pOut->u.i = nEntry;
+   break;
+@@ -73624,8 +85117,7 @@
+       /* A new savepoint cannot be created if there are active write 
+       ** statements (i.e. open read/write incremental blob handles).
+       */
+-      sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - "
+-        "SQL statements in progress");
++      sqlite3VdbeError(p, "cannot open savepoint - SQL statements in progress");
+       rc = SQLITE_BUSY;
+     }else{
+       nName = sqlite3Strlen30(zName);
+@@ -73642,7 +85134,7 @@
+ #endif
+ 
+       /* Create a new savepoint structure. */
+-      pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1);
++      pNew = sqlite3DbMallocRawNN(db, sizeof(Savepoint)+nName+1);
+       if( pNew ){
+         pNew->zName = (char *)&pNew[1];
+         memcpy(pNew->zName, zName, nName+1);
+@@ -73655,7 +85147,7 @@
+         }else{
+           db->nSavepoint++;
+         }
+-    
++
+         /* Link the new savepoint into the database handle's list. */
+         pNew->pNext = db->pSavepoint;
+         db->pSavepoint = pNew;
+@@ -73676,15 +85168,14 @@
+       iSavepoint++;
+     }
+     if( !pSavepoint ){
+-      sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName);
++      sqlite3VdbeError(p, "no such savepoint: %s", zName);
+       rc = SQLITE_ERROR;
+     }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){
+       /* It is not possible to release (commit) a savepoint if there are 
+       ** active write statements.
+       */
+-      sqlite3SetString(&p->zErrMsg, db, 
+-        "cannot release savepoint - SQL statements in progress"
+-      );
++      sqlite3VdbeError(p, "cannot release savepoint - "
++                          "SQL statements in progress");
+       rc = SQLITE_BUSY;
+     }else{
+ 
+@@ -73764,6 +85255,7 @@
+       }
+     }
+   }
++  if( rc ) goto abort_due_to_error;
+ 
+   break;
+ }
+@@ -73780,49 +85272,37 @@
+ case OP_AutoCommit: {
+   int desiredAutoCommit;
+   int iRollback;
+-  int turnOnAC;
+ 
+   desiredAutoCommit = pOp->p1;
+   iRollback = pOp->p2;
+-  turnOnAC = desiredAutoCommit && !db->autoCommit;
+   assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
+   assert( desiredAutoCommit==1 || iRollback==0 );
+   assert( db->nVdbeActive>0 );  /* At least this one VM is active */
+   assert( p->bIsReader );
+ 
+-#if 0
+-  if( turnOnAC && iRollback && db->nVdbeActive>1 ){
+-    /* If this instruction implements a ROLLBACK and other VMs are
+-    ** still running, and a transaction is active, return an error indicating
+-    ** that the other VMs must complete first. 
+-    */
+-    sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
+-        "SQL statements in progress");
+-    rc = SQLITE_BUSY;
+-  }else
+-#endif
+-  if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){
+-    /* If this instruction implements a COMMIT and other VMs are writing
+-    ** return an error indicating that the other VMs must complete first. 
+-    */
+-    sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
+-        "SQL statements in progress");
+-    rc = SQLITE_BUSY;
+-  }else if( desiredAutoCommit!=db->autoCommit ){
++  if( desiredAutoCommit!=db->autoCommit ){
+     if( iRollback ){
+       assert( desiredAutoCommit==1 );
+       sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
+       db->autoCommit = 1;
++    }else if( desiredAutoCommit && db->nVdbeWrite>0 ){
++      /* If this instruction implements a COMMIT and other VMs are writing
++      ** return an error indicating that the other VMs must complete first. 
++      */
++      sqlite3VdbeError(p, "cannot commit transaction - "
++                          "SQL statements in progress");
++      rc = SQLITE_BUSY;
++      goto abort_due_to_error;
+     }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
+       goto vdbe_return;
+     }else{
+       db->autoCommit = (u8)desiredAutoCommit;
+-      if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
+-        p->pc = (int)(pOp - aOp);
+-        db->autoCommit = (u8)(1-desiredAutoCommit);
+-        p->rc = rc = SQLITE_BUSY;
+-        goto vdbe_return;
+-      }
++    }
++    if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
++      p->pc = (int)(pOp - aOp);
++      db->autoCommit = (u8)(1-desiredAutoCommit);
++      p->rc = rc = SQLITE_BUSY;
++      goto vdbe_return;
+     }
+     assert( db->nStatement==0 );
+     sqlite3CloseSavepoints(db);
+@@ -73833,12 +85313,13 @@
+     }
+     goto vdbe_return;
+   }else{
+-    sqlite3SetString(&p->zErrMsg, db,
++    sqlite3VdbeError(p,
+         (!desiredAutoCommit)?"cannot start a transaction within a transaction":(
+         (iRollback)?"cannot rollback - no transaction is active":
+                    "cannot commit - no transaction is active"));
+          
+     rc = SQLITE_ERROR;
++    goto abort_due_to_error;
+   }
+   break;
+ }
+@@ -73894,12 +85375,14 @@
+ 
+   if( pBt ){
+     rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
+-    if( rc==SQLITE_BUSY ){
+-      p->pc = (int)(pOp - aOp);
+-      p->rc = rc = SQLITE_BUSY;
+-      goto vdbe_return;
+-    }
++    testcase( rc==SQLITE_BUSY_SNAPSHOT );
++    testcase( rc==SQLITE_BUSY_RECOVERY );
+     if( rc!=SQLITE_OK ){
++      if( (rc&0xff)==SQLITE_BUSY ){
++        p->pc = (int)(pOp - aOp);
++        p->rc = rc;
++        goto vdbe_return;
++      }
+       goto abort_due_to_error;
+     }
+ 
+@@ -73926,10 +85409,9 @@
+     }
+ 
+     /* Gather the schema version number for checking:
+-    ** IMPLEMENTATION-OF: R-32195-19465 The schema version is used by SQLite
+-    ** each time a query is executed to ensure that the internal cache of the
+-    ** schema used when compiling the SQL query matches the schema of the
+-    ** database against which the compiled query is actually executed.
++    ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
++    ** version is checked to ensure that the schema has not changed since the
++    ** SQL statement was prepared.
+     */
+     sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
+     iGen = db->aDb[pOp->p1].pSchema->iGeneration;
+@@ -73959,6 +85441,7 @@
+     p->expired = 1;
+     rc = SQLITE_SCHEMA;
+   }
++  if( rc ) goto abort_due_to_error;
+   break;
+ }
+ 
+@@ -73995,15 +85478,15 @@
+ 
+ /* Opcode: SetCookie P1 P2 P3 * *
+ **
+-** Write the content of register P3 (interpreted as an integer)
+-** into cookie number P2 of database P1.  P2==1 is the schema version.  
+-** P2==2 is the database format. P2==3 is the recommended pager cache 
++** Write the integer value P3 into cookie number P2 of database P1.
++** P2==1 is the schema version.  P2==2 is the database format.
++** P2==3 is the recommended pager cache 
+ ** size, and so forth.  P1==0 is the main database file and P1==1 is the 
+ ** database file used to store temporary tables.
+ **
+ ** A transaction must be started before executing this opcode.
+ */
+-case OP_SetCookie: {       /* in3 */
++case OP_SetCookie: {
+   Db *pDb;
+   assert( pOp->p2<SQLITE_N_BTREE_META );
+   assert( pOp->p1>=0 && pOp->p1<db->nDb );
+@@ -74012,17 +85495,15 @@
+   pDb = &db->aDb[pOp->p1];
+   assert( 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(pDb->pBt, pOp->p2, (int)pIn3->u.i);
++  rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3);
+   if( pOp->p2==BTREE_SCHEMA_VERSION ){
+     /* When the schema cookie changes, record the new cookie internally */
+-    pDb->pSchema->schema_cookie = (int)pIn3->u.i;
++    pDb->pSchema->schema_cookie = pOp->p3;
+     db->flags |= SQLITE_InternChanges;
+   }else if( pOp->p2==BTREE_FILE_FORMAT ){
+     /* Record changes in the file format */
+-    pDb->pSchema->file_format = (u8)pIn3->u.i;
++    pDb->pSchema->file_format = pOp->p3;
+   }
+   if( pOp->p1==1 ){
+     /* Invalidate all prepared statements whenever the TEMP database
+@@ -74030,6 +85511,7 @@
+     sqlite3ExpirePreparedStatements(db);
+     p->expired = 0;
+   }
++  if( rc ) goto abort_due_to_error;
+   break;
+ }
+ 
+@@ -74120,7 +85602,6 @@
+ case OP_OpenRead:
+ case OP_OpenWrite:
+ 
+-  assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR|OPFLAG_SEEKEQ))==pOp->p5 );
+   assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ );
+   assert( p->bIsReader );
+   assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx
+@@ -74128,7 +85609,7 @@
+ 
+   if( p->expired ){
+     rc = SQLITE_ABORT_ROLLBACK;
+-    break;
++    goto abort_due_to_error;
+   }
+ 
+   nField = 0;
+@@ -74141,7 +85622,8 @@
+   pX = pDb->pBt;
+   assert( pX!=0 );
+   if( pOp->opcode==OP_OpenWrite ){
+-    wrFlag = 1;
++    assert( OPFLAG_FORDELETE==BTREE_FORDELETE );
++    wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE);
+     assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+     if( pDb->pSchema->file_format < p->minWriteFileFormat ){
+       p->minWriteFileFormat = pDb->pSchema->file_format;
+@@ -74151,7 +85633,7 @@
+   }
+   if( pOp->p5 & OPFLAG_P2ISREG ){
+     assert( p2>0 );
+-    assert( p2<=(p->nMem-p->nCursor) );
++    assert( p2<=(p->nMem+1 - p->nCursor) );
+     pIn2 = &aMem[p2];
+     assert( memIsValid(pIn2) );
+     assert( (pIn2->flags & MEM_Int)!=0 );
+@@ -74161,10 +85643,7 @@
+     ** that opcode will always set the 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(p2<2) ) {
+-      rc = SQLITE_CORRUPT_BKPT;
+-      goto abort_due_to_error;
+-    }
++    assert( p2>=2 );
+   }
+   if( pOp->p4type==P4_KEYINFO ){
+     pKeyInfo = pOp->p4.pKeyInfo;
+@@ -74177,12 +85656,15 @@
+   assert( pOp->p1>=0 );
+   assert( nField>=0 );
+   testcase( nField==0 );  /* Table with INTEGER PRIMARY KEY and nothing else */
+-  pCur = allocateCursor(p, pOp->p1, nField, iDb, 1);
++  pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE);
+   if( pCur==0 ) goto no_mem;
+   pCur->nullRow = 1;
+   pCur->isOrdered = 1;
+   pCur->pgnoRoot = p2;
+-  rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
++#ifdef SQLITE_DEBUG
++  pCur->wrFlag = wrFlag;
++#endif
++  rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor);
+   pCur->pKeyInfo = pKeyInfo;
+   /* Set the VdbeCursor.isTable variable. Previous versions of
+   ** SQLite used to check if the root-page flags were sane at this point
+@@ -74193,11 +85675,47 @@
+ open_cursor_set_hints:
+   assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
+   assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ );
+-  sqlite3BtreeCursorHints(pCur->pCursor,
+-                          (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
++  testcase( pOp->p5 & OPFLAG_BULKCSR );
++#ifdef SQLITE_ENABLE_CURSOR_HINTS
++  testcase( pOp->p2 & OPFLAG_SEEKEQ );
++#endif
++  sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
++                               (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
++  if( rc ) goto abort_due_to_error;
++  break;
++}
++
++/* Opcode: OpenDup P1 P2 * * *
++**
++** Open a new cursor P1 that points to the same ephemeral table as
++** cursor P2.  The P2 cursor must have been opened by a prior OP_OpenEphemeral
++** opcode.  Only ephemeral cursors may be duplicated.
++**
++** Duplicate ephemeral cursors are used for self-joins of materialized views.
++*/
++case OP_OpenDup: {
++  VdbeCursor *pOrig;    /* The original cursor to be duplicated */
++  VdbeCursor *pCx;      /* The new cursor */
++
++  pOrig = p->apCsr[pOp->p2];
++  assert( pOrig->pBtx!=0 );  /* Only ephemeral cursors can be duplicated */
++
++  pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE);
++  if( pCx==0 ) goto no_mem;
++  pCx->nullRow = 1;
++  pCx->isEphemeral = 1;
++  pCx->pKeyInfo = pOrig->pKeyInfo;
++  pCx->isTable = pOrig->isTable;
++  rc = sqlite3BtreeCursor(pOrig->pBtx, MASTER_ROOT, BTREE_WRCSR,
++                          pCx->pKeyInfo, pCx->uc.pCursor);
++  /* The sqlite3BtreeCursor() routine can only fail for the first cursor
++  ** opened for a database.  Since there is already an open cursor when this
++  ** opcode is run, the sqlite3BtreeCursor() cannot fail */
++  assert( rc==SQLITE_OK );
+   break;
+ }
+ 
++
+ /* Opcode: OpenEphemeral P1 P2 * P4 P5
+ ** Synopsis: nColumn=P2
+ **
+@@ -74237,14 +85755,14 @@
+       SQLITE_OPEN_TRANSIENT_DB;
+   assert( pOp->p1>=0 );
+   assert( pOp->p2>=0 );
+-  pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
++  pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
+   if( pCx==0 ) goto no_mem;
+   pCx->nullRow = 1;
+   pCx->isEphemeral = 1;
+-  rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, 
++  rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, 
+                         BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
+   if( rc==SQLITE_OK ){
+-    rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
++    rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1);
+   }
+   if( rc==SQLITE_OK ){
+     /* If a transient index is required, create it by calling
+@@ -74252,23 +85770,25 @@
+     ** opening it. If a transient table is required, just use the
+     ** automatically created table with root-page 1 (an BLOB_INTKEY table).
+     */
+-    if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
++    if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
+       int pgno;
+       assert( pOp->p4type==P4_KEYINFO );
+-      rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); 
++      rc = sqlite3BtreeCreateTable(pCx->pBtx, &pgno, BTREE_BLOBKEY | pOp->p5); 
+       if( rc==SQLITE_OK ){
+         assert( pgno==MASTER_ROOT+1 );
+         assert( pKeyInfo->db==db );
+         assert( pKeyInfo->enc==ENC(db) );
+-        pCx->pKeyInfo = pKeyInfo;
+-        rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, pKeyInfo, pCx->pCursor);
++        rc = sqlite3BtreeCursor(pCx->pBtx, pgno, BTREE_WRCSR,
++                                pKeyInfo, pCx->uc.pCursor);
+       }
+       pCx->isTable = 0;
+     }else{
+-      rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor);
++      rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
++                              0, pCx->uc.pCursor);
+       pCx->isTable = 1;
+     }
+   }
++  if( rc ) goto abort_due_to_error;
+   pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
+   break;
+ }
+@@ -74288,12 +85808,13 @@
+ 
+   assert( pOp->p1>=0 );
+   assert( pOp->p2>=0 );
+-  pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
++  pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_SORTER);
+   if( pCx==0 ) goto no_mem;
+   pCx->pKeyInfo = pOp->p4.pKeyInfo;
+   assert( pCx->pKeyInfo->db==db );
+   assert( pCx->pKeyInfo->enc==ENC(db) );
+   rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx);
++  if( rc ) goto abort_due_to_error;
+   break;
+ }
+ 
+@@ -74308,7 +85829,7 @@
+   VdbeCursor *pC;
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+-  assert( pC->pSorter );
++  assert( isSorter(pC) );
+   if( (pC->seqCount++)==0 ){
+     goto jump_to_p2;
+   }
+@@ -74336,10 +85857,10 @@
+ 
+   assert( pOp->p1>=0 );
+   assert( pOp->p3>=0 );
+-  pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
++  pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO);
+   if( pCx==0 ) goto no_mem;
+   pCx->nullRow = 1;
+-  pCx->pseudoTableReg = pOp->p2;
++  pCx->uc.pseudoTableReg = pOp->p2;
+   pCx->isTable = 1;
+   assert( pOp->p5==0 );
+   break;
+@@ -74357,6 +85878,26 @@
+   break;
+ }
+ 
++#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
++/* Opcode: ColumnsUsed P1 * * P4 *
++**
++** This opcode (which only exists if SQLite was compiled with
++** SQLITE_ENABLE_COLUMN_USED_MASK) identifies which columns of the
++** table or index for cursor P1 are used.  P4 is a 64-bit integer
++** (P4_INT64) in which the first 63 bits are one for each of the
++** first 63 columns of the table or index that are actually used
++** by the cursor.  The high-order bit is set if any column after
++** the 64th is used.
++*/
++case OP_ColumnsUsed: {
++  VdbeCursor *pC;
++  pC = p->apCsr[pOp->p1];
++  assert( pC->eCurType==CURTYPE_BTREE );
++  pC->maskUsed = *(u64*)pOp->p4.pI64;
++  break;
++}
++#endif
++
+ /* Opcode: SeekGE P1 P2 P3 P4 *
+ ** Synopsis: key=r[P3@P4]
+ **
+@@ -74369,6 +85910,13 @@
+ ** is greater than or equal to the key value. If there are no records 
+ ** greater than or equal to the key and P2 is not zero, then jump to P2.
+ **
++** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
++** opcode will always land on a record that equally equals the key, or
++** else jump immediately to P2.  When the cursor is OPFLAG_SEEKEQ, this
++** opcode must be followed by an IdxLE opcode with the same arguments.
++** The IdxLE opcode will be skipped if this opcode succeeds, but the
++** IdxLE opcode will be used on subsequent loop iterations.
++**
+ ** This opcode leaves the cursor configured to move in forward order,
+ ** from the beginning toward the end.  In other words, the cursor is
+ ** configured to use Next, not Prev.
+@@ -74427,51 +85975,49 @@
+ ** from the end toward the beginning.  In other words, the cursor is
+ ** configured to use Prev, not Next.
+ **
++** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
++** opcode will always land on a record that equally equals the key, or
++** else jump immediately to P2.  When the cursor is OPFLAG_SEEKEQ, this
++** opcode must be followed by an IdxGE opcode with the same arguments.
++** The IdxGE opcode will be skipped if this opcode succeeds, but the
++** IdxGE opcode will be used on subsequent loop iterations.
++**
+ ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
+ */
+ case OP_SeekLT:         /* jump, in3 */
+ case OP_SeekLE:         /* jump, in3 */
+ case OP_SeekGE:         /* jump, in3 */
+ case OP_SeekGT: {       /* jump, in3 */
+-  int res;
+-  int oc;
+-  VdbeCursor *pC;
+-  UnpackedRecord r;
+-  int nField;
+-  i64 iKey;      /* The rowid we are to seek to */
++  int res;           /* Comparison result */
++  int oc;            /* Opcode */
++  VdbeCursor *pC;    /* The cursor to seek */
++  UnpackedRecord r;  /* The key to seek for */
++  int nField;        /* Number of columns or fields in the key */
++  i64 iKey;          /* The rowid we are to seek to */
++  int eqOnly;        /* Only interested in == results */
+ 
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   assert( pOp->p2!=0 );
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+-  assert( pC->pseudoTableReg==0 );
++  assert( pC->eCurType==CURTYPE_BTREE );
+   assert( OP_SeekLE == OP_SeekLT+1 );
+   assert( OP_SeekGE == OP_SeekLT+2 );
+   assert( OP_SeekGT == OP_SeekLT+3 );
+   assert( pC->isOrdered );
+-  assert( pC->pCursor!=0 );
++  assert( pC->uc.pCursor!=0 );
+   oc = pOp->opcode;
++  eqOnly = 0;
+   pC->nullRow = 0;
+ #ifdef SQLITE_DEBUG
+   pC->seekOp = pOp->opcode;
+ #endif
+ 
+-  /* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and
+-  ** OP_SeekLE opcodes are allowed, and these must be immediately followed
+-  ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key.
+-  */
+-#ifdef SQLITE_DEBUG
+-  if( sqlite3BtreeCursorHasHint(pC->pCursor, BTREE_SEEK_EQ) ){
+-    assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
+-    assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
+-    assert( pOp[1].p1==pOp[0].p1 );
+-    assert( pOp[1].p2==pOp[0].p2 );
+-    assert( pOp[1].p3==pOp[0].p3 );
+-    assert( pOp[1].p4.i==pOp[0].p4.i );
+-  }
+-#endif
+- 
+   if( pC->isTable ){
++    /* The BTREE_SEEK_EQ flag is only set on index cursors */
++    assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
++              || CORRUPT_DB );
++
+     /* 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 convert it. */
+@@ -74514,12 +86060,26 @@
+         if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
+       }
+     } 
+-    rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
++    rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
+     pC->movetoTarget = iKey;  /* Used by OP_Delete */
+     if( rc!=SQLITE_OK ){
+       goto abort_due_to_error;
+     }
+   }else{
++    /* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and
++    ** OP_SeekLE opcodes are allowed, and these must be immediately followed
++    ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key.
++    */
++    if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){
++      eqOnly = 1;
++      assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
++      assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
++      assert( pOp[1].p1==pOp[0].p1 );
++      assert( pOp[1].p2==pOp[0].p2 );
++      assert( pOp[1].p3==pOp[0].p3 );
++      assert( pOp[1].p4.i==pOp[0].p4.i );
++    }
++
+     nField = pOp->p4.i;
+     assert( pOp->p4type==P4_INT32 );
+     assert( nField>0 );
+@@ -74543,11 +86103,15 @@
+ #ifdef SQLITE_DEBUG
+     { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
+ #endif
+-    ExpandBlob(r.aMem);
+-    rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
++    r.eqSeen = 0;
++    rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, &r, 0, 0, &res);
+     if( rc!=SQLITE_OK ){
+       goto abort_due_to_error;
+     }
++    if( eqOnly && r.eqSeen==0 ){
++      assert( res!=0 );
++      goto seek_not_found;
++    }
+   }
+   pC->deferredMoveto = 0;
+   pC->cacheStatus = CACHE_STALE;
+@@ -74557,8 +86121,15 @@
+   if( oc>=OP_SeekGE ){  assert( oc==OP_SeekGE || oc==OP_SeekGT );
+     if( res<0 || (res==0 && oc==OP_SeekGT) ){
+       res = 0;
+-      rc = sqlite3BtreeNext(pC->pCursor, &res);
+-      if( rc!=SQLITE_OK ) goto abort_due_to_error;
++      rc = sqlite3BtreeNext(pC->uc.pCursor, 0);
++      if( rc!=SQLITE_OK ){
++        if( rc==SQLITE_DONE ){
++          rc = SQLITE_OK;
++          res = 1;
++        }else{
++          goto abort_due_to_error;
++        }
++      }
+     }else{
+       res = 0;
+     }
+@@ -74566,49 +86137,34 @@
+     assert( oc==OP_SeekLT || oc==OP_SeekLE );
+     if( res>0 || (res==0 && oc==OP_SeekLT) ){
+       res = 0;
+-      rc = sqlite3BtreePrevious(pC->pCursor, &res);
+-      if( rc!=SQLITE_OK ) goto abort_due_to_error;
++      rc = sqlite3BtreePrevious(pC->uc.pCursor, 0);
++      if( rc!=SQLITE_OK ){
++        if( rc==SQLITE_DONE ){
++          rc = SQLITE_OK;
++          res = 1;
++        }else{
++          goto abort_due_to_error;
++        }
++      }
+     }else{
+       /* res might be negative because the table is empty.  Check to
+       ** see if this is the case.
+       */
+-      res = sqlite3BtreeEof(pC->pCursor);
++      res = sqlite3BtreeEof(pC->uc.pCursor);
+     }
+   }
++seek_not_found:
+   assert( pOp->p2>0 );
+   VdbeBranchTaken(res!=0,2);
+   if( res ){
+     goto jump_to_p2;
++  }else if( eqOnly ){
++    assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
++    pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */
+   }
+   break;
+ }
+ 
+-/* Opcode: Seek P1 P2 * * *
+-** Synopsis:  intkey=r[P2]
+-**
+-** P1 is an open table cursor and P2 is a rowid integer.  Arrange
+-** for P1 to move so that it points to the rowid given by P2.
+-**
+-** This is actually a deferred seek.  Nothing actually happens until
+-** the cursor is used to read a record.  That way, if no reads
+-** occur, no unnecessary I/O happens.
+-*/
+-case OP_Seek: {    /* in2 */
+-  VdbeCursor *pC;
+-
+-  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+-  pC = p->apCsr[pOp->p1];
+-  assert( pC!=0 );
+-  assert( pC->pCursor!=0 );
+-  assert( pC->isTable );
+-  pC->nullRow = 0;
+-  pIn2 = &aMem[pOp->p2];
+-  pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
+-  pC->deferredMoveto = 1;
+-  break;
+-}
+-  
+-
+ /* Opcode: Found P1 P2 P3 P4 *
+ ** Synopsis: key=r[P3@P4]
+ **
+@@ -74676,10 +86232,9 @@
+   int ii;
+   VdbeCursor *pC;
+   int res;
+-  char *pFree;
++  UnpackedRecord *pFree;
+   UnpackedRecord *pIdxKey;
+   UnpackedRecord r;
+-  char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7];
+ 
+ #ifdef SQLITE_TEST
+   if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++;
+@@ -74693,28 +86248,29 @@
+   pC->seekOp = pOp->opcode;
+ #endif
+   pIn3 = &aMem[pOp->p3];
+-  assert( pC->pCursor!=0 );
++  assert( pC->eCurType==CURTYPE_BTREE );
++  assert( pC->uc.pCursor!=0 );
+   assert( pC->isTable==0 );
+-  pFree = 0;
+   if( pOp->p4.i>0 ){
+     r.pKeyInfo = pC->pKeyInfo;
+     r.nField = (u16)pOp->p4.i;
+     r.aMem = pIn3;
++#ifdef SQLITE_DEBUG
+     for(ii=0; ii<r.nField; ii++){
+       assert( memIsValid(&r.aMem[ii]) );
+-      ExpandBlob(&r.aMem[ii]);
+-#ifdef SQLITE_DEBUG
++      assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 );
+       if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
+-#endif
+     }
++#endif
+     pIdxKey = &r;
++    pFree = 0;
+   }else{
+-    pIdxKey = sqlite3VdbeAllocUnpackedRecord(
+-        pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree
+-    );
+-    if( pIdxKey==0 ) goto no_mem;
+     assert( pIn3->flags & MEM_Blob );
+-    ExpandBlob(pIn3);
++    rc = ExpandBlob(pIn3);
++    assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
++    if( rc ) goto no_mem;
++    pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
++    if( pIdxKey==0 ) goto no_mem;
+     sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
+   }
+   pIdxKey->default_rc = 0;
+@@ -74730,10 +86286,10 @@
+       }
+     }
+   }
+-  rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
+-  sqlite3DbFree(db, pFree);
++  rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res);
++  if( pFree ) sqlite3DbFreeNN(db, pFree);
+   if( rc!=SQLITE_OK ){
+-    break;
++    goto abort_due_to_error;
+   }
+   pC->seekResult = res;
+   alreadyExists = (res==0);
+@@ -74750,14 +86306,43 @@
+   break;
+ }
+ 
++/* Opcode: SeekRowid P1 P2 P3 * *
++** Synopsis: intkey=r[P3]
++**
++** P1 is the index of a cursor open on an SQL table btree (with integer
++** keys).  If register P3 does not contain an integer or if P1 does not
++** contain a record with rowid P3 then jump immediately to P2.  
++** Or, if P2 is 0, raise an SQLITE_CORRUPT error. If P1 does contain
++** a record with rowid P3 then 
++** leave the cursor pointing at that record and fall through to the next
++** instruction.
++**
++** The OP_NotExists opcode performs the same operation, but with OP_NotExists
++** the P3 register must be guaranteed to contain an integer value.  With this
++** opcode, register P3 might not contain an integer.
++**
++** The OP_NotFound opcode performs the same operation on index btrees
++** (with arbitrary multi-value keys).
++**
++** This opcode leaves the cursor in a state where it cannot be advanced
++** in either direction.  In other words, the Next and Prev opcodes will
++** not work following this opcode.
++**
++** See also: Found, NotFound, NoConflict, SeekRowid
++*/
+ /* Opcode: NotExists P1 P2 P3 * *
+ ** Synopsis: intkey=r[P3]
+ **
+ ** P1 is the index of a cursor open on an SQL table btree (with integer
+ ** keys).  P3 is an integer rowid.  If P1 does not contain a record with
+-** rowid P3 then jump immediately to P2.  If P1 does contain a record
+-** with rowid P3 then leave the cursor pointing at that record and fall
+-** through to the next instruction.
++** rowid P3 then jump immediately to P2.  Or, if P2 is 0, raise an
++** SQLITE_CORRUPT error. If P1 does contain a record with rowid P3 then 
++** leave the cursor pointing at that record and fall through to the next
++** instruction.
++**
++** The OP_SeekRowid opcode performs the same operation but also allows the
++** P3 register to contain a non-integer value, in which case the jump is
++** always taken.  This opcode requires that P3 always contain an integer.
+ **
+ ** The OP_NotFound opcode performs the same operation on index btrees
+ ** (with arbitrary multi-value keys).
+@@ -74766,15 +86351,22 @@
+ ** in either direction.  In other words, the Next and Prev opcodes will
+ ** not work following this opcode.
+ **
+-** See also: Found, NotFound, NoConflict
++** See also: Found, NotFound, NoConflict, SeekRowid
+ */
+-case OP_NotExists: {        /* jump, in3 */
++case OP_SeekRowid: {        /* jump, in3 */
+   VdbeCursor *pC;
+   BtCursor *pCrsr;
+   int res;
+   u64 iKey;
+ 
+   pIn3 = &aMem[pOp->p3];
++  if( (pIn3->flags & MEM_Int)==0 ){
++    applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding);
++    if( (pIn3->flags & MEM_Int)==0 ) goto jump_to_p2;
++  }
++  /* Fall through into OP_NotExists */
++case OP_NotExists:          /* jump, in3 */
++  pIn3 = &aMem[pOp->p3];
+   assert( pIn3->flags & MEM_Int );
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+@@ -74783,19 +86375,28 @@
+   pC->seekOp = 0;
+ #endif
+   assert( pC->isTable );
+-  assert( pC->pseudoTableReg==0 );
+-  pCrsr = pC->pCursor;
++  assert( pC->eCurType==CURTYPE_BTREE );
++  pCrsr = pC->uc.pCursor;
+   assert( pCrsr!=0 );
+   res = 0;
+   iKey = pIn3->u.i;
+   rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
++  assert( rc==SQLITE_OK || res==0 );
+   pC->movetoTarget = iKey;  /* Used by OP_Delete */
+   pC->nullRow = 0;
+   pC->cacheStatus = CACHE_STALE;
+   pC->deferredMoveto = 0;
+   VdbeBranchTaken(res!=0,2);
+   pC->seekResult = res;
+-  if( res!=0 ) goto jump_to_p2;
++  if( res!=0 ){
++    assert( rc==SQLITE_OK );
++    if( pOp->p2==0 ){
++      rc = SQLITE_CORRUPT_BKPT;
++    }else{
++      goto jump_to_p2;
++    }
++  }
++  if( rc ) goto abort_due_to_error;
+   break;
+ }
+ 
+@@ -74810,6 +86411,7 @@
+ case OP_Sequence: {           /* out2 */
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   assert( p->apCsr[pOp->p1]!=0 );
++  assert( p->apCsr[pOp->p1]->eCurType!=CURTYPE_VTAB );
+   pOut = out2Prerelease(p, pOp);
+   pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
+   break;
+@@ -74845,9 +86447,9 @@
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+-  if( NEVER(pC->pCursor==0) ){
+-    /* The zero initialization above is all that is needed */
+-  }else{
++  assert( pC->eCurType==CURTYPE_BTREE );
++  assert( pC->uc.pCursor!=0 );
++  {
+     /* The next rowid or record number (different terms for the same
+     ** thing) is obtained in a two-step algorithm.
+     **
+@@ -74874,16 +86476,15 @@
+ #endif
+ 
+     if( !pC->useRandomRowid ){
+-      rc = sqlite3BtreeLast(pC->pCursor, &res);
++      rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
+       if( rc!=SQLITE_OK ){
+         goto abort_due_to_error;
+       }
+       if( res ){
+         v = 1;   /* IMP: R-61914-48074 */
+       }else{
+-        assert( sqlite3BtreeCursorIsValid(pC->pCursor) );
+-        rc = sqlite3BtreeKeySize(pC->pCursor, &v);
+-        assert( rc==SQLITE_OK );   /* Cannot fail following BtreeLast() */
++        assert( sqlite3BtreeCursorIsValid(pC->uc.pCursor) );
++        v = sqlite3BtreeIntegerKey(pC->uc.pCursor);
+         if( v>=MAX_ROWID ){
+           pC->useRandomRowid = 1;
+         }else{
+@@ -74903,7 +86504,7 @@
+         pMem = &pFrame->aMem[pOp->p3];
+       }else{
+         /* Assert that P3 is a valid memory cell. */
+-        assert( pOp->p3<=(p->nMem-p->nCursor) );
++        assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
+         pMem = &aMem[pOp->p3];
+         memAboutToChange(p, pMem);
+       }
+@@ -74913,7 +86514,7 @@
+       sqlite3VdbeMemIntegerify(pMem);
+       assert( (pMem->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
+       if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
+-        rc = SQLITE_FULL;   /* IMP: R-12275-61338 */
++        rc = SQLITE_FULL;   /* IMP: R-17817-00630 */
+         goto abort_due_to_error;
+       }
+       if( v<pMem->u.i+1 ){
+@@ -74933,11 +86534,12 @@
+       do{
+         sqlite3_randomness(sizeof(v), &v);
+         v &= (MAX_ROWID>>1); v++;  /* Ensure that v is greater than zero */
+-      }while(  ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v,
++      }while(  ((rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)v,
+                                                  0, &res))==SQLITE_OK)
+             && (res==0)
+             && (++cnt<100));
+-      if( rc==SQLITE_OK && res==0 ){
++      if( rc ) goto abort_due_to_error;
++      if( res==0 ){
+         rc = SQLITE_FULL;   /* IMP: R-38219-53002 */
+         goto abort_due_to_error;
+       }
+@@ -74964,22 +86566,19 @@
+ ** then rowid is stored for subsequent return by the
+ ** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
+ **
+-** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of
+-** the last seek operation (OP_NotExists) was a success, then this
+-** operation will not attempt to find the appropriate row before doing
+-** the insert but will instead overwrite the row that the cursor is
+-** currently pointing to.  Presumably, the prior OP_NotExists opcode
+-** has already positioned the cursor correctly.  This is an optimization
+-** that boosts performance by avoiding redundant seeks.
++** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might
++** run faster by avoiding an unnecessary seek on cursor P1.  However,
++** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior
++** seeks on the cursor or if the most recent seek used a key equal to P3.
+ **
+ ** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an
+ ** UPDATE operation.  Otherwise (if the flag is clear) then this opcode
+ ** is part of an INSERT operation.  The difference is only important to
+ ** the update hook.
+ **
+-** Parameter P4 may point to a string containing the table-name, or
+-** may be NULL. If it is not NULL, then the update-hook 
+-** (sqlite3.xUpdateCallback) is invoked following a successful insert.
++** Parameter P4 may point to a Table structure, or may be NULL. If it is 
++** not NULL, then the update-hook (sqlite3.xUpdateCallback) is invoked 
++** following a successful insert.
+ **
+ ** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically
+ ** allocated, then ownership of P2 is transferred to the pseudo-cursor
+@@ -74991,7 +86590,7 @@
+ ** for indices is OP_IdxInsert.
+ */
+ /* Opcode: InsertInt P1 P2 P3 P4 P5
+-** Synopsis:  intkey=P3 data=r[P2]
++** Synopsis: intkey=P3 data=r[P2]
+ **
+ ** This works exactly like OP_Insert except that the key is the
+ ** integer value P3, not the value of the integer stored in register P3.
+@@ -75000,22 +86599,23 @@
+ case OP_InsertInt: {
+   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 */
+   VdbeCursor *pC;   /* Cursor to table into which insert is written */
+-  int nZero;        /* Number of zero-bytes to append */
+   int seekResult;   /* Result of prior seek or 0 if no USESEEKRESULT flag */
+   const char *zDb;  /* database name - used by the update hook */
+-  const char *zTbl; /* Table name - used by the opdate hook */
++  Table *pTab;      /* Table structure - used by update and pre-update hooks */
+   int op;           /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
++  BtreePayload x;   /* Payload to be inserted */
+ 
++  op = 0;
+   pData = &aMem[pOp->p2];
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   assert( memIsValid(pData) );
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+-  assert( pC->pCursor!=0 );
+-  assert( pC->pseudoTableReg==0 );
+-  assert( pC->isTable );
++  assert( pC->eCurType==CURTYPE_BTREE );
++  assert( pC->uc.pCursor!=0 );
++  assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable );
++  assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC );
+   REGISTER_TRACE(pOp->p2, pData);
+ 
+   if( pOp->opcode==OP_Insert ){
+@@ -75023,95 +86623,192 @@
+     assert( pKey->flags & MEM_Int );
+     assert( memIsValid(pKey) );
+     REGISTER_TRACE(pOp->p3, pKey);
+-    iKey = pKey->u.i;
++    x.nKey = pKey->u.i;
+   }else{
+     assert( pOp->opcode==OP_InsertInt );
+-    iKey = pOp->p3;
++    x.nKey = pOp->p3;
++  }
++
++  if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
++    assert( pC->iDb>=0 );
++    zDb = db->aDb[pC->iDb].zDbSName;
++    pTab = pOp->p4.pTab;
++    assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) );
++    op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
++  }else{
++    pTab = 0; /* Not needed.  Silence a compiler warning. */
++    zDb = 0;  /* Not needed.  Silence a compiler warning. */
+   }
+ 
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++  /* Invoke the pre-update hook, if any */
++  if( db->xPreUpdateCallback 
++   && pOp->p4type==P4_TABLE
++   && !(pOp->p5 & OPFLAG_ISUPDATE)
++  ){
++    sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey, pOp->p2);
++  }
++  if( pOp->p5 & OPFLAG_ISNOOP ) break;
++#endif
++
+   if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
+-  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = iKey;
++  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
+   if( pData->flags & MEM_Null ){
+-    pData->z = 0;
+-    pData->n = 0;
++    x.pData = 0;
++    x.nData = 0;
+   }else{
+     assert( pData->flags & (MEM_Blob|MEM_Str) );
++    x.pData = pData->z;
++    x.nData = pData->n;
+   }
+   seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
+   if( pData->flags & MEM_Zero ){
+-    nZero = pData->u.nZero;
++    x.nZero = pData->u.nZero;
+   }else{
+-    nZero = 0;
++    x.nZero = 0;
+   }
+-  rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
+-                          pData->z, pData->n, nZero,
+-                          (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
++  x.pKey = 0;
++  rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
++      (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), seekResult
+   );
+   pC->deferredMoveto = 0;
+   pC->cacheStatus = CACHE_STALE;
+ 
+   /* Invoke the update-hook if required. */
+-  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
+-    zDb = db->aDb[pC->iDb].zName;
+-    zTbl = pOp->p4.z;
+-    op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
+-    assert( pC->isTable );
+-    db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
+-    assert( pC->iDb>=0 );
++  if( rc ) goto abort_due_to_error;
++  if( db->xUpdateCallback && op ){
++    db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, x.nKey);
+   }
+   break;
+ }
+ 
+-/* Opcode: Delete P1 P2 * P4 *
++/* Opcode: Delete P1 P2 P3 P4 P5
+ **
+ ** Delete the record at which the P1 cursor is currently pointing.
+ **
+-** The cursor will be left pointing at either the next or the previous
++** If the OPFLAG_SAVEPOSITION bit of the P5 parameter is set, then
++** the cursor will be left pointing at  either the next or the previous
+ ** record in the table. If it is left pointing at the next record, then
+-** the next Next instruction will be a no-op.  Hence it is OK to delete
+-** a record from within a Next loop.
++** the next Next instruction will be a no-op. As a result, in this case
++** it is ok to delete a record from within a Next loop. If 
++** OPFLAG_SAVEPOSITION bit of P5 is clear, then the cursor will be
++** left in an undefined state.
++**
++** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this
++** delete one of several associated with deleting a table row and all its
++** associated index entries.  Exactly one of those deletes is the "primary"
++** delete.  The others are all on OPFLAG_FORDELETE cursors or else are
++** marked with the AUXDELETE flag.
+ **
+-** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
+-** incremented (otherwise not).
++** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row
++** change count is incremented (otherwise not).
+ **
+ ** P1 must not be pseudo-table.  It has to be a real table with
+ ** multiple rows.
+ **
+-** If P4 is not NULL, then it is the name of the table that P1 is
+-** pointing to.  The update hook will be invoked, if it exists.
+-** If P4 is not NULL then the P1 cursor must have been positioned
+-** using OP_NotFound prior to invoking this opcode.
++** If P4 is not NULL then it points to a Table object. In this case either 
++** the update or pre-update hook, or both, may be invoked. The P1 cursor must
++** have been positioned using OP_NotFound prior to invoking this opcode in 
++** this case. Specifically, if one is configured, the pre-update hook is 
++** invoked if P4 is not NULL. The update-hook is invoked if one is configured, 
++** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2.
++**
++** If the OPFLAG_ISUPDATE flag is set in P2, then P3 contains the address
++** of the memory cell that contains the value that the rowid of the row will
++** be set to by the update.
+ */
+ case OP_Delete: {
+   VdbeCursor *pC;
++  const char *zDb;
++  Table *pTab;
++  int opflags;
+ 
++  opflags = pOp->p2;
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+-  assert( pC->pCursor!=0 );  /* Only valid for real tables, no pseudotables */
++  assert( pC->eCurType==CURTYPE_BTREE );
++  assert( pC->uc.pCursor!=0 );
+   assert( pC->deferredMoveto==0 );
+ 
+ #ifdef SQLITE_DEBUG
+-  /* The seek operation that positioned the cursor prior to OP_Delete will
+-  ** have also set the pC->movetoTarget field to the rowid of the row that
+-  ** is being deleted */
+-  if( pOp->p4.z && pC->isTable ){
+-    i64 iKey = 0;
+-    sqlite3BtreeKeySize(pC->pCursor, &iKey);
+-    assert( pC->movetoTarget==iKey ); 
++  if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){
++    /* If p5 is zero, the seek operation that positioned the cursor prior to
++    ** OP_Delete will have also set the pC->movetoTarget field to the rowid of
++    ** the row that is being deleted */
++    i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor);
++    assert( pC->movetoTarget==iKey );
++  }
++#endif
++
++  /* If the update-hook or pre-update-hook will be invoked, set zDb to
++  ** the name of the db to pass as to it. Also set local pTab to a copy
++  ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was
++  ** last moved with OP_Next or OP_Prev, not Seek or NotFound, set 
++  ** VdbeCursor.movetoTarget to the current rowid.  */
++  if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
++    assert( pC->iDb>=0 );
++    assert( pOp->p4.pTab!=0 );
++    zDb = db->aDb[pC->iDb].zDbSName;
++    pTab = pOp->p4.pTab;
++    if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){
++      pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor);
++    }
++  }else{
++    zDb = 0;   /* Not needed.  Silence a compiler warning. */
++    pTab = 0;  /* Not needed.  Silence a compiler warning. */
++  }
++
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++  /* Invoke the pre-update-hook if required. */
++  if( db->xPreUpdateCallback && pOp->p4.pTab ){
++    assert( !(opflags & OPFLAG_ISUPDATE) 
++         || HasRowid(pTab)==0 
++         || (aMem[pOp->p3].flags & MEM_Int) 
++    );
++    sqlite3VdbePreUpdateHook(p, pC,
++        (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, 
++        zDb, pTab, pC->movetoTarget,
++        pOp->p3
++    );
+   }
++  if( opflags & OPFLAG_ISNOOP ) break;
+ #endif
+  
+-  rc = sqlite3BtreeDelete(pC->pCursor);
++  /* Only flags that can be set are SAVEPOISTION and AUXDELETE */ 
++  assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 );
++  assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION );
++  assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE );
++
++#ifdef SQLITE_DEBUG
++  if( p->pFrame==0 ){
++    if( pC->isEphemeral==0
++        && (pOp->p5 & OPFLAG_AUXDELETE)==0
++        && (pC->wrFlag & OPFLAG_FORDELETE)==0
++      ){
++      nExtraDelete++;
++    }
++    if( pOp->p2 & OPFLAG_NCHANGE ){
++      nExtraDelete--;
++    }
++  }
++#endif
++
++  rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
+   pC->cacheStatus = CACHE_STALE;
++  pC->seekResult = 0;
++  if( rc ) goto abort_due_to_error;
+ 
+   /* Invoke the update-hook if required. */
+-  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){
+-    db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
+-                        db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
+-    assert( pC->iDb>=0 );
++  if( opflags & OPFLAG_NCHANGE ){
++    p->nChange++;
++    if( db->xUpdateCallback && HasRowid(pTab) ){
++      db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,
++          pC->movetoTarget);
++      assert( pC->iDb>=0 );
++    }
+   }
+-  if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
++
+   break;
+ }
+ /* Opcode: ResetCount * * * * *
+@@ -75128,7 +86825,7 @@
+ }
+ 
+ /* Opcode: SorterCompare P1 P2 P3 P4
+-** Synopsis:  if key(P1)!=trim(r[P3],P4) goto P2
++** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2
+ **
+ ** P1 is a sorter cursor. This instruction compares a prefix of the
+ ** record blob in register P3 against a prefix of the entry that 
+@@ -75155,6 +86852,7 @@
+   res = 0;
+   rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
+   VdbeBranchTaken(res!=0,2);
++  if( rc ) goto abort_due_to_error;
+   if( res ) goto jump_to_p2;
+   break;
+ };
+@@ -75180,57 +86878,59 @@
+   rc = sqlite3VdbeSorterRowkey(pC, pOut);
+   assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
++  if( rc ) goto abort_due_to_error;
+   p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
+   break;
+ }
+ 
+-/* Opcode: RowData P1 P2 * * *
++/* Opcode: RowData P1 P2 P3 * *
+ ** Synopsis: r[P2]=data
+ **
+-** Write into register P2 the complete row data for cursor P1.
++** Write into register P2 the complete row content for the row at 
++** which cursor P1 is currently pointing.
+ ** There is no interpretation of the data.  
+ ** It is just copied onto the P2 register exactly as 
+ ** it is found in the database file.
+ **
+-** If the P1 cursor must be pointing to a valid row (not a NULL row)
+-** of a real table, not a pseudo-table.
+-*/
+-/* Opcode: RowKey P1 P2 * * *
+-** Synopsis: r[P2]=key
+-**
+-** Write into register P2 the complete row key for cursor P1.
+-** There is no interpretation of the data.  
+-** The key is copied onto the P2 register exactly as 
+-** it is found in the database file.
++** If cursor P1 is an index, then the content is the key of the row.
++** If cursor P2 is a table, then the content extracted is the data.
+ **
+ ** If the P1 cursor must be pointing to a valid row (not a NULL row)
+ ** of a real table, not a pseudo-table.
++**
++** If P3!=0 then this opcode is allowed to make an ephermeral pointer
++** into the database page.  That means that the content of the output
++** register will be invalidated as soon as the cursor moves - including
++** moves caused by other cursors that "save" the the current cursors
++** position in order that they can write to the same table.  If P3==0
++** then a copy of the data is made into memory.  P3!=0 is faster, but
++** P3==0 is safer.
++**
++** If P3!=0 then the content of the P2 register is unsuitable for use
++** in OP_Result and any OP_Result will invalidate the P2 register content.
++** The P2 register content is invalidated by opcodes like OP_Function or
++** by any use of another cursor pointing to the same table.
+ */
+-case OP_RowKey:
+ case OP_RowData: {
+   VdbeCursor *pC;
+   BtCursor *pCrsr;
+   u32 n;
+-  i64 n64;
+ 
+-  pOut = &aMem[pOp->p2];
+-  memAboutToChange(p, pOut);
++  pOut = out2Prerelease(p, pOp);
+ 
+-  /* Note that RowKey and RowData are really exactly the same instruction */
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+-  assert( isSorter(pC)==0 );
+-  assert( pC->isTable || pOp->opcode!=OP_RowData );
+-  assert( pC->isTable==0 || pOp->opcode==OP_RowData );
+   assert( pC!=0 );
++  assert( pC->eCurType==CURTYPE_BTREE );
++  assert( isSorter(pC)==0 );
+   assert( pC->nullRow==0 );
+-  assert( pC->pseudoTableReg==0 );
+-  assert( pC->pCursor!=0 );
+-  pCrsr = pC->pCursor;
+-
+-  /* 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.  If this where not the case, on of the following assert()s
++  assert( pC->uc.pCursor!=0 );
++  pCrsr = pC->uc.pCursor;
++
++  /* The OP_RowData opcodes always follow OP_NotExists or
++  ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions
++  ** that might invalidate the cursor.
++  ** If this where not the case, on of the following assert()s
+   ** would fail.  Should this ever change (because of changes in the code
+   ** generator) then the fix would be to insert a call to
+   ** sqlite3VdbeCursorMoveto().
+@@ -75242,33 +86942,14 @@
+   if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ #endif
+ 
+-  if( pC->isTable==0 ){
+-    assert( !pC->isTable );
+-    VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
+-    assert( rc==SQLITE_OK );    /* True because of CursorMoveto() call above */
+-    if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+-      goto too_big;
+-    }
+-    n = (u32)n64;
+-  }else{
+-    VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &n);
+-    assert( rc==SQLITE_OK );    /* DataSize() cannot fail */
+-    if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+-      goto too_big;
+-    }
++  n = sqlite3BtreePayloadSize(pCrsr);
++  if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
++    goto too_big;
+   }
+   testcase( n==0 );
+-  if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
+-    goto no_mem;
+-  }
+-  pOut->n = n;
+-  MemSetTypeFlag(pOut, MEM_Blob);
+-  if( pC->isTable==0 ){
+-    rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
+-  }else{
+-    rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
+-  }
+-  pOut->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
++  rc = sqlite3VdbeMemFromBtree(pCrsr, 0, n, pOut);
++  if( rc ) goto abort_due_to_error;
++  if( !pOp->p3 ) Deephemeralize(pOut);
+   UPDATE_MAX_BLOBSIZE(pOut);
+   REGISTER_TRACE(pOp->p2, pOut);
+   break;
+@@ -75294,30 +86975,32 @@
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+-  assert( pC->pseudoTableReg==0 || pC->nullRow );
++  assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
+   if( pC->nullRow ){
+     pOut->flags = MEM_Null;
+     break;
+   }else if( pC->deferredMoveto ){
+     v = pC->movetoTarget;
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-  }else if( pC->pVtabCursor ){
+-    pVtab = pC->pVtabCursor->pVtab;
++  }else if( pC->eCurType==CURTYPE_VTAB ){
++    assert( pC->uc.pVCur!=0 );
++    pVtab = pC->uc.pVCur->pVtab;
+     pModule = pVtab->pModule;
+     assert( pModule->xRowid );
+-    rc = pModule->xRowid(pC->pVtabCursor, &v);
++    rc = pModule->xRowid(pC->uc.pVCur, &v);
+     sqlite3VtabImportErrmsg(p, pVtab);
++    if( rc ) goto abort_due_to_error;
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+   }else{
+-    assert( pC->pCursor!=0 );
++    assert( pC->eCurType==CURTYPE_BTREE );
++    assert( pC->uc.pCursor!=0 );
+     rc = sqlite3VdbeCursorRestore(pC);
+     if( rc ) goto abort_due_to_error;
+     if( pC->nullRow ){
+       pOut->flags = MEM_Null;
+       break;
+     }
+-    rc = sqlite3BtreeKeySize(pC->pCursor, &v);
+-    assert( rc==SQLITE_OK );  /* Always so because of CursorRestore() above */
++    v = sqlite3BtreeIntegerKey(pC->uc.pCursor);
+   }
+   pOut->u.i = v;
+   break;
+@@ -75337,8 +87020,9 @@
+   assert( pC!=0 );
+   pC->nullRow = 1;
+   pC->cacheStatus = CACHE_STALE;
+-  if( pC->pCursor ){
+-    sqlite3BtreeClearCursor(pC->pCursor);
++  if( pC->eCurType==CURTYPE_BTREE ){
++    assert( pC->uc.pCursor!=0 );
++    sqlite3BtreeClearCursor(pC->uc.pCursor);
+   }
+   break;
+ }
+@@ -75354,6 +87038,13 @@
+ ** This opcode leaves the cursor configured to move in reverse order,
+ ** from the end toward the beginning.  In other words, the cursor is
+ ** configured to use Prev, not Next.
++**
++** If P3 is -1, then the cursor is positioned at the end of the btree
++** for the purpose of appending a new entry onto the btree.  In that
++** case P2 must be 0.  It is assumed that the cursor is used only for
++** appending and so if the cursor is valid, then the cursor must already
++** be pointing at the end of the btree and so no changes are made to
++** the cursor.
+ */
+ case OP_Last: {        /* jump */
+   VdbeCursor *pC;
+@@ -75363,25 +87054,67 @@
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+-  pCrsr = pC->pCursor;
++  assert( pC->eCurType==CURTYPE_BTREE );
++  pCrsr = pC->uc.pCursor;
+   res = 0;
+   assert( pCrsr!=0 );
+-  rc = sqlite3BtreeLast(pCrsr, &res);
+-  pC->nullRow = (u8)res;
+-  pC->deferredMoveto = 0;
+-  pC->cacheStatus = CACHE_STALE;
+   pC->seekResult = pOp->p3;
+ #ifdef SQLITE_DEBUG
+   pC->seekOp = OP_Last;
+ #endif
+-  if( pOp->p2>0 ){
+-    VdbeBranchTaken(res!=0,2);
+-    if( res ) goto jump_to_p2;
++  if( pOp->p3==0 || !sqlite3BtreeCursorIsValidNN(pCrsr) ){
++    rc = sqlite3BtreeLast(pCrsr, &res);
++    pC->nullRow = (u8)res;
++    pC->deferredMoveto = 0;
++    pC->cacheStatus = CACHE_STALE;
++    if( rc ) goto abort_due_to_error;
++    if( pOp->p2>0 ){
++      VdbeBranchTaken(res!=0,2);
++      if( res ) goto jump_to_p2;
++    }
++  }else{
++    assert( pOp->p2==0 );
++  }
++  break;
++}
++
++/* Opcode: IfSmaller P1 P2 P3 * *
++**
++** Estimate the number of rows in the table P1.  Jump to P2 if that
++** estimate is less than approximately 2**(0.1*P3).
++*/
++case OP_IfSmaller: {        /* jump */
++  VdbeCursor *pC;
++  BtCursor *pCrsr;
++  int res;
++  i64 sz;
++
++  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
++  pC = p->apCsr[pOp->p1];
++  assert( pC!=0 );
++  pCrsr = pC->uc.pCursor;
++  assert( pCrsr );
++  rc = sqlite3BtreeFirst(pCrsr, &res);
++  if( rc ) goto abort_due_to_error;
++  if( res==0 ){
++    sz = sqlite3BtreeRowCountEst(pCrsr);
++    if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)<pOp->p3 ) res = 1;
+   }
++  VdbeBranchTaken(res!=0,2);
++  if( res ) goto jump_to_p2;
+   break;
+ }
+ 
+ 
++/* Opcode: SorterSort P1 P2 * * *
++**
++** After all records have been inserted into the Sorter object
++** identified by P1, invoke this opcode to actually do the sorting.
++** Jump to P2 if there are no records to be sorted.
++**
++** This opcode is an alias for OP_Sort and OP_Rewind that is used
++** for Sorter objects.
++*/
+ /* Opcode: Sort P1 P2 * * *
+ **
+ ** This opcode does exactly the same thing as OP_Rewind except that
+@@ -75431,12 +87164,14 @@
+   if( isSorter(pC) ){
+     rc = sqlite3VdbeSorterRewind(pC, &res);
+   }else{
+-    pCrsr = pC->pCursor;
++    assert( pC->eCurType==CURTYPE_BTREE );
++    pCrsr = pC->uc.pCursor;
+     assert( pCrsr );
+     rc = sqlite3BtreeFirst(pCrsr, &res);
+     pC->deferredMoveto = 0;
+     pC->cacheStatus = CACHE_STALE;
+   }
++  if( rc ) goto abort_due_to_error;
+   pC->nullRow = (u8)res;
+   assert( pOp->p2>0 && pOp->p2<p->nOp );
+   VdbeBranchTaken(res!=0,2);
+@@ -75507,14 +87242,19 @@
+ ** This opcode works just like Prev except that if cursor P1 is not
+ ** open it behaves a no-op.
+ */
++/* Opcode: SorterNext P1 P2 * * P5
++**
++** This opcode works just like OP_Next except that P1 must be a
++** sorter object for which the OP_SorterSort opcode has been
++** invoked.  This opcode advances the cursor to the next sorted
++** record, or jumps to P2 if there are no more sorted records.
++*/
+ case OP_SorterNext: {  /* jump */
+   VdbeCursor *pC;
+-  int res;
+ 
+   pC = p->apCsr[pOp->p1];
+   assert( isSorter(pC) );
+-  res = 0;
+-  rc = sqlite3VdbeSorterNext(db, pC, &res);
++  rc = sqlite3VdbeSorterNext(db, pC);
+   goto next_tail;
+ case OP_PrevIfOpen:    /* jump */
+ case OP_NextIfOpen:    /* jump */
+@@ -75525,12 +87265,9 @@
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   assert( pOp->p5<ArraySize(p->aCounter) );
+   pC = p->apCsr[pOp->p1];
+-  res = pOp->p3;
+   assert( pC!=0 );
+   assert( pC->deferredMoveto==0 );
+-  assert( pC->pCursor );
+-  assert( res==0 || (res==1 && pC->isTable==0) );
+-  testcase( res==1 );
++  assert( pC->eCurType==CURTYPE_BTREE );
+   assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
+   assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
+   assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext );
+@@ -75545,50 +87282,63 @@
+        || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
+        || pC->seekOp==OP_Last );
+ 
+-  rc = pOp->p4.xAdvance(pC->pCursor, &res);
++  rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
+ next_tail:
+   pC->cacheStatus = CACHE_STALE;
+-  VdbeBranchTaken(res==0,2);
+-  if( res==0 ){
++  VdbeBranchTaken(rc==SQLITE_OK,2);
++  if( rc==SQLITE_OK ){
+     pC->nullRow = 0;
+     p->aCounter[pOp->p5]++;
+ #ifdef SQLITE_TEST
+     sqlite3_search_count++;
+ #endif
+     goto jump_to_p2_and_check_for_interrupt;
+-  }else{
+-    pC->nullRow = 1;
+   }
++  if( rc!=SQLITE_DONE ) goto abort_due_to_error;
++  rc = SQLITE_OK;
++  pC->nullRow = 1;
+   goto check_for_interrupt;
+ }
+ 
+-/* Opcode: IdxInsert P1 P2 P3 * P5
++/* Opcode: IdxInsert P1 P2 P3 P4 P5
+ ** Synopsis: key=r[P2]
+ **
+ ** Register P2 holds an SQL index key made using the
+ ** MakeRecord instructions.  This opcode writes that key
+ ** into the index P1.  Data for the entry is nil.
+ **
+-** P3 is a flag that provides a hint to the b-tree layer that this
+-** insert is likely to be an append.
++** If P4 is not zero, then it is the number of values in the unpacked
++** key of reg(P2).  In that case, P3 is the index of the first register
++** for the unpacked key.  The availability of the unpacked key can sometimes
++** be an optimization.
++**
++** If P5 has the OPFLAG_APPEND bit set, that is a hint to the b-tree layer
++** that this insert is likely to be an append.
+ **
+ ** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is
+ ** incremented by this instruction.  If the OPFLAG_NCHANGE bit is clear,
+ ** then the change counter is unchanged.
+ **
+-** If P5 has the OPFLAG_USESEEKRESULT bit set, then the cursor must have
+-** just done a seek to the spot where the new entry is to be inserted.
+-** This flag avoids doing an extra seek.
++** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might
++** run faster by avoiding an unnecessary seek on cursor P1.  However,
++** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior
++** seeks on the cursor or if the most recent seek used a key equivalent
++** to P2. 
+ **
+ ** This instruction only works for indices.  The equivalent instruction
+ ** for tables is OP_Insert.
+ */
++/* Opcode: SorterInsert P1 P2 * * *
++** Synopsis: key=r[P2]
++**
++** Register P2 holds an SQL index key made using the
++** MakeRecord instructions.  This opcode writes that key
++** into the sorter P1.  Data for the entry is nil.
++*/
+ case OP_SorterInsert:       /* in2 */
+ case OP_IdxInsert: {        /* in2 */
+   VdbeCursor *pC;
+-  BtCursor *pCrsr;
+-  int nKey;
+-  const char *zKey;
++  BtreePayload x;
+ 
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+@@ -75596,24 +87346,26 @@
+   assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) );
+   pIn2 = &aMem[pOp->p2];
+   assert( pIn2->flags & MEM_Blob );
+-  pCrsr = pC->pCursor;
+   if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
+-  assert( pCrsr!=0 );
++  assert( pC->eCurType==CURTYPE_BTREE || pOp->opcode==OP_SorterInsert );
+   assert( pC->isTable==0 );
+   rc = ExpandBlob(pIn2);
+-  if( rc==SQLITE_OK ){
+-    if( isSorter(pC) ){
+-      rc = sqlite3VdbeSorterWrite(pC, pIn2);
+-    }else{
+-      nKey = pIn2->n;
+-      zKey = pIn2->z;
+-      rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3, 
+-          ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
+-          );
+-      assert( pC->deferredMoveto==0 );
+-      pC->cacheStatus = CACHE_STALE;
+-    }
++  if( rc ) goto abort_due_to_error;
++  if( pOp->opcode==OP_SorterInsert ){
++    rc = sqlite3VdbeSorterWrite(pC, pIn2);
++  }else{
++    x.nKey = pIn2->n;
++    x.pKey = pIn2->z;
++    x.aMem = aMem + pOp->p3;
++    x.nMem = (u16)pOp->p4.i;
++    rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
++         (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), 
++        ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
++        );
++    assert( pC->deferredMoveto==0 );
++    pC->cacheStatus = CACHE_STALE;
+   }
++  if( rc) goto abort_due_to_error;
+   break;
+ }
+ 
+@@ -75631,29 +87383,49 @@
+   UnpackedRecord r;
+ 
+   assert( pOp->p3>0 );
+-  assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 );
++  assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 );
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+-  pCrsr = pC->pCursor;
++  assert( pC->eCurType==CURTYPE_BTREE );
++  pCrsr = pC->uc.pCursor;
+   assert( pCrsr!=0 );
+   assert( pOp->p5==0 );
+   r.pKeyInfo = pC->pKeyInfo;
+   r.nField = (u16)pOp->p3;
+   r.default_rc = 0;
+   r.aMem = &aMem[pOp->p2];
+-#ifdef SQLITE_DEBUG
+-  { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
+-#endif
+   rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
+-  if( rc==SQLITE_OK && res==0 ){
+-    rc = sqlite3BtreeDelete(pCrsr);
++  if( rc ) goto abort_due_to_error;
++  if( res==0 ){
++    rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
++    if( rc ) goto abort_due_to_error;
+   }
+   assert( pC->deferredMoveto==0 );
+   pC->cacheStatus = CACHE_STALE;
++  pC->seekResult = 0;
+   break;
+ }
+ 
++/* Opcode: DeferredSeek P1 * P3 P4 *
++** Synopsis: Move P3 to P1.rowid if needed
++**
++** P1 is an open index cursor and P3 is a cursor on the corresponding
++** table.  This opcode does a deferred seek of the P3 table cursor
++** to the row that corresponds to the current row of P1.
++**
++** This is a deferred seek.  Nothing actually happens until
++** the cursor is used to read a record.  That way, if no reads
++** occur, no unnecessary I/O happens.
++**
++** P4 may be an array of integers (type P4_INTARRAY) containing
++** one entry for each column in the P3 table.  If array entry a(i)
++** is non-zero, then reading column a(i)-1 from cursor P3 is 
++** equivalent to performing the deferred seek and then reading column i 
++** from P1.  This information is stored in P3 and used to redirect
++** reads against P3 over to P1, thus possibly avoiding the need to
++** seek and read cursor P3.
++*/
+ /* Opcode: IdxRowid P1 P2 * * *
+ ** Synopsis: r[P2]=rowid
+ **
+@@ -75663,36 +87435,56 @@
+ **
+ ** See also: Rowid, MakeRecord.
+ */
+-case OP_IdxRowid: {              /* out2 */
+-  BtCursor *pCrsr;
+-  VdbeCursor *pC;
+-  i64 rowid;
++case OP_DeferredSeek:
++case OP_IdxRowid: {           /* out2 */
++  VdbeCursor *pC;             /* The P1 index cursor */
++  VdbeCursor *pTabCur;        /* The P2 table cursor (OP_DeferredSeek only) */
++  i64 rowid;                  /* Rowid that P1 current points to */
+ 
+-  pOut = out2Prerelease(p, pOp);
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+-  pCrsr = pC->pCursor;
+-  assert( pCrsr!=0 );
+-  pOut->flags = MEM_Null;
++  assert( pC->eCurType==CURTYPE_BTREE );
++  assert( pC->uc.pCursor!=0 );
+   assert( pC->isTable==0 );
+   assert( pC->deferredMoveto==0 );
++  assert( !pC->nullRow || pOp->opcode==OP_IdxRowid );
+ 
+-  /* sqlite3VbeCursorRestore() can only fail if the record has been deleted
+-  ** out from under the cursor.  That will never happend for an IdxRowid
+-  ** opcode, hence the NEVER() arround the check of the return value.
+-  */
++  /* The IdxRowid and Seek opcodes are combined because of the commonality
++  ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */
+   rc = sqlite3VdbeCursorRestore(pC);
++
++  /* sqlite3VbeCursorRestore() can only fail if the record has been deleted
++  ** out from under the cursor.  That will never happens for an IdxRowid
++  ** or Seek opcode */
+   if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
+ 
+   if( !pC->nullRow ){
+     rowid = 0;  /* Not needed.  Only used to silence a warning. */
+-    rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
++    rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid);
+     if( rc!=SQLITE_OK ){
+       goto abort_due_to_error;
+     }
+-    pOut->u.i = rowid;
+-    pOut->flags = MEM_Int;
++    if( pOp->opcode==OP_DeferredSeek ){
++      assert( pOp->p3>=0 && pOp->p3<p->nCursor );
++      pTabCur = p->apCsr[pOp->p3];
++      assert( pTabCur!=0 );
++      assert( pTabCur->eCurType==CURTYPE_BTREE );
++      assert( pTabCur->uc.pCursor!=0 );
++      assert( pTabCur->isTable );
++      pTabCur->nullRow = 0;
++      pTabCur->movetoTarget = rowid;
++      pTabCur->deferredMoveto = 1;
++      assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
++      pTabCur->aAltMap = pOp->p4.ai;
++      pTabCur->pAltCursor = pC;
++    }else{
++      pOut = out2Prerelease(p, pOp);
++      pOut->u.i = rowid;
++    }
++  }else{
++    assert( pOp->opcode==OP_IdxRowid );
++    sqlite3VdbeMemSetNull(&aMem[pOp->p2]);
+   }
+   break;
+ }
+@@ -75753,7 +87545,8 @@
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+   assert( pC->isOrdered );
+-  assert( pC->pCursor!=0);
++  assert( pC->eCurType==CURTYPE_BTREE );
++  assert( pC->uc.pCursor!=0);
+   assert( pC->deferredMoveto==0 );
+   assert( pOp->p5==0 || pOp->p5==1 );
+   assert( pOp->p4type==P4_INT32 );
+@@ -75781,6 +87574,7 @@
+     res++;
+   }
+   VdbeBranchTaken(res>0,2);
++  if( rc ) goto abort_due_to_error;
+   if( res>0 ) goto jump_to_p2;
+   break;
+ }
+@@ -75798,10 +87592,17 @@
+ ** might be moved into the newly deleted root page in order to keep all
+ ** root pages contiguous at the beginning of the database.  The former
+ ** value of the root page that moved - its value before the move occurred -
+-** is stored in register P2.  If no page 
+-** movement was required (because the table being dropped was already 
+-** the last one in the database) then a zero is stored in register P2.
+-** If AUTOVACUUM is disabled then a zero is stored in register P2.
++** is stored in register P2. If no page movement was required (because the
++** table being dropped was already the last one in the database) then a 
++** zero is stored in register P2.  If AUTOVACUUM is disabled then a zero 
++** is stored in register P2.
++**
++** This opcode throws an error if there are any active reader VMs when
++** it is invoked. This is done to avoid the difficulty associated with 
++** updating existing cursors when a root page is moved in an AUTOVACUUM 
++** database. This error is thrown even if the database is not an AUTOVACUUM 
++** db in order to avoid introducing an incompatibility between autovacuum 
++** and non-autovacuum modes.
+ **
+ ** See also: Clear
+ */
+@@ -75810,11 +87611,13 @@
+   int iDb;
+ 
+   assert( p->readOnly==0 );
++  assert( pOp->p1>1 );
+   pOut = out2Prerelease(p, pOp);
+   pOut->flags = MEM_Null;
+   if( db->nVdbeRead > db->nVDestroy+1 ){
+     rc = SQLITE_LOCKED;
+     p->errorAction = OE_Abort;
++    goto abort_due_to_error;
+   }else{
+     iDb = pOp->p3;
+     assert( DbMaskTest(p->btreeMask, iDb) );
+@@ -75822,8 +87625,9 @@
+     rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
+     pOut->flags = MEM_Int;
+     pOut->u.i = iMoved;
++    if( rc ) goto abort_due_to_error;
+ #ifndef SQLITE_OMIT_AUTOVACUUM
+-    if( rc==SQLITE_OK && iMoved!=0 ){
++    if( iMoved!=0 ){
+       sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1);
+       /* All OP_Destroy operations occur on the same btree */
+       assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 );
+@@ -75869,6 +87673,7 @@
+       aMem[pOp->p3].u.i += nChange;
+     }
+   }
++  if( rc ) goto abort_due_to_error;
+   break;
+ }
+ 
+@@ -75886,11 +87691,13 @@
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+-  if( pC->pSorter ){
+-    sqlite3VdbeSorterReset(db, pC->pSorter);
++  if( isSorter(pC) ){
++    sqlite3VdbeSorterReset(db, pC->uc.pSorter);
+   }else{
++    assert( pC->eCurType==CURTYPE_BTREE );
+     assert( pC->isEphemeral );
+-    rc = sqlite3BtreeClearTableOfCursor(pC->pCursor);
++    rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor);
++    if( rc ) goto abort_due_to_error;
+   }
+   break;
+ }
+@@ -75939,10 +87746,23 @@
+     flags = BTREE_BLOBKEY;
+   }
+   rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
++  if( rc ) goto abort_due_to_error;
+   pOut->u.i = pgno;
+   break;
+ }
+ 
++/* Opcode: SqlExec * * * P4 *
++**
++** Run the SQL statement or statements specified in the P4 string.
++*/
++case OP_SqlExec: {
++  db->nSqlExec++;
++  rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0);
++  db->nSqlExec--;
++  if( rc ) goto abort_due_to_error;
++  break;
++}
++
+ /* Opcode: ParseSchema P1 * * P4 *
+ **
+ ** Read and parse all entries from the SQLITE_MASTER table of database P1
+@@ -75971,15 +87791,15 @@
+   assert( iDb>=0 && iDb<db->nDb );
+   assert( DbHasProperty(db, iDb, DB_SchemaLoaded) );
+   /* Used to be a conditional */ {
+-    zMaster = SCHEMA_TABLE(iDb);
++    zMaster = MASTER_NAME;
+     initData.db = db;
+     initData.iDb = pOp->p1;
+     initData.pzErrMsg = &p->zErrMsg;
+     zSql = sqlite3MPrintf(db,
+        "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
+-       db->aDb[iDb].zName, zMaster, pOp->p4.z);
++       db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
+     if( zSql==0 ){
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+     }else{
+       assert( db->init.busy==0 );
+       db->init.busy = 1;
+@@ -75987,13 +87807,16 @@
+       assert( !db->mallocFailed );
+       rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
+       if( rc==SQLITE_OK ) rc = initData.rc;
+-      sqlite3DbFree(db, zSql);
++      sqlite3DbFreeNN(db, zSql);
+       db->init.busy = 0;
+     }
+   }
+-  if( rc ) sqlite3ResetAllSchemasOfConnection(db);
+-  if( rc==SQLITE_NOMEM ){
+-    goto no_mem;
++  if( rc ){
++    sqlite3ResetAllSchemasOfConnection(db);
++    if( rc==SQLITE_NOMEM ){
++      goto no_mem;
++    }
++    goto abort_due_to_error;
+   }
+   break;  
+ }
+@@ -76008,6 +87831,7 @@
+ case OP_LoadAnalysis: {
+   assert( pOp->p1>=0 && pOp->p1<db->nDb );
+   rc = sqlite3AnalysisLoad(db, pOp->p1);
++  if( rc ) goto abort_due_to_error;
+   break;  
+ }
+ #endif /* !defined(SQLITE_OMIT_ANALYZE) */
+@@ -76053,20 +87877,19 @@
+ 
+ 
+ #ifndef SQLITE_OMIT_INTEGRITY_CHECK
+-/* Opcode: IntegrityCk P1 P2 P3 * P5
++/* Opcode: IntegrityCk P1 P2 P3 P4 P5
+ **
+ ** Do an analysis of the currently open database.  Store in
+ ** register P1 the text of an error message describing any problems.
+ ** If no problems are found, store a NULL in register P1.
+ **
+-** The register P3 contains the maximum number of allowed errors.
++** The register P3 contains one less than the maximum number of allowed errors.
+ ** At most reg(P3) errors will be reported.
+ ** In other words, the analysis stops as soon as reg(P1) errors are 
+ ** seen.  Reg(P1) is updated with the number of errors remaining.
+ **
+-** The root page numbers of all tables in the database are integer
+-** stored in reg(P1), reg(P1+1), reg(P1+2), ....  There are P2 tables
+-** total.
++** The root page numbers of all tables in the database are integers
++** stored in P4_INTARRAY argument.
+ **
+ ** If P5 is not zero, the check is done on the auxiliary database
+ ** file, not the main database file.
+@@ -76076,37 +87899,31 @@
+ case OP_IntegrityCk: {
+   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 */
+ 
+   assert( p->bIsReader );
+   nRoot = pOp->p2;
++  aRoot = pOp->p4.ai;
+   assert( nRoot>0 );
+-  aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) );
+-  if( aRoot==0 ) goto no_mem;
+-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
++  assert( aRoot[nRoot]==0 );
++  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+   pnErr = &aMem[pOp->p3];
+   assert( (pnErr->flags & MEM_Int)!=0 );
+   assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 );
+   pIn1 = &aMem[pOp->p1];
+-  for(j=0; j<nRoot; j++){
+-    aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]);
+-  }
+-  aRoot[j] = 0;
+   assert( pOp->p5<db->nDb );
+   assert( DbMaskTest(p->btreeMask, pOp->p5) );
+   z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
+-                                 (int)pnErr->u.i, &nErr);
+-  sqlite3DbFree(db, aRoot);
+-  pnErr->u.i -= nErr;
++                                 (int)pnErr->u.i+1, &nErr);
+   sqlite3VdbeMemSetNull(pIn1);
+   if( nErr==0 ){
+     assert( z==0 );
+   }else if( z==0 ){
+     goto no_mem;
+   }else{
++    pnErr->u.i -= nErr-1;
+     sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
+   }
+   UPDATE_MAX_BLOBSIZE(pIn1);
+@@ -76116,9 +87933,9 @@
+ #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+ 
+ /* Opcode: RowSetAdd P1 P2 * * *
+-** Synopsis:  rowset(P1)=r[P2]
++** Synopsis: rowset(P1)=r[P2]
+ **
+-** Insert the integer value held by register P2 into a boolean index
++** Insert the integer value held by register P2 into a RowSet object
+ ** held in register P1.
+ **
+ ** An assertion fails if P2 is not an integer.
+@@ -76136,10 +87953,11 @@
+ }
+ 
+ /* Opcode: RowSetRead P1 P2 P3 * *
+-** Synopsis:  r[P3]=rowset(P1)
++** Synopsis: r[P3]=rowset(P1)
+ **
+-** Extract the smallest value from boolean index P1 and put that value into
+-** register P3.  Or, if boolean index P1 is initially empty, leave P3
++** Extract the smallest value from the RowSet object in P1
++** and put that value into register P3.
++** Or, if RowSet object P1 is initially empty, leave P3
+ ** unchanged and jump to instruction P2.
+ */
+ case OP_RowSetRead: {       /* jump, in1, out3 */
+@@ -76170,15 +87988,14 @@
+ ** integer in P3 into the RowSet and continue on to the
+ ** next opcode.
+ **
+-** The RowSet object is optimized for the case where successive sets
+-** of integers, where each set contains no duplicates. Each set
+-** of values is identified by a unique P4 value. The first set
+-** must have P4==0, the final set P4=-1.  P4 must be either -1 or
+-** non-negative.  For non-negative values of P4 only the lower 4
+-** bits are significant.
++** The RowSet object is optimized for the case where sets of integers
++** are inserted in distinct phases, which each set contains no duplicates.
++** Each set is identified by a unique P4 value. The first set
++** must have P4==0, the final set must have P4==-1, and for all other sets
++** must have P4>0.
+ **
+ ** This allows optimizations: (a) when P4==0 there is no need to test
+-** the rowset object for P3, as it is guaranteed not to contain it,
++** the RowSet object for P3, as it is guaranteed not to contain it,
+ ** (b) when P4==-1 there is no need to insert the value, as it will
+ ** never be tested for, and (c) when a value that is part of set X is
+ ** inserted, there is no need to search to see if the same value was
+@@ -76266,8 +88083,8 @@
+ 
+   if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
+     rc = SQLITE_ERROR;
+-    sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion");
+-    break;
++    sqlite3VdbeError(p, "too many levels of trigger recursion");
++    goto abort_due_to_error;
+   }
+ 
+   /* Register pRt is used to store the memory required to save the state
+@@ -76281,10 +88098,12 @@
+     ** variable nMem (and later, VdbeFrame.nChildMem) to this value.
+     */
+     nMem = pProgram->nMem + pProgram->nCsr;
++    assert( nMem>0 );
++    if( pProgram->nCsr==0 ) nMem++;
+     nByte = ROUND8(sizeof(VdbeFrame))
+               + nMem * sizeof(Mem)
+-              + pProgram->nCsr * sizeof(VdbeCursor *)
+-              + pProgram->nOnce * sizeof(u8);
++              + pProgram->nCsr * sizeof(VdbeCursor*)
++              + (pProgram->nOp + 7)/8;
+     pFrame = sqlite3DbMallocZero(db, nByte);
+     if( !pFrame ){
+       goto no_mem;
+@@ -76304,8 +88123,6 @@
+     pFrame->aOp = p->aOp;
+     pFrame->nOp = p->nOp;
+     pFrame->token = pProgram->token;
+-    pFrame->aOnceFlag = p->aOnceFlag;
+-    pFrame->nOnceFlag = p->nOnceFlag;
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+     pFrame->anExec = p->anExec;
+ #endif
+@@ -76317,31 +88134,34 @@
+     }
+   }else{
+     pFrame = pRt->u.pFrame;
+-    assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
++    assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem 
++        || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) );
+     assert( pProgram->nCsr==pFrame->nChildCsr );
+     assert( (int)(pOp - aOp)==pFrame->pc );
+   }
+ 
+   p->nFrame++;
+   pFrame->pParent = p->pFrame;
+-  pFrame->lastRowid = lastRowid;
++  pFrame->lastRowid = db->lastRowid;
+   pFrame->nChange = p->nChange;
+   pFrame->nDbChange = p->db->nChange;
++  assert( pFrame->pAuxData==0 );
++  pFrame->pAuxData = p->pAuxData;
++  p->pAuxData = 0;
+   p->nChange = 0;
+   p->pFrame = pFrame;
+-  p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
++  p->aMem = aMem = VdbeFrameMem(pFrame);
+   p->nMem = pFrame->nChildMem;
+   p->nCursor = (u16)pFrame->nChildCsr;
+-  p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
++  p->apCsr = (VdbeCursor **)&aMem[p->nMem];
++  pFrame->aOnce = (u8*)&p->apCsr[pProgram->nCsr];
++  memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8);
+   p->aOp = aOp = pProgram->aOp;
+   p->nOp = pProgram->nOp;
+-  p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
+-  p->nOnceFlag = pProgram->nOnce;
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+   p->anExec = 0;
+ #endif
+   pOp = &aOp[-1];
+-  memset(p->aOnceFlag, 0, p->nOnceFlag);
+ 
+   break;
+ }
+@@ -76445,12 +88265,12 @@
+ }
+ #endif /* SQLITE_OMIT_AUTOINCREMENT */
+ 
+-/* Opcode: IfPos P1 P2 * * *
+-** Synopsis: if r[P1]>0 goto P2
++/* Opcode: IfPos P1 P2 P3 * *
++** Synopsis: if r[P1]>0 then r[P1]-=P3, goto P2
+ **
+ ** Register P1 must contain an integer.
+-** If the value of register P1 is 1 or greater, jump to P2 and
+-** add the literal value P3 to register P1.
++** If the value of register P1 is 1 or greater, subtract P3 from the
++** value in P1 and jump to P2.
+ **
+ ** If the initial value of register P1 is less than 1, then the
+ ** value is unchanged and control passes through to the next instruction.
+@@ -76459,38 +88279,68 @@
+   pIn1 = &aMem[pOp->p1];
+   assert( pIn1->flags&MEM_Int );
+   VdbeBranchTaken( pIn1->u.i>0, 2);
+-  if( pIn1->u.i>0 ) goto jump_to_p2;
++  if( pIn1->u.i>0 ){
++    pIn1->u.i -= pOp->p3;
++    goto jump_to_p2;
++  }
+   break;
+ }
+ 
+-/* Opcode: IfNeg P1 P2 P3 * *
+-** Synopsis: r[P1]+=P3, if r[P1]<0 goto P2
++/* Opcode: OffsetLimit P1 P2 P3 * *
++** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)
++**
++** This opcode performs a commonly used computation associated with
++** LIMIT and OFFSET process.  r[P1] holds the limit counter.  r[P3]
++** holds the offset counter.  The opcode computes the combined value
++** of the LIMIT and OFFSET and stores that value in r[P2].  The r[P2]
++** value computed is the total number of rows that will need to be
++** visited in order to complete the query.
++**
++** If r[P3] is zero or negative, that means there is no OFFSET
++** and r[P2] is set to be the value of the LIMIT, r[P1].
+ **
+-** Register P1 must contain an integer.  Add literal P3 to the value in
+-** register P1 then if the value of register P1 is less than zero, jump to P2. 
++** if r[P1] is zero or negative, that means there is no LIMIT
++** and r[P2] is set to -1. 
++**
++** Otherwise, r[P2] is set to the sum of r[P1] and r[P3].
+ */
+-case OP_IfNeg: {        /* jump, in1 */
++case OP_OffsetLimit: {    /* in1, out2, in3 */
++  i64 x;
+   pIn1 = &aMem[pOp->p1];
+-  assert( pIn1->flags&MEM_Int );
+-  pIn1->u.i += pOp->p3;
+-  VdbeBranchTaken(pIn1->u.i<0, 2);
+-  if( pIn1->u.i<0 ) goto jump_to_p2;
++  pIn3 = &aMem[pOp->p3];
++  pOut = out2Prerelease(p, pOp);
++  assert( pIn1->flags & MEM_Int );
++  assert( pIn3->flags & MEM_Int );
++  x = pIn1->u.i;
++  if( x<=0 || sqlite3AddInt64(&x, pIn3->u.i>0?pIn3->u.i:0) ){
++    /* If the LIMIT is less than or equal to zero, loop forever.  This
++    ** is documented.  But also, if the LIMIT+OFFSET exceeds 2^63 then
++    ** also loop forever.  This is undocumented.  In fact, one could argue
++    ** that the loop should terminate.  But assuming 1 billion iterations
++    ** per second (far exceeding the capabilities of any current hardware)
++    ** it would take nearly 300 years to actually reach the limit.  So
++    ** looping forever is a reasonable approximation. */
++    pOut->u.i = -1;
++  }else{
++    pOut->u.i = x;
++  }
+   break;
+ }
+ 
+-/* Opcode: IfNotZero P1 P2 P3 * *
+-** Synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2
++/* Opcode: IfNotZero P1 P2 * * *
++** Synopsis: if r[P1]!=0 then r[P1]--, goto P2
+ **
+ ** Register P1 must contain an integer.  If the content of register P1 is
+-** initially nonzero, then add P3 to P1 and jump to P2.  If register P1 is
+-** initially zero, leave it unchanged and fall through.
++** initially greater than zero, then decrement the value in register P1.
++** If it is non-zero (negative or positive) and then also jump to P2.  
++** If register P1 is initially zero, leave it unchanged and fall through.
+ */
+ case OP_IfNotZero: {        /* jump, in1 */
+   pIn1 = &aMem[pOp->p1];
+   assert( pIn1->flags&MEM_Int );
+   VdbeBranchTaken(pIn1->u.i<0, 2);
+   if( pIn1->u.i ){
+-     pIn1->u.i += pOp->p3;
++     if( pIn1->u.i>0 ) pIn1->u.i--;
+      goto jump_to_p2;
+   }
+   break;
+@@ -76499,85 +88349,115 @@
+ /* Opcode: DecrJumpZero P1 P2 * * *
+ ** Synopsis: if (--r[P1])==0 goto P2
+ **
+-** Register P1 must hold an integer.  Decrement the value in register P1
+-** then jump to P2 if the new value is exactly zero.
++** Register P1 must hold an integer.  Decrement the value in P1
++** and jump to P2 if the new value is exactly zero.
+ */
+ case OP_DecrJumpZero: {      /* jump, in1 */
+   pIn1 = &aMem[pOp->p1];
+   assert( pIn1->flags&MEM_Int );
+-  pIn1->u.i--;
++  if( pIn1->u.i>SMALLEST_INT64 ) pIn1->u.i--;
+   VdbeBranchTaken(pIn1->u.i==0, 2);
+   if( pIn1->u.i==0 ) goto jump_to_p2;
+   break;
+ }
+ 
+ 
+-/* Opcode: JumpZeroIncr P1 P2 * * *
+-** Synopsis: if (r[P1]++)==0 ) goto P2
++/* Opcode: AggStep0 * P2 P3 P4 P5
++** Synopsis: accum=r[P3] step(r[P2@P5])
++**
++** Execute the step function for an aggregate.  The
++** function has P5 arguments.   P4 is a pointer to the FuncDef
++** structure that specifies the function.  Register P3 is the
++** accumulator.
+ **
+-** The register P1 must contain an integer.  If register P1 is initially
+-** zero, then jump to P2.  Increment register P1 regardless of whether or
+-** not the jump is taken.
++** The P5 arguments are taken from register P2 and its
++** successors.
+ */
+-case OP_JumpZeroIncr: {        /* jump, in1 */
+-  pIn1 = &aMem[pOp->p1];
+-  assert( pIn1->flags&MEM_Int );
+-  VdbeBranchTaken(pIn1->u.i==0, 2);
+-  if( (pIn1->u.i++)==0 ) goto jump_to_p2;
+-  break;
+-}
+-
+ /* Opcode: AggStep * P2 P3 P4 P5
+ ** Synopsis: accum=r[P3] step(r[P2@P5])
+ **
+ ** Execute the step function for an aggregate.  The
+-** function has P5 arguments.   P4 is a pointer to the FuncDef
+-** structure that specifies the function.  Use register
+-** P3 as the accumulator.
++** function has P5 arguments.   P4 is a pointer to an sqlite3_context
++** object that is used to run the function.  Register P3 is
++** as the accumulator.
+ **
+ ** The P5 arguments are taken from register P2 and its
+ ** successors.
++**
++** This opcode is initially coded as OP_AggStep0.  On first evaluation,
++** the FuncDef stored in P4 is converted into an sqlite3_context and
++** the opcode is changed.  In this way, the initialization of the
++** sqlite3_context only happens once, instead of on each call to the
++** step function.
+ */
+-case OP_AggStep: {
++case OP_AggStep0: {
+   int n;
++  sqlite3_context *pCtx;
++
++  assert( pOp->p4type==P4_FUNCDEF );
++  n = pOp->p5;
++  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
++  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
++  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
++  pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
++  if( pCtx==0 ) goto no_mem;
++  pCtx->pMem = 0;
++  pCtx->pFunc = pOp->p4.pFunc;
++  pCtx->iOp = (int)(pOp - aOp);
++  pCtx->pVdbe = p;
++  pCtx->argc = n;
++  pOp->p4type = P4_FUNCCTX;
++  pOp->p4.pCtx = pCtx;
++  pOp->opcode = OP_AggStep;
++  /* Fall through into OP_AggStep */
++}
++case OP_AggStep: {
+   int i;
++  sqlite3_context *pCtx;
+   Mem *pMem;
+-  Mem *pRec;
+   Mem t;
+-  sqlite3_context ctx;
+-  sqlite3_value **apVal;
+ 
+-  n = pOp->p5;
+-  assert( n>=0 );
+-  pRec = &aMem[pOp->p2];
+-  apVal = p->apArg;
+-  assert( apVal || n==0 );
+-  for(i=0; i<n; i++, pRec++){
+-    assert( memIsValid(pRec) );
+-    apVal[i] = pRec;
+-    memAboutToChange(p, pRec);
++  assert( pOp->p4type==P4_FUNCCTX );
++  pCtx = pOp->p4.pCtx;
++  pMem = &aMem[pOp->p3];
++
++  /* If this function is inside of a trigger, the register array in aMem[]
++  ** might change from one evaluation to the next.  The next block of code
++  ** checks to see if the register array has changed, and if so it
++  ** reinitializes the relavant parts of the sqlite3_context object */
++  if( pCtx->pMem != pMem ){
++    pCtx->pMem = pMem;
++    for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
++  }
++
++#ifdef SQLITE_DEBUG
++  for(i=0; i<pCtx->argc; i++){
++    assert( memIsValid(pCtx->argv[i]) );
++    REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
+   }
+-  ctx.pFunc = pOp->p4.pFunc;
+-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+-  ctx.pMem = pMem = &aMem[pOp->p3];
++#endif
++
+   pMem->n++;
+   sqlite3VdbeMemInit(&t, db, MEM_Null);
+-  ctx.pOut = &t;
+-  ctx.isError = 0;
+-  ctx.pVdbe = p;
+-  ctx.iOp = (int)(pOp - aOp);
+-  ctx.skipFlag = 0;
+-  (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
+-  if( ctx.isError ){
+-    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
+-    rc = ctx.isError;
++  pCtx->pOut = &t;
++  pCtx->fErrorOrAux = 0;
++  pCtx->skipFlag = 0;
++  (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
++  if( pCtx->fErrorOrAux ){
++    if( pCtx->isError ){
++      sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
++      rc = pCtx->isError;
++    }
++    sqlite3VdbeMemRelease(&t);
++    if( rc ) goto abort_due_to_error;
++  }else{
++    assert( t.flags==MEM_Null );
+   }
+-  if( ctx.skipFlag ){
++  if( pCtx->skipFlag ){
+     assert( pOp[-1].opcode==OP_CollSeq );
+     i = pOp[-1].p1;
+     if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
+   }
+-  sqlite3VdbeMemRelease(&t);
+   break;
+ }
+ 
+@@ -76596,12 +88476,13 @@
+ */
+ case OP_AggFinal: {
+   Mem *pMem;
+-  assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
++  assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
+   pMem = &aMem[pOp->p1];
+   assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
+   rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
+   if( rc ){
+-    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem));
++    sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
++    goto abort_due_to_error;
+   }
+   sqlite3VdbeChangeEncoding(pMem, encoding);
+   UPDATE_MAX_BLOBSIZE(pMem);
+@@ -76637,7 +88518,8 @@
+        || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
+   );
+   rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
+-  if( rc==SQLITE_BUSY ){
++  if( rc ){
++    if( rc!=SQLITE_BUSY ) goto abort_due_to_error;
+     rc = SQLITE_OK;
+     aRes[0] = 1;
+   }
+@@ -76706,11 +88588,11 @@
+   ){
+     if( !db->autoCommit || db->nVdbeRead>1 ){
+       rc = SQLITE_ERROR;
+-      sqlite3SetString(&p->zErrMsg, db, 
++      sqlite3VdbeError(p,
+           "cannot change %s wal mode from within a transaction",
+           (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
+       );
+-      break;
++      goto abort_due_to_error;
+     }else{
+  
+       if( eOld==PAGER_JOURNALMODE_WAL ){
+@@ -76719,7 +88601,7 @@
+         ** file. An EXCLUSIVE lock may still be held on the database file 
+         ** after a successful return. 
+         */
+-        rc = sqlite3PagerCloseWal(pPager);
++        rc = sqlite3PagerCloseWal(pPager, db);
+         if( rc==SQLITE_OK ){
+           sqlite3PagerSetJournalMode(pPager, eNew);
+         }
+@@ -76740,9 +88622,7 @@
+   }
+ #endif /* ifndef SQLITE_OMIT_WAL */
+ 
+-  if( rc ){
+-    eNew = eOld;
+-  }
++  if( rc ) eNew = eOld;
+   eNew = sqlite3PagerSetJournalMode(pPager, eNew);
+ 
+   pOut->flags = MEM_Str|MEM_Static|MEM_Term;
+@@ -76750,20 +88630,21 @@
+   pOut->n = sqlite3Strlen30(pOut->z);
+   pOut->enc = SQLITE_UTF8;
+   sqlite3VdbeChangeEncoding(pOut, encoding);
++  if( rc ) goto abort_due_to_error;
+   break;
+ };
+ #endif /* SQLITE_OMIT_PRAGMA */
+ 
+ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
+-/* Opcode: Vacuum * * * * *
++/* Opcode: Vacuum P1 * * * *
+ **
+-** Vacuum the entire database.  This opcode will cause other virtual
+-** machines to be created and run.  It may not be called from within
+-** a transaction.
++** Vacuum the entire database P1.  P1 is 0 for "main", and 2 or more
++** for an attached database.  The "temp" database may not be vacuumed.
+ */
+ case OP_Vacuum: {
+   assert( p->readOnly==0 );
+-  rc = sqlite3RunVacuum(&p->zErrMsg, db);
++  rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1);
++  if( rc ) goto abort_due_to_error;
+   break;
+ }
+ #endif
+@@ -76784,7 +88665,8 @@
+   pBt = db->aDb[pOp->p1].pBt;
+   rc = sqlite3BtreeIncrVacuum(pBt);
+   VdbeBranchTaken(rc==SQLITE_DONE,2);
+-  if( rc==SQLITE_DONE ){
++  if( rc ){
++    if( rc!=SQLITE_DONE ) goto abort_due_to_error;
+     rc = SQLITE_OK;
+     goto jump_to_p2;
+   }
+@@ -76829,15 +88711,18 @@
+ */
+ case OP_TableLock: {
+   u8 isWriteLock = (u8)pOp->p3;
+-  if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){
++  if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommit) ){
+     int p1 = pOp->p1; 
+     assert( p1>=0 && p1<db->nDb );
+     assert( DbMaskTest(p->btreeMask, p1) );
+     assert( isWriteLock==0 || isWriteLock==1 );
+     rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
+-    if( (rc&0xFF)==SQLITE_LOCKED ){
+-      const char *z = pOp->p4.z;
+-      sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
++    if( rc ){
++      if( (rc&0xFF)==SQLITE_LOCKED ){
++        const char *z = pOp->p4.z;
++        sqlite3VdbeError(p, "database table is locked: %s", z);
++      }
++      goto abort_due_to_error;
+     }
+   }
+   break;
+@@ -76859,6 +88744,7 @@
+   pVTab = pOp->p4.pVtab;
+   rc = sqlite3VtabBegin(db, pVTab);
+   if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
++  if( rc ) goto abort_due_to_error;
+   break;
+ }
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+@@ -76887,6 +88773,7 @@
+     rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg);
+   }
+   sqlite3VdbeMemRelease(&sMem);
++  if( rc ) goto abort_due_to_error;
+   break;
+ }
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+@@ -76901,6 +88788,7 @@
+   db->nVDestroy++;
+   rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
+   db->nVDestroy--;
++  if( rc ) goto abort_due_to_error;
+   break;
+ }
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+@@ -76914,35 +88802,35 @@
+ */
+ case OP_VOpen: {
+   VdbeCursor *pCur;
+-  sqlite3_vtab_cursor *pVtabCursor;
++  sqlite3_vtab_cursor *pVCur;
+   sqlite3_vtab *pVtab;
+   const sqlite3_module *pModule;
+ 
+   assert( p->bIsReader );
+   pCur = 0;
+-  pVtabCursor = 0;
++  pVCur = 0;
+   pVtab = pOp->p4.pVtab->pVtab;
+   if( pVtab==0 || NEVER(pVtab->pModule==0) ){
+     rc = SQLITE_LOCKED;
+-    break;
++    goto abort_due_to_error;
+   }
+   pModule = pVtab->pModule;
+-  rc = pModule->xOpen(pVtab, &pVtabCursor);
++  rc = pModule->xOpen(pVtab, &pVCur);
+   sqlite3VtabImportErrmsg(p, pVtab);
+-  if( SQLITE_OK==rc ){
+-    /* Initialize sqlite3_vtab_cursor base class */
+-    pVtabCursor->pVtab = pVtab;
++  if( rc ) goto abort_due_to_error;
+ 
+-    /* Initialize vdbe cursor object */
+-    pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
+-    if( pCur ){
+-      pCur->pVtabCursor = pVtabCursor;
+-      pVtab->nRef++;
+-    }else{
+-      assert( db->mallocFailed );
+-      pModule->xClose(pVtabCursor);
+-      goto no_mem;
+-    }
++  /* Initialize sqlite3_vtab_cursor base class */
++  pVCur->pVtab = pVtab;
++
++  /* Initialize vdbe cursor object */
++  pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB);
++  if( pCur ){
++    pCur->uc.pVCur = pVCur;
++    pVtab->nRef++;
++  }else{
++    assert( db->mallocFailed );
++    pModule->xClose(pVCur);
++    goto no_mem;
+   }
+   break;
+ }
+@@ -76974,7 +88862,7 @@
+   const sqlite3_module *pModule;
+   Mem *pQuery;
+   Mem *pArgc;
+-  sqlite3_vtab_cursor *pVtabCursor;
++  sqlite3_vtab_cursor *pVCur;
+   sqlite3_vtab *pVtab;
+   VdbeCursor *pCur;
+   int res;
+@@ -76986,9 +88874,9 @@
+   pCur = p->apCsr[pOp->p1];
+   assert( memIsValid(pQuery) );
+   REGISTER_TRACE(pOp->p3, pQuery);
+-  assert( pCur->pVtabCursor );
+-  pVtabCursor = pCur->pVtabCursor;
+-  pVtab = pVtabCursor->pVtab;
++  assert( pCur->eCurType==CURTYPE_VTAB );
++  pVCur = pCur->uc.pVCur;
++  pVtab = pVCur->pVtab;
+   pModule = pVtab->pModule;
+ 
+   /* Grab the index number and argc parameters */
+@@ -77002,11 +88890,10 @@
+   for(i = 0; i<nArg; i++){
+     apArg[i] = &pArgc[i+1];
+   }
+-  rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
++  rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg);
+   sqlite3VtabImportErrmsg(p, pVtab);
+-  if( rc==SQLITE_OK ){
+-    res = pModule->xEof(pVtabCursor);
+-  }
++  if( rc ) goto abort_due_to_error;
++  res = pModule->xEof(pVCur);
+   pCur->nullRow = 0;
+   VdbeBranchTaken(res!=0,2);
+   if( res ) goto jump_to_p2;
+@@ -77029,21 +88916,21 @@
+   sqlite3_context sContext;
+ 
+   VdbeCursor *pCur = p->apCsr[pOp->p1];
+-  assert( pCur->pVtabCursor );
+-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
++  assert( pCur->eCurType==CURTYPE_VTAB );
++  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+   pDest = &aMem[pOp->p3];
+   memAboutToChange(p, pDest);
+   if( pCur->nullRow ){
+     sqlite3VdbeMemSetNull(pDest);
+     break;
+   }
+-  pVtab = pCur->pVtabCursor->pVtab;
++  pVtab = pCur->uc.pVCur->pVtab;
+   pModule = pVtab->pModule;
+   assert( pModule->xColumn );
+   memset(&sContext, 0, sizeof(sContext));
+   sContext.pOut = pDest;
+   MemSetTypeFlag(pDest, MEM_Null);
+-  rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
++  rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2);
+   sqlite3VtabImportErrmsg(p, pVtab);
+   if( sContext.isError ){
+     rc = sContext.isError;
+@@ -77055,6 +88942,7 @@
+   if( sqlite3VdbeMemTooBig(pDest) ){
+     goto too_big;
+   }
++  if( rc ) goto abort_due_to_error;
+   break;
+ }
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+@@ -77074,11 +88962,11 @@
+ 
+   res = 0;
+   pCur = p->apCsr[pOp->p1];
+-  assert( pCur->pVtabCursor );
++  assert( pCur->eCurType==CURTYPE_VTAB );
+   if( pCur->nullRow ){
+     break;
+   }
+-  pVtab = pCur->pVtabCursor->pVtab;
++  pVtab = pCur->uc.pVCur->pVtab;
+   pModule = pVtab->pModule;
+   assert( pModule->xNext );
+ 
+@@ -77088,11 +88976,10 @@
+   ** data is available) and the error code returned when xColumn or
+   ** some other method is next invoked on the save virtual table cursor.
+   */
+-  rc = pModule->xNext(pCur->pVtabCursor);
++  rc = pModule->xNext(pCur->uc.pVCur);
+   sqlite3VtabImportErrmsg(p, pVtab);
+-  if( rc==SQLITE_OK ){
+-    res = pModule->xEof(pCur->pVtabCursor);
+-  }
++  if( rc ) goto abort_due_to_error;
++  res = pModule->xEof(pCur->uc.pVCur);
+   VdbeBranchTaken(!res,2);
+   if( !res ){
+     /* If there is data, jump to P2 */
+@@ -77124,11 +89011,11 @@
+   testcase( pName->enc==SQLITE_UTF16BE );
+   testcase( pName->enc==SQLITE_UTF16LE );
+   rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
+-  if( rc==SQLITE_OK ){
+-    rc = pVtab->pModule->xRename(pVtab, pName->z);
+-    sqlite3VtabImportErrmsg(p, pVtab);
+-    p->expired = 0;
+-  }
++  if( rc ) goto abort_due_to_error;
++  rc = pVtab->pModule->xRename(pVtab, pName->z);
++  sqlite3VtabImportErrmsg(p, pVtab);
++  p->expired = 0;
++  if( rc ) goto abort_due_to_error;
+   break;
+ }
+ #endif
+@@ -77177,7 +89064,7 @@
+   pVtab = pOp->p4.pVtab->pVtab;
+   if( pVtab==0 || NEVER(pVtab->pModule==0) ){
+     rc = SQLITE_LOCKED;
+-    break;
++    goto abort_due_to_error;
+   }
+   pModule = pVtab->pModule;
+   nArg = pOp->p2;
+@@ -77198,7 +89085,7 @@
+     sqlite3VtabImportErrmsg(p, pVtab);
+     if( rc==SQLITE_OK && pOp->p1 ){
+       assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
+-      db->lastRowid = lastRowid = rowid;
++      db->lastRowid = rowid;
+     }
+     if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
+       if( pOp->p5==OE_Ignore ){
+@@ -77209,6 +89096,7 @@
+     }else{
+       p->nChange++;
+     }
++    if( rc ) goto abort_due_to_error;
+   }
+   break;
+ }
+@@ -77252,9 +89140,124 @@
+ }
+ #endif
+ 
++/* Opcode: Function0 P1 P2 P3 P4 P5
++** Synopsis: r[P3]=func(r[P2@P5])
++**
++** Invoke a user function (P4 is a pointer to a FuncDef object that
++** defines the function) with P5 arguments taken from register P2 and
++** successors.  The result of the function is stored in register P3.
++** Register P3 must not be one of the function inputs.
++**
++** P1 is a 32-bit bitmask indicating whether or not each argument to the 
++** function was determined to be constant at compile time. If the first
++** argument was constant then bit 0 of P1 is set. This is used to determine
++** whether meta data associated with a user function argument using the
++** sqlite3_set_auxdata() API may be safely retained until the next
++** invocation of this opcode.
++**
++** See also: Function, AggStep, AggFinal
++*/
++/* Opcode: Function P1 P2 P3 P4 P5
++** Synopsis: r[P3]=func(r[P2@P5])
++**
++** Invoke a user function (P4 is a pointer to an sqlite3_context object that
++** contains a pointer to the function to be run) with P5 arguments taken
++** from register P2 and successors.  The result of the function is stored
++** in register P3.  Register P3 must not be one of the function inputs.
++**
++** P1 is a 32-bit bitmask indicating whether or not each argument to the 
++** function was determined to be constant at compile time. If the first
++** argument was constant then bit 0 of P1 is set. This is used to determine
++** whether meta data associated with a user function argument using the
++** sqlite3_set_auxdata() API may be safely retained until the next
++** invocation of this opcode.
++**
++** SQL functions are initially coded as OP_Function0 with P4 pointing
++** to a FuncDef object.  But on first evaluation, the P4 operand is
++** automatically converted into an sqlite3_context object and the operation
++** changed to this OP_Function opcode.  In this way, the initialization of
++** the sqlite3_context object occurs only once, rather than once for each
++** evaluation of the function.
++**
++** See also: Function0, AggStep, AggFinal
++*/
++case OP_PureFunc0:
++case OP_Function0: {
++  int n;
++  sqlite3_context *pCtx;
++
++  assert( pOp->p4type==P4_FUNCDEF );
++  n = pOp->p5;
++  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
++  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
++  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
++  pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
++  if( pCtx==0 ) goto no_mem;
++  pCtx->pOut = 0;
++  pCtx->pFunc = pOp->p4.pFunc;
++  pCtx->iOp = (int)(pOp - aOp);
++  pCtx->pVdbe = p;
++  pCtx->argc = n;
++  pOp->p4type = P4_FUNCCTX;
++  pOp->p4.pCtx = pCtx;
++  assert( OP_PureFunc == OP_PureFunc0+2 );
++  assert( OP_Function == OP_Function0+2 );
++  pOp->opcode += 2;
++  /* Fall through into OP_Function */
++}
++case OP_PureFunc:
++case OP_Function: {
++  int i;
++  sqlite3_context *pCtx;
++
++  assert( pOp->p4type==P4_FUNCCTX );
++  pCtx = pOp->p4.pCtx;
++
++  /* If this function is inside of a trigger, the register array in aMem[]
++  ** might change from one evaluation to the next.  The next block of code
++  ** checks to see if the register array has changed, and if so it
++  ** reinitializes the relavant parts of the sqlite3_context object */
++  pOut = &aMem[pOp->p3];
++  if( pCtx->pOut != pOut ){
++    pCtx->pOut = pOut;
++    for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
++  }
++
++  memAboutToChange(p, pOut);
++#ifdef SQLITE_DEBUG
++  for(i=0; i<pCtx->argc; i++){
++    assert( memIsValid(pCtx->argv[i]) );
++    REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
++  }
++#endif
++  MemSetTypeFlag(pOut, MEM_Null);
++  pCtx->fErrorOrAux = 0;
++  (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
++
++  /* If the function returned an error, throw an exception */
++  if( pCtx->fErrorOrAux ){
++    if( pCtx->isError ){
++      sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
++      rc = pCtx->isError;
++    }
++    sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
++    if( rc ) goto abort_due_to_error;
++  }
++
++  /* Copy the result of the function into register P3 */
++  if( pOut->flags & (MEM_Str|MEM_Blob) ){
++    sqlite3VdbeChangeEncoding(pOut, encoding);
++    if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
++  }
++
++  REGISTER_TRACE(pOp->p3, pOut);
++  UPDATE_MAX_BLOBSIZE(pOut);
++  break;
++}
++
+ 
+-/* Opcode: Init * P2 * P4 *
+-** Synopsis:  Start at P2
++/* Opcode: Init P1 P2 * P4 *
++** Synopsis: Start at P2
+ **
+ ** Programs contain a single instance of this opcode as the very first
+ ** opcode.
+@@ -77264,27 +89267,54 @@
+ ** Or if P4 is blank, use the string returned by sqlite3_sql().
+ **
+ ** If P2 is not zero, jump to instruction P2.
++**
++** Increment the value of P1 so that OP_Once opcodes will jump the
++** first time they are evaluated for this run.
+ */
+ case OP_Init: {          /* jump */
+   char *zTrace;
+-  char *z;
++  int i;
++
++  /* If the P4 argument is not NULL, then it must be an SQL comment string.
++  ** The "--" string is broken up to prevent false-positives with srcck1.c.
++  **
++  ** This assert() provides evidence for:
++  ** EVIDENCE-OF: R-50676-09860 The callback can compute the same text that
++  ** would have been returned by the legacy sqlite3_trace() interface by
++  ** using the X argument when X begins with "--" and invoking
++  ** sqlite3_expanded_sql(P) otherwise.
++  */
++  assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 );
++  assert( pOp==p->aOp );  /* Always instruction 0 */
+ 
+ #ifndef SQLITE_OMIT_TRACE
+-  if( db->xTrace
++  if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
+    && !p->doingRerun
+    && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
+   ){
+-    z = sqlite3VdbeExpandSql(p, zTrace);
+-    db->xTrace(db->pTraceArg, z);
+-    sqlite3DbFree(db, z);
++#ifndef SQLITE_OMIT_DEPRECATED
++    if( db->mTrace & SQLITE_TRACE_LEGACY ){
++      void (*x)(void*,const char*) = (void(*)(void*,const char*))db->xTrace;
++      char *z = sqlite3VdbeExpandSql(p, zTrace);
++      x(db->pTraceArg, z);
++      sqlite3_free(z);
++    }else
++#endif
++    if( db->nVdbeExec>1 ){
++      char *z = sqlite3MPrintf(db, "-- %s", zTrace);
++      (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, z);
++      sqlite3DbFree(db, z);
++    }else{
++      (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace);
++    }
+   }
+ #ifdef SQLITE_USE_FCNTL_TRACE
+   zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
+   if( zTrace ){
+-    int i;
+-    for(i=0; i<db->nDb; i++){
+-      if( DbMaskTest(p->btreeMask, i)==0 ) continue;
+-      sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace);
++    int j;
++    for(j=0; j<db->nDb; j++){
++      if( DbMaskTest(p->btreeMask, j)==0 ) continue;
++      sqlite3_file_control(db, db->aDb[j].zDbSName, SQLITE_FCNTL_TRACE, zTrace);
+     }
+   }
+ #endif /* SQLITE_USE_FCNTL_TRACE */
+@@ -77296,10 +89326,40 @@
+   }
+ #endif /* SQLITE_DEBUG */
+ #endif /* SQLITE_OMIT_TRACE */
+-  if( pOp->p2 ) goto jump_to_p2;
+-  break;
++  assert( pOp->p2>0 );
++  if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){
++    for(i=1; i<p->nOp; i++){
++      if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0;
++    }
++    pOp->p1 = 0;
++  }
++  pOp->p1++;
++  p->aCounter[SQLITE_STMTSTATUS_RUN]++;
++  goto jump_to_p2;
+ }
+ 
++#ifdef SQLITE_ENABLE_CURSOR_HINTS
++/* Opcode: CursorHint P1 * * P4 *
++**
++** Provide a hint to cursor P1 that it only needs to return rows that
++** satisfy the Expr in P4.  TK_REGISTER terms in the P4 expression refer
++** to values currently held in registers.  TK_COLUMN terms in the P4
++** expression refer to columns in the b-tree to which cursor P1 is pointing.
++*/
++case OP_CursorHint: {
++  VdbeCursor *pC;
++
++  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
++  assert( pOp->p4type==P4_EXPR );
++  pC = p->apCsr[pOp->p1];
++  if( pC ){
++    assert( pC->eCurType==CURTYPE_BTREE );
++    sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE,
++                           pOp->p4.pExpr, aMem);
++  }
++  break;
++}
++#endif /* SQLITE_ENABLE_CURSOR_HINTS */
+ 
+ /* Opcode: Noop * * * * *
+ **
+@@ -77343,11 +89403,12 @@
+ 
+ #ifdef SQLITE_DEBUG
+     if( db->flags & SQLITE_VdbeTrace ){
++      u8 opProperty = sqlite3OpcodeProperty[pOrigOp->opcode];
+       if( rc!=0 ) printf("rc=%d\n",rc);
+-      if( pOrigOp->opflags & (OPFLG_OUT2) ){
++      if( opProperty & (OPFLG_OUT2) ){
+         registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
+       }
+-      if( pOrigOp->opflags & OPFLG_OUT3 ){
++      if( opProperty & OPFLG_OUT3 ){
+         registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
+       }
+     }
+@@ -77358,14 +89419,19 @@
+   /* If we reach this point, it means that execution is finished with
+   ** an error of some kind.
+   */
+-vdbe_error_halt:
++abort_due_to_error:
++  if( db->mallocFailed ) rc = SQLITE_NOMEM_BKPT;
+   assert( rc );
++  if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
++    sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
++  }
+   p->rc = rc;
++  sqlite3SystemError(db, rc);
+   testcase( sqlite3GlobalConfig.xLog!=0 );
+   sqlite3_log(rc, "statement aborts at %d: [%s] %s", 
+                    (int)(pOp - aOp), p->zSql, p->zErrMsg);
+   sqlite3VdbeHalt(p);
+-  if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
++  if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
+   rc = SQLITE_ERROR;
+   if( resetSchemaOnFault>0 ){
+     sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
+@@ -77375,48 +89441,39 @@
+   ** release the mutexes on btrees that were acquired at the
+   ** top. */
+ vdbe_return:
+-  db->lastRowid = lastRowid;
+   testcase( nVmStep>0 );
+   p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
+   sqlite3VdbeLeave(p);
++  assert( rc!=SQLITE_OK || nExtraDelete==0 
++       || sqlite3_strlike("DELETE%",p->zSql,0)!=0 
++  );
+   return rc;
+ 
+   /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
+   ** is encountered.
+   */
+ too_big:
+-  sqlite3SetString(&p->zErrMsg, db, "string or blob too big");
++  sqlite3VdbeError(p, "string or blob too big");
+   rc = SQLITE_TOOBIG;
+-  goto vdbe_error_halt;
++  goto abort_due_to_error;
+ 
+   /* Jump to here if a malloc() fails.
+   */
+ no_mem:
+-  db->mallocFailed = 1;
+-  sqlite3SetString(&p->zErrMsg, db, "out of memory");
+-  rc = SQLITE_NOMEM;
+-  goto vdbe_error_halt;
+-
+-  /* Jump to here for any other kind of fatal error.  The "rc" variable
+-  ** should hold the error number.
+-  */
+-abort_due_to_error:
+-  assert( p->zErrMsg==0 );
+-  if( db->mallocFailed ) rc = SQLITE_NOMEM;
+-  if( rc!=SQLITE_IOERR_NOMEM ){
+-    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
+-  }
+-  goto vdbe_error_halt;
++  sqlite3OomFault(db);
++  sqlite3VdbeError(p, "out of memory");
++  rc = SQLITE_NOMEM_BKPT;
++  goto abort_due_to_error;
+ 
+   /* Jump to here if the sqlite3_interrupt() API sets the interrupt
+   ** flag.
+   */
+ abort_due_to_interrupt:
+   assert( db->u1.isInterrupted );
+-  rc = SQLITE_INTERRUPT;
++  rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
+   p->rc = rc;
+-  sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
+-  goto vdbe_error_halt;
++  sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
++  goto abort_due_to_error;
+ }
+ 
+ 
+@@ -77437,6 +89494,8 @@
+ ** This file contains code used to implement incremental BLOB I/O.
+ */
+ 
++/* #include "sqliteInt.h" */
++/* #include "vdbeInt.h" */
+ 
+ #ifndef SQLITE_OMIT_INCRBLOB
+ 
+@@ -77445,13 +89504,14 @@
+ */
+ typedef struct Incrblob Incrblob;
+ struct Incrblob {
+-  int flags;              /* Copy of "flags" passed to sqlite3_blob_open() */
+   int nByte;              /* Size of open blob, in bytes */
+   int iOffset;            /* Byte offset of blob in cursor data */
+-  int iCol;               /* Table column this handle is open on */
++  u16 iCol;               /* Table column this handle is open on */
+   BtCursor *pCsr;         /* Cursor pointing at blob row */
+   sqlite3_stmt *pStmt;    /* Statement holding cursor open */
+   sqlite3 *db;            /* The associated database */
++  char *zDb;              /* Database name */
++  Table *pTab;            /* Table object */
+ };
+ 
+ 
+@@ -77477,17 +89537,27 @@
+   char *zErr = 0;                 /* Error message */
+   Vdbe *v = (Vdbe *)p->pStmt;
+ 
+-  /* Set the value of the SQL statements only variable to integer iRow. 
+-  ** This is done directly instead of using sqlite3_bind_int64() to avoid 
+-  ** triggering asserts related to mutexes.
++  /* Set the value of register r[1] in the SQL statement to integer iRow. 
++  ** This is done directly as a performance optimization
+   */
+-  assert( v->aVar[0].flags&MEM_Int );
+-  v->aVar[0].u.i = iRow;
++  v->aMem[1].flags = MEM_Int;
++  v->aMem[1].u.i = iRow;
+ 
+-  rc = sqlite3_step(p->pStmt);
++  /* If the statement has been run before (and is paused at the OP_ResultRow)
++  ** then back it up to the point where it does the OP_SeekRowid.  This could
++  ** have been down with an extra OP_Goto, but simply setting the program
++  ** counter is faster. */
++  if( v->pc>3 ){
++    v->pc = 3;
++    rc = sqlite3VdbeExec(v);
++  }else{
++    rc = sqlite3_step(p->pStmt);
++  }
+   if( rc==SQLITE_ROW ){
+     VdbeCursor *pC = v->apCsr[0];
+-    u32 type = pC->aType[p->iCol];
++    u32 type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0;
++    testcase( pC->nHdrParsed==p->iCol );
++    testcase( pC->nHdrParsed==p->iCol+1 );
+     if( type<12 ){
+       zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
+           type==0?"null": type==7?"real": "integer"
+@@ -77498,7 +89568,7 @@
+     }else{
+       p->iOffset = pC->aType[p->iCol + pC->nField];
+       p->nByte = sqlite3VdbeSerialTypeLen(type);
+-      p->pCsr =  pC->pCursor;
++      p->pCsr =  pC->uc.pCursor;
+       sqlite3BtreeIncrblobCursor(p->pCsr);
+     }
+   }
+@@ -77526,49 +89596,17 @@
+ /*
+ ** Open a blob handle.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
++SQLITE_API int sqlite3_blob_open(
+   sqlite3* db,            /* The database connection */
+   const char *zDb,        /* The attached database containing the blob */
+   const char *zTable,     /* The table containing the blob */
+   const char *zColumn,    /* The column containing the blob */
+   sqlite_int64 iRow,      /* The row containing the glob */
+-  int flags,              /* True -> read/write access, false -> read-only */
++  int wrFlag,             /* True -> read/write access, false -> read-only */
+   sqlite3_blob **ppBlob   /* Handle for accessing the blob returned here */
+ ){
+   int nAttempt = 0;
+   int iCol;               /* Index of zColumn in row-record */
+-
+-  /* This VDBE program seeks a btree cursor to the identified 
+-  ** db/table/row entry. The reason for using a vdbe program instead
+-  ** of writing code to use the b-tree layer directly is that the
+-  ** vdbe program will take advantage of the various transaction,
+-  ** locking and error handling infrastructure built into the vdbe.
+-  **
+-  ** After seeking the cursor, the vdbe executes an OP_ResultRow.
+-  ** Code external to the Vdbe then "borrows" the b-tree cursor and
+-  ** uses it to implement the blob_read(), blob_write() and 
+-  ** blob_bytes() functions.
+-  **
+-  ** The sqlite3_blob_close() function finalizes the vdbe program,
+-  ** which closes the b-tree cursor and (possibly) commits the 
+-  ** transaction.
+-  */
+-  static const int iLn = VDBE_OFFSET_LINENO(4);
+-  static const VdbeOpList openBlob[] = {
+-    /* {OP_Transaction, 0, 0, 0},  // 0: Inserted separately */
+-    {OP_TableLock, 0, 0, 0},       /* 1: Acquire a read or write lock */
+-    /* One of the following two instructions is replaced by an OP_Noop. */
+-    {OP_OpenRead, 0, 0, 0},        /* 2: Open cursor 0 for reading */
+-    {OP_OpenWrite, 0, 0, 0},       /* 3: Open cursor 0 for read/write */
+-    {OP_Variable, 1, 1, 1},        /* 4: Push the rowid to the stack */
+-    {OP_NotExists, 0, 10, 1},      /* 5: Seek the cursor */
+-    {OP_Column, 0, 0, 1},          /* 6  */
+-    {OP_ResultRow, 1, 0, 0},       /* 7  */
+-    {OP_Goto, 0, 4, 0},            /* 8  */
+-    {OP_Close, 0, 0, 0},           /* 9  */
+-    {OP_Halt, 0, 0, 0},            /* 10 */
+-  };
+-
+   int rc = SQLITE_OK;
+   char *zErr = 0;
+   Table *pTab;
+@@ -77586,7 +89624,7 @@
+     return SQLITE_MISUSE_BKPT;
+   }
+ #endif
+-  flags = !!flags;                /* flags = (flags ? 1 : 0); */
++  wrFlag = !!wrFlag;                /* wrFlag = (wrFlag ? 1 : 0); */
+ 
+   sqlite3_mutex_enter(db->mutex);
+ 
+@@ -77627,6 +89665,8 @@
+       sqlite3BtreeLeaveAll(db);
+       goto blob_open_out;
+     }
++    pBlob->pTab = pTab;
++    pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName;
+ 
+     /* Now search pTab for the exact column. */
+     for(iCol=0; iCol<pTab->nCol; iCol++) {
+@@ -77644,9 +89684,8 @@
+ 
+     /* If the value is being opened for writing, check that the
+     ** column is not indexed, and that it is not part of a foreign key. 
+-    ** It is against the rules to open a column to which either of these
+-    ** descriptions applies for writing.  */
+-    if( flags ){
++    */
++    if( wrFlag ){
+       const char *zFault = 0;
+       Index *pIdx;
+ #ifndef SQLITE_OMIT_FOREIGN_KEY
+@@ -77669,7 +89708,8 @@
+       for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+         int j;
+         for(j=0; j<pIdx->nKeyCol; j++){
+-          if( pIdx->aiColumn[j]==iCol ){
++          /* FIXME: Be smarter about indexes that use expressions */
++          if( pIdx->aiColumn[j]==iCol || pIdx->aiColumn[j]==XN_EXPR ){
+             zFault = "indexed";
+           }
+         }
+@@ -77686,60 +89726,89 @@
+     pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse);
+     assert( pBlob->pStmt || db->mallocFailed );
+     if( pBlob->pStmt ){
++      
++      /* This VDBE program seeks a btree cursor to the identified 
++      ** db/table/row entry. The reason for using a vdbe program instead
++      ** of writing code to use the b-tree layer directly is that the
++      ** vdbe program will take advantage of the various transaction,
++      ** locking and error handling infrastructure built into the vdbe.
++      **
++      ** After seeking the cursor, the vdbe executes an OP_ResultRow.
++      ** Code external to the Vdbe then "borrows" the b-tree cursor and
++      ** uses it to implement the blob_read(), blob_write() and 
++      ** blob_bytes() functions.
++      **
++      ** The sqlite3_blob_close() function finalizes the vdbe program,
++      ** which closes the b-tree cursor and (possibly) commits the 
++      ** transaction.
++      */
++      static const int iLn = VDBE_OFFSET_LINENO(2);
++      static const VdbeOpList openBlob[] = {
++        {OP_TableLock,      0, 0, 0},  /* 0: Acquire a read or write lock */
++        {OP_OpenRead,       0, 0, 0},  /* 1: Open a cursor */
++        /* blobSeekToRow() will initialize r[1] to the desired rowid */
++        {OP_NotExists,      0, 5, 1},  /* 2: Seek the cursor to rowid=r[1] */
++        {OP_Column,         0, 0, 1},  /* 3  */
++        {OP_ResultRow,      1, 0, 0},  /* 4  */
++        {OP_Halt,           0, 0, 0},  /* 5  */
++      };
+       Vdbe *v = (Vdbe *)pBlob->pStmt;
+       int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
++      VdbeOp *aOp;
+ 
+-
+-      sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags, 
++      sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, 
+                            pTab->pSchema->schema_cookie,
+                            pTab->pSchema->iGeneration);
+       sqlite3VdbeChangeP5(v, 1);     
+-      sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn);
++      aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn);
+ 
+       /* Make sure a mutex is held on the table to be accessed */
+       sqlite3VdbeUsesBtree(v, iDb); 
+ 
+-      /* Configure the OP_TableLock instruction */
++      if( db->mallocFailed==0 ){
++        assert( aOp!=0 );
++        /* Configure the OP_TableLock instruction */
+ #ifdef SQLITE_OMIT_SHARED_CACHE
+-      sqlite3VdbeChangeToNoop(v, 1);
++        aOp[0].opcode = OP_Noop;
+ #else
+-      sqlite3VdbeChangeP1(v, 1, iDb);
+-      sqlite3VdbeChangeP2(v, 1, pTab->tnum);
+-      sqlite3VdbeChangeP3(v, 1, flags);
+-      sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT);
+-#endif
+-
+-      /* Remove either the OP_OpenWrite or OpenRead. Set the P2 
+-      ** parameter of the other to pTab->tnum.  */
+-      sqlite3VdbeChangeToNoop(v, 3 - flags);
+-      sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum);
+-      sqlite3VdbeChangeP3(v, 2 + flags, iDb);
+-
+-      /* Configure the number of columns. Configure the cursor to
+-      ** think that the table has one more column than it really
+-      ** does. An OP_Column to retrieve this imaginary column will
+-      ** always return an SQL NULL. This is useful because it means
+-      ** we can invoke OP_Column to fill in the vdbe cursors type 
+-      ** and offset cache without causing any IO.
+-      */
+-      sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
+-      sqlite3VdbeChangeP2(v, 6, pTab->nCol);
+-      if( !db->mallocFailed ){
+-        pParse->nVar = 1;
++        aOp[0].p1 = iDb;
++        aOp[0].p2 = pTab->tnum;
++        aOp[0].p3 = wrFlag;
++        sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT);
++      }
++      if( db->mallocFailed==0 ){
++#endif
++
++        /* Remove either the OP_OpenWrite or OpenRead. Set the P2 
++        ** parameter of the other to pTab->tnum.  */
++        if( wrFlag ) aOp[1].opcode = OP_OpenWrite;
++        aOp[1].p2 = pTab->tnum;
++        aOp[1].p3 = iDb;   
++
++        /* Configure the number of columns. Configure the cursor to
++        ** think that the table has one more column than it really
++        ** does. An OP_Column to retrieve this imaginary column will
++        ** always return an SQL NULL. This is useful because it means
++        ** we can invoke OP_Column to fill in the vdbe cursors type 
++        ** and offset cache without causing any IO.
++        */
++        aOp[1].p4type = P4_INT32;
++        aOp[1].p4.i = pTab->nCol+1;
++        aOp[3].p2 = pTab->nCol;
++
++        pParse->nVar = 0;
+         pParse->nMem = 1;
+         pParse->nTab = 1;
+         sqlite3VdbeMakeReady(v, pParse);
+       }
+     }
+    
+-    pBlob->flags = flags;
+     pBlob->iCol = iCol;
+     pBlob->db = db;
+     sqlite3BtreeLeaveAll(db);
+     if( db->mallocFailed ){
+       goto blob_open_out;
+     }
+-    sqlite3_bind_int64(pBlob->pStmt, 1, iRow);
+     rc = blobSeekToRow(pBlob, iRow, &zErr);
+   } while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
+ 
+@@ -77763,7 +89832,7 @@
+ ** Close a blob handle that was previously created using
+ ** sqlite3_blob_open().
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *pBlob){
++SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){
+   Incrblob *p = (Incrblob *)pBlob;
+   int rc;
+   sqlite3 *db;
+@@ -77814,6 +89883,30 @@
+     */
+     assert( db == v->db );
+     sqlite3BtreeEnterCursor(p->pCsr);
++
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++    if( xCall==sqlite3BtreePutData && db->xPreUpdateCallback ){
++      /* If a pre-update hook is registered and this is a write cursor, 
++      ** invoke it here. 
++      ** 
++      ** TODO: The preupdate-hook is passed SQLITE_DELETE, even though this
++      ** operation should really be an SQLITE_UPDATE. This is probably
++      ** incorrect, but is convenient because at this point the new.* values 
++      ** are not easily obtainable. And for the sessions module, an 
++      ** SQLITE_UPDATE where the PK columns do not change is handled in the 
++      ** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually
++      ** slightly more efficient). Since you cannot write to a PK column
++      ** using the incremental-blob API, this works. For the sessions module
++      ** anyhow.
++      */
++      sqlite3_int64 iKey;
++      iKey = sqlite3BtreeIntegerKey(p->pCsr);
++      sqlite3VdbePreUpdateHook(
++          v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1
++      );
++    }
++#endif
++
+     rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
+     sqlite3BtreeLeaveCursor(p->pCsr);
+     if( rc==SQLITE_ABORT ){
+@@ -77832,14 +89925,14 @@
+ /*
+ ** Read data from a blob handle.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
+-  return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData);
++SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
++  return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreePayloadChecked);
+ }
+ 
+ /*
+ ** Write data to a blob handle.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
++SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
+   return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
+ }
+ 
+@@ -77849,7 +89942,7 @@
+ ** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
+ ** so no mutex is required for access.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *pBlob){
++SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
+   Incrblob *p = (Incrblob *)pBlob;
+   return (p && p->pStmt) ? p->nByte : 0;
+ }
+@@ -77864,7 +89957,7 @@
+ ** subsequent calls to sqlite3_blob_xxx() functions (except blob_close()) 
+ ** immediately return SQLITE_ABORT.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
++SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
+   int rc;
+   Incrblob *p = (Incrblob *)pBlob;
+   sqlite3 *db;
+@@ -78035,6 +90128,8 @@
+ ** thread to merge the output of each of the others to a single PMA for
+ ** the main thread to read from.
+ */
++/* #include "sqliteInt.h" */
++/* #include "vdbeInt.h" */
+ 
+ /* 
+ ** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various
+@@ -78438,7 +90533,7 @@
+       int nNew = MAX(128, p->nAlloc*2);
+       while( nByte>nNew ) nNew = nNew*2;
+       aNew = sqlite3Realloc(p->aAlloc, nNew);
+-      if( !aNew ) return SQLITE_NOMEM;
++      if( !aNew ) return SQLITE_NOMEM_BKPT;
+       p->nAlloc = nNew;
+       p->aAlloc = aNew;
+     }
+@@ -78550,7 +90645,7 @@
+     int iBuf = pReadr->iReadOff % pgsz;
+     if( pReadr->aBuffer==0 ){
+       pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz);
+-      if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM;
++      if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM_BKPT;
+       pReadr->nBuffer = pgsz;
+     }
+     if( rc==SQLITE_OK && iBuf ){
+@@ -78635,7 +90730,7 @@
+ 
+   rc = vdbePmaReaderSeek(pTask, pReadr, pFile, iStart);
+   if( rc==SQLITE_OK ){
+-    u64 nByte;                    /* Size of PMA in bytes */
++    u64 nByte = 0;                 /* Size of PMA in bytes */
+     rc = vdbePmaReadVarint(pReadr, &nByte);
+     pReadr->iEof = pReadr->iReadOff + nByte;
+     *pnByte += nByte;
+@@ -78713,9 +90808,9 @@
+   int n2;
+   int res;
+ 
+-  getVarint32(&p1[1], n1); n1 = (n1 - 13) / 2;
+-  getVarint32(&p2[1], n2); n2 = (n2 - 13) / 2;
+-  res = memcmp(v1, v2, MIN(n1, n2));
++  getVarint32(&p1[1], n1);
++  getVarint32(&p2[1], n2);
++  res = memcmp(v1, v2, (MIN(n1, n2) - 13)/2);
+   if( res==0 ){
+     res = n1 - n2;
+   }
+@@ -78756,37 +90851,36 @@
+   assert( (s1>0 && s1<7) || s1==8 || s1==9 );
+   assert( (s2>0 && s2<7) || s2==8 || s2==9 );
+ 
+-  if( s1>7 && s2>7 ){
+-    res = s1 - s2;
+-  }else{
+-    if( s1==s2 ){
+-      if( (*v1 ^ *v2) & 0x80 ){
+-        /* The two values have different signs */
+-        res = (*v1 & 0x80) ? -1 : +1;
+-      }else{
+-        /* The two values have the same sign. Compare using memcmp(). */
+-        static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 };
+-        int i;
+-        res = 0;
+-        for(i=0; i<aLen[s1]; i++){
+-          if( (res = v1[i] - v2[i]) ) break;
++  if( s1==s2 ){
++    /* The two values have the same sign. Compare using memcmp(). */
++    static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8, 0, 0, 0 };
++    const u8 n = aLen[s1];
++    int i;
++    res = 0;
++    for(i=0; i<n; i++){
++      if( (res = v1[i] - v2[i])!=0 ){
++        if( ((v1[0] ^ v2[0]) & 0x80)!=0 ){
++          res = v1[0] & 0x80 ? -1 : +1;
+         }
++        break;
+       }
++    }
++  }else if( s1>7 && s2>7 ){
++    res = s1 - s2;
++  }else{
++    if( s2>7 ){
++      res = +1;
++    }else if( s1>7 ){
++      res = -1;
+     }else{
+-      if( s2>7 ){
+-        res = +1;
+-      }else if( s1>7 ){
+-        res = -1;
+-      }else{
+-        res = s1 - s2;
+-      }
+-      assert( res!=0 );
++      res = s1 - s2;
++    }
++    assert( res!=0 );
+ 
+-      if( res>0 ){
+-        if( *v1 & 0x80 ) res = -1;
+-      }else{
+-        if( *v2 & 0x80 ) res = +1;
+-      }
++    if( res>0 ){
++      if( *v1 & 0x80 ) res = -1;
++    }else{
++      if( *v2 & 0x80 ) res = +1;
+     }
+   }
+ 
+@@ -78829,7 +90923,6 @@
+ ){
+   int pgsz;                       /* Page size of main database */
+   int i;                          /* Used to iterate through aTask[] */
+-  int mxCache;                    /* Cache size */
+   VdbeSorter *pSorter;            /* The new sorter */
+   KeyInfo *pKeyInfo;              /* Copy of pCsr->pKeyInfo with db==0 */
+   int szKeyInfo;                  /* Size of pCsr->pKeyInfo in bytes */
+@@ -78858,14 +90951,15 @@
+   }
+ #endif
+ 
+-  assert( pCsr->pKeyInfo && pCsr->pBt==0 );
++  assert( pCsr->pKeyInfo && pCsr->pBtx==0 );
++  assert( pCsr->eCurType==CURTYPE_SORTER );
+   szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*);
+   sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
+ 
+   pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
+-  pCsr->pSorter = pSorter;
++  pCsr->uc.pSorter = pSorter;
+   if( pSorter==0 ){
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+   }else{
+     pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
+     memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
+@@ -78876,7 +90970,7 @@
+     }
+     pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
+     pSorter->nTask = nWorker + 1;
+-    pSorter->iPrev = nWorker-1;
++    pSorter->iPrev = (u8)(nWorker - 1);
+     pSorter->bUseThreads = (pSorter->nTask>1);
+     pSorter->db = db;
+     for(i=0; i<pSorter->nTask; i++){
+@@ -78885,11 +90979,20 @@
+     }
+ 
+     if( !sqlite3TempInMemory(db) ){
++      i64 mxCache;                /* Cache size in bytes*/
+       u32 szPma = sqlite3GlobalConfig.szPma;
+       pSorter->mnPmaSize = szPma * pgsz;
++
+       mxCache = db->aDb[0].pSchema->cache_size;
+-      if( mxCache<(int)szPma ) mxCache = (int)szPma;
+-      pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ);
++      if( mxCache<0 ){
++        /* A negative cache-size value C indicates that the cache is abs(C)
++        ** KiB in size.  */
++        mxCache = mxCache * -1024;
++      }else{
++        mxCache = mxCache * pgsz;
++      }
++      mxCache = MIN(mxCache, SQLITE_MAX_PMASZ);
++      pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache);
+ 
+       /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
+       ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
+@@ -78899,7 +91002,7 @@
+         assert( pSorter->iMemory==0 );
+         pSorter->nMemory = pgsz;
+         pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
+-        if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
++        if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT;
+       }
+     }
+ 
+@@ -79147,12 +91250,14 @@
+ ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
+ */
+ SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
+-  VdbeSorter *pSorter = pCsr->pSorter;
++  VdbeSorter *pSorter;
++  assert( pCsr->eCurType==CURTYPE_SORTER );
++  pSorter = pCsr->uc.pSorter;
+   if( pSorter ){
+     sqlite3VdbeSorterReset(db, pSorter);
+     sqlite3_free(pSorter->list.aMemory);
+     sqlite3DbFree(db, pSorter);
+-    pCsr->pSorter = 0;
++    pCsr->uc.pSorter = 0;
+   }
+ }
+ 
+@@ -79214,12 +91319,8 @@
+ */
+ static int vdbeSortAllocUnpacked(SortSubtask *pTask){
+   if( pTask->pUnpacked==0 ){
+-    char *pFree;
+-    pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(
+-        pTask->pSorter->pKeyInfo, 0, 0, &pFree
+-    );
+-    assert( pTask->pUnpacked==(UnpackedRecord*)pFree );
+-    if( pFree==0 ) return SQLITE_NOMEM;
++    pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo);
++    if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT;
+     pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField;
+     pTask->pUnpacked->errCode = 0;
+   }
+@@ -79229,19 +91330,18 @@
+ 
+ /*
+ ** Merge the two sorted lists p1 and p2 into a single list.
+-** Set *ppOut to the head of the new list.
+ */
+-static void vdbeSorterMerge(
++static SorterRecord *vdbeSorterMerge(
+   SortSubtask *pTask,             /* Calling thread context */
+   SorterRecord *p1,               /* First list to merge */
+-  SorterRecord *p2,               /* Second list to merge */
+-  SorterRecord **ppOut            /* OUT: Head of merged list */
++  SorterRecord *p2                /* Second list to merge */
+ ){
+   SorterRecord *pFinal = 0;
+   SorterRecord **pp = &pFinal;
+   int bCached = 0;
+ 
+-  while( p1 && p2 ){
++  assert( p1!=0 && p2!=0 );
++  for(;;){
+     int res;
+     res = pTask->xCompare(
+         pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal
+@@ -79251,15 +91351,22 @@
+       *pp = p1;
+       pp = &p1->u.pNext;
+       p1 = p1->u.pNext;
++      if( p1==0 ){
++        *pp = p2;
++        break;
++      }
+     }else{
+       *pp = p2;
+       pp = &p2->u.pNext;
+       p2 = p2->u.pNext;
+       bCached = 0;
++      if( p2==0 ){
++        *pp = p1;
++        break;
++      }
+     }
+   }
+-  *pp = p1 ? p1 : p2;
+-  *ppOut = pFinal;
++  return pFinal;
+ }
+ 
+ /*
+@@ -79294,7 +91401,7 @@
+ 
+   aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
+   if( !aSlot ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+ 
+   while( p ){
+@@ -79312,7 +91419,7 @@
+ 
+     p->u.pNext = 0;
+     for(i=0; aSlot[i]; i++){
+-      vdbeSorterMerge(pTask, p, aSlot[i], &p);
++      p = vdbeSorterMerge(pTask, p, aSlot[i]);
+       aSlot[i] = 0;
+     }
+     aSlot[i] = p;
+@@ -79321,7 +91428,8 @@
+ 
+   p = 0;
+   for(i=0; i<64; i++){
+-    vdbeSorterMerge(pTask, p, aSlot[i], &p);
++    if( aSlot[i]==0 ) continue;
++    p = p ? vdbeSorterMerge(pTask, p, aSlot[i]) : aSlot[i];
+   }
+   pList->pList = p;
+ 
+@@ -79344,7 +91452,7 @@
+   memset(p, 0, sizeof(PmaWriter));
+   p->aBuffer = (u8*)sqlite3Malloc(nBuf);
+   if( !p->aBuffer ){
+-    p->eFWErr = SQLITE_NOMEM;
++    p->eFWErr = SQLITE_NOMEM_BKPT;
+   }else{
+     p->iBufEnd = p->iBufStart = (iStart % nBuf);
+     p->iWriteOff = iStart - p->iBufStart;
+@@ -79632,7 +91740,7 @@
+         pSorter->nMemory = sqlite3MallocSize(aMem);
+       }else if( pSorter->list.aMemory ){
+         pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory);
+-        if( !pSorter->list.aMemory ) return SQLITE_NOMEM;
++        if( !pSorter->list.aMemory ) return SQLITE_NOMEM_BKPT;
+       }
+ 
+       rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx);
+@@ -79650,15 +91758,16 @@
+   const VdbeCursor *pCsr,         /* Sorter cursor */
+   Mem *pVal                       /* Memory cell containing record */
+ ){
+-  VdbeSorter *pSorter = pCsr->pSorter;
++  VdbeSorter *pSorter;
+   int rc = SQLITE_OK;             /* Return Code */
+   SorterRecord *pNew;             /* New list element */
+-
+   int bFlush;                     /* True to flush contents of memory to PMA */
+   int nReq;                       /* Bytes of memory required */
+   int nPMA;                       /* Bytes of PMA space required */
+   int t;                          /* serial type of first record field */
+ 
++  assert( pCsr->eCurType==CURTYPE_SORTER );
++  pSorter = pCsr->uc.pSorter;
+   getVarint32((const u8*)&pVal->z[1], t);
+   if( t>0 && t<10 && t!=7 ){
+     pSorter->typeMask &= SORTER_TYPE_INTEGER;
+@@ -79715,27 +91824,28 @@
+ 
+     if( nMin>pSorter->nMemory ){
+       u8 *aNew;
++      int iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory;
+       int nNew = pSorter->nMemory * 2;
+       while( nNew < nMin ) nNew = nNew*2;
+       if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize;
+       if( nNew < nMin ) nNew = nMin;
+ 
+       aNew = sqlite3Realloc(pSorter->list.aMemory, nNew);
+-      if( !aNew ) return SQLITE_NOMEM;
+-      pSorter->list.pList = (SorterRecord*)(
+-          aNew + ((u8*)pSorter->list.pList - pSorter->list.aMemory)
+-      );
++      if( !aNew ) return SQLITE_NOMEM_BKPT;
++      pSorter->list.pList = (SorterRecord*)&aNew[iListOff];
+       pSorter->list.aMemory = aNew;
+       pSorter->nMemory = nNew;
+     }
+ 
+     pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory];
+     pSorter->iMemory += ROUND8(nReq);
+-    pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory);
++    if( pSorter->list.pList ){
++      pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory);
++    }
+   }else{
+     pNew = (SorterRecord *)sqlite3Malloc(nReq);
+     if( pNew==0 ){
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     pNew->u.pNext = pSorter->list.pList;
+   }
+@@ -79882,7 +91992,7 @@
+     pTask->file2.iEof += pIncr->mxSz;
+   }else{
+     vdbeMergeEngineFree(pMerger);
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+   }
+   return rc;
+ }
+@@ -80187,10 +92297,10 @@
+   int rc = SQLITE_OK;
+ 
+   *ppOut = pNew = vdbeMergeEngineNew(nPMA);
+-  if( pNew==0 ) rc = SQLITE_NOMEM;
++  if( pNew==0 ) rc = SQLITE_NOMEM_BKPT;
+ 
+   for(i=0; i<nPMA && rc==SQLITE_OK; i++){
+-    i64 nDummy;
++    i64 nDummy = 0;
+     PmaReader *pReadr = &pNew->aReadr[i];
+     rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy);
+     iOff = pReadr->iEof;
+@@ -80258,7 +92368,7 @@
+     if( pReadr->pIncr==0 ){
+       MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
+       if( pNew==0 ){
+-        rc = SQLITE_NOMEM;
++        rc = SQLITE_NOMEM_BKPT;
+       }else{
+         rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr);
+       }
+@@ -80303,7 +92413,7 @@
+   assert( pSorter->bUseThreads || pSorter->nTask==1 );
+   if( pSorter->nTask>1 ){
+     pMain = vdbeMergeEngineNew(pSorter->nTask);
+-    if( pMain==0 ) rc = SQLITE_NOMEM;
++    if( pMain==0 ) rc = SQLITE_NOMEM_BKPT;
+   }
+ #endif
+ 
+@@ -80321,7 +92431,7 @@
+         int i;
+         int iSeq = 0;
+         pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
+-        if( pRoot==0 ) rc = SQLITE_NOMEM;
++        if( pRoot==0 ) rc = SQLITE_NOMEM_BKPT;
+         for(i=0; i<pTask->nPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){
+           MergeEngine *pMerger = 0; /* New level-0 PMA merger */
+           int nReader;              /* Number of level-0 PMAs to merge */
+@@ -80392,7 +92502,7 @@
+       if( rc==SQLITE_OK ){
+         pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
+         pSorter->pReader = pReadr;
+-        if( pReadr==0 ) rc = SQLITE_NOMEM;
++        if( pReadr==0 ) rc = SQLITE_NOMEM_BKPT;
+       }
+       if( rc==SQLITE_OK ){
+         rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr);
+@@ -80450,9 +92560,11 @@
+ ** in sorted order.
+ */
+ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){
+-  VdbeSorter *pSorter = pCsr->pSorter;
++  VdbeSorter *pSorter;
+   int rc = SQLITE_OK;             /* Return code */
+ 
++  assert( pCsr->eCurType==CURTYPE_SORTER );
++  pSorter = pCsr->uc.pSorter;
+   assert( pSorter );
+ 
+   /* If no data has been written to disk, then do not do so now. Instead,
+@@ -80493,12 +92605,18 @@
+ }
+ 
+ /*
+-** Advance to the next element in the sorter.
++** Advance to the next element in the sorter.  Return value:
++**
++**    SQLITE_OK     success
++**    SQLITE_DONE   end of data
++**    otherwise     some kind of error.
+ */
+-SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
+-  VdbeSorter *pSorter = pCsr->pSorter;
++SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr){
++  VdbeSorter *pSorter;
+   int rc;                         /* Return code */
+ 
++  assert( pCsr->eCurType==CURTYPE_SORTER );
++  pSorter = pCsr->uc.pSorter;
+   assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) );
+   if( pSorter->bUsePMA ){
+     assert( pSorter->pReader==0 || pSorter->pMerger==0 );
+@@ -80507,21 +92625,22 @@
+ #if SQLITE_MAX_WORKER_THREADS>0
+     if( pSorter->bUseThreads ){
+       rc = vdbePmaReaderNext(pSorter->pReader);
+-      *pbEof = (pSorter->pReader->pFd==0);
++      if( rc==SQLITE_OK && pSorter->pReader->pFd==0 ) rc = SQLITE_DONE;
+     }else
+ #endif
+     /*if( !pSorter->bUseThreads )*/ {
++      int res = 0;
+       assert( pSorter->pMerger!=0 );
+       assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) );
+-      rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof);
++      rc = vdbeMergeEngineStep(pSorter->pMerger, &res);
++      if( rc==SQLITE_OK && res ) rc = SQLITE_DONE;
+     }
+   }else{
+     SorterRecord *pFree = pSorter->list.pList;
+     pSorter->list.pList = pFree->u.pNext;
+     pFree->u.pNext = 0;
+     if( pSorter->list.aMemory==0 ) vdbeSorterRecordFree(db, pFree);
+-    *pbEof = !pSorter->list.pList;
+-    rc = SQLITE_OK;
++    rc = pSorter->list.pList ? SQLITE_OK : SQLITE_DONE;
+   }
+   return rc;
+ }
+@@ -80558,12 +92677,14 @@
+ ** Copy the current sorter key into the memory cell pOut.
+ */
+ SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
+-  VdbeSorter *pSorter = pCsr->pSorter;
++  VdbeSorter *pSorter;
+   void *pKey; int nKey;           /* Sorter key to copy into pOut */
+ 
++  assert( pCsr->eCurType==CURTYPE_SORTER );
++  pSorter = pCsr->uc.pSorter;
+   pKey = vdbeSorterRowkey(pSorter, &nKey);
+   if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   pOut->n = nKey;
+   MemSetTypeFlag(pOut, MEM_Blob);
+@@ -80594,17 +92715,19 @@
+   int nKeyCol,                    /* Compare this many columns */
+   int *pRes                       /* OUT: Result of comparison */
+ ){
+-  VdbeSorter *pSorter = pCsr->pSorter;
+-  UnpackedRecord *r2 = pSorter->pUnpacked;
+-  KeyInfo *pKeyInfo = pCsr->pKeyInfo;
++  VdbeSorter *pSorter;
++  UnpackedRecord *r2;
++  KeyInfo *pKeyInfo;
+   int i;
+   void *pKey; int nKey;           /* Sorter key to compare pVal with */
+ 
++  assert( pCsr->eCurType==CURTYPE_SORTER );
++  pSorter = pCsr->uc.pSorter;
++  r2 = pSorter->pUnpacked;
++  pKeyInfo = pCsr->pKeyInfo;
+   if( r2==0 ){
+-    char *p;
+-    r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p);
+-    assert( pSorter->pUnpacked==(UnpackedRecord*)p );
+-    if( r2==0 ) return SQLITE_NOMEM;
++    r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
++    if( r2==0 ) return SQLITE_NOMEM_BKPT;
+     r2->nField = nKeyCol;
+   }
+   assert( r2->nField==nKeyCol );
+@@ -80623,264 +92746,6 @@
+ }
+ 
+ /************** End of vdbesort.c ********************************************/
+-/************** Begin file journal.c *****************************************/
+-/*
+-** 2007 August 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 implements a special kind of sqlite3_file object used
+-** by SQLite to create journal files if the atomic-write optimization
+-** is enabled.
+-**
+-** The distinctive characteristic of this sqlite3_file is that the
+-** actual on disk file is created lazily. When the file is created,
+-** the caller specifies a buffer size for an in-memory buffer to
+-** be used to service read() and write() requests. The actual file
+-** on disk is not created or populated until either:
+-**
+-**   1) The in-memory representation grows too large for the allocated 
+-**      buffer, or
+-**   2) The sqlite3JournalCreate() function is called.
+-*/
+-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+-
+-
+-/*
+-** A JournalFile object is a subclass of sqlite3_file used by
+-** as an open file handle for journal files.
+-*/
+-struct JournalFile {
+-  sqlite3_io_methods *pMethod;    /* I/O methods on journal files */
+-  int nBuf;                       /* Size of zBuf[] in bytes */
+-  char *zBuf;                     /* Space to buffer journal writes */
+-  int iSize;                      /* Amount of zBuf[] currently used */
+-  int flags;                      /* xOpen flags */
+-  sqlite3_vfs *pVfs;              /* The "real" underlying VFS */
+-  sqlite3_file *pReal;            /* The "real" underlying file descriptor */
+-  const char *zJournal;           /* Name of the journal file */
+-};
+-typedef struct JournalFile JournalFile;
+-
+-/*
+-** If it does not already exists, create and populate the on-disk file 
+-** for JournalFile p.
+-*/
+-static int createFile(JournalFile *p){
+-  int rc = SQLITE_OK;
+-  if( !p->pReal ){
+-    sqlite3_file *pReal = (sqlite3_file *)&p[1];
+-    rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0);
+-    if( rc==SQLITE_OK ){
+-      p->pReal = pReal;
+-      if( p->iSize>0 ){
+-        assert(p->iSize<=p->nBuf);
+-        rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
+-      }
+-      if( rc!=SQLITE_OK ){
+-        /* If an error occurred while writing to the file, close it before
+-        ** returning. This way, SQLite uses the in-memory journal data to 
+-        ** roll back changes made to the internal page-cache before this
+-        ** function was called.  */
+-        sqlite3OsClose(pReal);
+-        p->pReal = 0;
+-      }
+-    }
+-  }
+-  return rc;
+-}
+-
+-/*
+-** Close the file.
+-*/
+-static int jrnlClose(sqlite3_file *pJfd){
+-  JournalFile *p = (JournalFile *)pJfd;
+-  if( p->pReal ){
+-    sqlite3OsClose(p->pReal);
+-  }
+-  sqlite3_free(p->zBuf);
+-  return SQLITE_OK;
+-}
+-
+-/*
+-** Read data from the file.
+-*/
+-static int jrnlRead(
+-  sqlite3_file *pJfd,    /* The journal file from which to read */
+-  void *zBuf,            /* Put the results here */
+-  int iAmt,              /* Number of bytes to read */
+-  sqlite_int64 iOfst     /* Begin reading at this offset */
+-){
+-  int rc = SQLITE_OK;
+-  JournalFile *p = (JournalFile *)pJfd;
+-  if( p->pReal ){
+-    rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
+-  }else if( (iAmt+iOfst)>p->iSize ){
+-    rc = SQLITE_IOERR_SHORT_READ;
+-  }else{
+-    memcpy(zBuf, &p->zBuf[iOfst], iAmt);
+-  }
+-  return rc;
+-}
+-
+-/*
+-** Write data to the file.
+-*/
+-static int jrnlWrite(
+-  sqlite3_file *pJfd,    /* The journal file into which to write */
+-  const void *zBuf,      /* Take data to be written from here */
+-  int iAmt,              /* Number of bytes to write */
+-  sqlite_int64 iOfst     /* Begin writing at this offset into the file */
+-){
+-  int rc = SQLITE_OK;
+-  JournalFile *p = (JournalFile *)pJfd;
+-  if( !p->pReal && (iOfst+iAmt)>p->nBuf ){
+-    rc = createFile(p);
+-  }
+-  if( rc==SQLITE_OK ){
+-    if( p->pReal ){
+-      rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
+-    }else{
+-      memcpy(&p->zBuf[iOfst], zBuf, iAmt);
+-      if( p->iSize<(iOfst+iAmt) ){
+-        p->iSize = (iOfst+iAmt);
+-      }
+-    }
+-  }
+-  return rc;
+-}
+-
+-/*
+-** Truncate the file.
+-*/
+-static int jrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
+-  int rc = SQLITE_OK;
+-  JournalFile *p = (JournalFile *)pJfd;
+-  if( p->pReal ){
+-    rc = sqlite3OsTruncate(p->pReal, size);
+-  }else if( size<p->iSize ){
+-    p->iSize = size;
+-  }
+-  return rc;
+-}
+-
+-/*
+-** Sync the file.
+-*/
+-static int jrnlSync(sqlite3_file *pJfd, int flags){
+-  int rc;
+-  JournalFile *p = (JournalFile *)pJfd;
+-  if( p->pReal ){
+-    rc = sqlite3OsSync(p->pReal, flags);
+-  }else{
+-    rc = SQLITE_OK;
+-  }
+-  return rc;
+-}
+-
+-/*
+-** Query the size of the file in bytes.
+-*/
+-static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
+-  int rc = SQLITE_OK;
+-  JournalFile *p = (JournalFile *)pJfd;
+-  if( p->pReal ){
+-    rc = sqlite3OsFileSize(p->pReal, pSize);
+-  }else{
+-    *pSize = (sqlite_int64) p->iSize;
+-  }
+-  return rc;
+-}
+-
+-/*
+-** Table of methods for JournalFile sqlite3_file object.
+-*/
+-static struct sqlite3_io_methods JournalFileMethods = {
+-  1,             /* iVersion */
+-  jrnlClose,     /* xClose */
+-  jrnlRead,      /* xRead */
+-  jrnlWrite,     /* xWrite */
+-  jrnlTruncate,  /* xTruncate */
+-  jrnlSync,      /* xSync */
+-  jrnlFileSize,  /* xFileSize */
+-  0,             /* xLock */
+-  0,             /* xUnlock */
+-  0,             /* xCheckReservedLock */
+-  0,             /* xFileControl */
+-  0,             /* xSectorSize */
+-  0,             /* xDeviceCharacteristics */
+-  0,             /* xShmMap */
+-  0,             /* xShmLock */
+-  0,             /* xShmBarrier */
+-  0              /* xShmUnmap */
+-};
+-
+-/* 
+-** Open a journal file.
+-*/
+-SQLITE_PRIVATE int sqlite3JournalOpen(
+-  sqlite3_vfs *pVfs,         /* The VFS to use for actual file I/O */
+-  const char *zName,         /* Name of the journal file */
+-  sqlite3_file *pJfd,        /* Preallocated, blank file handle */
+-  int flags,                 /* Opening flags */
+-  int nBuf                   /* Bytes buffered before opening the file */
+-){
+-  JournalFile *p = (JournalFile *)pJfd;
+-  memset(p, 0, sqlite3JournalSize(pVfs));
+-  if( nBuf>0 ){
+-    p->zBuf = sqlite3MallocZero(nBuf);
+-    if( !p->zBuf ){
+-      return SQLITE_NOMEM;
+-    }
+-  }else{
+-    return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
+-  }
+-  p->pMethod = &JournalFileMethods;
+-  p->nBuf = nBuf;
+-  p->flags = flags;
+-  p->zJournal = zName;
+-  p->pVfs = pVfs;
+-  return SQLITE_OK;
+-}
+-
+-/*
+-** If the argument p points to a JournalFile structure, and the underlying
+-** file has not yet been created, create it now.
+-*/
+-SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){
+-  if( p->pMethods!=&JournalFileMethods ){
+-    return SQLITE_OK;
+-  }
+-  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.
+-*/
+-SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
+-  return (pVfs->szOsFile+sizeof(JournalFile));
+-}
+-#endif
+-
+-/************** End of journal.c *********************************************/
+ /************** Begin file memjournal.c **************************************/
+ /*
+ ** 2008 October 7
+@@ -80897,32 +92762,46 @@
+ ** This file contains code use to implement an in-memory rollback journal.
+ ** The in-memory rollback journal is used to journal transactions for
+ ** ":memory:" databases and when the journal_mode=MEMORY pragma is used.
++**
++** Update:  The in-memory journal is also used to temporarily cache
++** smaller journals that are not critical for power-loss recovery.
++** For example, statement journals that are not too big will be held
++** entirely in memory, thus reducing the number of file I/O calls, and
++** more importantly, reducing temporary file creation events.  If these
++** journals become too large for memory, they are spilled to disk.  But
++** in the common case, they are usually small and no file I/O needs to
++** occur.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /* Forward references to internal structures */
+ typedef struct MemJournal MemJournal;
+ typedef struct FilePoint FilePoint;
+ typedef struct FileChunk FileChunk;
+ 
+-/* Space to hold the rollback journal is allocated in increments of
+-** this many bytes.
+-**
+-** The size chosen is a little less than a power of two.  That way,
+-** the FileChunk object will have a size that almost exactly fills
+-** a power-of-two allocation.  This minimizes wasted space in power-of-two
+-** memory allocators.
+-*/
+-#define JOURNAL_CHUNKSIZE ((int)(1024-sizeof(FileChunk*)))
+-
+ /*
+ ** The rollback journal is composed of a linked list of these structures.
++**
++** The zChunk array is always at least 8 bytes in size - usually much more.
++** Its actual size is stored in the MemJournal.nChunkSize variable.
+ */
+ struct FileChunk {
+   FileChunk *pNext;               /* Next chunk in the journal */
+-  u8 zChunk[JOURNAL_CHUNKSIZE];   /* Content of this chunk */
++  u8 zChunk[8];                   /* Content of this chunk */
+ };
+ 
+ /*
++** By default, allocate this many bytes of memory for each FileChunk object.
++*/
++#define MEMJOURNAL_DFLT_FILECHUNKSIZE 1024
++
++/*
++** For chunk size nChunkSize, return the number of bytes that should
++** be allocated for each FileChunk structure.
++*/
++#define fileChunkSize(nChunkSize) (sizeof(FileChunk) + ((nChunkSize)-8))
++
++/*
+ ** An instance of this object serves as a cursor into the rollback journal.
+ ** The cursor can be either for reading or writing.
+ */
+@@ -80932,14 +92811,22 @@
+ };
+ 
+ /*
+-** This subclass is a subclass of sqlite3_file.  Each open memory-journal
++** This structure is a subclass of sqlite3_file. Each open memory-journal
+ ** is an instance of this class.
+ */
+ struct MemJournal {
+-  sqlite3_io_methods *pMethod;    /* Parent class. MUST BE FIRST */
++  const sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */
++  int nChunkSize;                 /* In-memory chunk-size */
++
++  int nSpill;                     /* Bytes of data before flushing */
++  int nSize;                      /* Bytes of data currently in memory */
+   FileChunk *pFirst;              /* Head of in-memory chunk-list */
+   FilePoint endpoint;             /* Pointer to the end of the file */
+   FilePoint readpoint;            /* Pointer to the end of the last xRead() */
++
++  int flags;                      /* xOpen flags */
++  sqlite3_vfs *pVfs;              /* The "real" underlying VFS */
++  const char *zJournal;           /* Name of the journal file */
+ };
+ 
+ /*
+@@ -80958,37 +92845,95 @@
+   int iChunkOffset;
+   FileChunk *pChunk;
+ 
+-  /* SQLite never tries to read past the end of a rollback journal file */
+-  assert( iOfst+iAmt<=p->endpoint.iOffset );
++#ifdef SQLITE_ENABLE_ATOMIC_WRITE
++  if( (iAmt+iOfst)>p->endpoint.iOffset ){
++    return SQLITE_IOERR_SHORT_READ;
++  }
++#endif
+ 
++  assert( (iAmt+iOfst)<=p->endpoint.iOffset );
++  assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 );
+   if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
+     sqlite3_int64 iOff = 0;
+     for(pChunk=p->pFirst; 
+-        ALWAYS(pChunk) && (iOff+JOURNAL_CHUNKSIZE)<=iOfst;
++        ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst;
+         pChunk=pChunk->pNext
+     ){
+-      iOff += JOURNAL_CHUNKSIZE;
++      iOff += p->nChunkSize;
+     }
+   }else{
+     pChunk = p->readpoint.pChunk;
++    assert( pChunk!=0 );
+   }
+ 
+-  iChunkOffset = (int)(iOfst%JOURNAL_CHUNKSIZE);
++  iChunkOffset = (int)(iOfst%p->nChunkSize);
+   do {
+-    int iSpace = JOURNAL_CHUNKSIZE - iChunkOffset;
+-    int nCopy = MIN(nRead, (JOURNAL_CHUNKSIZE - iChunkOffset));
+-    memcpy(zOut, &pChunk->zChunk[iChunkOffset], nCopy);
++    int iSpace = p->nChunkSize - iChunkOffset;
++    int nCopy = MIN(nRead, (p->nChunkSize - iChunkOffset));
++    memcpy(zOut, (u8*)pChunk->zChunk + iChunkOffset, nCopy);
+     zOut += nCopy;
+     nRead -= iSpace;
+     iChunkOffset = 0;
+   } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
+-  p->readpoint.iOffset = iOfst+iAmt;
++  p->readpoint.iOffset = pChunk ? iOfst+iAmt : 0;
+   p->readpoint.pChunk = pChunk;
+ 
+   return SQLITE_OK;
+ }
+ 
+ /*
++** Free the list of FileChunk structures headed at MemJournal.pFirst.
++*/
++static void memjrnlFreeChunks(MemJournal *p){
++  FileChunk *pIter;
++  FileChunk *pNext;
++  for(pIter=p->pFirst; pIter; pIter=pNext){
++    pNext = pIter->pNext;
++    sqlite3_free(pIter);
++  } 
++  p->pFirst = 0;
++}
++
++/*
++** Flush the contents of memory to a real file on disk.
++*/
++static int memjrnlCreateFile(MemJournal *p){
++  int rc;
++  sqlite3_file *pReal = (sqlite3_file*)p;
++  MemJournal copy = *p;
++
++  memset(p, 0, sizeof(MemJournal));
++  rc = sqlite3OsOpen(copy.pVfs, copy.zJournal, pReal, copy.flags, 0);
++  if( rc==SQLITE_OK ){
++    int nChunk = copy.nChunkSize;
++    i64 iOff = 0;
++    FileChunk *pIter;
++    for(pIter=copy.pFirst; pIter; pIter=pIter->pNext){
++      if( iOff + nChunk > copy.endpoint.iOffset ){
++        nChunk = copy.endpoint.iOffset - iOff;
++      }
++      rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nChunk, iOff);
++      if( rc ) break;
++      iOff += nChunk;
++    }
++    if( rc==SQLITE_OK ){
++      /* No error has occurred. Free the in-memory buffers. */
++      memjrnlFreeChunks(&copy);
++    }
++  }
++  if( rc!=SQLITE_OK ){
++    /* If an error occurred while creating or writing to the file, restore
++    ** the original before returning. This way, SQLite uses the in-memory
++    ** journal data to roll back changes made to the internal page-cache
++    ** before this function was called.  */
++    sqlite3OsClose(pReal);
++    *p = copy;
++  }
++  return rc;
++}
++
++
++/*
+ ** Write data to the file.
+ */
+ static int memjrnlWrite(
+@@ -81001,38 +92946,62 @@
+   int nWrite = iAmt;
+   u8 *zWrite = (u8 *)zBuf;
+ 
+-  /* An in-memory journal file should only ever be appended to. Random
+-  ** access writes are not required by sqlite.
+-  */
+-  assert( iOfst==p->endpoint.iOffset );
+-  UNUSED_PARAMETER(iOfst);
++  /* If the file should be created now, create it and write the new data
++  ** into the file on disk. */
++  if( p->nSpill>0 && (iAmt+iOfst)>p->nSpill ){
++    int rc = memjrnlCreateFile(p);
++    if( rc==SQLITE_OK ){
++      rc = sqlite3OsWrite(pJfd, zBuf, iAmt, iOfst);
++    }
++    return rc;
++  }
+ 
+-  while( nWrite>0 ){
+-    FileChunk *pChunk = p->endpoint.pChunk;
+-    int iChunkOffset = (int)(p->endpoint.iOffset%JOURNAL_CHUNKSIZE);
+-    int iSpace = MIN(nWrite, JOURNAL_CHUNKSIZE - iChunkOffset);
+-
+-    if( iChunkOffset==0 ){
+-      /* New chunk is required to extend the file. */
+-      FileChunk *pNew = sqlite3_malloc(sizeof(FileChunk));
+-      if( !pNew ){
+-        return SQLITE_IOERR_NOMEM;
+-      }
+-      pNew->pNext = 0;
+-      if( pChunk ){
+-        assert( p->pFirst );
+-        pChunk->pNext = pNew;
+-      }else{
+-        assert( !p->pFirst );
+-        p->pFirst = pNew;
++  /* If the contents of this write should be stored in memory */
++  else{
++    /* An in-memory journal file should only ever be appended to. Random
++    ** access writes are not required. The only exception to this is when
++    ** the in-memory journal is being used by a connection using the
++    ** atomic-write optimization. In this case the first 28 bytes of the
++    ** journal file may be written as part of committing the transaction. */ 
++    assert( iOfst==p->endpoint.iOffset || iOfst==0 );
++#ifdef SQLITE_ENABLE_ATOMIC_WRITE
++    if( iOfst==0 && p->pFirst ){
++      assert( p->nChunkSize>iAmt );
++      memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
++    }else
++#else
++    assert( iOfst>0 || p->pFirst==0 );
++#endif
++    {
++      while( nWrite>0 ){
++        FileChunk *pChunk = p->endpoint.pChunk;
++        int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
++        int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset);
++
++        if( iChunkOffset==0 ){
++          /* New chunk is required to extend the file. */
++          FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize));
++          if( !pNew ){
++            return SQLITE_IOERR_NOMEM_BKPT;
++          }
++          pNew->pNext = 0;
++          if( pChunk ){
++            assert( p->pFirst );
++            pChunk->pNext = pNew;
++          }else{
++            assert( !p->pFirst );
++            p->pFirst = pNew;
++          }
++          p->endpoint.pChunk = pNew;
++        }
++
++        memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace);
++        zWrite += iSpace;
++        nWrite -= iSpace;
++        p->endpoint.iOffset += iSpace;
+       }
+-      p->endpoint.pChunk = pNew;
++      p->nSize = iAmt + iOfst;
+     }
+-
+-    memcpy(&p->endpoint.pChunk->zChunk[iChunkOffset], zWrite, iSpace);
+-    zWrite += iSpace;
+-    nWrite -= iSpace;
+-    p->endpoint.iOffset += iSpace;
+   }
+ 
+   return SQLITE_OK;
+@@ -81040,19 +93009,21 @@
+ 
+ /*
+ ** Truncate the file.
++**
++** If the journal file is already on disk, truncate it there. Or, if it
++** is still in main memory but is being truncated to zero bytes in size,
++** ignore 
+ */
+ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
+   MemJournal *p = (MemJournal *)pJfd;
+-  FileChunk *pChunk;
+-  assert(size==0);
+-  UNUSED_PARAMETER(size);
+-  pChunk = p->pFirst;
+-  while( pChunk ){
+-    FileChunk *pTmp = pChunk;
+-    pChunk = pChunk->pNext;
+-    sqlite3_free(pTmp);
++  if( ALWAYS(size==0) ){
++    memjrnlFreeChunks(p);
++    p->nSize = 0;
++    p->endpoint.pChunk = 0;
++    p->endpoint.iOffset = 0;
++    p->readpoint.pChunk = 0;
++    p->readpoint.iOffset = 0;
+   }
+-  sqlite3MemJournalOpen(pJfd);
+   return SQLITE_OK;
+ }
+ 
+@@ -81060,21 +93031,19 @@
+ ** Close the file.
+ */
+ static int memjrnlClose(sqlite3_file *pJfd){
+-  memjrnlTruncate(pJfd, 0);
++  MemJournal *p = (MemJournal *)pJfd;
++  memjrnlFreeChunks(p);
+   return SQLITE_OK;
+ }
+ 
+-
+ /*
+ ** Sync the file.
+ **
+-** Syncing an in-memory journal is a no-op.  And, in fact, this routine
+-** is never called in a working implementation.  This implementation
+-** exists purely as a contingency, in case some malfunction in some other
+-** part of SQLite causes Sync to be called by mistake.
++** If the real file has been created, call its xSync method. Otherwise, 
++** syncing an in-memory journal is a no-op. 
+ */
+-static int memjrnlSync(sqlite3_file *NotUsed, int NotUsed2){
+-  UNUSED_PARAMETER2(NotUsed, NotUsed2);
++static int memjrnlSync(sqlite3_file *pJfd, int flags){
++  UNUSED_PARAMETER2(pJfd, flags);
+   return SQLITE_OK;
+ }
+ 
+@@ -81113,28 +93082,88 @@
+ };
+ 
+ /* 
+-** Open a journal file.
++** Open a journal file. 
++**
++** The behaviour of the journal file depends on the value of parameter 
++** nSpill. If nSpill is 0, then the journal file is always create and 
++** accessed using the underlying VFS. If nSpill is less than zero, then
++** all content is always stored in main-memory. Finally, if nSpill is a
++** positive value, then the journal file is initially created in-memory
++** but may be flushed to disk later on. In this case the journal file is
++** flushed to disk either when it grows larger than nSpill bytes in size,
++** or when sqlite3JournalCreate() is called.
++*/
++SQLITE_PRIVATE int sqlite3JournalOpen(
++  sqlite3_vfs *pVfs,         /* The VFS to use for actual file I/O */
++  const char *zName,         /* Name of the journal file */
++  sqlite3_file *pJfd,        /* Preallocated, blank file handle */
++  int flags,                 /* Opening flags */
++  int nSpill                 /* Bytes buffered before opening the file */
++){
++  MemJournal *p = (MemJournal*)pJfd;
++
++  /* Zero the file-handle object. If nSpill was passed zero, initialize
++  ** it using the sqlite3OsOpen() function of the underlying VFS. In this
++  ** case none of the code in this module is executed as a result of calls
++  ** made on the journal file-handle.  */
++  memset(p, 0, sizeof(MemJournal));
++  if( nSpill==0 ){
++    return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
++  }
++
++  if( nSpill>0 ){
++    p->nChunkSize = nSpill;
++  }else{
++    p->nChunkSize = 8 + MEMJOURNAL_DFLT_FILECHUNKSIZE - sizeof(FileChunk);
++    assert( MEMJOURNAL_DFLT_FILECHUNKSIZE==fileChunkSize(p->nChunkSize) );
++  }
++
++  p->pMethod = (const sqlite3_io_methods*)&MemJournalMethods;
++  p->nSpill = nSpill;
++  p->flags = flags;
++  p->zJournal = zName;
++  p->pVfs = pVfs;
++  return SQLITE_OK;
++}
++
++/*
++** Open an in-memory journal file.
+ */
+ SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *pJfd){
+-  MemJournal *p = (MemJournal *)pJfd;
+-  assert( EIGHT_BYTE_ALIGNMENT(p) );
+-  memset(p, 0, sqlite3MemJournalSize());
+-  p->pMethod = (sqlite3_io_methods*)&MemJournalMethods;
++  sqlite3JournalOpen(0, 0, pJfd, 0, -1);
++}
++
++#ifdef SQLITE_ENABLE_ATOMIC_WRITE
++/*
++** If the argument p points to a MemJournal structure that is not an 
++** in-memory-only journal file (i.e. is one that was opened with a +ve
++** nSpill parameter), and the underlying file has not yet been created, 
++** create it now.
++*/
++SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){
++  int rc = SQLITE_OK;
++  if( p->pMethods==&MemJournalMethods && ((MemJournal*)p)->nSpill>0 ){
++    rc = memjrnlCreateFile((MemJournal*)p);
++  }
++  return rc;
+ }
++#endif
+ 
+ /*
+-** Return true if the file-handle passed as an argument is 
+-** an in-memory journal 
++** The file-handle passed as the only argument is open on a journal file.
++** Return true if this "journal file" is currently stored in heap memory,
++** or false otherwise.
+ */
+-SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *pJfd){
+-  return pJfd->pMethods==&MemJournalMethods;
++SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p){
++  return p->pMethods==&MemJournalMethods;
+ }
+ 
+ /* 
+-** Return the number of bytes required to store a MemJournal file descriptor.
++** Return the number of bytes required to store a JournalFile that uses vfs
++** pVfs to create the underlying on-disk files.
+ */
+-SQLITE_PRIVATE int sqlite3MemJournalSize(void){
+-  return sizeof(MemJournal);
++SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
++  return MAX(pVfs->szOsFile, (int)sizeof(MemJournal));
+ }
+ 
+ /************** End of memjournal.c ******************************************/
+@@ -81153,6 +93182,7 @@
+ ** This file contains routines used for walking the parser tree for
+ ** an SQL statement.
+ */
++/* #include "sqliteInt.h" */
+ /* #include <stdlib.h> */
+ /* #include <string.h> */
+ 
+@@ -81167,32 +93197,36 @@
+ **
+ **    WRC_Continue      Continue descending down the tree.
+ **
+-**    WRC_Prune         Do not descend into child nodes.  But allow
++**    WRC_Prune         Do not descend into child nodes, but allow
+ **                      the walk to continue with sibling nodes.
+ **
+ **    WRC_Abort         Do no more callbacks.  Unwind the stack and
+-**                      return the top-level walk call.
++**                      return from the top-level walk call.
+ **
+ ** The return value from this routine is WRC_Abort to abandon the tree walk
+ ** and WRC_Continue to continue.
+ */
+-SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
++static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
+   int rc;
+-  if( pExpr==0 ) return WRC_Continue;
+   testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
+   testcase( ExprHasProperty(pExpr, EP_Reduced) );
+   rc = pWalker->xExprCallback(pWalker, pExpr);
+-  if( rc==WRC_Continue
+-              && !ExprHasProperty(pExpr,EP_TokenOnly) ){
+-    if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
+-    if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
+-    if( ExprHasProperty(pExpr, EP_xIsSelect) ){
++  if( rc ) return rc & WRC_Abort;
++  if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
++    if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
++    assert( pExpr->x.pList==0 || pExpr->pRight==0 );
++    if( pExpr->pRight ){
++      if( walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
++    }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+       if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
+-    }else{
++    }else if( pExpr->x.pList ){
+       if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
+     }
+   }
+-  return rc & WRC_Abort;
++  return WRC_Continue;
++}
++SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
++  return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue;
+ }
+ 
+ /*
+@@ -81242,7 +93276,12 @@
+   pSrc = p->pSrc;
+   if( ALWAYS(pSrc) ){
+     for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
+-      if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){
++      if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
++        return WRC_Abort;
++      }
++      if( pItem->fg.isTabFunc
++       && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
++      ){
+         return WRC_Abort;
+       }
+     }
+@@ -81257,8 +93296,9 @@
+ **
+ ** If it is not NULL, the xSelectCallback() callback is invoked before
+ ** the walk of the expressions and FROM clause. The xSelectCallback2()
+-** method, if it is not NULL, is invoked following the walk of the 
+-** expressions and FROM clause.
++** method is invoked following the walk of the expressions and FROM clause,
++** but only if both xSelectCallback and xSelectCallback2 are both non-NULL
++** and if the expressions and FROM clause both return WRC_Continue;
+ **
+ ** Return WRC_Continue under normal conditions.  Return WRC_Abort if
+ ** there is an abort request.
+@@ -81268,29 +93308,22 @@
+ */
+ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
+   int rc;
+-  if( p==0 || (pWalker->xSelectCallback==0 && pWalker->xSelectCallback2==0) ){
+-    return WRC_Continue;
+-  }
+-  rc = WRC_Continue;
+-  pWalker->walkerDepth++;
+-  while( p ){
+-    if( pWalker->xSelectCallback ){
+-       rc = pWalker->xSelectCallback(pWalker, p);
+-       if( rc ) break;
+-    }
++  if( p==0 ) return WRC_Continue;
++  if( pWalker->xSelectCallback==0 ) return WRC_Continue;
++  do{
++    rc = pWalker->xSelectCallback(pWalker, p);
++    if( rc ) return rc & WRC_Abort;
+     if( sqlite3WalkSelectExpr(pWalker, p)
+      || sqlite3WalkSelectFrom(pWalker, p)
+     ){
+-      pWalker->walkerDepth--;
+       return WRC_Abort;
+     }
+     if( pWalker->xSelectCallback2 ){
+       pWalker->xSelectCallback2(pWalker, p);
+     }
+     p = p->pPrior;
+-  }
+-  pWalker->walkerDepth--;
+-  return rc & WRC_Abort;
++  }while( p!=0 );
++  return WRC_Continue;
+ }
+ 
+ /************** End of walker.c **********************************************/
+@@ -81311,8 +93344,7 @@
+ ** resolve all identifiers by associating them with a particular
+ ** table and column.
+ */
+-/* #include <stdlib.h> */
+-/* #include <string.h> */
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** Walk the expression tree pExpr and increase the aggregate function
+@@ -81341,30 +93373,6 @@
+ ** Turn the pExpr expression into an alias for the iCol-th column of the
+ ** result set in pEList.
+ **
+-** If the result set column is a simple column reference, then this routine
+-** makes an exact copy.  But for any other kind of expression, this
+-** routine make a copy of the result set column as the argument to the
+-** TK_AS operator.  The TK_AS operator causes the expression to be
+-** evaluated just once and then reused for each alias.
+-**
+-** The reason for suppressing the TK_AS term when the expression is a simple
+-** column reference is so that the column reference will be recognized as
+-** usable by indices within the WHERE clause processing logic. 
+-**
+-** The TK_AS operator is inhibited if zType[0]=='G'.  This means
+-** that in a GROUP BY clause, the expression is evaluated twice.  Hence:
+-**
+-**     SELECT random()%5 AS x, count(*) FROM tab GROUP BY x
+-**
+-** Is equivalent to:
+-**
+-**     SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
+-**
+-** The result of random()%5 in the GROUP BY clause is probably different
+-** from the result in the result-set.  On the other hand Standard SQL does
+-** not allow the GROUP BY clause to contain references to result-set columns.
+-** So this should never come up in well-formed queries.
+-**
+ ** If the reference is followed by a COLLATE operator, then make sure
+ ** the COLLATE operator is preserved.  For example:
+ **
+@@ -81398,19 +93406,11 @@
+   db = pParse->db;
+   pDup = sqlite3ExprDup(db, pOrig, 0);
+   if( pDup==0 ) return;
+-  if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
+-    incrAggFunctionDepth(pDup, nSubquery);
+-    pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
+-    if( pDup==0 ) return;
+-    ExprSetProperty(pDup, EP_Skip);
+-    if( pEList->a[iCol].u.x.iAlias==0 ){
+-      pEList->a[iCol].u.x.iAlias = (u16)(++pParse->nAlias);
+-    }
+-    pDup->iTable = pEList->a[iCol].u.x.iAlias;
+-  }
++  if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery);
+   if( pExpr->op==TK_COLLATE ){
+     pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
+   }
++  ExprSetProperty(pDup, EP_Alias);
+ 
+   /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This 
+   ** prevents ExprDelete() from deleting the Expr structure itself,
+@@ -81549,8 +93549,8 @@
+       zDb = 0;
+     }else{
+       for(i=0; i<db->nDb; i++){
+-        assert( db->aDb[i].zName );
+-        if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
++        assert( db->aDb[i].zDbSName );
++        if( sqlite3StrICmp(db->aDb[i].zDbSName,zDb)==0 ){
+           pSchema = db->aDb[i].pSchema;
+           break;
+         }
+@@ -81559,7 +93559,8 @@
+   }
+ 
+   /* Start at the inner-most context and move outward until a match is found */
+-  while( pNC && cnt==0 ){
++  assert( pNC && cnt==0 );
++  do{
+     ExprList *pEList;
+     SrcList *pSrcList = pNC->pSrcList;
+ 
+@@ -81602,7 +93603,7 @@
+             ** USING clause, then skip this match.
+             */
+             if( cnt==1 ){
+-              if( pItem->jointype & JT_NATURAL ) continue;
++              if( pItem->fg.jointype & JT_NATURAL ) continue;
+               if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
+             }
+             cnt++;
+@@ -81617,8 +93618,8 @@
+         pExpr->iTable = pMatch->iCursor;
+         pExpr->pTab = pMatch->pTab;
+         /* RIGHT JOIN not (yet) supported */
+-        assert( (pMatch->jointype & JT_RIGHT)==0 );
+-        if( (pMatch->jointype & JT_LEFT)!=0 ){
++        assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
++        if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
+           ExprSetProperty(pExpr, EP_CanBeNull);
+         }
+         pSchema = pExpr->pTab->pSchema;
+@@ -81654,9 +93655,8 @@
+             break;
+           }
+         }
+-        if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
++        if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){
+           /* IMP: R-51414-32910 */
+-          /* IMP: R-44911-55124 */
+           iCol = -1;
+         }
+         if( iCol<pTab->nCol ){
+@@ -81683,10 +93683,15 @@
+     /*
+     ** Perhaps the name is a reference to the ROWID
+     */
+-    if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol)
+-     && HasRowid(pMatch->pTab) ){
++    if( cnt==0
++     && cntTab==1
++     && pMatch
++     && (pNC->ncFlags & NC_IdxExpr)==0
++     && sqlite3IsRowid(zCol)
++     && VisibleRowid(pMatch->pTab)
++    ){
+       cnt = 1;
+-      pExpr->iColumn = -1;     /* IMP: R-44911-55124 */
++      pExpr->iColumn = -1;
+       pExpr->affinity = SQLITE_AFF_INTEGER;
+     }
+ 
+@@ -81703,9 +93708,9 @@
+     ** resolved by the time the WHERE clause is resolved.
+     **
+     ** The ability to use an output result-set column in the WHERE, GROUP BY,
+-    ** or HAVING clauses, or as part of a larger expression in the ORDRE BY
++    ** or HAVING clauses, or as part of a larger expression in the ORDER BY
+     ** clause is not standard SQL.  This is a (goofy) SQLite extension, that
+-    ** is supported for backwards compatibility only.  TO DO: Issue a warning
++    ** is supported for backwards compatibility only. Hence, we issue a warning
+     ** on sqlite3_log() whenever the capability is used.
+     */
+     if( (pEList = pNC->pEList)!=0
+@@ -81724,6 +93729,10 @@
+             sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
+             return WRC_Abort;
+           }
++          if( sqlite3ExprVectorSize(pOrig)!=1 ){
++            sqlite3ErrorMsg(pParse, "row value misused");
++            return WRC_Abort;
++          }
+           resolveAlias(pParse, pEList, j, pExpr, "", nSubquery);
+           cnt = 1;
+           pMatch = 0;
+@@ -81736,11 +93745,11 @@
+     /* Advance to the next name context.  The loop will exit when either
+     ** we have a match (cnt>0) or when we run out of name contexts.
+     */
+-    if( cnt==0 ){
+-      pNC = pNC->pNext;
+-      nSubquery++;
+-    }
+-  }
++    if( cnt ) break;
++    pNC = pNC->pNext;
++    nSubquery++;
++  }while( pNC );
++
+ 
+   /*
+   ** If X and Y are NULL (in other words if only the column name Z is
+@@ -81799,10 +93808,11 @@
+   sqlite3ExprDelete(db, pExpr->pRight);
+   pExpr->pRight = 0;
+   pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
++  ExprSetProperty(pExpr, EP_Leaf);
+ lookupname_end:
+   if( cnt==1 ){
+     assert( pNC!=0 );
+-    if( pExpr->op!=TK_AS ){
++    if( !ExprHasProperty(pExpr, EP_Alias) ){
+       sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
+     }
+     /* Increment the nRef value on all name contexts from TopNC up to
+@@ -81837,42 +93847,30 @@
+       testcase( iCol==BMS-1 );
+       pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
+     }
+-    ExprSetProperty(p, EP_Resolved);
+   }
+   return p;
+ }
+ 
+ /*
+-** Report an error that an expression is not valid for a partial index WHERE
+-** clause.
++** Report an error that an expression is not valid for some set of
++** pNC->ncFlags values determined by validMask.
+ */
+-static void notValidPartIdxWhere(
++static void notValid(
+   Parse *pParse,       /* Leave error message here */
+   NameContext *pNC,    /* The name context */
+-  const char *zMsg     /* Type of error */
++  const char *zMsg,    /* Type of error */
++  int validMask        /* Set of contexts for which prohibited */
+ ){
+-  if( (pNC->ncFlags & NC_PartIdx)!=0 ){
+-    sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses",
+-                    zMsg);
+-  }
+-}
+-
++  assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr))==0 );
++  if( (pNC->ncFlags & validMask)!=0 ){
++    const char *zIn = "partial index WHERE clauses";
++    if( pNC->ncFlags & NC_IdxExpr )      zIn = "index expressions";
+ #ifndef SQLITE_OMIT_CHECK
+-/*
+-** Report an error that an expression is not valid for a CHECK constraint.
+-*/
+-static void notValidCheckConstraint(
+-  Parse *pParse,       /* Leave error message here */
+-  NameContext *pNC,    /* The name context */
+-  const char *zMsg     /* Type of error */
+-){
+-  if( (pNC->ncFlags & NC_IsCheck)!=0 ){
+-    sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg);
++    else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
++#endif
++    sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
+   }
+ }
+-#else
+-# define notValidCheckConstraint(P,N,M)
+-#endif
+ 
+ /*
+ ** Expression p should encode a floating point value between 1.0 and 0.0.
+@@ -81908,8 +93906,6 @@
+   pParse = pNC->pParse;
+   assert( pParse==pWalker->pParse );
+ 
+-  if( ExprHasProperty(pExpr, EP_Resolved) ) return WRC_Prune;
+-  ExprSetProperty(pExpr, EP_Resolved);
+ #ifndef NDEBUG
+   if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){
+     SrcList *pSrcList = pNC->pSrcList;
+@@ -81941,32 +93937,38 @@
+ #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
+           && !defined(SQLITE_OMIT_SUBQUERY) */
+ 
+-    /* A lone identifier is the name of a column.
+-    */
+-    case TK_ID: {
+-      return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr);
+-    }
+-  
+-    /* A table name and column name:     ID.ID
++    /* A column name:                    ID
++    ** Or table name and column name:    ID.ID
+     ** Or a database, table and column:  ID.ID.ID
++    **
++    ** The TK_ID and TK_OUT cases are combined so that there will only
++    ** be one call to lookupName().  Then the compiler will in-line 
++    ** lookupName() for a size reduction and performance increase.
+     */
++    case TK_ID:
+     case TK_DOT: {
+       const char *zColumn;
+       const char *zTable;
+       const char *zDb;
+       Expr *pRight;
+ 
+-      /* if( pSrcList==0 ) break; */
+-      pRight = pExpr->pRight;
+-      if( pRight->op==TK_ID ){
++      if( pExpr->op==TK_ID ){
+         zDb = 0;
+-        zTable = pExpr->pLeft->u.zToken;
+-        zColumn = pRight->u.zToken;
++        zTable = 0;
++        zColumn = pExpr->u.zToken;
+       }else{
+-        assert( pRight->op==TK_DOT );
+-        zDb = pExpr->pLeft->u.zToken;
+-        zTable = pRight->pLeft->u.zToken;
+-        zColumn = pRight->pRight->u.zToken;
++        notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
++        pRight = pExpr->pRight;
++        if( pRight->op==TK_ID ){
++          zDb = 0;
++          zTable = pExpr->pLeft->u.zToken;
++          zColumn = pRight->u.zToken;
++        }else{
++          assert( pRight->op==TK_DOT );
++          zDb = pExpr->pLeft->u.zToken;
++          zTable = pRight->pLeft->u.zToken;
++          zColumn = pRight->pRight->u.zToken;
++        }
+       }
+       return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
+     }
+@@ -81979,26 +93981,24 @@
+       int no_such_func = 0;       /* True if no such function exists */
+       int wrong_num_args = 0;     /* True if wrong number of arguments */
+       int is_agg = 0;             /* True if is an aggregate function */
+-      int auth;                   /* Authorization to use the function */
+       int nId;                    /* Number of characters in function name */
+       const char *zId;            /* The function name. */
+       FuncDef *pDef;              /* Information about the function */
+       u8 enc = ENC(pParse->db);   /* The database encoding */
+ 
+       assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+-      notValidPartIdxWhere(pParse, pNC, "functions");
+       zId = pExpr->u.zToken;
+       nId = sqlite3Strlen30(zId);
+-      pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
++      pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
+       if( pDef==0 ){
+-        pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
++        pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
+         if( pDef==0 ){
+           no_such_func = 1;
+         }else{
+           wrong_num_args = 1;
+         }
+       }else{
+-        is_agg = pDef->xFunc==0;
++        is_agg = pDef->xFinalize!=0;
+         if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
+           ExprSetProperty(pExpr, EP_Unlikely|EP_Skip);
+           if( n==2 ){
+@@ -82023,26 +94023,42 @@
+           }             
+         }
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+-        auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
+-        if( auth!=SQLITE_OK ){
+-          if( auth==SQLITE_DENY ){
+-            sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
+-                                    pDef->zName);
+-            pNC->nErr++;
++        {
++          int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0);
++          if( auth!=SQLITE_OK ){
++            if( auth==SQLITE_DENY ){
++              sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
++                                      pDef->zName);
++              pNC->nErr++;
++            }
++            pExpr->op = TK_NULL;
++            return WRC_Prune;
+           }
+-          pExpr->op = TK_NULL;
+-          return WRC_Prune;
+         }
+ #endif
+-        if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ){
++        if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
++          /* For the purposes of the EP_ConstFunc flag, date and time
++          ** functions and other functions that change slowly are considered
++          ** constant because they are constant for the duration of one query */
+           ExprSetProperty(pExpr,EP_ConstFunc);
+         }
++        if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
++          /* Date/time functions that use 'now', and other functions like
++          ** sqlite_version() that might change over time cannot be used
++          ** in an index. */
++          notValid(pParse, pNC, "non-deterministic functions",
++                   NC_IdxExpr|NC_PartIdx);
++        }
+       }
+       if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
+         sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
+         pNC->nErr++;
+         is_agg = 0;
+-      }else if( no_such_func && pParse->db->init.busy==0 ){
++      }else if( no_such_func && pParse->db->init.busy==0
++#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
++                && pParse->explain==0
++#endif
++      ){
+         sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
+         pNC->nErr++;
+       }else if( wrong_num_args ){
+@@ -82082,21 +94098,56 @@
+       testcase( pExpr->op==TK_IN );
+       if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+         int nRef = pNC->nRef;
+-        notValidCheckConstraint(pParse, pNC, "subqueries");
+-        notValidPartIdxWhere(pParse, pNC, "subqueries");
++        notValid(pParse, pNC, "subqueries", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
+         sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
+         assert( pNC->nRef>=nRef );
+         if( nRef!=pNC->nRef ){
+           ExprSetProperty(pExpr, EP_VarSelect);
++          pNC->ncFlags |= NC_VarSelect;
+         }
+       }
+       break;
+     }
+     case TK_VARIABLE: {
+-      notValidCheckConstraint(pParse, pNC, "parameters");
+-      notValidPartIdxWhere(pParse, pNC, "parameters");
++      notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
+       break;
+     }
++    case TK_BETWEEN:
++    case TK_EQ:
++    case TK_NE:
++    case TK_LT:
++    case TK_LE:
++    case TK_GT:
++    case TK_GE:
++    case TK_IS:
++    case TK_ISNOT: {
++      int nLeft, nRight;
++      if( pParse->db->mallocFailed ) break;
++      assert( pExpr->pLeft!=0 );
++      nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
++      if( pExpr->op==TK_BETWEEN ){
++        nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr);
++        if( nRight==nLeft ){
++          nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr);
++        }
++      }else{
++        assert( pExpr->pRight!=0 );
++        nRight = sqlite3ExprVectorSize(pExpr->pRight);
++      }
++      if( nLeft!=nRight ){
++        testcase( pExpr->op==TK_EQ );
++        testcase( pExpr->op==TK_NE );
++        testcase( pExpr->op==TK_LT );
++        testcase( pExpr->op==TK_LE );
++        testcase( pExpr->op==TK_GT );
++        testcase( pExpr->op==TK_GE );
++        testcase( pExpr->op==TK_IS );
++        testcase( pExpr->op==TK_ISNOT );
++        testcase( pExpr->op==TK_BETWEEN );
++        sqlite3ErrorMsg(pParse, "row value misused");
++      }
++      break; 
++    }
+   }
+   return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
+ }
+@@ -82187,7 +94238,7 @@
+   ** result-set entry.
+   */
+   for(i=0; i<pEList->nExpr; i++){
+-    if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){
++    if( sqlite3ExprCompare(0, pEList->a[i].pExpr, pE, -1)<2 ){
+       return i+1;
+     }
+   }
+@@ -82421,7 +94472,7 @@
+       return 1;
+     }
+     for(j=0; j<pSelect->pEList->nExpr; j++){
+-      if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
++      if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
+         pItem->u.x.iOrderByCol = j+1;
+       }
+     }
+@@ -82438,7 +94489,6 @@
+   int isCompound;         /* True if p is a compound select */
+   int nCompound;          /* Number of compound terms processed so far */
+   Parse *pParse;          /* Parsing context */
+-  ExprList *pEList;       /* Result set expression list */
+   int i;                  /* Loop counter */
+   ExprList *pGroupBy;     /* The GROUP BY clause */
+   Select *pLeftmost;      /* Left-most of SELECT of a compound */
+@@ -82511,7 +94561,7 @@
+         ** parent contexts. After resolving references to expressions in
+         ** pItem->pSelect, check if this value has changed. If so, then
+         ** SELECT statement pItem->pSelect must be correlated. Set the
+-        ** pItem->isCorrelated flag if this is the case. */
++        ** pItem->fg.isCorrelated flag if this is the case. */
+         for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef;
+ 
+         if( pItem->zName ) pParse->zAuthContext = pItem->zName;
+@@ -82520,8 +94570,8 @@
+         if( pParse->nErr || db->mallocFailed ) return WRC_Abort;
+ 
+         for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef;
+-        assert( pItem->isCorrelated==0 && nRef<=0 );
+-        pItem->isCorrelated = (nRef!=0);
++        assert( pItem->fg.isCorrelated==0 && nRef<=0 );
++        pItem->fg.isCorrelated = (nRef!=0);
+       }
+     }
+   
+@@ -82533,14 +94583,7 @@
+     sNC.pNext = pOuterNC;
+   
+     /* Resolve names in the result set. */
+-    pEList = p->pEList;
+-    assert( pEList!=0 );
+-    for(i=0; i<pEList->nExpr; i++){
+-      Expr *pX = pEList->a[i].pExpr;
+-      if( sqlite3ResolveExprNames(&sNC, pX) ){
+-        return WRC_Abort;
+-      }
+-    }
++    if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort;
+   
+     /* If there are no aggregate functions in the result-set, and no GROUP BY 
+     ** expression, do not allow aggregates in any of the other expressions.
+@@ -82573,6 +94616,16 @@
+     if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
+     if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
+ 
++    /* Resolve names in table-valued-function arguments */
++    for(i=0; i<p->pSrc->nSrc; i++){
++      struct SrcList_item *pItem = &p->pSrc->a[i];
++      if( pItem->fg.isTabFunc
++       && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) 
++      ){
++        return WRC_Abort;
++      }
++    }
++
+     /* The ORDER BY and GROUP BY clauses may not refer to terms in
+     ** outer queries 
+     */
+@@ -82627,6 +94680,13 @@
+       }
+     }
+ 
++    /* If this is part of a compound SELECT, check that it has the right
++    ** number of expressions in the select list. */
++    if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){
++      sqlite3SelectWrongNumTermsError(pParse, p->pNext);
++      return WRC_Abort;
++    }
++
+     /* Advance to the next term of the compound
+     */
+     p = p->pPrior;
+@@ -82698,37 +94758,48 @@
+   u16 savedHasAgg;
+   Walker w;
+ 
+-  if( pExpr==0 ) return 0;
+-#if SQLITE_MAX_EXPR_DEPTH>0
+-  {
+-    Parse *pParse = pNC->pParse;
+-    if( sqlite3ExprCheckHeight(pParse, pExpr->nHeight+pNC->pParse->nHeight) ){
+-      return 1;
+-    }
+-    pParse->nHeight += pExpr->nHeight;
+-  }
+-#endif
++  if( pExpr==0 ) return SQLITE_OK;
+   savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg);
+   pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg);
+-  memset(&w, 0, sizeof(w));
++  w.pParse = pNC->pParse;
+   w.xExprCallback = resolveExprStep;
+   w.xSelectCallback = resolveSelectStep;
+-  w.pParse = pNC->pParse;
++  w.xSelectCallback2 = 0;
+   w.u.pNC = pNC;
++#if SQLITE_MAX_EXPR_DEPTH>0
++  w.pParse->nHeight += pExpr->nHeight;
++  if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
++    return SQLITE_ERROR;
++  }
++#endif
+   sqlite3WalkExpr(&w, pExpr);
+ #if SQLITE_MAX_EXPR_DEPTH>0
+-  pNC->pParse->nHeight -= pExpr->nHeight;
++  w.pParse->nHeight -= pExpr->nHeight;
+ #endif
+-  if( pNC->nErr>0 || w.pParse->nErr>0 ){
+-    ExprSetProperty(pExpr, EP_Error);
+-  }
+   if( pNC->ncFlags & NC_HasAgg ){
+     ExprSetProperty(pExpr, EP_Agg);
+   }
+   pNC->ncFlags |= savedHasAgg;
+-  return ExprHasProperty(pExpr, EP_Error);
++  return pNC->nErr>0 || w.pParse->nErr>0;
+ }
+ 
++/*
++** Resolve all names for all expression in an expression list.  This is
++** just like sqlite3ResolveExprNames() except that it works for an expression
++** list rather than a single expression.
++*/
++SQLITE_PRIVATE int sqlite3ResolveExprListNames( 
++  NameContext *pNC,       /* Namespace to resolve expressions in. */
++  ExprList *pList         /* The expression list to be analyzed. */
++){
++  int i;
++  if( pList ){
++    for(i=0; i<pList->nExpr; i++){
++      if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort;
++    }
++  }
++  return WRC_Continue;
++}
+ 
+ /*
+ ** Resolve all names in all expressions of a SELECT and in all
+@@ -82750,9 +94821,9 @@
+   Walker w;
+ 
+   assert( p!=0 );
+-  memset(&w, 0, sizeof(w));
+   w.xExprCallback = resolveExprStep;
+   w.xSelectCallback = resolveSelectStep;
++  w.xSelectCallback2 = 0;
+   w.pParse = pParse;
+   w.u.pNC = pOuterNC;
+   sqlite3WalkSelect(&w, p);
+@@ -82772,15 +94843,14 @@
+ SQLITE_PRIVATE void sqlite3ResolveSelfReference(
+   Parse *pParse,      /* Parsing context */
+   Table *pTab,        /* The table being referenced */
+-  int type,           /* NC_IsCheck or NC_PartIdx */
++  int type,           /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */
+   Expr *pExpr,        /* Expression to resolve.  May be NULL. */
+   ExprList *pList     /* Expression list to resolve.  May be NUL. */
+ ){
+   SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
+   NameContext sNC;                /* Name context for pParse->pNewTable */
+-  int i;                          /* Loop counter */
+ 
+-  assert( type==NC_IsCheck || type==NC_PartIdx );
++  assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr );
+   memset(&sNC, 0, sizeof(sNC));
+   memset(&sSrc, 0, sizeof(sSrc));
+   sSrc.nSrc = 1;
+@@ -82791,13 +94861,7 @@
+   sNC.pSrcList = &sSrc;
+   sNC.ncFlags = type;
+   if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
+-  if( pList ){
+-    for(i=0; i<pList->nExpr; i++){
+-      if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
+-        return;
+-      }
+-    }
+-  }
++  if( pList ) sqlite3ResolveExprListNames(&sNC, pList);
+ }
+ 
+ /************** End of resolve.c *********************************************/
+@@ -82816,6 +94880,19 @@
+ ** This file contains routines used for analyzing expressions and
+ ** for generating VDBE code that evaluates expressions in SQLite.
+ */
++/* #include "sqliteInt.h" */
++
++/* Forward declarations */
++static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int);
++static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree);
++
++/*
++** Return the affinity character for a single column of a table.
++*/
++SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table *pTab, int iCol){
++  assert( iCol<pTab->nCol );
++  return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
++}
+ 
+ /*
+ ** Return the 'affinity' of the expression pExpr if any.
+@@ -82842,21 +94919,21 @@
+     assert( pExpr->flags&EP_xIsSelect );
+     return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
+   }
++  if( op==TK_REGISTER ) op = pExpr->op2;
+ #ifndef SQLITE_OMIT_CAST
+   if( op==TK_CAST ){
+     assert( !ExprHasProperty(pExpr, EP_IntValue) );
+     return sqlite3AffinityType(pExpr->u.zToken, 0);
+   }
+ #endif
+-  if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER) 
+-   && pExpr->pTab!=0
+-  ){
+-    /* op==TK_REGISTER && pExpr->pTab!=0 happens when pExpr was originally
+-    ** a TK_COLUMN but was previously evaluated and cached in a register */
+-    int j = pExpr->iColumn;
+-    if( j<0 ) return SQLITE_AFF_INTEGER;
+-    assert( pExpr->pTab && j<pExpr->pTab->nCol );
+-    return pExpr->pTab->aCol[j].affinity;
++  if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
++    return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
++  }
++  if( op==TK_SELECT_COLUMN ){
++    assert( pExpr->pLeft->flags&EP_xIsSelect );
++    return sqlite3ExprAffinity(
++        pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
++    );
+   }
+   return pExpr->affinity;
+ }
+@@ -82888,13 +94965,12 @@
+ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
+   Token s;
+   assert( zC!=0 );
+-  s.z = zC;
+-  s.n = sqlite3Strlen30(s.z);
++  sqlite3TokenInit(&s, (char*)zC);
+   return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
+ }
+ 
+ /*
+-** Skip over any TK_COLLATE or TK_AS operators and any unlikely()
++** Skip over any TK_COLLATE operators and any unlikely()
+ ** or likelihood() function at the root of an expression.
+ */
+ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
+@@ -82905,7 +94981,7 @@
+       assert( pExpr->op==TK_FUNCTION );
+       pExpr = pExpr->x.pList->a[0].pExpr;
+     }else{
+-      assert( pExpr->op==TK_COLLATE || pExpr->op==TK_AS );
++      assert( pExpr->op==TK_COLLATE );
+       pExpr = pExpr->pLeft;
+     }
+   }   
+@@ -82994,13 +95070,13 @@
+     if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){
+       return SQLITE_AFF_NUMERIC;
+     }else{
+-      return SQLITE_AFF_NONE;
++      return SQLITE_AFF_BLOB;
+     }
+   }else if( !aff1 && !aff2 ){
+     /* Neither side of the comparison is a column.  Compare the
+     ** results directly.
+     */
+-    return SQLITE_AFF_NONE;
++    return SQLITE_AFF_BLOB;
+   }else{
+     /* One side is a column, the other is not. Use the columns affinity. */
+     assert( aff1==0 || aff2==0 );
+@@ -83023,8 +95099,8 @@
+     aff = sqlite3CompareAffinity(pExpr->pRight, aff);
+   }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+     aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
+-  }else if( !aff ){
+-    aff = SQLITE_AFF_NONE;
++  }else if( aff==0 ){
++    aff = SQLITE_AFF_BLOB;
+   }
+   return aff;
+ }
+@@ -83038,7 +95114,7 @@
+ SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
+   char aff = comparisonAffinity(pExpr);
+   switch( aff ){
+-    case SQLITE_AFF_NONE:
++    case SQLITE_AFF_BLOB:
+       return 1;
+     case SQLITE_AFF_TEXT:
+       return idx_affinity==SQLITE_AFF_TEXT;
+@@ -83113,6 +95189,270 @@
+   return addr;
+ }
+ 
++/*
++** Return true if expression pExpr is a vector, or false otherwise.
++**
++** A vector is defined as any expression that results in two or more
++** columns of result.  Every TK_VECTOR node is an vector because the
++** parser will not generate a TK_VECTOR with fewer than two entries.
++** But a TK_SELECT might be either a vector or a scalar. It is only
++** considered a vector if it has two or more result columns.
++*/
++SQLITE_PRIVATE int sqlite3ExprIsVector(Expr *pExpr){
++  return sqlite3ExprVectorSize(pExpr)>1;
++}
++
++/*
++** If the expression passed as the only argument is of type TK_VECTOR 
++** return the number of expressions in the vector. Or, if the expression
++** is a sub-select, return the number of columns in the sub-select. For
++** any other type of expression, return 1.
++*/
++SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr){
++  u8 op = pExpr->op;
++  if( op==TK_REGISTER ) op = pExpr->op2;
++  if( op==TK_VECTOR ){
++    return pExpr->x.pList->nExpr;
++  }else if( op==TK_SELECT ){
++    return pExpr->x.pSelect->pEList->nExpr;
++  }else{
++    return 1;
++  }
++}
++
++/*
++** Return a pointer to a subexpression of pVector that is the i-th
++** column of the vector (numbered starting with 0).  The caller must
++** ensure that i is within range.
++**
++** If pVector is really a scalar (and "scalar" here includes subqueries
++** that return a single column!) then return pVector unmodified.
++**
++** pVector retains ownership of the returned subexpression.
++**
++** If the vector is a (SELECT ...) then the expression returned is
++** just the expression for the i-th term of the result set, and may
++** not be ready for evaluation because the table cursor has not yet
++** been positioned.
++*/
++SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
++  assert( i<sqlite3ExprVectorSize(pVector) );
++  if( sqlite3ExprIsVector(pVector) ){
++    assert( pVector->op2==0 || pVector->op==TK_REGISTER );
++    if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){
++      return pVector->x.pSelect->pEList->a[i].pExpr;
++    }else{
++      return pVector->x.pList->a[i].pExpr;
++    }
++  }
++  return pVector;
++}
++
++/*
++** Compute and return a new Expr object which when passed to
++** sqlite3ExprCode() will generate all necessary code to compute
++** the iField-th column of the vector expression pVector.
++**
++** It is ok for pVector to be a scalar (as long as iField==0).  
++** In that case, this routine works like sqlite3ExprDup().
++**
++** The caller owns the returned Expr object and is responsible for
++** ensuring that the returned value eventually gets freed.
++**
++** The caller retains ownership of pVector.  If pVector is a TK_SELECT,
++** then the returned object will reference pVector and so pVector must remain
++** valid for the life of the returned object.  If pVector is a TK_VECTOR
++** or a scalar expression, then it can be deleted as soon as this routine
++** returns.
++**
++** A trick to cause a TK_SELECT pVector to be deleted together with
++** the returned Expr object is to attach the pVector to the pRight field
++** of the returned TK_SELECT_COLUMN Expr object.
++*/
++SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(
++  Parse *pParse,       /* Parsing context */
++  Expr *pVector,       /* The vector.  List of expressions or a sub-SELECT */
++  int iField           /* Which column of the vector to return */
++){
++  Expr *pRet;
++  if( pVector->op==TK_SELECT ){
++    assert( pVector->flags & EP_xIsSelect );
++    /* The TK_SELECT_COLUMN Expr node:
++    **
++    ** pLeft:           pVector containing TK_SELECT.  Not deleted.
++    ** pRight:          not used.  But recursively deleted.
++    ** iColumn:         Index of a column in pVector
++    ** iTable:          0 or the number of columns on the LHS of an assignment
++    ** pLeft->iTable:   First in an array of register holding result, or 0
++    **                  if the result is not yet computed.
++    **
++    ** sqlite3ExprDelete() specifically skips the recursive delete of
++    ** pLeft on TK_SELECT_COLUMN nodes.  But pRight is followed, so pVector
++    ** can be attached to pRight to cause this node to take ownership of
++    ** pVector.  Typically there will be multiple TK_SELECT_COLUMN nodes
++    ** with the same pLeft pointer to the pVector, but only one of them
++    ** will own the pVector.
++    */
++    pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0);
++    if( pRet ){
++      pRet->iColumn = iField;
++      pRet->pLeft = pVector;
++    }
++    assert( pRet==0 || pRet->iTable==0 );
++  }else{
++    if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr;
++    pRet = sqlite3ExprDup(pParse->db, pVector, 0);
++  }
++  return pRet;
++}
++
++/*
++** If expression pExpr is of type TK_SELECT, generate code to evaluate
++** it. Return the register in which the result is stored (or, if the 
++** sub-select returns more than one column, the first in an array
++** of registers in which the result is stored).
++**
++** If pExpr is not a TK_SELECT expression, return 0.
++*/
++static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
++  int reg = 0;
++#ifndef SQLITE_OMIT_SUBQUERY
++  if( pExpr->op==TK_SELECT ){
++    reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
++  }
++#endif
++  return reg;
++}
++
++/*
++** Argument pVector points to a vector expression - either a TK_VECTOR
++** or TK_SELECT that returns more than one column. This function returns
++** the register number of a register that contains the value of
++** element iField of the vector.
++**
++** If pVector is a TK_SELECT expression, then code for it must have 
++** already been generated using the exprCodeSubselect() routine. In this
++** case parameter regSelect should be the first in an array of registers
++** containing the results of the sub-select. 
++**
++** If pVector is of type TK_VECTOR, then code for the requested field
++** is generated. In this case (*pRegFree) may be set to the number of
++** a temporary register to be freed by the caller before returning.
++**
++** Before returning, output parameter (*ppExpr) is set to point to the
++** Expr object corresponding to element iElem of the vector.
++*/
++static int exprVectorRegister(
++  Parse *pParse,                  /* Parse context */
++  Expr *pVector,                  /* Vector to extract element from */
++  int iField,                     /* Field to extract from pVector */
++  int regSelect,                  /* First in array of registers */
++  Expr **ppExpr,                  /* OUT: Expression element */
++  int *pRegFree                   /* OUT: Temp register to free */
++){
++  u8 op = pVector->op;
++  assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT );
++  if( op==TK_REGISTER ){
++    *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField);
++    return pVector->iTable+iField;
++  }
++  if( op==TK_SELECT ){
++    *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
++     return regSelect+iField;
++  }
++  *ppExpr = pVector->x.pList->a[iField].pExpr;
++  return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
++}
++
++/*
++** Expression pExpr is a comparison between two vector values. Compute
++** the result of the comparison (1, 0, or NULL) and write that
++** result into register dest.
++**
++** The caller must satisfy the following preconditions:
++**
++**    if pExpr->op==TK_IS:      op==TK_EQ and p5==SQLITE_NULLEQ
++**    if pExpr->op==TK_ISNOT:   op==TK_NE and p5==SQLITE_NULLEQ
++**    otherwise:                op==pExpr->op and p5==0
++*/
++static void codeVectorCompare(
++  Parse *pParse,        /* Code generator context */
++  Expr *pExpr,          /* The comparison operation */
++  int dest,             /* Write results into this register */
++  u8 op,                /* Comparison operator */
++  u8 p5                 /* SQLITE_NULLEQ or zero */
++){
++  Vdbe *v = pParse->pVdbe;
++  Expr *pLeft = pExpr->pLeft;
++  Expr *pRight = pExpr->pRight;
++  int nLeft = sqlite3ExprVectorSize(pLeft);
++  int i;
++  int regLeft = 0;
++  int regRight = 0;
++  u8 opx = op;
++  int addrDone = sqlite3VdbeMakeLabel(v);
++
++  if( nLeft!=sqlite3ExprVectorSize(pRight) ){
++    sqlite3ErrorMsg(pParse, "row value misused");
++    return;
++  }
++  assert( pExpr->op==TK_EQ || pExpr->op==TK_NE 
++       || pExpr->op==TK_IS || pExpr->op==TK_ISNOT 
++       || pExpr->op==TK_LT || pExpr->op==TK_GT 
++       || pExpr->op==TK_LE || pExpr->op==TK_GE 
++  );
++  assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ)
++            || (pExpr->op==TK_ISNOT && op==TK_NE) );
++  assert( p5==0 || pExpr->op!=op );
++  assert( p5==SQLITE_NULLEQ || pExpr->op==op );
++
++  p5 |= SQLITE_STOREP2;
++  if( opx==TK_LE ) opx = TK_LT;
++  if( opx==TK_GE ) opx = TK_GT;
++
++  regLeft = exprCodeSubselect(pParse, pLeft);
++  regRight = exprCodeSubselect(pParse, pRight);
++
++  for(i=0; 1 /*Loop exits by "break"*/; i++){
++    int regFree1 = 0, regFree2 = 0;
++    Expr *pL, *pR; 
++    int r1, r2;
++    assert( i>=0 && i<nLeft );
++    if( i>0 ) sqlite3ExprCachePush(pParse);
++    r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, &regFree1);
++    r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, &regFree2);
++    codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5);
++    testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
++    testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
++    testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
++    testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
++    testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
++    testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
++    sqlite3ReleaseTempReg(pParse, regFree1);
++    sqlite3ReleaseTempReg(pParse, regFree2);
++    if( i>0 ) sqlite3ExprCachePop(pParse);
++    if( i==nLeft-1 ){
++      break;
++    }
++    if( opx==TK_EQ ){
++      sqlite3VdbeAddOp2(v, OP_IfNot, dest, addrDone); VdbeCoverage(v);
++      p5 |= SQLITE_KEEPNULL;
++    }else if( opx==TK_NE ){
++      sqlite3VdbeAddOp2(v, OP_If, dest, addrDone); VdbeCoverage(v);
++      p5 |= SQLITE_KEEPNULL;
++    }else{
++      assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE );
++      sqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone);
++      VdbeCoverageIf(v, op==TK_LT);
++      VdbeCoverageIf(v, op==TK_GT);
++      VdbeCoverageIf(v, op==TK_LE);
++      VdbeCoverageIf(v, op==TK_GE);
++      if( i==nLeft-2 ) opx = op;
++    }
++  }
++  sqlite3VdbeResolveLabel(v, addrDone);
++}
++
+ #if SQLITE_MAX_EXPR_DEPTH>0
+ /*
+ ** Check that argument nHeight is less than or equal to the maximum
+@@ -83236,7 +95576,7 @@
+ ** is responsible for making sure the node eventually gets freed.
+ **
+ ** If dequote is true, then the token (if it exists) is dequoted.
+-** If dequote is false, no dequoting is performance.  The deQuote
++** If dequote is false, no dequoting is performed.  The deQuote
+ ** parameter is ignored if pToken is NULL or if the token does not
+ ** appear to be quoted.  If the quotes were of the form "..." (double-quotes)
+ ** then the EP_DblQuoted flag is set on the expression node.
+@@ -83248,7 +95588,7 @@
+ ** is allocated to hold the integer text and the dequote flag is ignored.
+ */
+ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
+-  sqlite3 *db,            /* Handle for sqlite3DbMallocZero() (may be null) */
++  sqlite3 *db,            /* Handle for sqlite3DbMallocRawNN() */
+   int op,                 /* Expression opcode */
+   const Token *pToken,    /* Token argument.  Might be NULL */
+   int dequote             /* True to dequote */
+@@ -83257,6 +95597,7 @@
+   int nExtra = 0;
+   int iValue = 0;
+ 
++  assert( db!=0 );
+   if( pToken ){
+     if( op!=TK_INTEGER || pToken->z==0
+           || sqlite3GetInt32(pToken->z, &iValue)==0 ){
+@@ -83264,24 +95605,23 @@
+       assert( iValue>=0 );
+     }
+   }
+-  pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra);
++  pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra);
+   if( pNew ){
++    memset(pNew, 0, sizeof(Expr));
+     pNew->op = (u8)op;
+     pNew->iAgg = -1;
+     if( pToken ){
+       if( nExtra==0 ){
+-        pNew->flags |= EP_IntValue;
++        pNew->flags |= EP_IntValue|EP_Leaf;
+         pNew->u.iValue = iValue;
+       }else{
+-        int c;
+         pNew->u.zToken = (char*)&pNew[1];
+         assert( pToken->z!=0 || pToken->n==0 );
+         if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
+         pNew->u.zToken[pToken->n] = 0;
+-        if( dequote && nExtra>=3 
+-             && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
++        if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
++          if( pNew->u.zToken[0]=='"' ) pNew->flags |= EP_DblQuoted;
+           sqlite3Dequote(pNew->u.zToken);
+-          if( c=='"' ) pNew->flags |= EP_DblQuoted;
+         }
+       }
+     }
+@@ -83347,15 +95687,19 @@
+   Parse *pParse,          /* Parsing context */
+   int op,                 /* Expression opcode */
+   Expr *pLeft,            /* Left operand */
+-  Expr *pRight,           /* Right operand */
+-  const Token *pToken     /* Argument token */
++  Expr *pRight            /* Right operand */
+ ){
+   Expr *p;
+-  if( op==TK_AND && pLeft && pRight && pParse->nErr==0 ){
++  if( op==TK_AND && pParse->nErr==0 ){
+     /* Take advantage of short-circuit false optimization for AND */
+     p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
+   }else{
+-    p = sqlite3ExprAlloc(pParse->db, op, pToken, 1);
++    p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
++    if( p ){
++      memset(p, 0, sizeof(Expr));
++      p->op = op & TKFLG_MASK;
++      p->iAgg = -1;
++    }
+     sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
+   }
+   if( p ) {
+@@ -83365,6 +95709,22 @@
+ }
+ 
+ /*
++** Add pSelect to the Expr.x.pSelect field.  Or, if pExpr is NULL (due
++** do a memory allocation failure) then delete the pSelect object.
++*/
++SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){
++  if( pExpr ){
++    pExpr->x.pSelect = pSelect;
++    ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery);
++    sqlite3ExprSetHeightAndFlags(pParse, pExpr);
++  }else{
++    assert( pParse->db->mallocFailed );
++    sqlite3SelectDelete(pParse->db, pSelect);
++  }
++}
++
++
++/*
+ ** If the expression is always either TRUE or FALSE (respectively),
+ ** then return 1.  If one cannot determine the truth value of the
+ ** expression at compile-time return 0.
+@@ -83442,7 +95802,7 @@
+ ** variable number.
+ **
+ ** Wildcards of the form "?nnn" are assigned the number "nnn".  We make
+-** sure "nnn" is not too be to avoid a denial of service attack when
++** sure "nnn" is not too big to avoid a denial of service attack when
+ ** the SQL statement comes from an external source.
+ **
+ ** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
+@@ -83450,28 +95810,34 @@
+ ** instance of the wildcard, the next sequential variable number is
+ ** assigned.
+ */
+-SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
++SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
+   sqlite3 *db = pParse->db;
+   const char *z;
++  ynVar x;
+ 
+   if( pExpr==0 ) return;
+   assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
+   z = pExpr->u.zToken;
+   assert( z!=0 );
+   assert( z[0]!=0 );
++  assert( n==(u32)sqlite3Strlen30(z) );
+   if( z[1]==0 ){
+     /* Wildcard of the form "?".  Assign the next variable number */
+     assert( z[0]=='?' );
+-    pExpr->iColumn = (ynVar)(++pParse->nVar);
++    x = (ynVar)(++pParse->nVar);
+   }else{
+-    ynVar x = 0;
+-    u32 n = sqlite3Strlen30(z);
++    int doAdd = 0;
+     if( z[0]=='?' ){
+       /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
+       ** use it as the variable number */
+       i64 i;
+-      int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
+-      pExpr->iColumn = x = (ynVar)i;
++      int bOk;
++      if( n==2 ){ /*OPTIMIZATION-IF-TRUE*/
++        i = z[1]-'0';  /* The common case of ?N for a single digit N */
++        bOk = 1;
++      }else{
++        bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
++      }
+       testcase( i==0 );
+       testcase( i==1 );
+       testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
+@@ -83479,41 +95845,32 @@
+       if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
+         sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
+             db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
+-        x = 0;
++        return;
+       }
+-      if( i>pParse->nVar ){
+-        pParse->nVar = (int)i;
++      x = (ynVar)i;
++      if( x>pParse->nVar ){
++        pParse->nVar = (int)x;
++        doAdd = 1;
++      }else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){
++        doAdd = 1;
+       }
+     }else{
+       /* Wildcards like ":aaa", "$aaa" or "@aaa".  Reuse the same variable
+       ** number as the prior appearance of the same name, or if the name
+       ** has never appeared before, reuse the same variable number
+       */
+-      ynVar i;
+-      for(i=0; i<pParse->nzVar; i++){
+-        if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){
+-          pExpr->iColumn = x = (ynVar)i+1;
+-          break;
+-        }
++      x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n);
++      if( x==0 ){
++        x = (ynVar)(++pParse->nVar);
++        doAdd = 1;
+       }
+-      if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar);
+     }
+-    if( x>0 ){
+-      if( x>pParse->nzVar ){
+-        char **a;
+-        a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0]));
+-        if( a==0 ) return;  /* Error reported through db->mallocFailed */
+-        pParse->azVar = a;
+-        memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0]));
+-        pParse->nzVar = x;
+-      }
+-      if( z[0]!='?' || pParse->azVar[x-1]==0 ){
+-        sqlite3DbFree(db, pParse->azVar[x-1]);
+-        pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n);
+-      }
++    if( doAdd ){
++      pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x);
+     }
+-  } 
+-  if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
++  }
++  pExpr->iColumn = x;
++  if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
+     sqlite3ErrorMsg(pParse, "too many SQL variables");
+   }
+ }
+@@ -83521,26 +95878,37 @@
+ /*
+ ** Recursively delete an expression tree.
+ */
+-SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
+-  if( p==0 ) return;
++static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
++  assert( p!=0 );
+   /* Sanity check: Assert that the IntValue is non-negative if it exists */
+   assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
+-  if( !ExprHasProperty(p, EP_TokenOnly) ){
++#ifdef SQLITE_DEBUG
++  if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
++    assert( p->pLeft==0 );
++    assert( p->pRight==0 );
++    assert( p->x.pSelect==0 );
++  }
++#endif
++  if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
+     /* The Expr.x union is never used at the same time as Expr.pRight */
+     assert( p->x.pList==0 || p->pRight==0 );
+-    sqlite3ExprDelete(db, p->pLeft);
+-    sqlite3ExprDelete(db, p->pRight);
+-    if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
+-    if( ExprHasProperty(p, EP_xIsSelect) ){
++    if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
++    if( p->pRight ){
++      sqlite3ExprDeleteNN(db, p->pRight);
++    }else if( ExprHasProperty(p, EP_xIsSelect) ){
+       sqlite3SelectDelete(db, p->x.pSelect);
+     }else{
+       sqlite3ExprListDelete(db, p->x.pList);
+     }
+   }
++  if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
+   if( !ExprHasProperty(p, EP_Static) ){
+-    sqlite3DbFree(db, p);
++    sqlite3DbFreeNN(db, p);
+   }
+ }
++SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
++  if( p ) sqlite3ExprDeleteNN(db, p);
++}
+ 
+ /*
+ ** Return the number of bytes allocated for the expression structure 
+@@ -83592,7 +95960,7 @@
+   assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
+   assert( EXPR_FULLSIZE<=0xfff );
+   assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
+-  if( 0==(flags&EXPRDUP_REDUCE) ){
++  if( 0==flags || p->op==TK_SELECT_COLUMN ){
+     nSize = EXPR_FULLSIZE;
+   }else{
+     assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
+@@ -83654,84 +96022,94 @@
+ ** if any. Before returning, *pzBuffer is set to the first byte past the
+ ** portion of the buffer copied into by this function.
+ */
+-static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
+-  Expr *pNew = 0;                      /* Value to return */
+-  if( p ){
+-    const int isReduced = (flags&EXPRDUP_REDUCE);
+-    u8 *zAlloc;
+-    u32 staticFlag = 0;
++static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
++  Expr *pNew;           /* Value to return */
++  u8 *zAlloc;           /* Memory space from which to build Expr object */
++  u32 staticFlag;       /* EP_Static if space not obtained from malloc */
+ 
+-    assert( pzBuffer==0 || isReduced );
++  assert( db!=0 );
++  assert( p );
++  assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE );
++  assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE );
+ 
+-    /* Figure out where to write the new Expr structure. */
+-    if( pzBuffer ){
+-      zAlloc = *pzBuffer;
+-      staticFlag = EP_Static;
+-    }else{
+-      zAlloc = sqlite3DbMallocRaw(db, dupedExprSize(p, flags));
+-    }
+-    pNew = (Expr *)zAlloc;
++  /* Figure out where to write the new Expr structure. */
++  if( pzBuffer ){
++    zAlloc = *pzBuffer;
++    staticFlag = EP_Static;
++  }else{
++    zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags));
++    staticFlag = 0;
++  }
++  pNew = (Expr *)zAlloc;
+ 
+-    if( pNew ){
+-      /* Set nNewSize to the size allocated for the structure pointed to
+-      ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
+-      ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
+-      ** by the copy of the p->u.zToken string (if any).
+-      */
+-      const unsigned nStructSize = dupedExprStructSize(p, flags);
+-      const int nNewSize = nStructSize & 0xfff;
+-      int nToken;
+-      if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+-        nToken = sqlite3Strlen30(p->u.zToken) + 1;
+-      }else{
+-        nToken = 0;
+-      }
+-      if( isReduced ){
+-        assert( ExprHasProperty(p, EP_Reduced)==0 );
+-        memcpy(zAlloc, p, nNewSize);
+-      }else{
+-        int nSize = exprStructSize(p);
+-        memcpy(zAlloc, p, nSize);
++  if( pNew ){
++    /* Set nNewSize to the size allocated for the structure pointed to
++    ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
++    ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
++    ** by the copy of the p->u.zToken string (if any).
++    */
++    const unsigned nStructSize = dupedExprStructSize(p, dupFlags);
++    const int nNewSize = nStructSize & 0xfff;
++    int nToken;
++    if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
++      nToken = sqlite3Strlen30(p->u.zToken) + 1;
++    }else{
++      nToken = 0;
++    }
++    if( dupFlags ){
++      assert( ExprHasProperty(p, EP_Reduced)==0 );
++      memcpy(zAlloc, p, nNewSize);
++    }else{
++      u32 nSize = (u32)exprStructSize(p);
++      memcpy(zAlloc, p, nSize);
++      if( nSize<EXPR_FULLSIZE ){ 
+         memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
+       }
++    }
+ 
+-      /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
+-      pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
+-      pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
+-      pNew->flags |= staticFlag;
++    /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
++    pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
++    pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
++    pNew->flags |= staticFlag;
+ 
+-      /* Copy the p->u.zToken string, if any. */
+-      if( nToken ){
+-        char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
+-        memcpy(zToken, p->u.zToken, nToken);
+-      }
++    /* Copy the p->u.zToken string, if any. */
++    if( nToken ){
++      char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
++      memcpy(zToken, p->u.zToken, nToken);
++    }
+ 
+-      if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
+-        /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
+-        if( ExprHasProperty(p, EP_xIsSelect) ){
+-          pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced);
+-        }else{
+-          pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced);
+-        }
++    if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
++      /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
++      if( ExprHasProperty(p, EP_xIsSelect) ){
++        pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
++      }else{
++        pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
+       }
++    }
+ 
+-      /* Fill in pNew->pLeft and pNew->pRight. */
+-      if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
+-        zAlloc += dupedExprNodeSize(p, flags);
+-        if( ExprHasProperty(pNew, EP_Reduced) ){
+-          pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
+-          pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc);
+-        }
+-        if( pzBuffer ){
+-          *pzBuffer = zAlloc;
+-        }
+-      }else{
+-        if( !ExprHasProperty(p, EP_TokenOnly) ){
++    /* Fill in pNew->pLeft and pNew->pRight. */
++    if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
++      zAlloc += dupedExprNodeSize(p, dupFlags);
++      if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
++        pNew->pLeft = p->pLeft ?
++                      exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
++        pNew->pRight = p->pRight ?
++                       exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
++      }
++      if( pzBuffer ){
++        *pzBuffer = zAlloc;
++      }
++    }else{
++      if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
++        if( pNew->op==TK_SELECT_COLUMN ){
++          pNew->pLeft = p->pLeft;
++          assert( p->iColumn==0 || p->pRight==0 );
++          assert( p->pRight==0  || p->pRight==p->pLeft );
++        }else{
+           pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
+-          pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
+         }
++        pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
+       }
+-
+     }
+   }
+   return pNew;
+@@ -83782,26 +96160,42 @@
+ ** part of the in-memory representation of the database schema.
+ */
+ SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
+-  return exprDup(db, p, flags, 0);
++  assert( flags==0 || flags==EXPRDUP_REDUCE );
++  return p ? exprDup(db, p, flags, 0) : 0;
+ }
+ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
+   ExprList *pNew;
+   struct ExprList_item *pItem, *pOldItem;
+   int i;
++  Expr *pPriorSelectCol = 0;
++  assert( db!=0 );
+   if( p==0 ) return 0;
+-  pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
++  pNew = sqlite3DbMallocRawNN(db, 
++             sizeof(*pNew)+sizeof(pNew->a[0])*(p->nExpr-1) );
+   if( pNew==0 ) return 0;
+-  pNew->nExpr = i = p->nExpr;
+-  if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; i<p->nExpr; i+=i){}
+-  pNew->a = pItem = sqlite3DbMallocRaw(db,  i*sizeof(p->a[0]) );
+-  if( pItem==0 ){
+-    sqlite3DbFree(db, pNew);
+-    return 0;
+-  } 
++  pNew->nAlloc = pNew->nExpr = p->nExpr;
++  pItem = pNew->a;
+   pOldItem = p->a;
+   for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
+     Expr *pOldExpr = pOldItem->pExpr;
++    Expr *pNewExpr;
+     pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags);
++    if( pOldExpr 
++     && pOldExpr->op==TK_SELECT_COLUMN
++     && (pNewExpr = pItem->pExpr)!=0 
++    ){
++      assert( pNewExpr->iColumn==0 || i>0 );
++      if( pNewExpr->iColumn==0 ){
++        assert( pOldExpr->pLeft==pOldExpr->pRight );
++        pPriorSelectCol = pNewExpr->pLeft = pNewExpr->pRight;
++      }else{
++        assert( i>0 );
++        assert( pItem[-1].pExpr!=0 );
++        assert( pNewExpr->iColumn==pItem[-1].pExpr->iColumn+1 );
++        assert( pPriorSelectCol==pItem[-1].pExpr->pLeft );
++        pNewExpr->pLeft = pPriorSelectCol;
++      }
++    }
+     pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
+     pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
+     pItem->sortOrder = pOldItem->sortOrder;
+@@ -83824,9 +96218,10 @@
+   SrcList *pNew;
+   int i;
+   int nByte;
++  assert( db!=0 );
+   if( p==0 ) return 0;
+   nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
+-  pNew = sqlite3DbMallocRaw(db, nByte );
++  pNew = sqlite3DbMallocRawNN(db, nByte );
+   if( pNew==0 ) return 0;
+   pNew->nSrc = pNew->nAlloc = p->nSrc;
+   for(i=0; i<p->nSrc; i++){
+@@ -83837,19 +96232,21 @@
+     pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
+     pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
+     pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
+-    pNewItem->jointype = pOldItem->jointype;
++    pNewItem->fg = pOldItem->fg;
+     pNewItem->iCursor = pOldItem->iCursor;
+     pNewItem->addrFillSub = pOldItem->addrFillSub;
+     pNewItem->regReturn = pOldItem->regReturn;
+-    pNewItem->isCorrelated = pOldItem->isCorrelated;
+-    pNewItem->viaCoroutine = pOldItem->viaCoroutine;
+-    pNewItem->isRecursive = pOldItem->isRecursive;
+-    pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex);
+-    pNewItem->notIndexed = pOldItem->notIndexed;
+-    pNewItem->pIndex = pOldItem->pIndex;
++    if( pNewItem->fg.isIndexedBy ){
++      pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
++    }
++    pNewItem->pIBIndex = pOldItem->pIBIndex;
++    if( pNewItem->fg.isTabFunc ){
++      pNewItem->u1.pFuncArg = 
++          sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
++    }
+     pTab = pNewItem->pTab = pOldItem->pTab;
+     if( pTab ){
+-      pTab->nRef++;
++      pTab->nTabRef++;
+     }
+     pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
+     pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags);
+@@ -83861,13 +96258,14 @@
+ SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
+   IdList *pNew;
+   int i;
++  assert( db!=0 );
+   if( p==0 ) return 0;
+-  pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
++  pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
+   if( pNew==0 ) return 0;
+   pNew->nId = p->nId;
+-  pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) );
++  pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) );
+   if( pNew->a==0 ){
+-    sqlite3DbFree(db, pNew);
++    sqlite3DbFreeNN(db, pNew);
+     return 0;
+   }
+   /* Note that because the size of the allocation for p->a[] is not
+@@ -83881,32 +96279,41 @@
+   }
+   return pNew;
+ }
+-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
+-  Select *pNew, *pPrior;
+-  if( p==0 ) return 0;
+-  pNew = sqlite3DbMallocRaw(db, sizeof(*p) );
+-  if( pNew==0 ) return 0;
+-  pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
+-  pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
+-  pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
+-  pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
+-  pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
+-  pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags);
+-  pNew->op = p->op;
+-  pNew->pPrior = pPrior = sqlite3SelectDup(db, p->pPrior, flags);
+-  if( pPrior ) pPrior->pNext = pNew;
+-  pNew->pNext = 0;
+-  pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
+-  pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags);
+-  pNew->iLimit = 0;
+-  pNew->iOffset = 0;
+-  pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
+-  pNew->addrOpenEphm[0] = -1;
+-  pNew->addrOpenEphm[1] = -1;
+-  pNew->nSelectRow = p->nSelectRow;
+-  pNew->pWith = withDup(db, p->pWith);
+-  sqlite3SelectSetName(pNew, p->zSelName);
+-  return pNew;
++SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
++  Select *pRet = 0;
++  Select *pNext = 0;
++  Select **pp = &pRet;
++  Select *p;
++
++  assert( db!=0 );
++  for(p=pDup; p; p=p->pPrior){
++    Select *pNew = sqlite3DbMallocRawNN(db, sizeof(*p) );
++    if( pNew==0 ) break;
++    pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
++    pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
++    pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
++    pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
++    pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
++    pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags);
++    pNew->op = p->op;
++    pNew->pNext = pNext;
++    pNew->pPrior = 0;
++    pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
++    pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags);
++    pNew->iLimit = 0;
++    pNew->iOffset = 0;
++    pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
++    pNew->addrOpenEphm[0] = -1;
++    pNew->addrOpenEphm[1] = -1;
++    pNew->nSelectRow = p->nSelectRow;
++    pNew->pWith = withDup(db, p->pWith);
++    sqlite3SelectSetName(pNew, p->zSelName);
++    *pp = pNew;
++    pp = &pNew->pPrior;
++    pNext = pNew;
++  }
++
++  return pRet;
+ }
+ #else
+ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
+@@ -83929,29 +96336,31 @@
+   ExprList *pList,        /* List to which to append. Might be NULL */
+   Expr *pExpr             /* Expression to be appended. Might be NULL */
+ ){
++  struct ExprList_item *pItem;
+   sqlite3 *db = pParse->db;
++  assert( db!=0 );
+   if( pList==0 ){
+-    pList = sqlite3DbMallocZero(db, sizeof(ExprList) );
++    pList = sqlite3DbMallocRawNN(db, sizeof(ExprList) );
+     if( pList==0 ){
+       goto no_mem;
+     }
+-    pList->a = sqlite3DbMallocRaw(db, sizeof(pList->a[0]));
+-    if( pList->a==0 ) goto no_mem;
+-  }else if( (pList->nExpr & (pList->nExpr-1))==0 ){
+-    struct ExprList_item *a;
+-    assert( pList->nExpr>0 );
+-    a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0]));
+-    if( a==0 ){
++    pList->nExpr = 0;
++    pList->nAlloc = 1;
++  }else if( pList->nExpr==pList->nAlloc ){
++    ExprList *pNew;
++    pNew = sqlite3DbRealloc(db, pList, 
++             sizeof(*pList)+(2*pList->nAlloc - 1)*sizeof(pList->a[0]));
++    if( pNew==0 ){
+       goto no_mem;
+     }
+-    pList->a = a;
+-  }
+-  assert( pList->a!=0 );
+-  if( 1 ){
+-    struct ExprList_item *pItem = &pList->a[pList->nExpr++];
+-    memset(pItem, 0, sizeof(*pItem));
+-    pItem->pExpr = pExpr;
++    pList = pNew;
++    pList->nAlloc *= 2;
+   }
++  pItem = &pList->a[pList->nExpr++];
++  assert( offsetof(struct ExprList_item,zName)==sizeof(pItem->pExpr) );
++  assert( offsetof(struct ExprList_item,pExpr)==0 );
++  memset(&pItem->zName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zName));
++  pItem->pExpr = pExpr;
+   return pList;
+ 
+ no_mem:     
+@@ -83962,6 +96371,88 @@
+ }
+ 
+ /*
++** pColumns and pExpr form a vector assignment which is part of the SET
++** clause of an UPDATE statement.  Like this:
++**
++**        (a,b,c) = (expr1,expr2,expr3)
++** Or:    (a,b,c) = (SELECT x,y,z FROM ....)
++**
++** For each term of the vector assignment, append new entries to the
++** expression list pList.  In the case of a subquery on the RHS, append
++** TK_SELECT_COLUMN expressions.
++*/
++SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(
++  Parse *pParse,         /* Parsing context */
++  ExprList *pList,       /* List to which to append. Might be NULL */
++  IdList *pColumns,      /* List of names of LHS of the assignment */
++  Expr *pExpr            /* Vector expression to be appended. Might be NULL */
++){
++  sqlite3 *db = pParse->db;
++  int n;
++  int i;
++  int iFirst = pList ? pList->nExpr : 0;
++  /* pColumns can only be NULL due to an OOM but an OOM will cause an
++  ** exit prior to this routine being invoked */
++  if( NEVER(pColumns==0) ) goto vector_append_error;
++  if( pExpr==0 ) goto vector_append_error;
++
++  /* If the RHS is a vector, then we can immediately check to see that 
++  ** the size of the RHS and LHS match.  But if the RHS is a SELECT, 
++  ** wildcards ("*") in the result set of the SELECT must be expanded before
++  ** we can do the size check, so defer the size check until code generation.
++  */
++  if( pExpr->op!=TK_SELECT && pColumns->nId!=(n=sqlite3ExprVectorSize(pExpr)) ){
++    sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
++                    pColumns->nId, n);
++    goto vector_append_error;
++  }
++
++  for(i=0; i<pColumns->nId; i++){
++    Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i);
++    pList = sqlite3ExprListAppend(pParse, pList, pSubExpr);
++    if( pList ){
++      assert( pList->nExpr==iFirst+i+1 );
++      pList->a[pList->nExpr-1].zName = pColumns->a[i].zName;
++      pColumns->a[i].zName = 0;
++    }
++  }
++
++  if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){
++    Expr *pFirst = pList->a[iFirst].pExpr;
++    assert( pFirst!=0 );
++    assert( pFirst->op==TK_SELECT_COLUMN );
++     
++    /* Store the SELECT statement in pRight so it will be deleted when
++    ** sqlite3ExprListDelete() is called */
++    pFirst->pRight = pExpr;
++    pExpr = 0;
++
++    /* Remember the size of the LHS in iTable so that we can check that
++    ** the RHS and LHS sizes match during code generation. */
++    pFirst->iTable = pColumns->nId;
++  }
++
++vector_append_error:
++  sqlite3ExprDelete(db, pExpr);
++  sqlite3IdListDelete(db, pColumns);
++  return pList;
++}
++
++/*
++** Set the sort order for the last element on the given ExprList.
++*/
++SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){
++  if( p==0 ) return;
++  assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC>=0 && SQLITE_SO_DESC>0 );
++  assert( p->nExpr>0 );
++  if( iSortOrder<0 ){
++    assert( p->a[p->nExpr-1].sortOrder==SQLITE_SO_ASC );
++    return;
++  }
++  p->a[p->nExpr-1].sortOrder = (u8)iSortOrder;
++}
++
++/*
+ ** Set the ExprList.a[].zName element of the most recently added item
+ ** on the expression list.
+ **
+@@ -83982,7 +96473,7 @@
+     pItem = &pList->a[pList->nExpr-1];
+     assert( pItem->zName==0 );
+     pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
+-    if( dequote && pItem->zName ) sqlite3Dequote(pItem->zName);
++    if( dequote ) sqlite3Dequote(pItem->zName);
+   }
+ }
+ 
+@@ -84031,18 +96522,20 @@
+ /*
+ ** Delete an entire expression list.
+ */
+-SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
+-  int i;
+-  struct ExprList_item *pItem;
+-  if( pList==0 ) return;
+-  assert( pList->a!=0 || pList->nExpr==0 );
+-  for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
++static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
++  int i = pList->nExpr;
++  struct ExprList_item *pItem =  pList->a;
++  assert( pList->nExpr>0 );
++  do{
+     sqlite3ExprDelete(db, pItem->pExpr);
+     sqlite3DbFree(db, pItem->zName);
+     sqlite3DbFree(db, pItem->zSpan);
+-  }
+-  sqlite3DbFree(db, pList->a);
+-  sqlite3DbFree(db, pList);
++    pItem++;
++  }while( --i>0 );
++  sqlite3DbFreeNN(db, pList);
++}
++SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
++  if( pList ) exprListDeleteNN(db, pList);
+ }
+ 
+ /*
+@@ -84055,7 +96548,8 @@
+   if( pList ){
+     for(i=0; i<pList->nExpr; i++){
+        Expr *pExpr = pList->a[i].pExpr;
+-       if( ALWAYS(pExpr) ) m |= pExpr->flags;
++       assert( pExpr!=0 );
++       m |= pExpr->flags;
+     }
+   }
+   return m;
+@@ -84071,7 +96565,7 @@
+ **
+ **     sqlite3ExprIsConstant()                  pWalker->eCode==1
+ **     sqlite3ExprIsConstantNotJoin()           pWalker->eCode==2
+-**     sqlite3ExprRefOneTableOnly()             pWalker->eCode==3
++**     sqlite3ExprIsTableConstant()             pWalker->eCode==3
+ **     sqlite3ExprIsConstantOrFunction()        pWalker->eCode==4 or 5
+ **
+ ** In all cases, the callbacks set Walker.eCode=0 and abort if the expression
+@@ -84117,10 +96611,12 @@
+       testcase( pExpr->op==TK_AGG_COLUMN );
+       if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
+         return WRC_Continue;
+-      }else{
+-        pWalker->eCode = 0;
+-        return WRC_Abort;
+       }
++      /* Fall through */
++    case TK_IF_NULL_ROW:
++      testcase( pExpr->op==TK_IF_NULL_ROW );
++      pWalker->eCode = 0;
++      return WRC_Abort;
+     case TK_VARIABLE:
+       if( pWalker->eCode==5 ){
+         /* Silently convert bound parameters that appear inside of CREATE
+@@ -84147,10 +96643,12 @@
+ }
+ static int exprIsConst(Expr *p, int initFlag, int iCur){
+   Walker w;
+-  memset(&w, 0, sizeof(w));
+   w.eCode = initFlag;
+   w.xExprCallback = exprNodeIsConstant;
+   w.xSelectCallback = selectNodeIsConstant;
++#ifdef SQLITE_DEBUG
++  w.xSelectCallback2 = sqlite3SelectWalkAssert2;
++#endif
+   w.u.iCur = iCur;
+   sqlite3WalkExpr(&w, p);
+   return w.eCode;
+@@ -84179,7 +96677,7 @@
+ }
+ 
+ /*
+-** Walk an expression tree.  Return non-zero if the expression constant
++** Walk an expression tree.  Return non-zero if the expression is constant
+ ** for any single row of the table with cursor iCur.  In other words, the
+ ** expression must not refer to any non-deterministic function nor any
+ ** table other than iCur.
+@@ -84188,6 +96686,65 @@
+   return exprIsConst(p, 3, iCur);
+ }
+ 
++
++/*
++** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy().
++*/
++static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
++  ExprList *pGroupBy = pWalker->u.pGroupBy;
++  int i;
++
++  /* Check if pExpr is identical to any GROUP BY term. If so, consider
++  ** it constant.  */
++  for(i=0; i<pGroupBy->nExpr; i++){
++    Expr *p = pGroupBy->a[i].pExpr;
++    if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){
++      CollSeq *pColl = sqlite3ExprCollSeq(pWalker->pParse, p);
++      if( pColl==0 || sqlite3_stricmp("BINARY", pColl->zName)==0 ){
++        return WRC_Prune;
++      }
++    }
++  }
++
++  /* Check if pExpr is a sub-select. If so, consider it variable. */
++  if( ExprHasProperty(pExpr, EP_xIsSelect) ){
++    pWalker->eCode = 0;
++    return WRC_Abort;
++  }
++
++  return exprNodeIsConstant(pWalker, pExpr);
++}
++
++/*
++** Walk the expression tree passed as the first argument. Return non-zero
++** if the expression consists entirely of constants or copies of terms 
++** in pGroupBy that sort with the BINARY collation sequence.
++**
++** This routine is used to determine if a term of the HAVING clause can
++** be promoted into the WHERE clause.  In order for such a promotion to work,
++** the value of the HAVING clause term must be the same for all members of
++** a "group".  The requirement that the GROUP BY term must be BINARY
++** assumes that no other collating sequence will have a finer-grained
++** grouping than binary.  In other words (A=B COLLATE binary) implies
++** A=B in every other collating sequence.  The requirement that the
++** GROUP BY be BINARY is stricter than necessary.  It would also work
++** to promote HAVING clauses that use the same alternative collating
++** sequence as the GROUP BY term, but that is much harder to check,
++** alternative collating sequences are uncommon, and this is only an
++** optimization, so we take the easy way out and simply require the
++** GROUP BY to use the BINARY collating sequence.
++*/
++SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){
++  Walker w;
++  w.eCode = 1;
++  w.xExprCallback = exprNodeIsConstantOrGroupBy;
++  w.xSelectCallback = 0;
++  w.u.pGroupBy = pGroupBy;
++  w.pParse = pParse;
++  sqlite3WalkExpr(&w, p);
++  return w.eCode;
++}
++
+ /*
+ ** Walk an expression tree.  Return non-zero if the expression is constant
+ ** or a function call with constant arguments.  Return and 0 if there
+@@ -84202,6 +96759,24 @@
+   return exprIsConst(p, 4+isInit, 0);
+ }
+ 
++#ifdef SQLITE_ENABLE_CURSOR_HINTS
++/*
++** Walk an expression tree.  Return 1 if the expression contains a
++** subquery of some kind.  Return 0 if there are no subqueries.
++*/
++SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){
++  Walker w;
++  w.eCode = 1;
++  w.xExprCallback = sqlite3ExprWalkNoop;
++  w.xSelectCallback = selectNodeIsConstant;
++#ifdef SQLITE_DEBUG
++  w.xSelectCallback2 = sqlite3SelectWalkAssert2;
++#endif
++  sqlite3WalkExpr(&w, p);
++  return w.eCode==0;
++}
++#endif
++
+ /*
+ ** If the expression p codes a constant integer that is small enough
+ ** to fit in a 32-bit integer, return 1 and put the value of the integer
+@@ -84210,6 +96785,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
+   int rc = 0;
++  if( p==0 ) return 0;  /* Can only happen following on OOM */
+ 
+   /* If an expression is an integer literal that fits in a signed 32-bit
+   ** integer, then the EP_IntValue flag will have already been set */
+@@ -84285,7 +96861,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){
+   u8 op;
+-  if( aff==SQLITE_AFF_NONE ) return 1;
++  if( aff==SQLITE_AFF_BLOB ) return 1;
+   while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
+   op = p->op;
+   if( op==TK_REGISTER ) op = p->op2;
+@@ -84324,23 +96900,22 @@
+ }
+ 
+ /*
+-** Return true if we are able to the IN operator optimization on a
+-** query of the form
+-**
+-**       x IN (SELECT ...)
+-**
+-** Where the SELECT... clause is as specified by the parameter to this
+-** routine.
+-**
+-** The Select object passed in has already been preprocessed and no
+-** errors have been found.
++** pX is the RHS of an IN operator.  If pX is a SELECT statement 
++** that can be simplified to a direct table access, then return
++** a pointer to the SELECT statement.  If pX is not a SELECT statement,
++** or if the SELECT statement needs to be manifested into a transient
++** table, then return NULL.
+ */
+ #ifndef SQLITE_OMIT_SUBQUERY
+-static int isCandidateForInOpt(Select *p){
++static Select *isCandidateForInOpt(Expr *pX){
++  Select *p;
+   SrcList *pSrc;
+   ExprList *pEList;
+   Table *pTab;
+-  if( p==0 ) return 0;                   /* right-hand side of IN is SELECT */
++  int i;
++  if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0;  /* Not a subquery */
++  if( ExprHasProperty(pX, EP_VarSelect)  ) return 0;  /* Correlated subq */
++  p = pX->x.pSelect;
+   if( p->pPrior ) return 0;              /* Not a compound SELECT */
+   if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
+     testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
+@@ -84356,25 +96931,22 @@
+   if( pSrc->nSrc!=1 ) return 0;          /* Single term in FROM clause */
+   if( pSrc->a[0].pSelect ) return 0;     /* FROM is not a subquery or view */
+   pTab = pSrc->a[0].pTab;
+-  if( NEVER(pTab==0) ) return 0;
++  assert( pTab!=0 );
+   assert( pTab->pSelect==0 );            /* FROM clause is not a view */
+   if( IsVirtual(pTab) ) return 0;        /* FROM clause not a virtual table */
+   pEList = p->pEList;
+-  if( pEList->nExpr!=1 ) return 0;       /* One column in the result set */
+-  if( pEList->a[0].pExpr->op!=TK_COLUMN ) return 0; /* Result is a column */
+-  return 1;
++  assert( pEList!=0 );
++  /* All SELECT results must be columns. */
++  for(i=0; i<pEList->nExpr; i++){
++    Expr *pRes = pEList->a[i].pExpr;
++    if( pRes->op!=TK_COLUMN ) return 0;
++    assert( pRes->iTable==pSrc->a[0].iCursor );  /* Not a correlated subquery */
++  }
++  return p;
+ }
+ #endif /* SQLITE_OMIT_SUBQUERY */
  
 -/*
--** Variables in which to record status information.
+-** Code an OP_Once instruction and allocate space for its flag. Return the 
+-** address of the new instruction.
 -*/
--typedef struct sqlite3StatType sqlite3StatType;
--static SQLITE_WSD struct sqlite3StatType {
--#if SQLITE_PTRSIZE>4
--  sqlite3_int64 nowValue[10];         /* Current value */
--  sqlite3_int64 mxValue[10];          /* Maximum value */
--#else
--  u32 nowValue[10];                   /* Current value */
--  u32 mxValue[10];                    /* Maximum value */
--#endif
--} sqlite3Stat = { {0,}, {0,} };
-+  /* setup default flags */
-+  ctx->flags = default_flags;
+-SQLITE_PRIVATE int sqlite3CodeOnce(Parse *pParse){
+-  Vdbe *v = sqlite3GetVdbe(pParse);      /* Virtual machine being coded */
+-  return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++);
+-}
+-
++#ifndef SQLITE_OMIT_SUBQUERY
+ /*
+ ** Generate code that checks the left-most column of index table iCur to see if
+ ** it contains any NULL entries.  Cause the register at regHasNull to be set
+@@ -84382,14 +96954,15 @@
+ ** to be set to NULL if iCur contains one or more NULL values.
+ */
+ static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){
+-  int j1;
++  int addr1;
+   sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull);
+-  j1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
++  addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
+   sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull);
+   sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
+   VdbeComment((v, "first_entry_in(%d)", iCur));
+-  sqlite3VdbeJumpHere(v, j1);
++  sqlite3VdbeJumpHere(v, addr1);
+ }
++#endif
+ 
+ 
+ #ifndef SQLITE_OMIT_SUBQUERY
+@@ -84434,7 +97007,7 @@
+ ** An existing b-tree might be used if the RHS expression pX is a simple
+ ** subquery such as:
+ **
+-**     SELECT <column> FROM <table>
++**     SELECT <column1>, <column2>... 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
+@@ -84450,14 +97023,14 @@
+ **
+ ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate
+ ** through the set members) then the b-tree must not contain duplicates.
+-** An epheremal table must be used unless the selected <column> is guaranteed
+-** to be unique - either because it is an INTEGER PRIMARY KEY or it
+-** has a UNIQUE constraint or UNIQUE index.
++** An epheremal table must be used unless the selected columns are guaranteed
++** to be unique - either because it is an INTEGER PRIMARY KEY or due to
++** a UNIQUE constraint or index.
+ **
+ ** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used 
+ ** for fast set membership tests) then an epheremal table must 
+-** be used unless <column> is an INTEGER PRIMARY KEY or an index can 
+-** be found with <column> as its left-most column.
++** be used unless <columns> is a single INTEGER PRIMARY KEY column or an 
++** index can be found with the specified <columns> as its left-most.
+ **
+ ** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and
+ ** if the RHS of the IN operator is a list (not a subquery) then this
+@@ -84478,9 +97051,26 @@
+ ** the value in that register will be NULL if the b-tree contains one or more
+ ** NULL values, and it will be some non-NULL value if the b-tree contains no
+ ** NULL values.
++**
++** If the aiMap parameter is not NULL, it must point to an array containing
++** one element for each column returned by the SELECT statement on the RHS
++** of the IN(...) operator. The i'th entry of the array is populated with the
++** offset of the index column that matches the i'th column returned by the
++** SELECT. For example, if the expression and selected index are:
++**
++**   (?,?,?) IN (SELECT a, b, c FROM t1)
++**   CREATE INDEX i1 ON t1(b, c, a);
++**
++** then aiMap[] is populated with {2, 0, 1}.
+ */
+ #ifndef SQLITE_OMIT_SUBQUERY
+-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){
++SQLITE_PRIVATE int sqlite3FindInIndex(
++  Parse *pParse,             /* Parsing context */
++  Expr *pX,                  /* The right-hand side (RHS) of the IN operator */
++  u32 inFlags,               /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
++  int *prRhsHasNull,         /* Register holding NULL status.  See notes */
++  int *aiMap                 /* Mapping from Index fields to RHS fields */
++){
+   Select *p;                            /* SELECT to the right of IN operator */
+   int eType = 0;                        /* Type of RHS table. IN_INDEX_* */
+   int iTab = pParse->nTab++;            /* Cursor of the RHS table */
+@@ -84490,38 +97080,46 @@
+   assert( pX->op==TK_IN );
+   mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0;
+ 
++  /* If the RHS of this IN(...) operator is a SELECT, and if it matters 
++  ** whether or not the SELECT result contains NULL values, check whether
++  ** or not NULL is actually possible (it may not be, for example, due 
++  ** to NOT NULL constraints in the schema). If no NULL values are possible,
++  ** set prRhsHasNull to 0 before continuing.  */
++  if( prRhsHasNull && (pX->flags & EP_xIsSelect) ){
++    int i;
++    ExprList *pEList = pX->x.pSelect->pEList;
++    for(i=0; i<pEList->nExpr; i++){
++      if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break;
++    }
++    if( i==pEList->nExpr ){
++      prRhsHasNull = 0;
++    }
++  }
++
+   /* Check to see if an existing table or index can be used to
+   ** satisfy the query.  This is preferable to generating a new 
+-  ** ephemeral table.
+-  */
+-  p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
+-  if( pParse->nErr==0 && isCandidateForInOpt(p) ){
++  ** ephemeral table.  */
++  if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){
+     sqlite3 *db = pParse->db;              /* Database connection */
+     Table *pTab;                           /* Table <table>. */
+-    Expr *pExpr;                           /* Expression <column> */
+-    i16 iCol;                              /* Index of column <column> */
+     i16 iDb;                               /* Database idx for pTab */
++    ExprList *pEList = p->pEList;
++    int nExpr = pEList->nExpr;
+ 
+-    assert( p );                        /* Because of isCandidateForInOpt(p) */
+     assert( p->pEList!=0 );             /* Because of isCandidateForInOpt(p) */
+     assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
+     assert( p->pSrc!=0 );               /* Because of isCandidateForInOpt(p) */
+     pTab = p->pSrc->a[0].pTab;
+-    pExpr = p->pEList->a[0].pExpr;
+-    iCol = (i16)pExpr->iColumn;
+-   
++
+     /* Code an OP_Transaction and OP_TableLock for <table>. */
+     iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+     sqlite3CodeVerifySchema(pParse, iDb);
+     sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
+ 
+-    /* This function is only called from two places. In both cases the vdbe
+-    ** has already been allocated. So assume sqlite3GetVdbe() is always
+-    ** successful here.
+-    */
+-    assert(v);
+-    if( iCol<0 ){
+-      int iAddr = sqlite3CodeOnce(pParse);
++    assert(v);  /* sqlite3GetVdbe() has always been previously called */
++    if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){
++      /* The "x IN (SELECT rowid FROM table)" case */
++      int iAddr = sqlite3VdbeAddOp0(v, OP_Once);
+       VdbeCoverage(v);
+ 
+       sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
+@@ -84530,44 +97128,114 @@
+       sqlite3VdbeJumpHere(v, iAddr);
+     }else{
+       Index *pIdx;                         /* Iterator variable */
++      int affinity_ok = 1;
++      int i;
+ 
+-      /* The collation sequence used by the comparison. If an index is to
+-      ** be used in place of a temp-table, it must be ordered according
+-      ** to this collation sequence.  */
+-      CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pExpr);
+-
+-      /* Check that the affinity that will be used to perform the 
+-      ** comparison is the same as the affinity of the column. If
+-      ** it is not, it is not possible to use any index.
+-      */
+-      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)
+-         && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
+-         && (!mustBeUnique || (pIdx->nKeyCol==1 && IsUniqueIndex(pIdx)))
+-        ){
+-          int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
+-          sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
+-          sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+-          VdbeComment((v, "%s", pIdx->zName));
+-          assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
+-          eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
+-
+-          if( prRhsHasNull && !pTab->aCol[iCol].notNull ){
+-            *prRhsHasNull = ++pParse->nMem;
+-            sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull);
+-          }
+-          sqlite3VdbeJumpHere(v, iAddr);
++      /* Check that the affinity that will be used to perform each 
++      ** comparison is the same as the affinity of each column in table
++      ** on the RHS of the IN operator.  If it not, it is not possible to
++      ** use any index of the RHS table.  */
++      for(i=0; i<nExpr && affinity_ok; i++){
++        Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
++        int iCol = pEList->a[i].pExpr->iColumn;
++        char idxaff = sqlite3TableColumnAffinity(pTab,iCol); /* RHS table */
++        char cmpaff = sqlite3CompareAffinity(pLhs, idxaff);
++        testcase( cmpaff==SQLITE_AFF_BLOB );
++        testcase( cmpaff==SQLITE_AFF_TEXT );
++        switch( cmpaff ){
++          case SQLITE_AFF_BLOB:
++            break;
++          case SQLITE_AFF_TEXT:
++            /* sqlite3CompareAffinity() only returns TEXT if one side or the
++            ** other has no affinity and the other side is TEXT.  Hence,
++            ** the only way for cmpaff to be TEXT is for idxaff to be TEXT
++            ** and for the term on the LHS of the IN to have no affinity. */
++            assert( idxaff==SQLITE_AFF_TEXT );
++            break;
++          default:
++            affinity_ok = sqlite3IsNumericAffinity(idxaff);
+         }
+       }
+-    }
+-  }
++
++      if( affinity_ok ){
++        /* Search for an existing index that will work for this IN operator */
++        for(pIdx=pTab->pIndex; pIdx && eType==0; pIdx=pIdx->pNext){
++          Bitmask colUsed;      /* Columns of the index used */
++          Bitmask mCol;         /* Mask for the current column */
++          if( pIdx->nColumn<nExpr ) continue;
++          /* Maximum nColumn is BMS-2, not BMS-1, so that we can compute
++          ** BITMASK(nExpr) without overflowing */
++          testcase( pIdx->nColumn==BMS-2 );
++          testcase( pIdx->nColumn==BMS-1 );
++          if( pIdx->nColumn>=BMS-1 ) continue;
++          if( mustBeUnique ){
++            if( pIdx->nKeyCol>nExpr
++             ||(pIdx->nColumn>nExpr && !IsUniqueIndex(pIdx))
++            ){
++              continue;  /* This index is not unique over the IN RHS columns */
++            }
++          }
++  
++          colUsed = 0;   /* Columns of index used so far */
++          for(i=0; i<nExpr; i++){
++            Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
++            Expr *pRhs = pEList->a[i].pExpr;
++            CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
++            int j;
++  
++            assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
++            for(j=0; j<nExpr; j++){
++              if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
++              assert( pIdx->azColl[j] );
++              if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
++                continue;
++              }
++              break;
++            }
++            if( j==nExpr ) break;
++            mCol = MASKBIT(j);
++            if( mCol & colUsed ) break; /* Each column used only once */
++            colUsed |= mCol;
++            if( aiMap ) aiMap[i] = j;
++          }
++  
++          assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) );
++          if( colUsed==(MASKBIT(nExpr)-1) ){
++            /* If we reach this point, that means the index pIdx is usable */
++            int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
++#ifndef SQLITE_OMIT_EXPLAIN
++            sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0,
++              sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName),
++              P4_DYNAMIC);
++#endif
++            sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
++            sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
++            VdbeComment((v, "%s", pIdx->zName));
++            assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
++            eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
++  
++            if( prRhsHasNull ){
++#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
++              i64 mask = (1<<nExpr)-1;
++              sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, 
++                  iTab, 0, 0, (u8*)&mask, P4_INT64);
++#endif
++              *prRhsHasNull = ++pParse->nMem;
++              if( nExpr==1 ){
++                sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull);
++              }
++            }
++            sqlite3VdbeJumpHere(v, iAddr);
++          }
++        } /* End loop over indexes */
++      } /* End if( affinity_ok ) */
++    } /* End if not an rowid index */
++  } /* End attempt to optimize using an index */
+ 
+   /* If no preexisting index is available for the IN clause
+   ** and IN_INDEX_NOOP is an allowed reply
+   ** and the RHS of the IN operator is a list, not a subquery
+-  ** and the RHS is not contant or has two or fewer terms,
++  ** and the RHS is not constant or has two or fewer terms,
+   ** then it is not worth creating an ephemeral table to evaluate
+   ** the IN operator so return IN_INDEX_NOOP.
+   */
+@@ -84578,7 +97246,6 @@
+   ){
+     eType = IN_INDEX_NOOP;
+   }
+-     
+ 
+   if( eType==0 ){
+     /* Could not find an existing table or index to use as the RHS b-tree.
+@@ -84600,10 +97267,85 @@
+   }else{
+     pX->iTable = iTab;
+   }
++
++  if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){
++    int i, n;
++    n = sqlite3ExprVectorSize(pX->pLeft);
++    for(i=0; i<n; i++) aiMap[i] = i;
++  }
+   return eType;
+ }
+ #endif
+ 
++#ifndef SQLITE_OMIT_SUBQUERY
++/*
++** Argument pExpr is an (?, ?...) IN(...) expression. This 
++** function allocates and returns a nul-terminated string containing 
++** the affinities to be used for each column of the comparison.
++**
++** It is the responsibility of the caller to ensure that the returned
++** string is eventually freed using sqlite3DbFree().
++*/
++static char *exprINAffinity(Parse *pParse, Expr *pExpr){
++  Expr *pLeft = pExpr->pLeft;
++  int nVal = sqlite3ExprVectorSize(pLeft);
++  Select *pSelect = (pExpr->flags & EP_xIsSelect) ? pExpr->x.pSelect : 0;
++  char *zRet;
++
++  assert( pExpr->op==TK_IN );
++  zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
++  if( zRet ){
++    int i;
++    for(i=0; i<nVal; i++){
++      Expr *pA = sqlite3VectorFieldSubexpr(pLeft, i);
++      char a = sqlite3ExprAffinity(pA);
++      if( pSelect ){
++        zRet[i] = sqlite3CompareAffinity(pSelect->pEList->a[i].pExpr, a);
++      }else{
++        zRet[i] = a;
++      }
++    }
++    zRet[nVal] = '\0';
++  }
++  return zRet;
++}
++#endif
++
++#ifndef SQLITE_OMIT_SUBQUERY
++/*
++** Load the Parse object passed as the first argument with an error 
++** message of the form:
++**
++**   "sub-select returns N columns - expected M"
++*/   
++SQLITE_PRIVATE void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){
++  const char *zFmt = "sub-select returns %d columns - expected %d";
++  sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
++}
++#endif
++
++/*
++** Expression pExpr is a vector that has been used in a context where
++** it is not permitted. If pExpr is a sub-select vector, this routine 
++** loads the Parse object with a message of the form:
++**
++**   "sub-select returns N columns - expected 1"
++**
++** Or, if it is a regular scalar vector:
++**
++**   "row value misused"
++*/   
++SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
++#ifndef SQLITE_OMIT_SUBQUERY
++  if( pExpr->flags & EP_xIsSelect ){
++    sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1);
++  }else
++#endif
++  {
++    sqlite3ErrorMsg(pParse, "row value misused");
++  }
++}
++
+ /*
+ ** Generate code for scalar subqueries used as a subquery expression, EXISTS,
+ ** or IN operators.  Examples:
+@@ -84629,7 +97371,9 @@
+ ** value to non-NULL if the RHS is NULL-free.
+ **
+ ** For a SELECT or EXISTS operator, return the register that holds the
+-** result.  For IN operators or if an error occurs, the return value is 0.
++** result.  For a multi-column SELECT, the result is stored in a contiguous
++** array of registers and the return value is the register of the left-most
++** result column.  Return 0 for IN operators or if an error occurs.
+ */
+ #ifndef SQLITE_OMIT_SUBQUERY
+ SQLITE_PRIVATE int sqlite3CodeSubselect(
+@@ -84644,8 +97388,8 @@
+   if( NEVER(v==0) ) return 0;
+   sqlite3ExprCachePush(pParse);
+ 
+-  /* This code must be run in its entirety every time it is encountered
+-  ** if any of the following is true:
++  /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it
++  ** is encountered if any of the following is true:
+   **
+   **    *  The right-hand side is a correlated subquery
+   **    *  The right-hand side is an expression list containing variables
+@@ -84655,14 +97399,15 @@
+   ** save the results, and reuse the same result on subsequent invocations.
+   */
+   if( !ExprHasProperty(pExpr, EP_VarSelect) ){
+-    jmpIfDynamic = sqlite3CodeOnce(pParse); VdbeCoverage(v);
++    jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+   }
  
--/*
--** Elements of sqlite3Stat[] are protected by either the memory allocator
--** mutex, or by the pcache1 mutex.  The following array determines which.
--*/
--static const char statMutex[] = {
--  0,  /* SQLITE_STATUS_MEMORY_USED */
--  1,  /* SQLITE_STATUS_PAGECACHE_USED */
--  1,  /* SQLITE_STATUS_PAGECACHE_OVERFLOW */
--  0,  /* SQLITE_STATUS_SCRATCH_USED */
--  0,  /* SQLITE_STATUS_SCRATCH_OVERFLOW */
--  0,  /* SQLITE_STATUS_MALLOC_SIZE */
--  0,  /* SQLITE_STATUS_PARSER_STACK */
--  1,  /* SQLITE_STATUS_PAGECACHE_SIZE */
--  0,  /* SQLITE_STATUS_SCRATCH_SIZE */
--  0,  /* SQLITE_STATUS_MALLOC_COUNT */
--};
-+  return SQLITE_OK;
+ #ifndef SQLITE_OMIT_EXPLAIN
+   if( pParse->explain==2 ){
+-    char *zMsg = sqlite3MPrintf(
+-        pParse->db, "EXECUTE %s%s SUBQUERY %d", jmpIfDynamic>=0?"":"CORRELATED ",
+-        pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId
++    char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %s%s SUBQUERY %d",
++        jmpIfDynamic>=0?"":"CORRELATED ",
++        pExpr->op==TK_IN?"LIST":"SCALAR",
++        pParse->iNextSelectId
+     );
+     sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
+   }
+@@ -84670,17 +97415,18 @@
+ 
+   switch( pExpr->op ){
+     case TK_IN: {
+-      char affinity;              /* Affinity of the LHS of the IN */
+       int addr;                   /* Address of OP_OpenEphemeral instruction */
+       Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
+       KeyInfo *pKeyInfo = 0;      /* Key information */
+-
+-      affinity = sqlite3ExprAffinity(pLeft);
++      int nVal;                   /* Size of vector pLeft */
++      
++      nVal = sqlite3ExprVectorSize(pLeft);
++      assert( !isRowid || nVal==1 );
+ 
+       /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
+       ** expression it is handled the same way.  An ephemeral table is 
+-      ** filled with single-field index keys representing the results
+-      ** from the SELECT or the <exprlist>.
++      ** filled with index keys representing the results from the 
++      ** SELECT or the <exprlist>.
+       **
+       ** If the 'x' expression is a column value, or the SELECT...
+       ** statement returns a column value, then the affinity of that
+@@ -84691,8 +97437,9 @@
+       ** is used.
+       */
+       pExpr->iTable = pParse->nTab++;
+-      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
+-      pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1, 1);
++      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, 
++          pExpr->iTable, (isRowid?0:nVal));
++      pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
+ 
+       if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+         /* Case 1:     expr IN (SELECT ...)
+@@ -84701,27 +97448,36 @@
+         ** table allocated and opened above.
+         */
+         Select *pSelect = pExpr->x.pSelect;
+-        SelectDest dest;
+-        ExprList *pEList;
++        ExprList *pEList = pSelect->pEList;
+ 
+         assert( !isRowid );
+-        sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
+-        dest.affSdst = (u8)affinity;
+-        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
+-        pSelect->iLimit = 0;
+-        testcase( pSelect->selFlags & SF_Distinct );
+-        testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
+-        if( sqlite3Select(pParse, pSelect, &dest) ){
+-          sqlite3KeyInfoUnref(pKeyInfo);
+-          return 0;
++        /* If the LHS and RHS of the IN operator do not match, that
++        ** error will have been caught long before we reach this point. */
++        if( ALWAYS(pEList->nExpr==nVal) ){
++          SelectDest dest;
++          int i;
++          sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
++          dest.zAffSdst = exprINAffinity(pParse, pExpr);
++          pSelect->iLimit = 0;
++          testcase( pSelect->selFlags & SF_Distinct );
++          testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
++          if( sqlite3Select(pParse, pSelect, &dest) ){
++            sqlite3DbFree(pParse->db, dest.zAffSdst);
++            sqlite3KeyInfoUnref(pKeyInfo);
++            return 0;
++          }
++          sqlite3DbFree(pParse->db, dest.zAffSdst);
++          assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
++          assert( pEList!=0 );
++          assert( pEList->nExpr>0 );
++          assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
++          for(i=0; i<nVal; i++){
++            Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
++            pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
++                pParse, p, pEList->a[i].pExpr
++            );
++          }
+         }
+-        pEList = pSelect->pEList;
+-        assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
+-        assert( pEList!=0 );
+-        assert( pEList->nExpr>0 );
+-        assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+-        pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
+-                                                         pEList->a[0].pExpr);
+       }else if( ALWAYS(pExpr->x.pList!=0) ){
+         /* Case 2:     expr IN (exprlist)
+         **
+@@ -84730,13 +97486,15 @@
+         ** that columns affinity when building index keys. If <expr> is not
+         ** a column, use numeric affinity.
+         */
++        char affinity;            /* Affinity of the LHS of the IN */
+         int i;
+         ExprList *pList = pExpr->x.pList;
+         struct ExprList_item *pItem;
+         int r1, r2, r3;
+ 
++        affinity = sqlite3ExprAffinity(pLeft);
+         if( !affinity ){
+-          affinity = SQLITE_AFF_NONE;
++          affinity = SQLITE_AFF_BLOB;
+         }
+         if( pKeyInfo ){
+           assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+@@ -84774,7 +97532,7 @@
+             }else{
+               sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
+               sqlite3ExprCacheAffinityChange(pParse, r3, 1);
+-              sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2);
++              sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
+             }
+           }
+         }
+@@ -84790,26 +97548,37 @@
+     case TK_EXISTS:
+     case TK_SELECT:
+     default: {
+-      /* If this has to be a scalar SELECT.  Generate code to put the
+-      ** value of this select in a memory cell and record the number
+-      ** of the memory cell in iColumn.  If this is an EXISTS, write
+-      ** an integer 0 (not exists) or 1 (exists) into a memory cell
+-      ** and record that memory cell in iColumn.
++      /* Case 3:    (SELECT ... FROM ...)
++      **     or:    EXISTS(SELECT ... FROM ...)
++      **
++      ** For a SELECT, generate code to put the values for all columns of
++      ** the first row into an array of registers and return the index of
++      ** the first register.
++      **
++      ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
++      ** into a register and return that register number.
++      **
++      ** In both cases, the query is augmented with "LIMIT 1".  Any 
++      ** preexisting limit is discarded in place of the new LIMIT 1.
+       */
+       Select *pSel;                         /* SELECT statement to encode */
+-      SelectDest dest;                      /* How to deal with SELECt result */
++      SelectDest dest;                      /* How to deal with SELECT result */
++      int nReg;                             /* Registers to allocate */
+ 
+       testcase( pExpr->op==TK_EXISTS );
+       testcase( pExpr->op==TK_SELECT );
+       assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
+-
+       assert( ExprHasProperty(pExpr, EP_xIsSelect) );
++
+       pSel = pExpr->x.pSelect;
+-      sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
++      nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
++      sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
++      pParse->nMem += nReg;
+       if( pExpr->op==TK_SELECT ){
+         dest.eDest = SRT_Mem;
+         dest.iSdst = dest.iSDParm;
+-        sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm);
++        dest.nSdst = nReg;
++        sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
+         VdbeComment((v, "Init subquery result"));
+       }else{
+         dest.eDest = SRT_Exists;
+@@ -84817,8 +97586,8 @@
+         VdbeComment((v, "Init EXISTS result"));
+       }
+       sqlite3ExprDelete(pParse->db, pSel->pLimit);
+-      pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
+-                                  &sqlite3IntTokens[1]);
++      pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,
++                                  &sqlite3IntTokens[1], 0);
+       pSel->iLimit = 0;
+       pSel->selFlags &= ~SF_MultiValue;
+       if( sqlite3Select(pParse, pSel, &dest) ){
+@@ -84845,21 +97614,51 @@
+ 
+ #ifndef SQLITE_OMIT_SUBQUERY
+ /*
++** Expr pIn is an IN(...) expression. This function checks that the 
++** sub-select on the RHS of the IN() operator has the same number of 
++** columns as the vector on the LHS. Or, if the RHS of the IN() is not 
++** a sub-query, that the LHS is a vector of size 1.
++*/
++SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
++  int nVector = sqlite3ExprVectorSize(pIn->pLeft);
++  if( (pIn->flags & EP_xIsSelect) ){
++    if( nVector!=pIn->x.pSelect->pEList->nExpr ){
++      sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector);
++      return 1;
++    }
++  }else if( nVector!=1 ){
++    sqlite3VectorErrorMsg(pParse, pIn->pLeft);
++    return 1;
++  }
++  return 0;
 +}
++#endif
++
++#ifndef SQLITE_OMIT_SUBQUERY
++/*
+ ** Generate code for an IN expression.
+ **
+ **      x IN (SELECT ...)
+ **      x IN (value, value, ...)
+ **
+-** The left-hand side (LHS) is a scalar expression.  The right-hand side (RHS)
+-** is an array of zero or more values.  The expression is true if the LHS is
+-** contained within the RHS.  The value of the expression is unknown (NULL)
+-** if the LHS is NULL or if the LHS is not contained within the RHS and the
+-** RHS contains one or more NULL values.
++** The left-hand side (LHS) is a scalar or vector expression.  The 
++** right-hand side (RHS) is an array of zero or more scalar values, or a
++** subquery.  If the RHS is a subquery, the number of result columns must
++** match the number of columns in the vector on the LHS.  If the RHS is
++** a list of values, the LHS must be a scalar. 
++**
++** The IN operator is true if the LHS value is contained within the RHS.
++** The result is false if the LHS is definitely not in the RHS.  The 
++** result is NULL if the presence of the LHS in the RHS cannot be 
++** determined due to NULLs.
+ **
+ ** This routine generates code that jumps to destIfFalse if the LHS is not 
+ ** contained within the RHS.  If due to NULLs we cannot determine if the LHS
+ ** is contained in the RHS then jump to destIfNull.  If the LHS is contained
+ ** within the RHS then fall through.
++**
++** See the separate in-operator.md documentation file in the canonical
++** SQLite source tree for additional information.
+ */
+ static void sqlite3ExprCodeIN(
+   Parse *pParse,        /* Parsing and code generating context */
+@@ -84868,36 +97667,83 @@
+   int destIfNull        /* Jump here if the results are unknown due to NULLs */
+ ){
+   int rRhsHasNull = 0;  /* Register that is true if RHS contains NULL values */
+-  char affinity;        /* Comparison affinity to use */
+   int eType;            /* Type of the RHS */
+-  int r1;               /* Temporary use register */
++  int rLhs;             /* Register(s) holding the LHS values */
++  int rLhsOrig;         /* LHS values prior to reordering by aiMap[] */
+   Vdbe *v;              /* Statement under construction */
++  int *aiMap = 0;       /* Map from vector field to index column */
++  char *zAff = 0;       /* Affinity string for comparisons */
++  int nVector;          /* Size of vectors for this IN operator */
++  int iDummy;           /* Dummy parameter to exprCodeVector() */
++  Expr *pLeft;          /* The LHS of the IN operator */
++  int i;                /* loop counter */
++  int destStep2;        /* Where to jump when NULLs seen in step 2 */
++  int destStep6 = 0;    /* Start of code for Step 6 */
++  int addrTruthOp;      /* Address of opcode that determines the IN is true */
++  int destNotNull;      /* Jump here if a comparison is not true in step 6 */
++  int addrTop;          /* Top of the step-6 loop */ 
++
++  pLeft = pExpr->pLeft;
++  if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
++  zAff = exprINAffinity(pParse, pExpr);
++  nVector = sqlite3ExprVectorSize(pExpr->pLeft);
++  aiMap = (int*)sqlite3DbMallocZero(
++      pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1
++  );
++  if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
  
-+/**
-+  * Free and wipe memory associated with a cipher_ctx
+-  /* Compute the RHS.   After this step, the table with cursor
+-  ** pExpr->iTable will contains the values that make up the RHS.
+-  */
++  /* Attempt to compute the RHS. After this step, if anything other than
++  ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable 
++  ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned,
++  ** the RHS has not yet been coded.  */
+   v = pParse->pVdbe;
+   assert( v!=0 );       /* OOM detected prior to this routine */
+   VdbeNoopComment((v, "begin IN expr"));
+   eType = sqlite3FindInIndex(pParse, pExpr,
+                              IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK,
+-                             destIfFalse==destIfNull ? 0 : &rRhsHasNull);
++                             destIfFalse==destIfNull ? 0 : &rRhsHasNull, aiMap);
+ 
+-  /* Figure out the affinity to use to create a key from the results
+-  ** of the expression. affinityStr stores a static string suitable for
+-  ** P4 of OP_MakeRecord.
+-  */
+-  affinity = comparisonAffinity(pExpr);
++  assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH
++       || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC 
++  );
++#ifdef SQLITE_DEBUG
++  /* Confirm that aiMap[] contains nVector integer values between 0 and
++  ** nVector-1. */
++  for(i=0; i<nVector; i++){
++    int j, cnt;
++    for(cnt=j=0; j<nVector; j++) if( aiMap[j]==i ) cnt++;
++    assert( cnt==1 );
++  }
++#endif
+ 
+-  /* Code the LHS, the <expr> from "<expr> IN (...)".
++  /* Code the LHS, the <expr> from "<expr> IN (...)". If the LHS is a 
++  ** vector, then it is stored in an array of nVector registers starting 
++  ** at r1.
++  **
++  ** sqlite3FindInIndex() might have reordered the fields of the LHS vector
++  ** so that the fields are in the same order as an existing index.   The
++  ** aiMap[] array contains a mapping from the original LHS field order to
++  ** the field order that matches the RHS index.
+   */
+   sqlite3ExprCachePush(pParse);
+-  r1 = sqlite3GetTempReg(pParse);
+-  sqlite3ExprCode(pParse, pExpr->pLeft, r1);
++  rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
++  for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
++  if( i==nVector ){
++    /* LHS fields are not reordered */
++    rLhs = rLhsOrig;
++  }else{
++    /* Need to reorder the LHS fields according to aiMap */
++    rLhs = sqlite3GetTempRange(pParse, nVector);
++    for(i=0; i<nVector; i++){
++      sqlite3VdbeAddOp3(v, OP_Copy, rLhsOrig+i, rLhs+aiMap[i], 0);
++    }
++  }
+ 
+   /* If sqlite3FindInIndex() did not find or create an index that is
+   ** suitable for evaluating the IN operator, then evaluate using a
+   ** sequence of comparisons.
++  **
++  ** This is step (1) in the in-operator.md optimized algorithm.
+   */
+   if( eType==IN_INDEX_NOOP ){
+     ExprList *pList = pExpr->x.pList;
+@@ -84909,7 +97755,7 @@
+     assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+     if( destIfNull!=destIfFalse ){
+       regCkNull = sqlite3GetTempReg(pParse);
+-      sqlite3VdbeAddOp3(v, OP_BitAnd, r1, r1, regCkNull);
++      sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
+     }
+     for(ii=0; ii<pList->nExpr; ii++){
+       r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, &regToFree);
+@@ -84917,111 +97763,135 @@
+         sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull);
+       }
+       if( ii<pList->nExpr-1 || destIfNull!=destIfFalse ){
+-        sqlite3VdbeAddOp4(v, OP_Eq, r1, labelOk, r2,
++        sqlite3VdbeAddOp4(v, OP_Eq, rLhs, labelOk, r2,
+                           (void*)pColl, P4_COLLSEQ);
+         VdbeCoverageIf(v, ii<pList->nExpr-1);
+         VdbeCoverageIf(v, ii==pList->nExpr-1);
+-        sqlite3VdbeChangeP5(v, affinity);
++        sqlite3VdbeChangeP5(v, zAff[0]);
+       }else{
+         assert( destIfNull==destIfFalse );
+-        sqlite3VdbeAddOp4(v, OP_Ne, r1, destIfFalse, r2,
++        sqlite3VdbeAddOp4(v, OP_Ne, rLhs, destIfFalse, r2,
+                           (void*)pColl, P4_COLLSEQ); VdbeCoverage(v);
+-        sqlite3VdbeChangeP5(v, affinity | SQLITE_JUMPIFNULL);
++        sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL);
+       }
+       sqlite3ReleaseTempReg(pParse, regToFree);
+     }
+     if( regCkNull ){
+       sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v);
+-      sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
++      sqlite3VdbeGoto(v, destIfFalse);
+     }
+     sqlite3VdbeResolveLabel(v, labelOk);
+     sqlite3ReleaseTempReg(pParse, regCkNull);
++    goto sqlite3ExprCodeIN_finished;
++  }
++
++  /* Step 2: Check to see if the LHS contains any NULL columns.  If the
++  ** LHS does contain NULLs then the result must be either FALSE or NULL.
++  ** We will then skip the binary search of the RHS.
 +  */
-+static void sqlcipher_cipher_ctx_free(cipher_ctx **iCtx) {
-+  cipher_ctx *ctx = *iCtx;
-+  CODEC_TRACE(("cipher_ctx_free: entered iCtx=%p\n", iCtx));
-+  ctx->provider->ctx_free(&ctx->provider_ctx);
-+  sqlcipher_free(ctx->provider, sizeof(sqlcipher_provider)); 
-+  sqlcipher_free(ctx->key, ctx->key_sz);
-+  sqlcipher_free(ctx->hmac_key, ctx->key_sz);
-+  sqlcipher_free(ctx->pass, ctx->pass_sz);
-+  sqlcipher_free(ctx->keyspec, ctx->keyspec_sz);
-+  sqlcipher_free(ctx, sizeof(cipher_ctx)); 
-+}
++  if( destIfNull==destIfFalse ){
++    destStep2 = destIfFalse;
+   }else{
+-  
+-    /* If the LHS is NULL, then the result is either false or NULL depending
+-    ** on whether the RHS is empty or not, respectively.
+-    */
+-    if( sqlite3ExprCanBeNull(pExpr->pLeft) ){
+-      if( destIfNull==destIfFalse ){
+-        /* Shortcut for the common case where the false and NULL outcomes are
+-        ** the same. */
+-        sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v);
+-      }else{
+-        int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
+-        sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
+-        VdbeCoverage(v);
+-        sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
+-        sqlite3VdbeJumpHere(v, addr1);
+-      }
+-    }
+-  
+-    if( eType==IN_INDEX_ROWID ){
+-      /* In this case, the RHS is the ROWID of table b-tree
+-      */
+-      sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v);
+-      sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);
++    destStep2 = destStep6 = sqlite3VdbeMakeLabel(v);
++  }
++  for(i=0; i<nVector; i++){
++    Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
++    if( sqlite3ExprCanBeNull(p) ){
++      sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
+       VdbeCoverage(v);
+-    }else{
+-      /* In this case, the RHS is an index b-tree.
+-      */
+-      sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1);
+-  
+-      /* If the set membership test fails, then the result of the 
+-      ** "x IN (...)" expression must be either 0 or NULL. If the set
+-      ** contains no NULL values, then the result is 0. If the set 
+-      ** contains one or more NULL values, then the result of the
+-      ** expression is also NULL.
+-      */
+-      assert( destIfFalse!=destIfNull || rRhsHasNull==0 );
+-      if( rRhsHasNull==0 ){
+-        /* This branch runs if it is known at compile time that the RHS
+-        ** cannot contain NULL values. This happens as the result
+-        ** of a "NOT NULL" constraint in the database schema.
+-        **
+-        ** Also run this branch if NULL is equivalent to FALSE
+-        ** for this particular IN operator.
+-        */
+-        sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1);
+-        VdbeCoverage(v);
+-      }else{
+-        /* In this branch, the RHS of the IN might contain a NULL and
+-        ** the presence of a NULL on the RHS makes a difference in the
+-        ** outcome.
+-        */
+-        int j1;
+-  
+-        /* First check to see if the LHS is contained in the RHS.  If so,
+-        ** then the answer is TRUE the presence of NULLs in the RHS does
+-        ** not matter.  If the LHS is not contained in the RHS, then the
+-        ** answer is NULL if the RHS contains NULLs and the answer is
+-        ** FALSE if the RHS is NULL-free.
+-        */
+-        j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
+-        VdbeCoverage(v);
+-        sqlite3VdbeAddOp2(v, OP_IsNull, rRhsHasNull, destIfNull);
+-        VdbeCoverage(v);
+-        sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
+-        sqlite3VdbeJumpHere(v, j1);
+-      }
+     }
+   }
+-  sqlite3ReleaseTempReg(pParse, r1);
 +
-+/**
-+  * Compare one cipher_ctx to another.
-+  *
-+  * returns 0 if all the parameters (except the derived key data) are the same
-+  * returns 1 otherwise
++  /* Step 3.  The LHS is now known to be non-NULL.  Do the binary search
++  ** of the RHS using the LHS as a probe.  If found, the result is
++  ** true.
 +  */
-+static int sqlcipher_cipher_ctx_cmp(cipher_ctx *c1, cipher_ctx *c2) {
-+  int are_equal = (
-+    c1->iv_sz == c2->iv_sz
-+    && c1->kdf_iter == c2->kdf_iter
-+    && c1->fast_kdf_iter == c2->fast_kdf_iter
-+    && c1->key_sz == c2->key_sz
-+    && c1->pass_sz == c2->pass_sz
-+    && c1->flags == c2->flags
-+    && c1->hmac_sz == c2->hmac_sz
-+    && c1->provider->ctx_cmp(c1->provider_ctx, c2->provider_ctx) 
-+    && (
-+      c1->pass == c2->pass
-+      || !sqlcipher_memcmp((const unsigned char*)c1->pass,
-+                           (const unsigned char*)c2->pass,
-+                           c1->pass_sz)
-+    ));
++  if( eType==IN_INDEX_ROWID ){
++    /* In this case, the RHS is the ROWID of table b-tree and so we also
++    ** know that the RHS is non-NULL.  Hence, we combine steps 3 and 4
++    ** into a single opcode. */
++    sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, rLhs);
++    VdbeCoverage(v);
++    addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto);  /* Return True */
++  }else{
++    sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
++    if( destIfFalse==destIfNull ){
++      /* Combine Step 3 and Step 5 into a single opcode */
++      sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse,
++                           rLhs, nVector); VdbeCoverage(v);
++      goto sqlite3ExprCodeIN_finished;
++    }
++    /* Ordinary Step 3, for the case where FALSE and NULL are distinct */
++    addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0,
++                                      rLhs, nVector); VdbeCoverage(v);
++  }
 +
-+  CODEC_TRACE(("sqlcipher_cipher_ctx_cmp: entered \
-+                  c1=%p c2=%p \
-+                  c1->iv_sz=%d c2->iv_sz=%d \
-+                  c1->kdf_iter=%d c2->kdf_iter=%d \
-+                  c1->fast_kdf_iter=%d c2->fast_kdf_iter=%d \
-+                  c1->key_sz=%d c2->key_sz=%d \
-+                  c1->pass_sz=%d c2->pass_sz=%d \
-+                  c1->flags=%d c2->flags=%d \
-+                  c1->hmac_sz=%d c2->hmac_sz=%d \
-+                  c1->provider_ctx=%p c2->provider_ctx=%p \
-+                  c1->pass=%p c2->pass=%p \
-+                  c1->pass=%s c2->pass=%s \
-+                  provider->ctx_cmp=%d \
-+                  sqlcipher_memcmp=%d \
-+                  are_equal=%d \
-+                   \n", 
-+                  c1, c2,
-+                  c1->iv_sz, c2->iv_sz,
-+                  c1->kdf_iter, c2->kdf_iter,
-+                  c1->fast_kdf_iter, c2->fast_kdf_iter,
-+                  c1->key_sz, c2->key_sz,
-+                  c1->pass_sz, c2->pass_sz,
-+                  c1->flags, c2->flags,
-+                  c1->hmac_sz, c2->hmac_sz,
-+                  c1->provider_ctx, c2->provider_ctx,
-+                  c1->pass, c2->pass,
-+                  c1->pass, c2->pass,
-+                  c1->provider->ctx_cmp(c1->provider_ctx, c2->provider_ctx),
-+                  sqlcipher_memcmp((const unsigned char*)c1->pass,
-+                           (const unsigned char*)c2->pass,
-+                           c1->pass_sz),
-+                  are_equal
-+                  ));
++  /* Step 4.  If the RHS is known to be non-NULL and we did not find
++  ** an match on the search above, then the result must be FALSE.
++  */
++  if( rRhsHasNull && nVector==1 ){
++    sqlite3VdbeAddOp2(v, OP_NotNull, rRhsHasNull, destIfFalse);
++    VdbeCoverage(v);
++  }
 +
-+  return !are_equal; /* return 0 if they are the same, 1 otherwise */
-+}
++  /* Step 5.  If we do not care about the difference between NULL and
++  ** FALSE, then just return false. 
++  */
++  if( destIfFalse==destIfNull ) sqlite3VdbeGoto(v, destIfFalse);
 +
-+/**
-+  * Copy one cipher_ctx to another. For instance, assuming that read_ctx is a 
-+  * fully initialized context, you could copy it to write_ctx and all yet data
-+  * and pass information across
-+  *
-+  * returns SQLITE_OK if initialization was successful
-+  * returns SQLITE_NOMEM if an error occured allocating memory
++  /* Step 6: Loop through rows of the RHS.  Compare each row to the LHS.
++  ** If any comparison is NULL, then the result is NULL.  If all
++  ** comparisons are FALSE then the final result is FALSE.
++  **
++  ** For a scalar LHS, it is sufficient to check just the first row
++  ** of the RHS.
 +  */
-+static int sqlcipher_cipher_ctx_copy(cipher_ctx *target, cipher_ctx *source) {
-+  void *key = target->key; 
-+  void *hmac_key = target->hmac_key; 
-+  void *provider = target->provider;
-+  void *provider_ctx = target->provider_ctx;
++  if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6);
++  addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
++  VdbeCoverage(v);
++  if( nVector>1 ){
++    destNotNull = sqlite3VdbeMakeLabel(v);
++  }else{
++    /* For nVector==1, combine steps 6 and 7 by immediately returning
++    ** FALSE if the first comparison is not NULL */
++    destNotNull = destIfFalse;
++  }
++  for(i=0; i<nVector; i++){
++    Expr *p;
++    CollSeq *pColl;
++    int r3 = sqlite3GetTempReg(pParse);
++    p = sqlite3VectorFieldSubexpr(pLeft, i);
++    pColl = sqlite3ExprCollSeq(pParse, p);
++    sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, i, r3);
++    sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3,
++                      (void*)pColl, P4_COLLSEQ);
++    VdbeCoverage(v);
++    sqlite3ReleaseTempReg(pParse, r3);
++  }
++  sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
++  if( nVector>1 ){
++    sqlite3VdbeResolveLabel(v, destNotNull);
++    sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrTop+1);
++    VdbeCoverage(v);
++
++    /* Step 7:  If we reach this point, we know that the result must
++    ** be false. */
++    sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
++  }
 +
-+  CODEC_TRACE(("sqlcipher_cipher_ctx_copy: entered target=%p, source=%p\n", target, source));
-+  sqlcipher_free(target->pass, target->pass_sz); 
-+  sqlcipher_free(target->keyspec, target->keyspec_sz); 
-+  memcpy(target, source, sizeof(cipher_ctx));
++  /* Jumps here in order to return true. */
++  sqlite3VdbeJumpHere(v, addrTruthOp);
 +
-+  target->key = key; //restore pointer to previously allocated key data
-+  memcpy(target->key, source->key, CIPHER_MAX_KEY_SZ);
++sqlite3ExprCodeIN_finished:
++  if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs);
+   sqlite3ExprCachePop(pParse);
+   VdbeComment((v, "end IN expr"));
++sqlite3ExprCodeIN_oom_error:
++  sqlite3DbFree(pParse->db, aiMap);
++  sqlite3DbFree(pParse->db, zAff);
+ }
+ #endif /* SQLITE_OMIT_SUBQUERY */
+ 
+-/*
+-** Duplicate an 8-byte value
+-*/
+-static char *dup8bytes(Vdbe *v, const char *in){
+-  char *out = sqlite3DbMallocRaw(sqlite3VdbeDb(v), 8);
+-  if( out ){
+-    memcpy(out, in, 8);
+-  }
+-  return out;
+-}
+-
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+ /*
+ ** Generate an instruction that will put the floating point
+@@ -85034,12 +97904,10 @@
+ static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
+   if( ALWAYS(z!=0) ){
+     double value;
+-    char *zV;
+     sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
+     assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */
+     if( negateFlag ) value = -value;
+-    zV = dup8bytes(v, (char*)&value);
+-    sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL);
++    sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL);
+   }
+ }
+ #endif
+@@ -85064,37 +97932,38 @@
+     const char *z = pExpr->u.zToken;
+     assert( z!=0 );
+     c = sqlite3DecOrHexToI64(z, &value);
+-    if( c==0 || (c==2 && negFlag) ){
+-      char *zV;
+-      if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
+-      zV = dup8bytes(v, (char*)&value);
+-      sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
+-    }else{
++    if( c==1 || (c==2 && !negFlag) || (negFlag && value==SMALLEST_INT64)){
+ #ifdef SQLITE_OMIT_FLOATING_POINT
+       sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
+ #else
+ #ifndef SQLITE_OMIT_HEX_INTEGER
+       if( sqlite3_strnicmp(z,"0x",2)==0 ){
+-        sqlite3ErrorMsg(pParse, "hex literal too big: %s", z);
++        sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z);
+       }else
+ #endif
+       {
+         codeReal(v, z, negFlag, iMem);
+       }
+ #endif
++    }else{
++      if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
++      sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64);
+     }
+   }
+ }
+ 
+ /*
+-** Clear a cache entry.
++** Erase column-cache entry number i
+ */
+-static void cacheEntryClear(Parse *pParse, struct yColCache *p){
+-  if( p->tempReg ){
++static void cacheEntryClear(Parse *pParse, int i){
++  if( pParse->aColCache[i].tempReg ){
+     if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
+-      pParse->aTempReg[pParse->nTempReg++] = p->iReg;
++      pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
+     }
+-    p->tempReg = 0;
++  }
++  pParse->nColCache--;
++  if( i<pParse->nColCache ){
++    pParse->aColCache[i] = pParse->aColCache[pParse->nColCache];
+   }
+ }
+ 
+@@ -85125,43 +97994,33 @@
+   ** that the object will never already be in cache.  Verify this guarantee.
+   */
+ #ifndef NDEBUG
+-  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+-    assert( p->iReg==0 || p->iTable!=iTab || p->iColumn!=iCol );
++  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
++    assert( p->iTable!=iTab || p->iColumn!=iCol );
+   }
+ #endif
+ 
+-  /* Find an empty slot and replace it */
+-  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+-    if( p->iReg==0 ){
+-      p->iLevel = pParse->iCacheLevel;
+-      p->iTable = iTab;
+-      p->iColumn = iCol;
+-      p->iReg = iReg;
+-      p->tempReg = 0;
+-      p->lru = pParse->iCacheCnt++;
+-      return;
+-    }
+-  }
+-
+-  /* Replace the last recently used */
+-  minLru = 0x7fffffff;
+-  idxLru = -1;
+-  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+-    if( p->lru<minLru ){
+-      idxLru = i;
+-      minLru = p->lru;
++  /* If the cache is already full, delete the least recently used entry */
++  if( pParse->nColCache>=SQLITE_N_COLCACHE ){
++    minLru = 0x7fffffff;
++    idxLru = -1;
++    for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
++      if( p->lru<minLru ){
++        idxLru = i;
++        minLru = p->lru;
++      }
+     }
+-  }
+-  if( ALWAYS(idxLru>=0) ){
+     p = &pParse->aColCache[idxLru];
+-    p->iLevel = pParse->iCacheLevel;
+-    p->iTable = iTab;
+-    p->iColumn = iCol;
+-    p->iReg = iReg;
+-    p->tempReg = 0;
+-    p->lru = pParse->iCacheCnt++;
+-    return;
++  }else{
++    p = &pParse->aColCache[pParse->nColCache++];
+   }
 +
-+  target->hmac_key = hmac_key; //restore pointer to previously allocated hmac key data
-+  memcpy(target->hmac_key, source->hmac_key, CIPHER_MAX_KEY_SZ);
++  /* Add the new entry to the end of the cache */
++  p->iLevel = pParse->iCacheLevel;
++  p->iTable = iTab;
++  p->iColumn = iCol;
++  p->iReg = iReg;
++  p->tempReg = 0;
++  p->lru = pParse->iCacheCnt++;
+ }
+ 
+ /*
+@@ -85169,14 +98028,13 @@
+ ** Purge the range of registers from the column cache.
+ */
+ SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
+-  int i;
+-  int iLast = iReg + nReg - 1;
+-  struct yColCache *p;
+-  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+-    int r = p->iReg;
+-    if( r>=iReg && r<=iLast ){
+-      cacheEntryClear(pParse, p);
+-      p->iReg = 0;
++  int i = 0;
++  while( i<pParse->nColCache ){
++    struct yColCache *p = &pParse->aColCache[i];
++    if( p->iReg >= iReg && p->iReg < iReg+nReg ){
++      cacheEntryClear(pParse, i);
++    }else{
++      i++;
+     }
+   }
+ }
+@@ -85201,8 +98059,7 @@
+ ** the cache to the state it was in prior the most recent Push.
+ */
+ SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
+-  int i;
+-  struct yColCache *p;
++  int i = 0;
+   assert( pParse->iCacheLevel>=1 );
+   pParse->iCacheLevel--;
+ #ifdef SQLITE_DEBUG
+@@ -85210,10 +98067,11 @@
+     printf("POP  to %d\n", pParse->iCacheLevel);
+   }
+ #endif
+-  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+-    if( p->iReg && p->iLevel>pParse->iCacheLevel ){
+-      cacheEntryClear(pParse, p);
+-      p->iReg = 0;
++  while( i<pParse->nColCache ){
++    if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){
++      cacheEntryClear(pParse, i);
++    }else{
++      i++;
+     }
+   }
+ }
+@@ -85227,13 +98085,36 @@
+ static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
+   int i;
+   struct yColCache *p;
+-  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
++  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+     if( p->iReg==iReg ){
+       p->tempReg = 0;
+     }
+   }
+ }
+ 
++/* Generate code that will load into register regOut a value that is
++** appropriate for the iIdxCol-th column of index pIdx.
++*/
++SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(
++  Parse *pParse,  /* The parsing context */
++  Index *pIdx,    /* The index whose column is to be loaded */
++  int iTabCur,    /* Cursor pointing to a table row */
++  int iIdxCol,    /* The column of the index to be loaded */
++  int regOut      /* Store the index column value in this register */
++){
++  i16 iTabCol = pIdx->aiColumn[iIdxCol];
++  if( iTabCol==XN_EXPR ){
++    assert( pIdx->aColExpr );
++    assert( pIdx->aColExpr->nExpr>iIdxCol );
++    pParse->iSelfTab = iTabCur + 1;
++    sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
++    pParse->iSelfTab = 0;
++  }else{
++    sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
++                                    iTabCol, regOut);
++  }
++}
 +
-+  target->provider = provider; // restore pointer to previouly allocated provider;
-+  memcpy(target->provider, source->provider, sizeof(sqlcipher_provider));
+ /*
+ ** Generate code to extract the value of the iCol-th column of a table.
+ */
+@@ -85244,12 +98125,16 @@
+   int iCol,       /* Index of the column to extract */
+   int regOut      /* Extract the value into this register */
+ ){
++  if( pTab==0 ){
++    sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
++    return;
++  }
+   if( iCol<0 || iCol==pTab->iPKey ){
+     sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
+   }else{
+     int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
+     int x = iCol;
+-    if( !HasRowid(pTab) ){
++    if( !HasRowid(pTab) && !IsVirtual(pTab) ){
+       x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
+     }
+     sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut);
+@@ -85261,9 +98146,12 @@
+ 
+ /*
+ ** Generate code that will extract the iColumn-th column from
+-** table pTab and store the column value in a register.  An effort
+-** is made to store the column value in register iReg, but this is
+-** not guaranteed.  The location of the column value is returned.
++** table pTab and store the column value in a register. 
++**
++** An effort is made to store the column value in register iReg.  This
++** is not garanteeed for GetColumn() - the result can be stored in
++** any register.  But the result is guaranteed to land in register iReg
++** for GetColumnToReg().
+ **
+ ** There must be an open cursor to pTab in iTable when this routine
+ ** is called.  If iColumn<0 then code is generated that extracts the rowid.
+@@ -85274,14 +98162,14 @@
+   int iColumn,     /* Index of the table column */
+   int iTable,      /* The cursor pointing to the table */
+   int iReg,        /* Store results here */
+-  u8 p5            /* P5 value for OP_Column */
++  u8 p5            /* P5 value for OP_Column + FLAGS */
+ ){
+   Vdbe *v = pParse->pVdbe;
+   int i;
+   struct yColCache *p;
+ 
+-  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+-    if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn ){
++  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
++    if( p->iTable==iTable && p->iColumn==iColumn ){
+       p->lru = pParse->iCacheCnt++;
+       sqlite3ExprCachePinRegister(pParse, p->iReg);
+       return p->iReg;
+@@ -85296,25 +98184,37 @@
+   }
+   return iReg;
+ }
++SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(
++  Parse *pParse,   /* Parsing and code generating context */
++  Table *pTab,     /* Description of the table we are reading from */
++  int iColumn,     /* Index of the table column */
++  int iTable,      /* The cursor pointing to the table */
++  int iReg         /* Store results here */
++){
++  int r1 = sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0);
++  if( r1!=iReg ) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg);
++}
 +
-+  target->provider_ctx = provider_ctx; // restore pointer to previouly allocated provider context;
-+  target->provider->ctx_copy(target->provider_ctx, source->provider_ctx);
+ 
+ /*
+ ** Clear all column cache entries.
+ */
+ SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
+   int i;
+-  struct yColCache *p;
+ 
+-#if SQLITE_DEBUG
++#ifdef SQLITE_DEBUG
+   if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+     printf("CLEAR\n");
+   }
+ #endif
+-  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+-    if( p->iReg ){
+-      cacheEntryClear(pParse, p);
+-      p->iReg = 0;
++  for(i=0; i<pParse->nColCache; i++){
++    if( pParse->aColCache[i].tempReg
++     && pParse->nTempReg<ArraySize(pParse->aTempReg)
++    ){
++       pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
+     }
+   }
++  pParse->nColCache = 0;
+ }
+ 
+ /*
+@@ -85346,7 +98246,7 @@
+ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
+   int i;
+   struct yColCache *p;
+-  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
++  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+     int r = p->iReg;
+     if( r>=iFrom && r<=iTo ) return 1;    /*NO_TEST*/
+   }
+@@ -85354,8 +98254,11 @@
+ }
+ #endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
+ 
 +
-+  if(source->pass && source->pass_sz) {
-+    target->pass = sqlcipher_malloc(source->pass_sz);
-+    if(target->pass == NULL) return SQLITE_NOMEM;
-+    memcpy(target->pass, source->pass, source->pass_sz);
-+  }
-+  if(source->keyspec && source->keyspec_sz) {
-+    target->keyspec = sqlcipher_malloc(source->keyspec_sz);
-+    if(target->keyspec == NULL) return SQLITE_NOMEM;
-+    memcpy(target->keyspec, source->keyspec, source->keyspec_sz);
+ /*
+-** Convert an expression node to a TK_REGISTER
++** Convert a scalar expression node to a TK_REGISTER referencing
++** register iReg.  The caller must ensure that iReg already contains
++** the correct value for the expression.
+ */
+ static void exprToRegister(Expr *p, int iReg){
+   p->op2 = p->op;
+@@ -85365,6 +98268,42 @@
+ }
+ 
+ /*
++** Evaluate an expression (either a vector or a scalar expression) and store
++** the result in continguous temporary registers.  Return the index of
++** the first register used to store the result.
++**
++** If the returned result register is a temporary scalar, then also write
++** that register number into *piFreeable.  If the returned result register
++** is not a temporary or if the expression is a vector set *piFreeable
++** to 0.
++*/
++static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
++  int iResult;
++  int nResult = sqlite3ExprVectorSize(p);
++  if( nResult==1 ){
++    iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable);
++  }else{
++    *piFreeable = 0;
++    if( p->op==TK_SELECT ){
++#if SQLITE_OMIT_SUBQUERY
++      iResult = 0;
++#else
++      iResult = sqlite3CodeSubselect(pParse, p, 0, 0);
++#endif
++    }else{
++      int i;
++      iResult = pParse->nMem+1;
++      pParse->nMem += nResult;
++      for(i=0; i<nResult; i++){
++        sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
++      }
++    }
 +  }
-+  return SQLITE_OK;
++  return iResult;
 +}
- 
--/* The "wsdStat" macro will resolve to the status information
--** state vector.  If writable static data is unsupported on the target,
--** we have to locate the state vector at run-time.  In the more common
--** case where writable static data is supported, wsdStat can refer directly
--** to the "sqlite3Stat" state vector declared above.
--*/
--#ifdef SQLITE_OMIT_WSD
--# define wsdStatInit  sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat)
--# define wsdStat x[0]
--#else
--# define wsdStatInit
--# define wsdStat sqlite3Stat
--#endif
-+/**
-+  * Set the keyspec for the cipher_ctx
-+  * 
-+  * returns SQLITE_OK if assignment was successfull
-+  * returns SQLITE_NOMEM if an error occured allocating memory
-+  */
-+static int sqlcipher_cipher_ctx_set_keyspec(cipher_ctx *ctx, const unsigned char *key, int key_sz, const 
unsigned char *salt, int salt_sz) {
 +
-+    /* free, zero existing pointers and size */
-+  sqlcipher_free(ctx->keyspec, ctx->keyspec_sz);
-+  ctx->keyspec = NULL;
-+  ctx->keyspec_sz = 0;
 +
-+  /* establic a hex-formated key specification, containing the raw encryption key and
-+     the salt used to generate it */
-+  ctx->keyspec_sz = ((key_sz + salt_sz) * 2) + 3;
-+  ctx->keyspec = sqlcipher_malloc(ctx->keyspec_sz);
-+  if(ctx->keyspec == NULL) return SQLITE_NOMEM;
++/*
+ ** Generate code into the current Vdbe to evaluate the given
+ ** expression.  Attempt to store the results in register "target".
+ ** Return the register where results are stored.
+@@ -85381,9 +98320,9 @@
+   int inReg = target;       /* Results stored in register inReg */
+   int regFree1 = 0;         /* If non-zero free this temporary register */
+   int regFree2 = 0;         /* If non-zero free this temporary register */
+-  int r1, r2, r3, r4;       /* Various register numbers */
+-  sqlite3 *db = pParse->db; /* The database connection */
++  int r1, r2;               /* Various register numbers */
+   Expr tempX;               /* Temporary expression node */
++  int p5 = 0;
+ 
+   assert( target>0 && target<=pParse->nMem );
+   if( v==0 ){
+@@ -85402,51 +98341,49 @@
+       struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
+       if( !pAggInfo->directMode ){
+         assert( pCol->iMem>0 );
+-        inReg = pCol->iMem;
+-        break;
++        return pCol->iMem;
+       }else if( pAggInfo->useSortingIdx ){
+         sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
+                               pCol->iSorterColumn, target);
+-        break;
++        return target;
+       }
+       /* Otherwise, fall thru into the TK_COLUMN case */
+     }
+     case TK_COLUMN: {
+       int iTab = pExpr->iTable;
+       if( iTab<0 ){
+-        if( pParse->ckBase>0 ){
++        if( pParse->iSelfTab<0 ){
+           /* Generating CHECK constraints or inserting into partial index */
+-          inReg = pExpr->iColumn + pParse->ckBase;
+-          break;
++          return pExpr->iColumn - pParse->iSelfTab;
+         }else{
+-          /* Deleting from a partial index */
+-          iTab = pParse->iPartIdxTab;
++          /* Coding an expression that is part of an index where column names
++          ** in the index refer to the table to which the index belongs */
++          iTab = pParse->iSelfTab - 1;
+         }
+       }
+-      inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
++      return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
+                                pExpr->iColumn, iTab, target,
+                                pExpr->op2);
+-      break;
+     }
+     case TK_INTEGER: {
+       codeInteger(pParse, pExpr, 0, target);
+-      break;
++      return target;
+     }
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+     case TK_FLOAT: {
+       assert( !ExprHasProperty(pExpr, EP_IntValue) );
+       codeReal(v, pExpr->u.zToken, 0, target);
+-      break;
++      return target;
+     }
+ #endif
+     case TK_STRING: {
+       assert( !ExprHasProperty(pExpr, EP_IntValue) );
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->u.zToken, 0);
+-      break;
++      sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
++      return target;
+     }
+     case TK_NULL: {
+       sqlite3VdbeAddOp2(v, OP_Null, 0, target);
+-      break;
++      return target;
+     }
+ #ifndef SQLITE_OMIT_BLOB_LITERAL
+     case TK_BLOB: {
+@@ -85461,7 +98398,7 @@
+       assert( z[n]=='\'' );
+       zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n);
+       sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC);
+-      break;
++      return target;
+     }
+ #endif
+     case TK_VARIABLE: {
+@@ -85470,19 +98407,15 @@
+       assert( pExpr->u.zToken[0]!=0 );
+       sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
+       if( pExpr->u.zToken[1]!=0 ){
+-        assert( pExpr->u.zToken[0]=='?' 
+-             || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 );
+-        sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC);
++        const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
++        assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 );
++        pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */
++        sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
+       }
+-      break;
++      return target;
+     }
+     case TK_REGISTER: {
+-      inReg = pExpr->iTable;
+-      break;
+-    }
+-    case TK_AS: {
+-      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
+-      break;
++      return pExpr->iTable;
+     }
+ #ifndef SQLITE_OMIT_CAST
+     case TK_CAST: {
+@@ -85496,42 +98429,37 @@
+                         sqlite3AffinityType(pExpr->u.zToken, 0));
+       testcase( usedAsColumnCache(pParse, inReg, inReg) );
+       sqlite3ExprCacheAffinityChange(pParse, inReg, 1);
+-      break;
++      return inReg;
+     }
+ #endif /* SQLITE_OMIT_CAST */
++    case TK_IS:
++    case TK_ISNOT:
++      op = (op==TK_IS) ? TK_EQ : TK_NE;
++      p5 = SQLITE_NULLEQ;
++      /* fall-through */
+     case TK_LT:
+     case TK_LE:
+     case TK_GT:
+     case TK_GE:
+     case TK_NE:
+     case TK_EQ: {
+-      r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
+-      r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
+-      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+-                  r1, r2, inReg, SQLITE_STOREP2);
+-      assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
+-      assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
+-      assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
+-      assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+-      assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+-      assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
+-      testcase( regFree1==0 );
+-      testcase( regFree2==0 );
+-      break;
+-    }
+-    case TK_IS:
+-    case TK_ISNOT: {
+-      testcase( op==TK_IS );
+-      testcase( op==TK_ISNOT );
+-      r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
+-      r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
+-      op = (op==TK_IS) ? TK_EQ : TK_NE;
+-      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+-                  r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ);
+-      VdbeCoverageIf(v, op==TK_EQ);
+-      VdbeCoverageIf(v, op==TK_NE);
+-      testcase( regFree1==0 );
+-      testcase( regFree2==0 );
++      Expr *pLeft = pExpr->pLeft;
++      if( sqlite3ExprIsVector(pLeft) ){
++        codeVectorCompare(pParse, pExpr, target, op, p5);
++      }else{
++        r1 = sqlite3ExprCodeTemp(pParse, pLeft, &regFree1);
++        r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
++        codeCompare(pParse, pLeft, pExpr->pRight, op,
++            r1, r2, inReg, SQLITE_STOREP2 | p5);
++        assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
++        assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
++        assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
++        assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
++        assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
++        assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
++        testcase( regFree1==0 );
++        testcase( regFree2==0 );
++      }
+       break;
+     }
+     case TK_AND:
+@@ -85569,10 +98497,12 @@
+       assert( pLeft );
+       if( pLeft->op==TK_INTEGER ){
+         codeInteger(pParse, pLeft, 1, target);
++        return target;
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+       }else if( pLeft->op==TK_FLOAT ){
+         assert( !ExprHasProperty(pExpr, EP_IntValue) );
+         codeReal(v, pLeft->u.zToken, 1, target);
++        return target;
+ #endif
+       }else{
+         tempX.op = TK_INTEGER;
+@@ -85583,7 +98513,6 @@
+         sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
+         testcase( regFree2==0 );
+       }
+-      inReg = target;
+       break;
+     }
+     case TK_BITNOT:
+@@ -85592,7 +98521,6 @@
+       assert( TK_NOT==OP_Not );         testcase( op==TK_NOT );
+       r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
+       testcase( regFree1==0 );
+-      inReg = target;
+       sqlite3VdbeAddOp2(v, op, r1, inReg);
+       break;
+     }
+@@ -85617,7 +98545,7 @@
+         assert( !ExprHasProperty(pExpr, EP_IntValue) );
+         sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
+       }else{
+-        inReg = pInfo->aFunc[pExpr->iAgg].iMem;
++        return pInfo->aFunc[pExpr->iAgg].iMem;
+       }
+       break;
+     }
+@@ -85625,13 +98553,18 @@
+       ExprList *pFarg;       /* List of function arguments */
+       int nFarg;             /* Number of function arguments */
+       FuncDef *pDef;         /* The function definition object */
+-      int nId;               /* Length of the function name in bytes */
+       const char *zId;       /* The function name */
+       u32 constMask = 0;     /* Mask of function arguments that are constant */
+       int i;                 /* Loop counter */
++      sqlite3 *db = pParse->db;  /* The database connection */
+       u8 enc = ENC(db);      /* The text encoding used by this database */
+       CollSeq *pColl = 0;    /* A collating sequence */
+ 
++      if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
++        /* SQL functions can be expensive. So try to move constant functions
++        ** out of the inner loop, even if that means an extra OP_Copy. */
++        return sqlite3ExprCodeAtInit(pParse, pExpr, -1);
++      }
+       assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+       if( ExprHasProperty(pExpr, EP_TokenOnly) ){
+         pFarg = 0;
+@@ -85641,10 +98574,14 @@
+       nFarg = pFarg ? pFarg->nExpr : 0;
+       assert( !ExprHasProperty(pExpr, EP_IntValue) );
+       zId = pExpr->u.zToken;
+-      nId = sqlite3Strlen30(zId);
+-      pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
+-      if( pDef==0 || pDef->xFunc==0 ){
+-        sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId);
++      pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
++#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
++      if( pDef==0 && pParse->explain ){
++        pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0);
++      }
++#endif
++      if( pDef==0 || pDef->xFinalize!=0 ){
++        sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
+         break;
+       }
+ 
+@@ -85673,9 +98610,24 @@
+       */
+       if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
+         assert( nFarg>=1 );
+-        sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
+-        break;
++        return sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
++      }
 +
-+  ctx->keyspec[0] = 'x';
-+  ctx->keyspec[1] = '\'';
-+  cipher_bin2hex(key, key_sz, ctx->keyspec + 2);
-+  cipher_bin2hex(salt, salt_sz, ctx->keyspec + (key_sz * 2) + 2);
-+  ctx->keyspec[ctx->keyspec_sz - 1] = '\'';
-+  return SQLITE_OK;
-+}
++#ifdef SQLITE_DEBUG
++      /* The AFFINITY() function evaluates to a string that describes
++      ** the type affinity of the argument.  This is used for testing of
++      ** the SQLite type logic.
++      */
++      if( pDef->funcFlags & SQLITE_FUNC_AFFINITY ){
++        const char *azAff[] = { "blob", "text", "numeric", "integer", "real" };
++        char aff;
++        assert( nFarg==1 );
++        aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
++        sqlite3VdbeLoadString(v, target, 
++                              aff ? azAff[aff-SQLITE_AFF_BLOB] : "none");
++        return target;
+       }
++#endif
  
--/*
--** Return the current value of a status parameter.  The caller must
--** be holding the appropriate mutex.
--*/
--SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int op){
--  wsdStatInit;
--  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
--  assert( op>=0 && op<ArraySize(statMutex) );
--  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
--                                           : sqlite3MallocMutex()) );
--  return wsdStat.nowValue[op];
-+int sqlcipher_codec_get_store_pass(codec_ctx *ctx) {
-+  return ctx->read_ctx->store_pass;
- }
+       for(i=0; i<nFarg; i++){
+         if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
+@@ -85714,7 +98666,7 @@
+         }
  
--/*
--** Add N to the value of a status record.  The caller must hold the
--** appropriate mutex.  (Locking is checked by assert()).
--**
--** The StatusUp() routine can accept positive or negative values for N.
--** The value of N is added to the current status value and the high-water
--** mark is adjusted if necessary.
--**
--** The StatusDown() routine lowers the current value by N.  The highwater
--** mark is unchanged.  N must be non-negative for StatusDown().
--*/
--SQLITE_PRIVATE void sqlite3StatusUp(int op, int N){
--  wsdStatInit;
--  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
--  assert( op>=0 && op<ArraySize(statMutex) );
--  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
--                                           : sqlite3MallocMutex()) );
--  wsdStat.nowValue[op] += N;
--  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
--    wsdStat.mxValue[op] = wsdStat.nowValue[op];
--  }
-+void sqlcipher_codec_set_store_pass(codec_ctx *ctx, int value) {
-+  ctx->read_ctx->store_pass = value;
- }
--SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){
--  wsdStatInit;
--  assert( N>=0 );
--  assert( op>=0 && op<ArraySize(statMutex) );
--  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
--                                           : sqlite3MallocMutex()) );
--  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
--  wsdStat.nowValue[op] -= N;
+         sqlite3ExprCachePush(pParse);     /* Ticket 2ea2425d34be */
+-        sqlite3ExprCodeExprList(pParse, pFarg, r1,
++        sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
+                                 SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
+         sqlite3ExprCachePop(pParse);      /* Ticket 2ea2425d34be */
+       }else{
+@@ -85743,22 +98695,41 @@
+         if( !pColl ) pColl = db->pDfltColl; 
+         sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
+       }
+-      sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target,
+-                        (char*)pDef, P4_FUNCDEF);
++      sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0,
++                        constMask, r1, target, (char*)pDef, P4_FUNCDEF);
+       sqlite3VdbeChangeP5(v, (u8)nFarg);
+       if( nFarg && constMask==0 ){
+         sqlite3ReleaseTempRange(pParse, r1, nFarg);
+       }
+-      break;
++      return target;
+     }
+ #ifndef SQLITE_OMIT_SUBQUERY
+     case TK_EXISTS:
+     case TK_SELECT: {
++      int nCol;
+       testcase( op==TK_EXISTS );
+       testcase( op==TK_SELECT );
+-      inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
++      if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
++        sqlite3SubselectError(pParse, nCol, 1);
++      }else{
++        return sqlite3CodeSubselect(pParse, pExpr, 0, 0);
++      }
+       break;
+     }
++    case TK_SELECT_COLUMN: {
++      int n;
++      if( pExpr->pLeft->iTable==0 ){
++        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0);
++      }
++      assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
++      if( pExpr->iTable
++       && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft)) 
++      ){
++        sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
++                                pExpr->iTable, n);
++      }
++      return pExpr->pLeft->iTable + pExpr->iColumn;
++    }
+     case TK_IN: {
+       int destIfFalse = sqlite3VdbeMakeLabel(v);
+       int destIfNull = sqlite3VdbeMakeLabel(v);
+@@ -85768,7 +98739,7 @@
+       sqlite3VdbeResolveLabel(v, destIfFalse);
+       sqlite3VdbeAddOp2(v, OP_AddImm, target, 0);
+       sqlite3VdbeResolveLabel(v, destIfNull);
+-      break;
++      return target;
+     }
+ #endif /* SQLITE_OMIT_SUBQUERY */
+ 
+@@ -85785,34 +98756,13 @@
+     ** Z is stored in pExpr->pList->a[1].pExpr.
+     */
+     case TK_BETWEEN: {
+-      Expr *pLeft = pExpr->pLeft;
+-      struct ExprList_item *pLItem = pExpr->x.pList->a;
+-      Expr *pRight = pLItem->pExpr;
+-
+-      r1 = sqlite3ExprCodeTemp(pParse, pLeft, &regFree1);
+-      r2 = sqlite3ExprCodeTemp(pParse, pRight, &regFree2);
+-      testcase( regFree1==0 );
+-      testcase( regFree2==0 );
+-      r3 = sqlite3GetTempReg(pParse);
+-      r4 = sqlite3GetTempReg(pParse);
+-      codeCompare(pParse, pLeft, pRight, OP_Ge,
+-                  r1, r2, r3, SQLITE_STOREP2);  VdbeCoverage(v);
+-      pLItem++;
+-      pRight = pLItem->pExpr;
+-      sqlite3ReleaseTempReg(pParse, regFree2);
+-      r2 = sqlite3ExprCodeTemp(pParse, pRight, &regFree2);
+-      testcase( regFree2==0 );
+-      codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2);
+-      VdbeCoverage(v);
+-      sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
+-      sqlite3ReleaseTempReg(pParse, r3);
+-      sqlite3ReleaseTempReg(pParse, r4);
+-      break;
++      exprCodeBetween(pParse, pExpr, target, 0, 0);
++      return target;
+     }
++    case TK_SPAN:
+     case TK_COLLATE: 
+     case TK_UPLUS: {
+-      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
+-      break;
++      return sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
+     }
+ 
+     case TK_TRIGGER: {
+@@ -85871,6 +98821,21 @@
+       break;
+     }
+ 
++    case TK_VECTOR: {
++      sqlite3ErrorMsg(pParse, "row value misused");
++      break;
++    }
 +
-+void sqlcipher_codec_get_pass(codec_ctx *ctx, void **zKey, int *nKey) {
-+  *zKey = ctx->read_ctx->pass;
-+  *nKey = ctx->read_ctx->pass_sz;
++    case TK_IF_NULL_ROW: {
++      int addrINR;
++      addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
++      sqlite3ExprCachePush(pParse);
++      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
++      sqlite3ExprCachePop(pParse);
++      sqlite3VdbeJumpHere(v, addrINR);
++      sqlite3VdbeChangeP3(v, addrINR, inReg);
++      break;
++    }
+ 
+     /*
+     ** Form A:
+@@ -85914,8 +98879,9 @@
+       if( (pX = pExpr->pLeft)!=0 ){
+         tempX = *pX;
+         testcase( pX->op==TK_COLUMN );
+-        exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, &regFree1));
++        exprToRegister(&tempX, exprCodeVector(pParse, &tempX, &regFree1));
+         testcase( regFree1==0 );
++        memset(&opCompare, 0, sizeof(opCompare));
+         opCompare.op = TK_EQ;
+         opCompare.pLeft = &tempX;
+         pTest = &opCompare;
+@@ -85938,7 +98904,7 @@
+         sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
+         testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
+         sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
+-        sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel);
++        sqlite3VdbeGoto(v, endLabel);
+         sqlite3ExprCachePop(pParse);
+         sqlite3VdbeResolveLabel(v, nextCase);
+       }
+@@ -85949,7 +98915,7 @@
+       }else{
+         sqlite3VdbeAddOp2(v, OP_Null, 0, target);
+       }
+-      assert( db->mallocFailed || pParse->nErr>0 
++      assert( pParse->db->mallocFailed || pParse->nErr>0 
+            || pParse->iCacheLevel==iCacheLevel );
+       sqlite3VdbeResolveLabel(v, endLabel);
+       break;
+@@ -85990,24 +98956,40 @@
+ 
+ /*
+ ** Factor out the code of the given expression to initialization time.
++**
++** If regDest>=0 then the result is always stored in that register and the
++** result is not reusable.  If regDest<0 then this routine is free to 
++** store the value whereever it wants.  The register where the expression 
++** is stored is returned.  When regDest<0, two identical expressions will
++** code to the same register.
+ */
+-SQLITE_PRIVATE void sqlite3ExprCodeAtInit(
++SQLITE_PRIVATE int sqlite3ExprCodeAtInit(
+   Parse *pParse,    /* Parsing context */
+   Expr *pExpr,      /* The expression to code when the VDBE initializes */
+-  int regDest,      /* Store the value in this register */
+-  u8 reusable       /* True if this expression is reusable */
++  int regDest       /* Store the value in this register */
+ ){
+   ExprList *p;
+   assert( ConstFactorOk(pParse) );
+   p = pParse->pConstExpr;
++  if( regDest<0 && p ){
++    struct ExprList_item *pItem;
++    int i;
++    for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
++      if( pItem->reusable && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 ){
++        return pItem->u.iConstExprReg;
++      }
++    }
++  }
+   pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
+   p = sqlite3ExprListAppend(pParse, p, pExpr);
+   if( p ){
+      struct ExprList_item *pItem = &p->a[p->nExpr-1];
++     pItem->reusable = regDest<0;
++     if( regDest<0 ) regDest = ++pParse->nMem;
+      pItem->u.iConstExprReg = regDest;
+-     pItem->reusable = reusable;
+   }
+   pParse->pConstExpr = p;
++  return regDest;
  }
  
--/*
--** Set the value of a status to X.  The highwater mark is adjusted if
--** necessary.  The caller must hold the appropriate mutex.
--*/
--SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
--  wsdStatInit;
--  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
--  assert( op>=0 && op<ArraySize(statMutex) );
--  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
--                                           : sqlite3MallocMutex()) );
--  wsdStat.nowValue[op] = X;
--  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
--    wsdStat.mxValue[op] = wsdStat.nowValue[op];
--  }
-+/**
-+  * Set the passphrase for the cipher_ctx
-+  * 
-+  * returns SQLITE_OK if assignment was successfull
-+  * returns SQLITE_NOMEM if an error occured allocating memory
-+  */
-+static int sqlcipher_cipher_ctx_set_pass(cipher_ctx *ctx, const void *zKey, int nKey) {
-+
-+  /* free, zero existing pointers and size */
-+  sqlcipher_free(ctx->pass, ctx->pass_sz);
-+  ctx->pass = NULL;
-+  ctx->pass_sz = 0;
+ /*
+@@ -86030,19 +99012,8 @@
+    && pExpr->op!=TK_REGISTER
+    && sqlite3ExprIsConstantNotJoin(pExpr)
+   ){
+-    ExprList *p = pParse->pConstExpr;
+-    int i;
+     *pReg  = 0;
+-    if( p ){
+-      struct ExprList_item *pItem;
+-      for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
+-        if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){
+-          return pItem->u.iConstExprReg;
+-        }
+-      }
+-    }
+-    r2 = ++pParse->nMem;
+-    sqlite3ExprCodeAtInit(pParse, pExpr, r2, 1);
++    r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1);
+   }else{
+     int r1 = sqlite3GetTempReg(pParse);
+     r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
+@@ -86069,7 +99040,7 @@
+     sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target);
+   }else{
+     inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
+-    assert( pParse->pVdbe || pParse->db->mallocFailed );
++    assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
+     if( inReg!=target && pParse->pVdbe ){
+       sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
+     }
+@@ -86077,6 +99048,18 @@
+ }
+ 
+ /*
++** Make a transient copy of expression pExpr and then code it using
++** sqlite3ExprCode().  This routine works just like sqlite3ExprCode()
++** except that the input expression is guaranteed to be unchanged.
++*/
++SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
++  sqlite3 *db = pParse->db;
++  pExpr = sqlite3ExprDup(db, pExpr, 0);
++  if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target);
++  sqlite3ExprDelete(db, pExpr);
++}
 +
-+  if(zKey && nKey) { /* if new password is provided, copy it */
-+    ctx->pass_sz = nKey;
-+    ctx->pass = sqlcipher_malloc(nKey);
-+    if(ctx->pass == NULL) return SQLITE_NOMEM;
-+    memcpy(ctx->pass, zKey, nKey);
-+  } 
-+  return SQLITE_OK;
++/*
+ ** Generate code that will evaluate expression pExpr and store the
+ ** results in register target.  The results are guaranteed to appear
+ ** in register target.  If the expression is constant, then this routine
+@@ -86084,7 +99067,7 @@
+ */
+ SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
+   if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){
+-    sqlite3ExprCodeAtInit(pParse, pExpr, target, 0);
++    sqlite3ExprCodeAtInit(pParse, pExpr, target);
+   }else{
+     sqlite3ExprCode(pParse, pExpr, target);
+   }
+@@ -86114,268 +99097,6 @@
+   exprToRegister(pExpr, iMem);
  }
  
+-#ifdef SQLITE_DEBUG
 -/*
--** Query status information.
+-** Generate a human-readable explanation of an expression tree.
 -*/
--SQLITE_API int SQLITE_STDCALL sqlite3_status64(
--  int op,
--  sqlite3_int64 *pCurrent,
--  sqlite3_int64 *pHighwater,
--  int resetFlag
--){
--  sqlite3_mutex *pMutex;
--  wsdStatInit;
--  if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
--    return SQLITE_MISUSE_BKPT;
+-SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
+-  const char *zBinOp = 0;   /* Binary operator */
+-  const char *zUniOp = 0;   /* Unary operator */
+-  pView = sqlite3TreeViewPush(pView, moreToFollow);
+-  if( pExpr==0 ){
+-    sqlite3TreeViewLine(pView, "nil");
+-    sqlite3TreeViewPop(pView);
+-    return;
 -  }
--#ifdef SQLITE_ENABLE_API_ARMOR
--  if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
+-  switch( pExpr->op ){
+-    case TK_AGG_COLUMN: {
+-      sqlite3TreeViewLine(pView, "AGG{%d:%d}",
+-            pExpr->iTable, pExpr->iColumn);
+-      break;
+-    }
+-    case TK_COLUMN: {
+-      if( pExpr->iTable<0 ){
+-        /* This only happens when coding check constraints */
+-        sqlite3TreeViewLine(pView, "COLUMN(%d)", pExpr->iColumn);
+-      }else{
+-        sqlite3TreeViewLine(pView, "{%d:%d}",
+-                             pExpr->iTable, pExpr->iColumn);
+-      }
+-      break;
+-    }
+-    case TK_INTEGER: {
+-      if( pExpr->flags & EP_IntValue ){
+-        sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue);
+-      }else{
+-        sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken);
+-      }
+-      break;
+-    }
+-#ifndef SQLITE_OMIT_FLOATING_POINT
+-    case TK_FLOAT: {
+-      sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
+-      break;
+-    }
 -#endif
--  pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex();
--  sqlite3_mutex_enter(pMutex);
--  *pCurrent = wsdStat.nowValue[op];
--  *pHighwater = wsdStat.mxValue[op];
--  if( resetFlag ){
--    wsdStat.mxValue[op] = wsdStat.nowValue[op];
+-    case TK_STRING: {
+-      sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken);
+-      break;
+-    }
+-    case TK_NULL: {
+-      sqlite3TreeViewLine(pView,"NULL");
+-      break;
+-    }
+-#ifndef SQLITE_OMIT_BLOB_LITERAL
+-    case TK_BLOB: {
+-      sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
+-      break;
+-    }
+-#endif
+-    case TK_VARIABLE: {
+-      sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)",
+-                          pExpr->u.zToken, pExpr->iColumn);
+-      break;
+-    }
+-    case TK_REGISTER: {
+-      sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
+-      break;
+-    }
+-    case TK_AS: {
+-      sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken);
+-      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+-      break;
+-    }
+-    case TK_ID: {
+-      sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
+-      break;
+-    }
+-#ifndef SQLITE_OMIT_CAST
+-    case TK_CAST: {
+-      /* Expressions of the form:   CAST(pLeft AS token) */
+-      sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);
+-      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+-      break;
+-    }
+-#endif /* SQLITE_OMIT_CAST */
+-    case TK_LT:      zBinOp = "LT";     break;
+-    case TK_LE:      zBinOp = "LE";     break;
+-    case TK_GT:      zBinOp = "GT";     break;
+-    case TK_GE:      zBinOp = "GE";     break;
+-    case TK_NE:      zBinOp = "NE";     break;
+-    case TK_EQ:      zBinOp = "EQ";     break;
+-    case TK_IS:      zBinOp = "IS";     break;
+-    case TK_ISNOT:   zBinOp = "ISNOT";  break;
+-    case TK_AND:     zBinOp = "AND";    break;
+-    case TK_OR:      zBinOp = "OR";     break;
+-    case TK_PLUS:    zBinOp = "ADD";    break;
+-    case TK_STAR:    zBinOp = "MUL";    break;
+-    case TK_MINUS:   zBinOp = "SUB";    break;
+-    case TK_REM:     zBinOp = "REM";    break;
+-    case TK_BITAND:  zBinOp = "BITAND"; break;
+-    case TK_BITOR:   zBinOp = "BITOR";  break;
+-    case TK_SLASH:   zBinOp = "DIV";    break;
+-    case TK_LSHIFT:  zBinOp = "LSHIFT"; break;
+-    case TK_RSHIFT:  zBinOp = "RSHIFT"; break;
+-    case TK_CONCAT:  zBinOp = "CONCAT"; break;
+-    case TK_DOT:     zBinOp = "DOT";    break;
+-
+-    case TK_UMINUS:  zUniOp = "UMINUS"; break;
+-    case TK_UPLUS:   zUniOp = "UPLUS";  break;
+-    case TK_BITNOT:  zUniOp = "BITNOT"; break;
+-    case TK_NOT:     zUniOp = "NOT";    break;
+-    case TK_ISNULL:  zUniOp = "ISNULL"; break;
+-    case TK_NOTNULL: zUniOp = "NOTNULL"; break;
+-
+-    case TK_COLLATE: {
+-      sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
+-      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+-      break;
+-    }
+-
+-    case TK_AGG_FUNCTION:
+-    case TK_FUNCTION: {
+-      ExprList *pFarg;       /* List of function arguments */
+-      if( ExprHasProperty(pExpr, EP_TokenOnly) ){
+-        pFarg = 0;
+-      }else{
+-        pFarg = pExpr->x.pList;
+-      }
+-      if( pExpr->op==TK_AGG_FUNCTION ){
+-        sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
+-                             pExpr->op2, pExpr->u.zToken);
+-      }else{
+-        sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
+-      }
+-      if( pFarg ){
+-        sqlite3TreeViewExprList(pView, pFarg, 0, 0);
+-      }
+-      break;
+-    }
+-#ifndef SQLITE_OMIT_SUBQUERY
+-    case TK_EXISTS: {
+-      sqlite3TreeViewLine(pView, "EXISTS-expr");
+-      sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
+-      break;
+-    }
+-    case TK_SELECT: {
+-      sqlite3TreeViewLine(pView, "SELECT-expr");
+-      sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
+-      break;
+-    }
+-    case TK_IN: {
+-      sqlite3TreeViewLine(pView, "IN");
+-      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
+-      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+-        sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
+-      }else{
+-        sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
+-      }
+-      break;
+-    }
+-#endif /* SQLITE_OMIT_SUBQUERY */
+-
+-    /*
+-    **    x BETWEEN y AND z
+-    **
+-    ** This is equivalent to
+-    **
+-    **    x>=y AND x<=z
+-    **
+-    ** X is stored in pExpr->pLeft.
+-    ** Y is stored in pExpr->pList->a[0].pExpr.
+-    ** Z is stored in pExpr->pList->a[1].pExpr.
+-    */
+-    case TK_BETWEEN: {
+-      Expr *pX = pExpr->pLeft;
+-      Expr *pY = pExpr->x.pList->a[0].pExpr;
+-      Expr *pZ = pExpr->x.pList->a[1].pExpr;
+-      sqlite3TreeViewLine(pView, "BETWEEN");
+-      sqlite3TreeViewExpr(pView, pX, 1);
+-      sqlite3TreeViewExpr(pView, pY, 1);
+-      sqlite3TreeViewExpr(pView, pZ, 0);
+-      break;
+-    }
+-    case TK_TRIGGER: {
+-      /* If the opcode is TK_TRIGGER, then the expression is a reference
+-      ** to a column in the new.* or old.* pseudo-tables available to
+-      ** trigger programs. In this case Expr.iTable is set to 1 for the
+-      ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
+-      ** is set to the column of the pseudo-table to read, or to -1 to
+-      ** read the rowid field.
+-      */
+-      sqlite3TreeViewLine(pView, "%s(%d)", 
+-          pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
+-      break;
+-    }
+-    case TK_CASE: {
+-      sqlite3TreeViewLine(pView, "CASE");
+-      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
+-      sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
+-      break;
+-    }
+-#ifndef SQLITE_OMIT_TRIGGER
+-    case TK_RAISE: {
+-      const char *zType = "unk";
+-      switch( pExpr->affinity ){
+-        case OE_Rollback:   zType = "rollback";  break;
+-        case OE_Abort:      zType = "abort";     break;
+-        case OE_Fail:       zType = "fail";      break;
+-        case OE_Ignore:     zType = "ignore";    break;
+-      }
+-      sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
+-      break;
+-    }
+-#endif
+-    default: {
+-      sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
+-      break;
+-    }
 -  }
--  sqlite3_mutex_leave(pMutex);
--  (void)pMutex;  /* Prevent warning when SQLITE_THREADSAFE=0 */
-+int sqlcipher_codec_ctx_set_pass(codec_ctx *ctx, const void *zKey, int nKey, int for_ctx) {
-+  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
-+  int rc;
-+
-+  if((rc = sqlcipher_cipher_ctx_set_pass(c_ctx, zKey, nKey)) != SQLITE_OK) return rc; 
-+  c_ctx->derive_key = 1;
-+
-+  if(for_ctx == 2)
-+    if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK) 
-+      return rc; 
-+
-+  return SQLITE_OK;
-+} 
-+
-+int sqlcipher_codec_ctx_set_cipher(codec_ctx *ctx, const char *cipher_name, int for_ctx) {
-+  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
-+  int rc;
-+
-+  c_ctx->provider->set_cipher(c_ctx->provider_ctx, cipher_name);
-+
-+  c_ctx->key_sz = c_ctx->provider->get_key_sz(c_ctx->provider_ctx);
-+  c_ctx->iv_sz = c_ctx->provider->get_iv_sz(c_ctx->provider_ctx);
-+  c_ctx->block_sz = c_ctx->provider->get_block_sz(c_ctx->provider_ctx);
-+  c_ctx->hmac_sz = c_ctx->provider->get_hmac_sz(c_ctx->provider_ctx);
-+  c_ctx->derive_key = 1;
-+
-+  if(for_ctx == 2)
-+    if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK)
-+      return rc; 
-+
-   return SQLITE_OK;
- }
--SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
--  sqlite3_int64 iCur, iHwtr;
-+
-+const char* sqlcipher_codec_ctx_get_cipher(codec_ctx *ctx, int for_ctx) {
-+  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
-+  return c_ctx->provider->get_cipher(c_ctx->provider_ctx);
-+}
-+
-+/* set the global default KDF iteration */
-+void sqlcipher_set_default_kdf_iter(int iter) {
-+  default_kdf_iter = iter; 
-+}
-+
-+int sqlcipher_get_default_kdf_iter() {
-+  return default_kdf_iter;
-+}
-+
-+int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *ctx, int kdf_iter, int for_ctx) {
-+  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
-   int rc;
--#ifdef SQLITE_ENABLE_API_ARMOR
--  if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
+-  if( zBinOp ){
+-    sqlite3TreeViewLine(pView, "%s", zBinOp);
+-    sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
+-    sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
+-  }else if( zUniOp ){
+-    sqlite3TreeViewLine(pView, "%s", zUniOp);
+-    sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+-  }
+-  sqlite3TreeViewPop(pView);
+-}
+-#endif /* SQLITE_DEBUG */
+-
+-#ifdef SQLITE_DEBUG
+-/*
+-** Generate a human-readable explanation of an expression list.
+-*/
+-SQLITE_PRIVATE void sqlite3TreeViewExprList(
+-  TreeView *pView,
+-  const ExprList *pList,
+-  u8 moreToFollow,
+-  const char *zLabel
+-){
+-  int i;
+-  pView = sqlite3TreeViewPush(pView, moreToFollow);
+-  if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST";
+-  if( pList==0 ){
+-    sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
+-  }else{
+-    sqlite3TreeViewLine(pView, "%s", zLabel);
+-    for(i=0; i<pList->nExpr; i++){
+-      sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1);
+-#if 0
+-     if( pList->a[i].zName ){
+-        sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName);
+-      }
+-      if( pList->a[i].bSpanIsTab ){
+-        sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan);
+-      }
 -#endif
--  rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag);
--  if( rc==0 ){
--    *pCurrent = (int)iCur;
--    *pHighwater = (int)iHwtr;
-+
-+  c_ctx->kdf_iter = kdf_iter;
-+  c_ctx->derive_key = 1;
-+
-+  if(for_ctx == 2)
-+    if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK)
-+      return rc; 
-+
-+  return SQLITE_OK;
-+}
-+
-+int sqlcipher_codec_ctx_get_kdf_iter(codec_ctx *ctx, int for_ctx) {
-+  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
-+  return c_ctx->kdf_iter;
-+}
-+
-+int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *ctx, int fast_kdf_iter, int for_ctx) {
-+  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
-+  int rc;
-+
-+  c_ctx->fast_kdf_iter = fast_kdf_iter;
-+  c_ctx->derive_key = 1;
-+
-+  if(for_ctx == 2)
-+    if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK)
-+      return rc; 
-+
-+  return SQLITE_OK;
-+}
-+
-+int sqlcipher_codec_ctx_get_fast_kdf_iter(codec_ctx *ctx, int for_ctx) {
-+  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
-+  return c_ctx->fast_kdf_iter;
-+}
-+
-+/* set the global default flag for HMAC */
-+void sqlcipher_set_default_use_hmac(int use) {
-+  if(use) default_flags |= CIPHER_FLAG_HMAC; 
-+  else default_flags &= ~CIPHER_FLAG_HMAC; 
-+}
-+
-+int sqlcipher_get_default_use_hmac() {
-+  return (default_flags & CIPHER_FLAG_HMAC) != 0;
-+}
-+
-+void sqlcipher_set_hmac_salt_mask(unsigned char mask) {
-+  hmac_salt_mask = mask;
-+}
-+
-+unsigned char sqlcipher_get_hmac_salt_mask() {
-+  return hmac_salt_mask;
-+}
-+
-+/* set the codec flag for whether this individual database should be using hmac */
-+int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use) {
-+  int reserve = CIPHER_MAX_IV_SZ; /* base reserve size will be IV only */ 
-+
-+  if(use) reserve += ctx->read_ctx->hmac_sz; /* if reserve will include hmac, update that size */
-+
-+  /* calculate the amount of reserve needed in even increments of the cipher block size */
-+
-+  reserve = ((reserve % ctx->read_ctx->block_sz) == 0) ? reserve :
-+               ((reserve / ctx->read_ctx->block_sz) + 1) * ctx->read_ctx->block_sz;  
-+
-+  CODEC_TRACE(("sqlcipher_codec_ctx_set_use_hmac: use=%d block_sz=%d md_size=%d reserve=%d\n", 
-+                use, ctx->read_ctx->block_sz, ctx->read_ctx->hmac_sz, reserve)); 
+-    }
+-  }
+-  sqlite3TreeViewPop(pView);
+-}
+-#endif /* SQLITE_DEBUG */
+-
+ /*
+ ** Generate code that pushes the value of every element of the given
+ ** expression list into a sequence of registers beginning at target.
+@@ -86387,16 +99108,22 @@
+ **
+ ** The SQLITE_ECEL_FACTOR argument allows constant arguments to be
+ ** factored out into initialization code.
++**
++** The SQLITE_ECEL_REF flag means that expressions in the list with
++** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored
++** in registers at srcReg, and so the value can be copied from there.
+ */
+ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
+   Parse *pParse,     /* Parsing context */
+   ExprList *pList,   /* The expression list to be coded */
+   int target,        /* Where to write results */
++  int srcReg,        /* Source registers if SQLITE_ECEL_REF */
+   u8 flags           /* SQLITE_ECEL_* flags */
+ ){
+   struct ExprList_item *pItem;
+-  int i, n;
++  int i, j, n;
+   u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy;
++  Vdbe *v = pParse->pVdbe;
+   assert( pList!=0 );
+   assert( target>0 );
+   assert( pParse->pVdbe!=0 );  /* Never gets this far otherwise */
+@@ -86404,13 +99131,19 @@
+   if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR;
+   for(pItem=pList->a, i=0; i<n; i++, pItem++){
+     Expr *pExpr = pItem->pExpr;
+-    if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
+-      sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0);
++    if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){
++      if( flags & SQLITE_ECEL_OMITREF ){
++        i--;
++        n--;
++      }else{
++        sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
++      }
++    }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
++      sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
+     }else{
+       int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
+       if( inReg!=target+i ){
+         VdbeOp *pOp;
+-        Vdbe *v = pParse->pVdbe;
+         if( copyOp==OP_Copy
+          && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy
+          && pOp->p1+pOp->p3+1==inReg
+@@ -86437,20 +99170,33 @@
+ **
+ ** Code it as such, taking care to do the common subexpression
+ ** elimination of x.
++**
++** The xJumpIf parameter determines details:
++**
++**    NULL:                   Store the boolean result in reg[dest]
++**    sqlite3ExprIfTrue:      Jump to dest if true
++**    sqlite3ExprIfFalse:     Jump to dest if false
++**
++** The jumpIfNull parameter is ignored if xJumpIf is NULL.
+ */
+ static void exprCodeBetween(
+   Parse *pParse,    /* Parsing and code generating context */
+   Expr *pExpr,      /* The BETWEEN expression */
+-  int dest,         /* Jump here if the jump is taken */
+-  int jumpIfTrue,   /* Take the jump if the BETWEEN is true */
++  int dest,         /* Jump destination or storage location */
++  void (*xJump)(Parse*,Expr*,int,int), /* Action to take */
+   int jumpIfNull    /* Take the jump if the BETWEEN is NULL */
+ ){
+-  Expr exprAnd;     /* The AND operator in  x>=y AND x<=z  */
++ Expr exprAnd;     /* The AND operator in  x>=y AND x<=z  */
+   Expr compLeft;    /* The  x>=y  term */
+   Expr compRight;   /* The  x<=z  term */
+   Expr exprX;       /* The  x  subexpression */
+   int regFree1 = 0; /* Temporary use register */
+ 
++
++  memset(&compLeft, 0, sizeof(Expr));
++  memset(&compRight, 0, sizeof(Expr));
++  memset(&exprAnd, 0, sizeof(Expr));
++
+   assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+   exprX = *pExpr->pLeft;
+   exprAnd.op = TK_AND;
+@@ -86462,23 +99208,30 @@
+   compRight.op = TK_LE;
+   compRight.pLeft = &exprX;
+   compRight.pRight = pExpr->x.pList->a[1].pExpr;
+-  exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, &regFree1));
+-  if( jumpIfTrue ){
+-    sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
+-  }else{
+-    sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull);
++  exprToRegister(&exprX, exprCodeVector(pParse, &exprX, &regFree1));
++  if( xJump ){
++    xJump(pParse, &exprAnd, dest, jumpIfNull);
++  }else{
++    /* Mark the expression is being from the ON or USING clause of a join
++    ** so that the sqlite3ExprCodeTarget() routine will not attempt to move
++    ** it into the Parse.pConstExpr list.  We should use a new bit for this,
++    ** for clarity, but we are out of bits in the Expr.flags field so we
++    ** have to reuse the EP_FromJoin bit.  Bummer. */
++    exprX.flags |= EP_FromJoin;
++    sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
+   }
+   sqlite3ReleaseTempReg(pParse, regFree1);
+ 
+   /* Ensure adequate test coverage */
+-  testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1==0 );
+-  testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1!=0 );
+-  testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1==0 );
+-  testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1!=0 );
+-  testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1==0 );
+-  testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1!=0 );
+-  testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1==0 );
+-  testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1!=0 );
++  testcase( xJump==sqlite3ExprIfTrue  && jumpIfNull==0 && regFree1==0 );
++  testcase( xJump==sqlite3ExprIfTrue  && jumpIfNull==0 && regFree1!=0 );
++  testcase( xJump==sqlite3ExprIfTrue  && jumpIfNull!=0 && regFree1==0 );
++  testcase( xJump==sqlite3ExprIfTrue  && jumpIfNull!=0 && regFree1!=0 );
++  testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 );
++  testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1!=0 );
++  testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1==0 );
++  testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1!=0 );
++  testcase( xJump==0 );
+ }
+ 
+ /*
+@@ -86530,12 +99283,20 @@
+       sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+       break;
+     }
++    case TK_IS:
++    case TK_ISNOT:
++      testcase( op==TK_IS );
++      testcase( op==TK_ISNOT );
++      op = (op==TK_IS) ? TK_EQ : TK_NE;
++      jumpIfNull = SQLITE_NULLEQ;
++      /* Fall thru */
+     case TK_LT:
+     case TK_LE:
+     case TK_GT:
+     case TK_GE:
+     case TK_NE:
+     case TK_EQ: {
++      if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
+       testcase( jumpIfNull==0 );
+       r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
+       r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
+@@ -86545,23 +99306,12 @@
+       assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
+       assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
+       assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+-      assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+-      assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
+-      testcase( regFree1==0 );
+-      testcase( regFree2==0 );
+-      break;
+-    }
+-    case TK_IS:
+-    case TK_ISNOT: {
+-      testcase( op==TK_IS );
+-      testcase( op==TK_ISNOT );
+-      r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
+-      r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
+-      op = (op==TK_IS) ? TK_EQ : TK_NE;
+-      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+-                  r1, r2, dest, SQLITE_NULLEQ);
+-      VdbeCoverageIf(v, op==TK_EQ);
+-      VdbeCoverageIf(v, op==TK_NE);
++      assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
++      VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
++      VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
++      assert(TK_NE==OP_Ne); testcase(op==OP_Ne);
++      VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ);
++      VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ);
+       testcase( regFree1==0 );
+       testcase( regFree2==0 );
+       break;
+@@ -86579,7 +99329,7 @@
+     }
+     case TK_BETWEEN: {
+       testcase( jumpIfNull==0 );
+-      exprCodeBetween(pParse, pExpr, dest, 1, jumpIfNull);
++      exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull);
+       break;
+     }
+ #ifndef SQLITE_OMIT_SUBQUERY
+@@ -86587,14 +99337,15 @@
+       int destIfFalse = sqlite3VdbeMakeLabel(v);
+       int destIfNull = jumpIfNull ? dest : destIfFalse;
+       sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
+-      sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
++      sqlite3VdbeGoto(v, dest);
+       sqlite3VdbeResolveLabel(v, destIfFalse);
+       break;
+     }
+ #endif
+     default: {
++    default_expr:
+       if( exprAlwaysTrue(pExpr) ){
+-        sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
++        sqlite3VdbeGoto(v, dest);
+       }else if( exprAlwaysFalse(pExpr) ){
+         /* No-op */
+       }else{
+@@ -86686,12 +99437,20 @@
+       sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+       break;
+     }
++    case TK_IS:
++    case TK_ISNOT:
++      testcase( pExpr->op==TK_IS );
++      testcase( pExpr->op==TK_ISNOT );
++      op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
++      jumpIfNull = SQLITE_NULLEQ;
++      /* Fall thru */
+     case TK_LT:
+     case TK_LE:
+     case TK_GT:
+     case TK_GE:
+     case TK_NE:
+     case TK_EQ: {
++      if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
+       testcase( jumpIfNull==0 );
+       r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
+       r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
+@@ -86701,23 +99460,12 @@
+       assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
+       assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
+       assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+-      assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+-      assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
+-      testcase( regFree1==0 );
+-      testcase( regFree2==0 );
+-      break;
+-    }
+-    case TK_IS:
+-    case TK_ISNOT: {
+-      testcase( pExpr->op==TK_IS );
+-      testcase( pExpr->op==TK_ISNOT );
+-      r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
+-      r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
+-      op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
+-      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+-                  r1, r2, dest, SQLITE_NULLEQ);
+-      VdbeCoverageIf(v, op==TK_EQ);
+-      VdbeCoverageIf(v, op==TK_NE);
++      assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
++      VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
++      VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
++      assert(TK_NE==OP_Ne); testcase(op==OP_Ne);
++      VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ);
++      VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ);
+       testcase( regFree1==0 );
+       testcase( regFree2==0 );
+       break;
+@@ -86733,7 +99481,7 @@
+     }
+     case TK_BETWEEN: {
+       testcase( jumpIfNull==0 );
+-      exprCodeBetween(pParse, pExpr, dest, 0, jumpIfNull);
++      exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull);
+       break;
+     }
+ #ifndef SQLITE_OMIT_SUBQUERY
+@@ -86749,8 +99497,9 @@
+     }
+ #endif
+     default: {
++    default_expr: 
+       if( exprAlwaysFalse(pExpr) ){
+-        sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
++        sqlite3VdbeGoto(v, dest);
+       }else if( exprAlwaysTrue(pExpr) ){
+         /* no-op */
+       }else{
+@@ -86768,6 +99517,56 @@
+ }
+ 
+ /*
++** Like sqlite3ExprIfFalse() except that a copy is made of pExpr before
++** code generation, and that copy is deleted after code generation. This
++** ensures that the original pExpr is unchanged.
++*/
++SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){
++  sqlite3 *db = pParse->db;
++  Expr *pCopy = sqlite3ExprDup(db, pExpr, 0);
++  if( db->mallocFailed==0 ){
++    sqlite3ExprIfFalse(pParse, pCopy, dest, jumpIfNull);
++  }
++  sqlite3ExprDelete(db, pCopy);
++}
 +
++/*
++** Expression pVar is guaranteed to be an SQL variable. pExpr may be any
++** type of expression.
++**
++** If pExpr is a simple SQL value - an integer, real, string, blob
++** or NULL value - then the VDBE currently being prepared is configured
++** to re-prepare each time a new value is bound to variable pVar.
++**
++** Additionally, if pExpr is a simple SQL value and the value is the
++** same as that currently bound to variable pVar, non-zero is returned.
++** Otherwise, if the values are not the same or if pExpr is not a simple
++** SQL value, zero is returned.
++*/
++static int exprCompareVariable(Parse *pParse, Expr *pVar, Expr *pExpr){
++  int res = 0;
++  int iVar;
++  sqlite3_value *pL, *pR = 0;
 +  
-+  if(use) {
-+    sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_HMAC);
-+  } else {
-+    sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_HMAC);
-+  } 
-+  
-+  ctx->write_ctx->reserve_sz = ctx->read_ctx->reserve_sz = reserve;
++  sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR);
++  if( pR ){
++    iVar = pVar->iColumn;
++    sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
++    pL = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB);
++    if( pL ){
++      if( sqlite3_value_type(pL)==SQLITE_TEXT ){
++        sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */
++      }
++      res =  0==sqlite3MemCompare(pL, pR, 0);
++    }
++    sqlite3ValueFree(pR);
++    sqlite3ValueFree(pL);
++  }
 +
-+  return SQLITE_OK;
++  return res;
 +}
 +
-+int sqlcipher_codec_ctx_get_use_hmac(codec_ctx *ctx, int for_ctx) {
-+  cipher_ctx * c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
-+  return (c_ctx->flags & CIPHER_FLAG_HMAC) != 0;
++/*
+ ** Do a deep comparison of two expression trees.  Return 0 if the two
+ ** expressions are completely identical.  Return 1 if they differ only
+ ** by a COLLATE operator at the top level.  Return 2 if there are differences
+@@ -86788,12 +99587,22 @@
+ ** this routine is used, it does not hurt to get an extra 2 - that
+ ** just might result in some slightly slower code.  But returning
+ ** an incorrect 0 or 1 could lead to a malfunction.
++**
++** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in
++** pParse->pReprepare can be matched against literals in pB.  The 
++** pParse->pVdbe->expmask bitmask is updated for each variable referenced.
++** If pParse is NULL (the normal case) then any TK_VARIABLE term in 
++** Argument pParse should normally be NULL. If it is not NULL and pA or
++** pB causes a return value of 2.
+ */
+-SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
++SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
+   u32 combinedFlags;
+   if( pA==0 || pB==0 ){
+     return pB==pA ? 0 : 2;
+   }
++  if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){
++    return 0;
++  }
+   combinedFlags = pA->flags | pB->flags;
+   if( combinedFlags & EP_IntValue ){
+     if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
+@@ -86802,24 +99611,26 @@
+     return 2;
+   }
+   if( pA->op!=pB->op ){
+-    if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){
++    if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){
+       return 1;
+     }
+-    if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){
++    if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){
+       return 1;
+     }
+     return 2;
+   }
+-  if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken ){
+-    if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
++  if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
++    if( pA->op==TK_FUNCTION ){
++      if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
++    }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
+       return pA->op==TK_COLLATE ? 1 : 2;
+     }
+   }
+   if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
+   if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
+     if( combinedFlags & EP_xIsSelect ) return 2;
+-    if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
+-    if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
++    if( sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
++    if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
+     if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
+     if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
+       if( pA->iColumn!=pB->iColumn ) return 2;
+@@ -86854,12 +99665,23 @@
+     Expr *pExprA = pA->a[i].pExpr;
+     Expr *pExprB = pB->a[i].pExpr;
+     if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
+-    if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1;
++    if( sqlite3ExprCompare(0, pExprA, pExprB, iTab) ) return 1;
+   }
+   return 0;
+ }
+ 
+ /*
++** Like sqlite3ExprCompare() except COLLATE operators at the top-level
++** are ignored.
++*/
++SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
++  return sqlite3ExprCompare(0,
++             sqlite3ExprSkipCollate(pA),
++             sqlite3ExprSkipCollate(pB),
++             iTab);
 +}
 +
-+int sqlcipher_codec_ctx_set_flag(codec_ctx *ctx, unsigned int flag) {
-+  ctx->write_ctx->flags |= flag;
-+  ctx->read_ctx->flags |= flag;
-+  return SQLITE_OK;
-+}
++/*
+ ** Return true if we can prove the pE2 will always be true if pE1 is
+ ** true.  Return false if we cannot complete the proof or if pE2 might
+ ** be false.  Examples:
+@@ -86875,31 +99697,90 @@
+ ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
+ ** Expr.iTable<0 then assume a table number given by iTab.
+ **
++** If pParse is not NULL, then the values of bound variables in pE1 are 
++** compared against literal values in pE2 and pParse->pVdbe->expmask is
++** modified to record which bound variables are referenced.  If pParse 
++** is NULL, then false will be returned if pE1 contains any bound variables.
++**
+ ** When in doubt, return false.  Returning true might give a performance
+ ** improvement.  Returning false might cause a performance reduction, but
+ ** it will always give the correct answer and is hence always safe.
+ */
+-SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
+-  if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){
++SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){
++  if( sqlite3ExprCompare(pParse, pE1, pE2, iTab)==0 ){
+     return 1;
+   }
+   if( pE2->op==TK_OR
+-   && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
+-             || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
++   && (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab)
++             || sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) )
+   ){
+     return 1;
+   }
+-  if( pE2->op==TK_NOTNULL
+-   && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0
+-   && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS)
+-  ){
+-    return 1;
++  if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
++    Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
++    testcase( pX!=pE1->pLeft );
++    if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1;
+   }
+   return 0;
+ }
+ 
+ /*
+ ** An instance of the following structure is used by the tree walker
++** to determine if an expression can be evaluated by reference to the
++** index only, without having to do a search for the corresponding
++** table entry.  The IdxCover.pIdx field is the index.  IdxCover.iCur
++** is the cursor for the table.
++*/
++struct IdxCover {
++  Index *pIdx;     /* The index to be tested for coverage */
++  int iCur;        /* Cursor number for the table corresponding to the index */
++};
 +
-+int sqlcipher_codec_ctx_unset_flag(codec_ctx *ctx, unsigned int flag) {
-+  ctx->write_ctx->flags &= ~flag;
-+  ctx->read_ctx->flags &= ~flag;
-+  return SQLITE_OK;
++/*
++** Check to see if there are references to columns in table 
++** pWalker->u.pIdxCover->iCur can be satisfied using the index
++** pWalker->u.pIdxCover->pIdx.
++*/
++static int exprIdxCover(Walker *pWalker, Expr *pExpr){
++  if( pExpr->op==TK_COLUMN
++   && pExpr->iTable==pWalker->u.pIdxCover->iCur
++   && sqlite3ColumnOfIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
++  ){
++    pWalker->eCode = 1;
++    return WRC_Abort;
++  }
++  return WRC_Continue;
 +}
 +
-+int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag, int for_ctx) {
-+  cipher_ctx * c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
-+  return (c_ctx->flags & flag) != 0;
++/*
++** Determine if an index pIdx on table with cursor iCur contains will
++** the expression pExpr.  Return true if the index does cover the
++** expression and false if the pExpr expression references table columns
++** that are not found in the index pIdx.
++**
++** An index covering an expression means that the expression can be
++** evaluated using only the index and without having to lookup the
++** corresponding table entry.
++*/
++SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(
++  Expr *pExpr,        /* The index to be tested */
++  int iCur,           /* The cursor number for the corresponding table */
++  Index *pIdx         /* The index that might be used for coverage */
++){
++  Walker w;
++  struct IdxCover xcov;
++  memset(&w, 0, sizeof(w));
++  xcov.iCur = iCur;
++  xcov.pIdx = pIdx;
++  w.xExprCallback = exprIdxCover;
++  w.u.pIdxCover = &xcov;
++  sqlite3WalkExpr(&w, pExpr);
++  return !w.eCode;
 +}
 +
-+void sqlcipher_codec_ctx_set_error(codec_ctx *ctx, int error) {
-+  CODEC_TRACE(("sqlcipher_codec_ctx_set_error: ctx=%p, error=%d\n", ctx, error));
-+  sqlite3pager_sqlite3PagerSetError(ctx->pBt->pBt->pPager, error);
-+  ctx->pBt->pBt->db->errCode = error;
-+}
 +
-+int sqlcipher_codec_ctx_get_reservesize(codec_ctx *ctx) {
-+  return ctx->read_ctx->reserve_sz;
++/*
++** 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.
+@@ -86946,8 +99827,8 @@
+   Walker w;
+   struct SrcCount cnt;
+   assert( pExpr->op==TK_AGG_FUNCTION );
+-  memset(&w, 0, sizeof(w));
+   w.xExprCallback = exprSrcCount;
++  w.xSelectCallback = 0;
+   w.u.pSrcCount = &cnt;
+   cnt.pSrc = pSrcList;
+   cnt.nThis = 0;
+@@ -87079,7 +99960,7 @@
+         */
+         struct AggInfo_func *pItem = pAggInfo->aFunc;
+         for(i=0; i<pAggInfo->nFunc; i++, pItem++){
+-          if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){
++          if( sqlite3ExprCompare(0, pItem->pExpr, pExpr, -1)==0 ){
+             break;
+           }
+         }
+@@ -87095,7 +99976,7 @@
+             pItem->iMem = ++pParse->nMem;
+             assert( !ExprHasProperty(pExpr, EP_IntValue) );
+             pItem->pFunc = sqlite3FindFunction(pParse->db,
+-                   pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken),
++                   pExpr->u.zToken, 
+                    pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
+             if( pExpr->flags & EP_Distinct ){
+               pItem->iDistinct = pParse->nTab++;
+@@ -87119,10 +100000,14 @@
+   return WRC_Continue;
+ }
+ static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
+-  UNUSED_PARAMETER(pWalker);
+   UNUSED_PARAMETER(pSelect);
++  pWalker->walkerDepth++;
+   return WRC_Continue;
+ }
++static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){
++  UNUSED_PARAMETER(pSelect);
++  pWalker->walkerDepth--;
 +}
-+
-+void* sqlcipher_codec_ctx_get_data(codec_ctx *ctx) {
-+  return ctx->buffer;
+ 
+ /*
+ ** Analyze the pExpr expression looking for aggregate functions and
+@@ -87135,9 +100020,10 @@
+ */
+ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
+   Walker w;
+-  memset(&w, 0, sizeof(w));
+   w.xExprCallback = analyzeAggregate;
+   w.xSelectCallback = analyzeAggregatesInSelect;
++  w.xSelectCallback2 = analyzeAggregatesInSelectEnd;
++  w.walkerDepth = 0;
+   w.u.pNC = pNC;
+   assert( pNC->pSrcList!=0 );
+   sqlite3WalkExpr(&w, pExpr);
+@@ -87181,7 +100067,7 @@
+   if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
+     int i;
+     struct yColCache *p;
+-    for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
++    for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+       if( p->iReg==iReg ){
+         p->tempReg = 1;
+         return;
+@@ -87192,10 +100078,11 @@
+ }
+ 
+ /*
+-** Allocate or deallocate a block of nReg consecutive registers
++** Allocate or deallocate a block of nReg consecutive registers.
+ */
+ SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){
+   int i, n;
++  if( nReg==1 ) return sqlite3GetTempReg(pParse);
+   i = pParse->iRangeReg;
+   n = pParse->nRangeReg;
+   if( nReg<=n ){
+@@ -87209,6 +100096,10 @@
+   return i;
+ }
+ SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
++  if( nReg==1 ){
++    sqlite3ReleaseTempReg(pParse, iReg);
++    return;
++  }
+   sqlite3ExprCacheRemove(pParse, iReg, nReg);
+   if( nReg>pParse->nRangeReg ){
+     pParse->nRangeReg = nReg;
+@@ -87224,6 +100115,29 @@
+   pParse->nRangeReg = 0;
+ }
+ 
++/*
++** Validate that no temporary register falls within the range of
++** iFirst..iLast, inclusive.  This routine is only call from within assert()
++** statements.
++*/
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
++  int i;
++  if( pParse->nRangeReg>0
++   && pParse->iRangeReg+pParse->nRangeReg > iFirst
++   && pParse->iRangeReg <= iLast
++  ){
++     return 0;
++  }
++  for(i=0; i<pParse->nTempReg; i++){
++    if( pParse->aTempReg[i]>=iFirst && pParse->aTempReg[i]<=iLast ){
++      return 0;
++    }
++  }
++  return 1;
 +}
++#endif /* SQLITE_DEBUG */
++
+ /************** End of expr.c ************************************************/
+ /************** Begin file alter.c *******************************************/
+ /*
+@@ -87240,6 +100154,7 @@
+ ** This file contains C code routines that used to generate VDBE code
+ ** that implements the ALTER TABLE command.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** The code in this file only exists if we are not omitting the
+@@ -87456,7 +100371,7 @@
+ ** Register built-in functions used to help implement ALTER TABLE
+ */
+ SQLITE_PRIVATE void sqlite3AlterFunctions(void){
+-  static SQLITE_WSD FuncDef aAlterTableFuncs[] = {
++  static FuncDef aAlterTableFuncs[] = {
+     FUNCTION(sqlite_rename_table,   2, 0, 0, renameTableFunc),
+ #ifndef SQLITE_OMIT_TRIGGER
+     FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
+@@ -87465,13 +100380,7 @@
+     FUNCTION(sqlite_rename_parent,  3, 0, 0, renameParentFunc),
+ #endif
+   };
+-  int i;
+-  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
+-  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAlterTableFuncs);
+-
+-  for(i=0; i<ArraySize(aAlterTableFuncs); i++){
+-    sqlite3FuncDefInsert(pHash, &aFunc[i]);
+-  }
++  sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
+ }
+ 
+ /*
+@@ -87608,7 +100517,7 @@
+ ** Or, if zName is not a system table, zero is returned.
+ */
+ static int isSystemTable(Parse *pParse, const char *zName){
+-  if( sqlite3Strlen30(zName)>6 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
++  if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
+     sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
+     return 1;
+   }
+@@ -87646,7 +100555,7 @@
+   pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
+   if( !pTab ) goto exit_rename_table;
+   iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+-  zDb = db->aDb[iDb].zName;
++  zDb = db->aDb[iDb].zDbSName;
+   db->flags |= SQLITE_PreferBuiltin;
+ 
+   /* Get a NULL terminated version of the new table name. */
+@@ -87718,7 +100627,7 @@
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+   if( pVTab ){
+     int i = ++pParse->nMem;
+-    sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0);
++    sqlite3VdbeLoadString(v, i, zName);
+     sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
+     sqlite3MayAbort(pParse);
+   }
+@@ -87737,7 +100646,7 @@
+       sqlite3NestedParse(pParse, 
+           "UPDATE \"%w\".%s SET "
+               "sql = sqlite_rename_parent(sql, %Q, %Q) "
+-              "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere);
++              "WHERE %s;", zDb, MASTER_NAME, zTabName, zName, zWhere);
+       sqlite3DbFree(db, zWhere);
+     }
+   }
+@@ -87761,7 +100670,7 @@
+             "ELSE name END "
+       "WHERE tbl_name=%Q COLLATE nocase AND "
+           "(type='table' OR type='index' OR type='trigger');", 
+-      zDb, SCHEMA_TABLE(iDb), zName, zName, zName, 
++      zDb, MASTER_NAME, zName, zName, zName, 
+ #ifndef SQLITE_OMIT_TRIGGER
+       zName,
+ #endif
+@@ -87815,33 +100724,6 @@
+   db->flags = savedDbFlags;
+ }
+ 
+-
+-/*
+-** Generate code to make sure the file format number is at least minFormat.
+-** The generated code will increase the file format number if necessary.
+-*/
+-SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
+-  Vdbe *v;
+-  v = sqlite3GetVdbe(pParse);
+-  /* The VDBE should have been allocated before this routine is called.
+-  ** If that allocation failed, we would have quit before reaching this
+-  ** point */
+-  if( ALWAYS(v) ){
+-    int r1 = sqlite3GetTempReg(pParse);
+-    int r2 = sqlite3GetTempReg(pParse);
+-    int j1;
+-    sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
+-    sqlite3VdbeUsesBtree(v, iDb);
+-    sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
+-    j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
+-    sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v);
+-    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
+-    sqlite3VdbeJumpHere(v, j1);
+-    sqlite3ReleaseTempReg(pParse, r1);
+-    sqlite3ReleaseTempReg(pParse, r2);
+-  }
+-}
+-
+ /*
+ ** This function is called after an "ALTER TABLE ... ADD" statement
+ ** has been parsed. Argument pColDef contains the text of the new
+@@ -87860,15 +100742,18 @@
+   Column *pCol;             /* The new column */
+   Expr *pDflt;              /* Default value for the new column */
+   sqlite3 *db;              /* The database connection; */
++  Vdbe *v = pParse->pVdbe;  /* The prepared statement under construction */
++  int r1;                   /* Temporary registers */
+ 
+   db = pParse->db;
+   if( pParse->nErr || db->mallocFailed ) return;
++  assert( v!=0 );
+   pNew = pParse->pNewTable;
+   assert( pNew );
+ 
+   assert( sqlite3BtreeHoldsAllMutexes(db) );
+   iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
+-  zDb = db->aDb[iDb].zName;
++  zDb = db->aDb[iDb].zDbSName;
+   zTab = &pNew->zName[16];  /* Skip the "sqlite_altertab_" prefix on the name */
+   pCol = &pNew->aCol[pNew->nCol-1];
+   pDflt = pCol->pDflt;
+@@ -87886,7 +100771,8 @@
+   ** literal NULL, then set pDflt to 0. This simplifies checking
+   ** for an SQL NULL default below.
+   */
+-  if( pDflt && pDflt->op==TK_NULL ){
++  assert( pDflt==0 || pDflt->op==TK_SPAN );
++  if( pDflt && pDflt->pLeft->op==TK_NULL ){
+     pDflt = 0;
+   }
+ 
+@@ -87919,10 +100805,10 @@
+   if( pDflt ){
+     sqlite3_value *pVal = 0;
+     int rc;
+-    rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal);
++    rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal);
+     assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+     if( rc!=SQLITE_OK ){
+-      db->mallocFailed = 1;
++      assert( db->mallocFailed == 1 );
+       return;
+     }
+     if( !pVal ){
+@@ -87945,18 +100831,25 @@
+         "UPDATE \"%w\".%s SET "
+           "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
+         "WHERE type = 'table' AND name = %Q", 
+-      zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
++      zDb, MASTER_NAME, pNew->addColOffset, zCol, pNew->addColOffset+1,
+       zTab
+     );
+     sqlite3DbFree(db, zCol);
+     db->flags = savedDbFlags;
+   }
+ 
+-  /* If the default value of the new column is NULL, then set the file
+-  ** format to 2. If the default value of the new column is not NULL,
+-  ** the file format becomes 3.
++  /* Make sure the schema version is at least 3.  But do not upgrade
++  ** from less than 3 to 4, as that will corrupt any preexisting DESC
++  ** index.
+   */
+-  sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);
++  r1 = sqlite3GetTempReg(pParse);
++  sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
++  sqlite3VdbeUsesBtree(v, iDb);
++  sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2);
++  sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
++  sqlite3ReleaseTempReg(pParse, r1);
+ 
+   /* Reload the schema of the modified table. */
+   reloadTableSchema(pParse, pTab, pTab->zName);
+@@ -88022,7 +100915,7 @@
+   pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table));
+   if( !pNew ) goto exit_begin_add_column;
+   pParse->pNewTable = pNew;
+-  pNew->nRef = 1;
++  pNew->nTabRef = 1;
+   pNew->nCol = pTab->nCol;
+   assert( pNew->nCol>0 );
+   nAlloc = (((pNew->nCol-1)/8)*8)+8;
+@@ -88030,7 +100923,7 @@
+   pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc);
+   pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName);
+   if( !pNew->aCol || !pNew->zName ){
+-    db->mallocFailed = 1;
++    assert( db->mallocFailed );
+     goto exit_begin_add_column;
+   }
+   memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
+@@ -88038,13 +100931,11 @@
+     Column *pCol = &pNew->aCol[i];
+     pCol->zName = sqlite3DbStrDup(db, pCol->zName);
+     pCol->zColl = 0;
+-    pCol->zType = 0;
+     pCol->pDflt = 0;
+-    pCol->zDflt = 0;
+   }
+   pNew->pSchema = db->aDb[iDb].pSchema;
+   pNew->addColOffset = pTab->addColOffset;
+-  pNew->nRef = 1;
++  pNew->nTabRef = 1;
+ 
+   /* Begin a transaction and increment the schema cookie.  */
+   sqlite3BeginWriteOperation(pParse, 0, iDb);
+@@ -88202,6 +101093,7 @@
+ ** integer in the equivalent columns in sqlite_stat4.
+ */
+ #ifndef SQLITE_OMIT_ANALYZE
++/* #include "sqliteInt.h" */
+ 
+ #if defined(SQLITE_ENABLE_STAT4)
+ # define IsStat4     1
+@@ -88271,14 +101163,14 @@
+   for(i=0; i<ArraySize(aTable); i++){
+     const char *zTab = aTable[i].zName;
+     Table *pStat;
+-    if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
++    if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
+       if( aTable[i].zCols ){
+         /* The sqlite_statN table does not exist. Create it. Note that a 
+         ** side-effect of the CREATE TABLE statement is to leave the rootpage 
+         ** of the new table in register pParse->regRoot. This is important 
+         ** because the OpenWrite opcode below will be needing it. */
+         sqlite3NestedParse(pParse,
+-            "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
++            "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols
+         );
+         aRoot[i] = pParse->regRoot;
+         aCreateTbl[i] = OPFLAG_P2ISREG;
+@@ -88293,7 +101185,7 @@
+       if( zWhere ){
+         sqlite3NestedParse(pParse,
+            "DELETE FROM %Q.%s WHERE %s=%Q",
+-           pDb->zName, zTab, zWhereType, zWhere
++           pDb->zDbSName, zTab, zWhereType, zWhere
+         );
+       }else{
+         /* The sqlite_stat[134] table already exists.  Delete all rows. */
+@@ -88351,6 +101243,7 @@
+   Stat4Sample *aBest;       /* Array of nCol best samples */
+   int iMin;                 /* Index in a[] of entry with minimum score */
+   int nSample;              /* Current number of samples */
++  int nMaxEqZero;           /* Max leading 0 in anEq[] for any a[] entry */
+   int iGet;                 /* Index of current sample accessed by stat_get() */
+   Stat4Sample *a;           /* Array of mxSample Stat4Sample objects */
+   sqlite3 *db;              /* Database connection, for malloc() */
+@@ -88374,7 +101267,7 @@
+ static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
+   assert( db!=0 );
+   if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
+-  p->u.aRowid = sqlite3DbMallocRaw(db, n);
++  p->u.aRowid = sqlite3DbMallocRawNN(db, n);
+   if( p->u.aRowid ){
+     p->nRowid = n;
+     memcpy(p->u.aRowid, pData, n);
+@@ -88539,12 +101432,10 @@
+   SQLITE_UTF8,     /* funcFlags */
+   0,               /* pUserData */
+   0,               /* pNext */
+-  statInit,        /* xFunc */
+-  0,               /* xStep */
++  statInit,        /* xSFunc */
+   0,               /* xFinalize */
+   "stat_init",     /* zName */
+-  0,               /* pHash */
+-  0                /* pDestructor */
++  {0}
+ };
+ 
+ #ifdef SQLITE_ENABLE_STAT4
+@@ -88617,6 +101508,13 @@
+   assert( IsStat4 || nEqZero==0 );
+ 
+ #ifdef SQLITE_ENABLE_STAT4
++  /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
++  ** values in the anEq[] array of any sample in Stat4Accum.a[]. In
++  ** other words, if nMaxEqZero is n, then it is guaranteed that there
++  ** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
++  if( nEqZero>p->nMaxEqZero ){
++    p->nMaxEqZero = nEqZero;
++  }
+   if( pNew->isPSample==0 ){
+     Stat4Sample *pUpgrade = 0;
+     assert( pNew->anEq[pNew->iCol]>0 );
+@@ -88714,12 +101612,22 @@
+     }
+   }
+ 
+-  /* Update the anEq[] fields of any samples already collected. */
++  /* Check that no sample contains an anEq[] entry with an index of
++  ** p->nMaxEqZero or greater set to zero. */
+   for(i=p->nSample-1; i>=0; i--){
+     int j;
+-    for(j=iChng; j<p->nCol; j++){
+-      if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
++    for(j=p->nMaxEqZero; j<p->nCol; j++) assert( p->a[i].anEq[j]>0 );
++  }
++
++  /* Update the anEq[] fields of any samples already collected. */
++  if( iChng<p->nMaxEqZero ){
++    for(i=p->nSample-1; i>=0; i--){
++      int j;
++      for(j=iChng; j<p->nCol; j++){
++        if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
++      }
+     }
++    p->nMaxEqZero = iChng;
+   }
+ #endif
+ 
+@@ -88840,12 +101748,10 @@
+   SQLITE_UTF8,     /* funcFlags */
+   0,               /* pUserData */
+   0,               /* pNext */
+-  statPush,        /* xFunc */
+-  0,               /* xStep */
++  statPush,        /* xSFunc */
+   0,               /* xFinalize */
+   "stat_push",     /* zName */
+-  0,               /* pHash */
+-  0                /* pDestructor */
++  {0}
+ };
+ 
+ #define STAT_GET_STAT1 0          /* "stat" column of stat1 table */
+@@ -88862,6 +101768,12 @@
+ ** The content to returned is determined by the parameter J
+ ** which is one of the STAT_GET_xxxx values defined above.
+ **
++** The stat_get(P,J) function is not available to generic SQL.  It is
++** inserted as part of a manually constructed bytecode program.  (See
++** the callStatGet() routine below.)  It is guaranteed that the P
++** parameter will always be a poiner to a Stat4Accum object, never a
++** NULL.
++**
+ ** If neither STAT3 nor STAT4 are enabled, then J is always
+ ** STAT_GET_STAT1 and is hence omitted and this routine becomes
+ ** a one-parameter function, stat_get(P), that always returns the
+@@ -88987,12 +101899,10 @@
+   SQLITE_UTF8,     /* funcFlags */
+   0,               /* pUserData */
+   0,               /* pNext */
+-  statGet,         /* xFunc */
+-  0,               /* xStep */
++  statGet,         /* xSFunc */
+   0,               /* xFinalize */
+   "stat_get",      /* zName */
+-  0,               /* pHash */
+-  0                /* pDestructor */
++  {0}
+ };
+ 
+ static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
+@@ -89004,8 +101914,8 @@
+ #else
+   UNUSED_PARAMETER( iParam );
+ #endif
+-  sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regOut);
+-  sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF);
++  sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4, regOut,
++                    (char*)&statGetFuncdef, P4_FUNCDEF);
+   sqlite3VdbeChangeP5(v, 1 + IsStat34);
+ }
+ 
+@@ -89051,7 +101961,7 @@
+     /* Do not gather statistics on views or virtual tables */
+     return;
+   }
+-  if( sqlite3_strnicmp(pTab->zName, "sqlite_", 7)==0 ){
++  if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){
+     /* Do not gather statistics on system tables */
+     return;
+   }
+@@ -89061,7 +101971,7 @@
+   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+   if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
+-      db->aDb[iDb].zName ) ){
++      db->aDb[iDb].zDbSName ) ){
+     return;
+   }
+ #endif
+@@ -89075,7 +101985,7 @@
+   iIdxCur = iTab++;
+   pParse->nTab = MAX(pParse->nTab, iTab);
+   sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
+-  sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
++  sqlite3VdbeLoadString(v, regTabname, pTab->zName);
+ 
+   for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+     int nCol;                     /* Number of columns in pIdx. "N" */
+@@ -89097,7 +102007,7 @@
+     }
+ 
+     /* Populate the register containing the index name. */
+-    sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0);
++    sqlite3VdbeLoadString(v, regIdxname, zIdxName);
+     VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName));
+ 
+     /*
+@@ -89159,8 +102069,8 @@
+ #endif
+     sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
+     sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
+-    sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4);
+-    sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF);
++    sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4+1, regStat4,
++                     (char*)&statInitFuncdef, P4_FUNCDEF);
+     sqlite3VdbeChangeP5(v, 2+IsStat34);
+ 
+     /* Implementation of the following:
+@@ -89179,7 +102089,7 @@
+     if( nColTest>0 ){
+       int endDistinctTest = sqlite3VdbeMakeLabel(v);
+       int *aGotoChng;               /* Array of jump instruction addresses */
+-      aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest);
++      aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest);
+       if( aGotoChng==0 ) continue;
+ 
+       /*
+@@ -89211,7 +102121,7 @@
+         VdbeCoverage(v);
+       }
+       sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng);
+-      sqlite3VdbeAddOp2(v, OP_Goto, 0, endDistinctTest);
++      sqlite3VdbeGoto(v, endDistinctTest);
+   
+   
+       /*
+@@ -89247,6 +102157,7 @@
+       regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
+       for(j=0; j<pPk->nKeyCol; j++){
+         k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
++        assert( k>=0 && k<pIdx->nColumn );
+         sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
+         VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
+       }
+@@ -89255,8 +102166,8 @@
+     }
+ #endif
+     assert( regChng==(regStat4+1) );
+-    sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp);
+-    sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF);
++    sqlite3VdbeAddOp4(v, OP_Function0, 1, regStat4, regTemp,
++                     (char*)&statPushFuncdef, P4_FUNCDEF);
+     sqlite3VdbeChangeP5(v, 2+IsStat34);
+     sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
+ 
+@@ -89296,12 +102207,10 @@
+       ** be taken */
+       VdbeCoverageNeverTaken(v);
+ #ifdef SQLITE_ENABLE_STAT3
+-      sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, 
+-                                      pIdx->aiColumn[0], regSample);
++      sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample);
+ #else
+       for(i=0; i<nCol; i++){
+-        i16 iCol = pIdx->aiColumn[i];
+-        sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
++        sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
+       }
+       sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample);
+ #endif
+@@ -89432,27 +102341,14 @@
+       if( i==1 ) continue;  /* Do not analyze the TEMP database */
+       analyzeDatabase(pParse, i);
+     }
+-  }else if( pName2->n==0 ){
+-    /* Form 2:  Analyze the database or table named */
+-    iDb = sqlite3FindDb(db, pName1);
+-    if( iDb>=0 ){
+-      analyzeDatabase(pParse, iDb);
+-    }else{
+-      z = sqlite3NameFromToken(db, pName1);
+-      if( z ){
+-        if( (pIdx = sqlite3FindIndex(db, z, 0))!=0 ){
+-          analyzeTable(pParse, pIdx->pTable, pIdx);
+-        }else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){
+-          analyzeTable(pParse, pTab, 0);
+-        }
+-        sqlite3DbFree(db, z);
+-      }
+-    }
++  }else if( pName2->n==0 && (iDb = sqlite3FindDb(db, pName1))>=0 ){
++    /* Analyze the schema named as the argument */
++    analyzeDatabase(pParse, iDb);
+   }else{
+-    /* Form 3: Analyze the fully qualified table name */
++    /* Form 3: Analyze the table or index named as an argument */
+     iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
+     if( iDb>=0 ){
+-      zDb = db->aDb[iDb].zName;
++      zDb = pName2->n ? db->aDb[iDb].zDbSName : 0;
+       z = sqlite3NameFromToken(db, pTableName);
+       if( z ){
+         if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){
+@@ -89462,10 +102358,11 @@
+         }
+         sqlite3DbFree(db, z);
+       }
+-    }   
++    }
++  }
++  if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){
++    sqlite3VdbeAddOp0(v, OP_Expire);
+   }
+-  v = sqlite3GetVdbe(pParse);
+-  if( v ) sqlite3VdbeAddOp0(v, OP_Expire);
+ }
+ 
+ /*
+@@ -89588,13 +102485,17 @@
+     ** the old data with the new instead of allocating a new array.  */
+     if( pIndex->aiRowEst==0 ){
+       pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
+-      if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1;
++      if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db);
+     }
+     aiRowEst = pIndex->aiRowEst;
+ #endif
+     pIndex->bUnordered = 0;
+     decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
+-    if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
++    pIndex->hasStat1 = 1;
++    if( pIndex->pPartIdxWhere==0 ){
++      pTable->nRowLogEst = pIndex->aiRowLogEst[0];
++      pTable->tabFlags |= TF_HasStat1;
++    }
+   }else{
+     Index fakeIdx;
+     fakeIdx.szIdxRow = pTable->szTabRow;
+@@ -89603,6 +102504,7 @@
+ #endif
+     decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx);
+     pTable->szTabRow = fakeIdx.szIdxRow;
++    pTable->tabFlags |= TF_HasStat1;
+   }
+ 
+   return 0;
+@@ -89683,7 +102585,7 @@
+         }
+       }
+ 
+-      if( nDist100>nSum100 ){
++      if( nDist100>nSum100 && sumEq<nRow ){
+         avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100);
+       }
+       if( avgEq==0 ) avgEq = 1;
+@@ -89735,10 +102637,10 @@
+   Index *pPrevIdx = 0;          /* Previous index in the loop */
+   IndexSample *pSample;         /* A slot in pIdx->aSample[] */
+ 
+-  assert( db->lookaside.bEnabled==0 );
++  assert( db->lookaside.bDisable );
+   zSql = sqlite3MPrintf(db, zSql1, zDb);
+   if( !zSql ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
+   sqlite3DbFree(db, zSql);
+@@ -89778,7 +102680,7 @@
+     pIdx->aSample = sqlite3DbMallocZero(db, nByte);
+     if( pIdx->aSample==0 ){
+       sqlite3_finalize(pStmt);
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     pSpace = (tRowcnt*)&pIdx->aSample[nSample];
+     pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
+@@ -89794,7 +102696,7 @@
+ 
+   zSql = sqlite3MPrintf(db, zSql2, zDb);
+   if( !zSql ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
+   sqlite3DbFree(db, zSql);
+@@ -89832,9 +102734,11 @@
+     pSample->p = sqlite3DbMallocZero(db, pSample->n + 2);
+     if( pSample->p==0 ){
+       sqlite3_finalize(pStmt);
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
++    }
++    if( pSample->n ){
++      memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
+     }
+-    memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
+     pIdx->nSample++;
+   }
+   rc = sqlite3_finalize(pStmt);
+@@ -89849,7 +102753,7 @@
+ static int loadStat4(sqlite3 *db, const char *zDb){
+   int rc = SQLITE_OK;             /* Result codes from subroutines */
+ 
+-  assert( db->lookaside.bEnabled==0 );
++  assert( db->lookaside.bDisable );
+   if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){
+     rc = loadStatTbl(db, 0,
+       "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", 
+@@ -89894,49 +102798,56 @@
+   analysisInfo sInfo;
+   HashElem *i;
+   char *zSql;
+-  int rc;
++  int rc = SQLITE_OK;
++  Schema *pSchema = db->aDb[iDb].pSchema;
+ 
+   assert( iDb>=0 && iDb<db->nDb );
+   assert( db->aDb[iDb].pBt!=0 );
+ 
+   /* Clear any prior statistics */
+   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+-  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
++  for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){
++    Table *pTab = sqliteHashData(i);
++    pTab->tabFlags &= ~TF_HasStat1;
++  }
++  for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
+     Index *pIdx = sqliteHashData(i);
+-    sqlite3DefaultRowEst(pIdx);
++    pIdx->hasStat1 = 0;
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+     sqlite3DeleteIndexSamples(db, pIdx);
+     pIdx->aSample = 0;
+ #endif
+   }
+ 
+-  /* Check to make sure the sqlite_stat1 table exists */
++  /* Load new statistics out of the sqlite_stat1 table */
+   sInfo.db = db;
+-  sInfo.zDatabase = db->aDb[iDb].zName;
+-  if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
+-    return SQLITE_ERROR;
++  sInfo.zDatabase = db->aDb[iDb].zDbSName;
++  if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){
++    zSql = sqlite3MPrintf(db, 
++        "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
++    if( zSql==0 ){
++      rc = SQLITE_NOMEM_BKPT;
++    }else{
++      rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
++      sqlite3DbFree(db, zSql);
++    }
+   }
+ 
+-  /* Load new statistics out of the sqlite_stat1 table */
+-  zSql = sqlite3MPrintf(db, 
+-      "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
+-  if( zSql==0 ){
+-    rc = SQLITE_NOMEM;
+-  }else{
+-    rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
+-    sqlite3DbFree(db, zSql);
++  /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */
++  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
++  for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
++    Index *pIdx = sqliteHashData(i);
++    if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx);
+   }
+ 
+-
+   /* Load the statistics from the sqlite_stat4 table. */
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+   if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){
+-    int lookasideEnabled = db->lookaside.bEnabled;
+-    db->lookaside.bEnabled = 0;
++    db->lookaside.bDisable++;
+     rc = loadStat4(db, sInfo.zDatabase);
+-    db->lookaside.bEnabled = lookasideEnabled;
++    db->lookaside.bDisable--;
+   }
+-  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
++  for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
+     Index *pIdx = sqliteHashData(i);
+     sqlite3_free(pIdx->aiRowEst);
+     pIdx->aiRowEst = 0;
+@@ -89944,7 +102855,7 @@
+ #endif
+ 
+   if( rc==SQLITE_NOMEM ){
+-    db->mallocFailed = 1;
++    sqlite3OomFault(db);
+   }
+   return rc;
+ }
+@@ -89967,6 +102878,7 @@
+ *************************************************************************
+ ** This file contains code used to implement the ATTACH and DETACH commands.
+ */
++/* #include "sqliteInt.h" */
+ 
+ #ifndef SQLITE_OMIT_ATTACH
+ /*
+@@ -90024,7 +102936,8 @@
+   char *zPath = 0;
+   char *zErr = 0;
+   unsigned int flags;
+-  Db *aNew;
++  Db *aNew;                 /* New array of Db pointers */
++  Db *pNew;                 /* Db object for the newly attached database */
+   char *zErrDyn = 0;
+   sqlite3_vfs *pVfs;
+ 
+@@ -90052,7 +102965,7 @@
+     goto attach_error;
+   }
+   for(i=0; i<db->nDb; i++){
+-    char *z = db->aDb[i].zName;
++    char *z = db->aDb[i].zDbSName;
+     assert( z && zName );
+     if( sqlite3StrICmp(z, zName)==0 ){
+       zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
+@@ -90064,7 +102977,7 @@
+   ** hash tables.
+   */
+   if( db->aDb==db->aDbStatic ){
+-    aNew = sqlite3DbMallocRaw(db, sizeof(db->aDb[0])*3 );
++    aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
+     if( aNew==0 ) return;
+     memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
+   }else{
+@@ -90072,8 +102985,8 @@
+     if( aNew==0 ) return;
+   }
+   db->aDb = aNew;
+-  aNew = &db->aDb[db->nDb];
+-  memset(aNew, 0, sizeof(*aNew));
++  pNew = &db->aDb[db->nDb];
++  memset(pNew, 0, sizeof(*pNew));
+ 
+   /* Open the database file. If the btree is successfully opened, use
+   ** it to obtain the database schema. At this point the schema may
+@@ -90082,43 +102995,45 @@
+   flags = db->openFlags;
+   rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
+   if( rc!=SQLITE_OK ){
+-    if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
++    if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
+     sqlite3_result_error(context, zErr, -1);
+     sqlite3_free(zErr);
+     return;
+   }
+   assert( pVfs );
+   flags |= SQLITE_OPEN_MAIN_DB;
+-  rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags);
++  rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
+   sqlite3_free( zPath );
+   db->nDb++;
++  db->skipBtreeMutex = 0;
+   if( rc==SQLITE_CONSTRAINT ){
+     rc = SQLITE_ERROR;
+     zErrDyn = sqlite3MPrintf(db, "database is already attached");
+   }else if( rc==SQLITE_OK ){
+     Pager *pPager;
+-    aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
+-    if( !aNew->pSchema ){
+-      rc = SQLITE_NOMEM;
+-    }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
++    pNew->pSchema = sqlite3SchemaGet(db, pNew->pBt);
++    if( !pNew->pSchema ){
++      rc = SQLITE_NOMEM_BKPT;
++    }else if( pNew->pSchema->file_format && pNew->pSchema->enc!=ENC(db) ){
+       zErrDyn = sqlite3MPrintf(db, 
+         "attached databases must use the same text encoding as main database");
+       rc = SQLITE_ERROR;
+     }
+-    sqlite3BtreeEnter(aNew->pBt);
+-    pPager = sqlite3BtreePager(aNew->pBt);
++    sqlite3BtreeEnter(pNew->pBt);
++    pPager = sqlite3BtreePager(pNew->pBt);
+     sqlite3PagerLockingMode(pPager, db->dfltLockMode);
+-    sqlite3BtreeSecureDelete(aNew->pBt,
++    sqlite3BtreeSecureDelete(pNew->pBt,
+                              sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
+ #ifndef SQLITE_OMIT_PAGER_PRAGMAS
+-    sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK));
++    sqlite3BtreeSetPagerFlags(pNew->pBt,
++                      PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK));
+ #endif
+-    sqlite3BtreeLeave(aNew->pBt);
++    sqlite3BtreeLeave(pNew->pBt);
+   }
+-  aNew->safety_level = 3;
+-  aNew->zName = sqlite3DbStrDup(db, zName);
+-  if( rc==SQLITE_OK && aNew->zName==0 ){
+-    rc = SQLITE_NOMEM;
++  pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
++  pNew->zDbSName = sqlite3DbStrDup(db, zName);
++  if( rc==SQLITE_OK && pNew->zDbSName==0 ){
++    rc = SQLITE_NOMEM_BKPT;
+   }
+ 
+ 
+@@ -90146,7 +103061,7 @@
+       case SQLITE_NULL:
+         /* No key specified.  Use the key from the main database */
+         sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
+-        if( nKey>0 || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
++        if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
+           rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
+         }
+         break;
+@@ -90184,7 +103099,7 @@
+     sqlite3ResetAllSchemasOfConnection(db);
+     db->nDb = iDb;
+     if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+-      db->mallocFailed = 1;
++      sqlite3OomFault(db);
+       sqlite3DbFree(db, zErrDyn);
+       zErrDyn = sqlite3MPrintf(db, "out of memory");
+     }else if( zErrDyn==0 ){
+@@ -90229,7 +103144,7 @@
+   for(i=0; i<db->nDb; i++){
+     pDb = &db->aDb[i];
+     if( pDb->pBt==0 ) continue;
+-    if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
++    if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break;
+   }
+ 
+   if( i>=db->nDb ){
+@@ -90279,6 +103194,7 @@
+   sqlite3* db = pParse->db;
+   int regArgs;
+ 
++  if( pParse->nErr ) goto attach_end;
+   memset(&sName, 0, sizeof(NameContext));
+   sName.pParse = pParse;
+ 
+@@ -90314,11 +103230,11 @@
+ 
+   assert( v || db->mallocFailed );
+   if( v ){
+-    sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3);
++    sqlite3VdbeAddOp4(v, OP_Function0, 0, regArgs+3-pFunc->nArg, regArgs+3,
++                      (char *)pFunc, P4_FUNCDEF);
+     assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg );
+     sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg));
+-    sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);
+-
++ 
+     /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
+     ** statement only). For DETACH, set it to false (expire all existing
+     ** statements).
+@@ -90343,12 +103259,10 @@
+     SQLITE_UTF8,      /* funcFlags */
+     0,                /* pUserData */
+     0,                /* pNext */
+-    detachFunc,       /* xFunc */
+-    0,                /* xStep */
++    detachFunc,       /* xSFunc */
+     0,                /* xFinalize */
+     "sqlite_detach",  /* zName */
+-    0,                /* pHash */
+-    0                 /* pDestructor */
++    {0}
+   };
+   codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
+ }
+@@ -90364,12 +103278,10 @@
+     SQLITE_UTF8,      /* funcFlags */
+     0,                /* pUserData */
+     0,                /* pNext */
+-    attachFunc,       /* xFunc */
+-    0,                /* xStep */
++    attachFunc,       /* xSFunc */
+     0,                /* xFinalize */
+     "sqlite_attach",  /* zName */
+-    0,                /* pHash */
+-    0                 /* pDestructor */
++    {0}
+   };
+   codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
+ }
+@@ -90391,7 +103303,7 @@
+   db = pParse->db;
+   assert( db->nDb>iDb );
+   pFix->pParse = pParse;
+-  pFix->zDb = db->aDb[iDb].zName;
++  pFix->zDb = db->aDb[iDb].zDbSName;
+   pFix->pSchema = db->aDb[iDb].pSchema;
+   pFix->zType = zType;
+   pFix->pName = pName;
+@@ -90488,7 +103400,7 @@
+         return 1;
+       }
+     }
+-    if( ExprHasProperty(pExpr, EP_TokenOnly) ) break;
++    if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break;
+     if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+       if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
+     }else{
+@@ -90556,6 +103468,7 @@
+ ** systems that do not need this facility may omit it by recompiling
+ ** the library with -DSQLITE_OMIT_AUTHORIZATION=1
+ */
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** All of the code in this file may be omitted by defining a single
+@@ -90608,7 +103521,7 @@
+ ** Setting the auth function to NULL disables this hook.  The default
+ ** setting of the auth function is NULL.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
++SQLITE_API int sqlite3_set_authorizer(
+   sqlite3 *db,
+   int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
+   void *pArg
+@@ -90648,10 +103561,11 @@
+   const char *zCol,               /* Column name */
+   int iDb                         /* Index of containing database. */
+ ){
+-  sqlite3 *db = pParse->db;       /* Database handle */
+-  char *zDb = db->aDb[iDb].zName; /* Name of attached database */
+-  int rc;                         /* Auth callback return code */
++  sqlite3 *db = pParse->db;          /* Database handle */
++  char *zDb = db->aDb[iDb].zDbSName; /* Schema name of attached database */
++  int rc;                            /* Auth callback return code */
+ 
++  if( db->init.busy ) return SQLITE_OK;
+   rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext
+ #ifdef SQLITE_USER_AUTHENTICATION
+                  ,db->auth.zAuthUser
+@@ -90756,6 +103670,18 @@
+   if( db->xAuth==0 ){
+     return SQLITE_OK;
+   }
 +
-+void* sqlcipher_codec_ctx_get_kdf_salt(codec_ctx *ctx) {
-+  return ctx->kdf_salt;
-+}
++  /* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the
++  ** callback are either NULL pointers or zero-terminated strings that
++  ** contain additional details about the action to be authorized.
++  **
++  ** The following testcase() macros show that any of the 3rd through 6th
++  ** parameters can be either NULL or a string. */
++  testcase( zArg1==0 );
++  testcase( zArg2==0 );
++  testcase( zArg3==0 );
++  testcase( pParse->zAuthContext==0 );
++
+   rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext
+ #ifdef SQLITE_USER_AUTHENTICATION
+                  ,db->auth.zAuthUser
+@@ -90826,15 +103752,7 @@
+ **     COMMIT
+ **     ROLLBACK
+ */
+-
+-/*
+-** This routine is called when a new SQL statement is beginning to
+-** be parsed.  Initialize the pParse structure as needed.
+-*/
+-SQLITE_PRIVATE void sqlite3BeginParse(Parse *pParse, int explainFlag){
+-  pParse->explain = (u8)explainFlag;
+-  pParse->nVar = 0;
+-}
++/* #include "sqliteInt.h" */
+ 
+ #ifndef SQLITE_OMIT_SHARED_CACHE
+ /*
+@@ -90842,10 +103760,10 @@
+ ** codeTableLocks() functions.
+ */
+ struct TableLock {
+-  int iDb;             /* The database containing the table to be locked */
+-  int iTab;            /* The root page of the table to be locked */
+-  u8 isWriteLock;      /* True for write lock.  False for a read lock */
+-  const char *zName;   /* Name of the table */
++  int iDb;               /* The database containing the table to be locked */
++  int iTab;              /* The root page of the table to be locked */
++  u8 isWriteLock;        /* True for write lock.  False for a read lock */
++  const char *zLockName; /* Name of the table */
+ };
+ 
+ /*
+@@ -90871,6 +103789,8 @@
+   TableLock *p;
+   assert( iDb>=0 );
+ 
++  if( iDb==1 ) return;
++  if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return;
+   for(i=0; i<pToplevel->nTableLock; i++){
+     p = &pToplevel->aTableLock[i];
+     if( p->iDb==iDb && p->iTab==iTab ){
+@@ -90887,10 +103807,10 @@
+     p->iDb = iDb;
+     p->iTab = iTab;
+     p->isWriteLock = isWriteLock;
+-    p->zName = zName;
++    p->zLockName = zName;
+   }else{
+     pToplevel->nTableLock = 0;
+-    pToplevel->db->mallocFailed = 1;
++    sqlite3OomFault(pToplevel->db);
+   }
+ }
+ 
+@@ -90909,7 +103829,7 @@
+     TableLock *p = &pParse->aTableLock[i];
+     int p1 = p->iDb;
+     sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock,
+-                      p->zName, P4_STATIC);
++                      p->zLockName, P4_STATIC);
+   }
+ }
+ #else
+@@ -90958,15 +103878,14 @@
+   assert( !pParse->isMultiWrite 
+        || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
+   if( v ){
+-    while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){}
+     sqlite3VdbeAddOp0(v, OP_Halt);
+ 
+ #if SQLITE_USER_AUTHENTICATION
+     if( pParse->nTableLock>0 && db->init.busy==0 ){
+       sqlite3UserAuthInit(db);
+       if( db->auth.authLevel<UAUTH_User ){
+-        pParse->rc = SQLITE_AUTH_USER;
+         sqlite3ErrorMsg(pParse, "user not authenticated");
++        pParse->rc = SQLITE_AUTH_USER;
+         return;
+       }
+     }
+@@ -90985,16 +103904,20 @@
+       assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
+       sqlite3VdbeJumpHere(v, 0);
+       for(iDb=0; iDb<db->nDb; iDb++){
++        Schema *pSchema;
+         if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
+         sqlite3VdbeUsesBtree(v, iDb);
++        pSchema = db->aDb[iDb].pSchema;
+         sqlite3VdbeAddOp4Int(v,
+           OP_Transaction,                    /* Opcode */
+           iDb,                               /* P1 */
+           DbMaskTest(pParse->writeMask,iDb), /* P2 */
+-          pParse->cookieValue[iDb],          /* P3 */
+-          db->aDb[iDb].pSchema->iGeneration  /* P4 */
++          pSchema->schema_cookie,            /* P3 */
++          pSchema->iGeneration               /* P4 */
+         );
+         if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
++        VdbeComment((v,
++              "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
+       }
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+       for(i=0; i<pParse->nVtabLock; i++){
+@@ -91024,7 +103947,7 @@
+       }
+ 
+       /* Finally, jump back to the beginning of the executable code. */
+-      sqlite3VdbeAddOp2(v, OP_Goto, 0, 1);
++      sqlite3VdbeGoto(v, 1);
+     }
+   }
+ 
+@@ -91038,15 +103961,9 @@
+     if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
+     sqlite3VdbeMakeReady(v, pParse);
+     pParse->rc = SQLITE_DONE;
+-    pParse->colNamesSet = 0;
+   }else{
+     pParse->rc = SQLITE_ERROR;
+   }
+-  pParse->nTab = 0;
+-  pParse->nMem = 0;
+-  pParse->nSet = 0;
+-  pParse->nVar = 0;
+-  DbMaskZero(pParse->cookieMask);
+ }
+ 
+ /*
+@@ -91066,8 +103983,7 @@
+   char *zSql;
+   char *zErrMsg = 0;
+   sqlite3 *db = pParse->db;
+-# define SAVE_SZ  (sizeof(Parse) - offsetof(Parse,nVar))
+-  char saveBuf[SAVE_SZ];
++  char saveBuf[PARSE_TAIL_SZ];
+ 
+   if( pParse->nErr ) return;
+   assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
+@@ -91078,12 +103994,12 @@
+     return;   /* A malloc must have failed */
+   }
+   pParse->nested++;
+-  memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
+-  memset(&pParse->nVar, 0, SAVE_SZ);
++  memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
++  memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
+   sqlite3RunParser(pParse, zSql, &zErrMsg);
+   sqlite3DbFree(db, zErrMsg);
+   sqlite3DbFree(db, zSql);
+-  memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
++  memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
+   pParse->nested--;
+ }
+ 
+@@ -91122,14 +104038,22 @@
+     return 0;
+   }
+ #endif
+-  for(i=OMIT_TEMPDB; i<db->nDb; i++){
+-    int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
+-    if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
+-    assert( sqlite3SchemaMutexHeld(db, j, 0) );
+-    p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
+-    if( p ) break;
++  while(1){
++    for(i=OMIT_TEMPDB; i<db->nDb; i++){
++      int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
++      if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){
++        assert( sqlite3SchemaMutexHeld(db, j, 0) );
++        p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
++        if( p ) return p;
++      }
++    }
++    /* Not found.  If the name we were looking for was temp.sqlite_master
++    ** then change the name to sqlite_temp_master and try again. */
++    if( sqlite3StrICmp(zName, MASTER_NAME)!=0 ) break;
++    if( sqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break;
++    zName = TEMP_MASTER_NAME;
+   }
+-  return p;
++  return 0;
+ }
+ 
+ /*
+@@ -91144,7 +104068,7 @@
+ */
+ SQLITE_PRIVATE Table *sqlite3LocateTable(
+   Parse *pParse,         /* context in which to report errors */
+-  int isView,            /* True if looking for a VIEW rather than a TABLE */
++  u32 flags,             /* LOCATE_VIEW or LOCATE_NOERR */
+   const char *zName,     /* Name of the table we are looking for */
+   const char *zDbase     /* Name of the database.  Might be NULL */
+ ){
+@@ -91158,20 +104082,31 @@
+ 
+   p = sqlite3FindTable(pParse->db, zName, zDbase);
+   if( p==0 ){
+-    const char *zMsg = isView ? "no such view" : "no such table";
+-    if( zDbase ){
+-      sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
+-    }else{
+-      sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
++    const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++    if( sqlite3FindDbName(pParse->db, zDbase)<1 ){
++      /* If zName is the not the name of a table in the schema created using
++      ** CREATE, then check to see if it is the name of an virtual table that
++      ** can be an eponymous virtual table. */
++      Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName);
++      if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
++        pMod = sqlite3PragmaVtabRegister(pParse->db, zName);
++      }
++      if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
++        return pMod->pEpoTab;
++      }
+     }
+-    pParse->checkSchema = 1;
+-  }
+-#if SQLITE_USER_AUTHENICATION
+-  else if( pParse->db->auth.authLevel<UAUTH_User ){
+-    sqlite3ErrorMsg(pParse, "user not authenticated");
+-    p = 0;
+-  }
+ #endif
++    if( (flags & LOCATE_NOERR)==0 ){
++      if( zDbase ){
++        sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
++      }else{
++        sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
++      }
++      pParse->checkSchema = 1;
++    }
++  }
 +
-+void sqlcipher_codec_get_keyspec(codec_ctx *ctx, void **zKey, int *nKey) {
-+  *zKey = ctx->read_ctx->keyspec;
-+  *nKey = ctx->read_ctx->keyspec_sz;
+   return p;
+ }
+ 
+@@ -91186,18 +104121,18 @@
+ */
+ SQLITE_PRIVATE Table *sqlite3LocateTableItem(
+   Parse *pParse, 
+-  int isView, 
++  u32 flags,
+   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;
++    zDb = pParse->db->aDb[iDb].zDbSName;
+   }else{
+     zDb = p->zDatabase;
+   }
+-  return sqlite3LocateTable(pParse, isView, p->zName, zDb);
++  return sqlite3LocateTable(pParse, flags, p->zName, zDb);
+ }
+ 
+ /*
+@@ -91221,7 +104156,7 @@
+     int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
+     Schema *pSchema = db->aDb[j].pSchema;
+     assert( pSchema );
+-    if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
++    if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue;
+     assert( sqlite3SchemaMutexHeld(db, j, 0) );
+     p = sqlite3HashFind(&pSchema->idxHash, zName);
+     if( p ) break;
+@@ -91237,8 +104172,9 @@
+   sqlite3DeleteIndexSamples(db, p);
+ #endif
+   sqlite3ExprDelete(db, p->pPartIdxWhere);
++  sqlite3ExprListDelete(db, p->aColExpr);
+   sqlite3DbFree(db, p->zColAff);
+-  if( p->isResized ) sqlite3DbFree(db, p->azColl);
++  if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl);
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+   sqlite3_free(p->aiRowEst);
+ #endif
+@@ -91289,8 +104225,8 @@
+   for(i=j=2; i<db->nDb; i++){
+     struct Db *pDb = &db->aDb[i];
+     if( pDb->pBt==0 ){
+-      sqlite3DbFree(db, pDb->zName);
+-      pDb->zName = 0;
++      sqlite3DbFree(db, pDb->zDbSName);
++      pDb->zDbSName = 0;
+       continue;
+     }
+     if( j<i ){
+@@ -91298,7 +104234,6 @@
+     }
+     j++;
+   }
+-  memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j]));
+   db->nDb = j;
+   if( db->nDb<=2 && db->aDb!=db->aDbStatic ){
+     memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));
+@@ -91363,7 +104298,7 @@
+ ** Delete memory allocated for the column names of a table or view (the
+ ** Table.aCol[] array).
+ */
+-static void sqliteDeleteColumnNames(sqlite3 *db, Table *pTable){
++SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
+   int i;
+   Column *pCol;
+   assert( pTable!=0 );
+@@ -91371,8 +104306,6 @@
+     for(i=0; i<pTable->nCol; i++, pCol++){
+       sqlite3DbFree(db, pCol->zName);
+       sqlite3ExprDelete(db, pCol->pDflt);
+-      sqlite3DbFree(db, pCol->zDflt);
+-      sqlite3DbFree(db, pCol->zType);
+       sqlite3DbFree(db, pCol->zColl);
+     }
+     sqlite3DbFree(db, pTable->aCol);
+@@ -91394,16 +104327,10 @@
+ ** db parameter can be used with db->pnBytesFreed to measure the memory
+ ** used by the Table object.
+ */
+-SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
++static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
+   Index *pIndex, *pNext;
+   TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */
+ 
+-  assert( !pTable || pTable->nRef>0 );
+-
+-  /* Do not delete the table until the reference count reaches zero. */
+-  if( !pTable ) return;
+-  if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return;
+-
+   /* Record the number of outstanding lookaside allocations in schema Tables
+   ** prior to doing any free() operations.  Since schema Tables do not use
+   ** lookaside, this number should not change. */
+@@ -91413,8 +104340,9 @@
+   /* Delete all indices associated with this table. */
+   for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
+     pNext = pIndex->pNext;
+-    assert( pIndex->pSchema==pTable->pSchema );
+-    if( !db || db->pnBytesFreed==0 ){
++    assert( pIndex->pSchema==pTable->pSchema
++         || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) );
++    if( (db==0 || db->pnBytesFreed==0) && !IsVirtual(pTable) ){
+       char *zName = pIndex->zName; 
+       TESTONLY ( Index *pOld = ) sqlite3HashInsert(
+          &pIndex->pSchema->idxHash, zName, 0
+@@ -91430,13 +104358,11 @@
+ 
+   /* Delete the Table structure itself.
+   */
+-  sqliteDeleteColumnNames(db, pTable);
++  sqlite3DeleteColumnNames(db, pTable);
+   sqlite3DbFree(db, pTable->zName);
+   sqlite3DbFree(db, pTable->zColAff);
+   sqlite3SelectDelete(db, pTable->pSelect);
+-#ifndef SQLITE_OMIT_CHECK
+   sqlite3ExprListDelete(db, pTable->pCheck);
+-#endif
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+   sqlite3VtabClear(db, pTable);
+ #endif
+@@ -91445,6 +104371,13 @@
+   /* Verify that no lookaside memory was used by schema tables */
+   assert( nLookaside==0 || nLookaside==db->lookaside.nOut );
+ }
++SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
++  /* Do not delete the table until the reference count reaches zero. */
++  if( !pTable ) return;
++  if( ((!db || db->pnBytesFreed==0) && (--pTable->nTabRef)>0) ) return;
++  deleteTable(db, pTable);
 +}
 +
-+int sqlcipher_codec_ctx_set_pagesize(codec_ctx *ctx, int size) {
-+  /* attempt to free the existing page buffer */
-+  sqlcipher_free(ctx->buffer,ctx->page_sz);
-+  ctx->page_sz = size;
-+
-+  /* pre-allocate a page buffer of PageSize bytes. This will
-+     be used as a persistent buffer for encryption and decryption 
-+     operations to avoid overhead of multiple memory allocations*/
-+  ctx->buffer = sqlcipher_malloc(size);
-+  if(ctx->buffer == NULL) return SQLITE_NOMEM;
-+
-+  return SQLITE_OK;
+ 
+ /*
+ ** Unlink the given table from the hash tables and the delete the
+@@ -91495,7 +104428,7 @@
+ */
+ SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *p, int iDb){
+   Vdbe *v = sqlite3GetVdbe(p);
+-  sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
++  sqlite3TableLock(p, iDb, MASTER_ROOT, 1, MASTER_NAME);
+   sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5);
+   if( p->nTab==0 ){
+     p->nTab = 1;
+@@ -91512,12 +104445,11 @@
+   int i = -1;         /* Database number */
+   if( zName ){
+     Db *pDb;
+-    int n = sqlite3Strlen30(zName);
+     for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
+-      if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) && 
+-          0==sqlite3StrICmp(pDb->zName, zName) ){
+-        break;
+-      }
++      if( 0==sqlite3_stricmp(pDb->zDbSName, zName) ) break;
++      /* "main" is always an acceptable alias for the primary database
++      ** even if it has been renamed using SQLITE_DBCONFIG_MAINDBNAME. */
++      if( i==0 && 0==sqlite3_stricmp("main", zName) ) break;
+     }
+   }
+   return i;
+@@ -91563,7 +104495,8 @@
+   int iDb;                    /* Database holding the object */
+   sqlite3 *db = pParse->db;
+ 
+-  if( ALWAYS(pName2!=0) && pName2->n>0 ){
++  assert( pName2!=0 );
++  if( pName2->n>0 ){
+     if( db->init.busy ) {
+       sqlite3ErrorMsg(pParse, "corrupt database");
+       return -1;
+@@ -91575,7 +104508,7 @@
+       return -1;
+     }
+   }else{
+-    assert( db->init.iDb==0 || db->init.busy );
++    assert( db->init.iDb==0 || db->init.busy || (db->flags & SQLITE_Vacuum)!=0);
+     iDb = db->init.iDb;
+     *pUnqual = pName1;
+   }
+@@ -91652,62 +104585,46 @@
+   int iDb;         /* Database number to create the table in */
+   Token *pName;    /* Unqualified name of the table to create */
+ 
+-  /* The table or view name to create is passed to this routine via tokens
+-  ** pName1 and pName2. If the table name was fully qualified, for example:
+-  **
+-  ** CREATE TABLE xxx.yyy (...);
+-  ** 
+-  ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if
+-  ** the table name is not fully qualified, i.e.:
+-  **
+-  ** CREATE TABLE yyy(...);
+-  **
+-  ** Then pName1 is set to "yyy" and pName2 is "".
+-  **
+-  ** The call below sets the pName pointer to point at the token (pName1 or
+-  ** pName2) that stores the unqualified table name. The variable iDb is
+-  ** set to the index of the database that the table or view is to be
+-  ** created in.
+-  */
+-  iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
+-  if( iDb<0 ) return;
+-  if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){
+-    /* If creating a temp table, the name may not be qualified. Unless 
+-    ** the database name is "temp" anyway.  */
+-    sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
+-    return;
++  if( db->init.busy && db->init.newTnum==1 ){
++    /* Special case:  Parsing the sqlite_master or sqlite_temp_master schema */
++    iDb = db->init.iDb;
++    zName = sqlite3DbStrDup(db, SCHEMA_TABLE(iDb));
++    pName = pName1;
++  }else{
++    /* The common case */
++    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
++    if( iDb<0 ) return;
++    if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){
++      /* If creating a temp table, the name may not be qualified. Unless 
++      ** the database name is "temp" anyway.  */
++      sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
++      return;
++    }
++    if( !OMIT_TEMPDB && isTemp ) iDb = 1;
++    zName = sqlite3NameFromToken(db, pName);
+   }
+-  if( !OMIT_TEMPDB && isTemp ) iDb = 1;
+-
+   pParse->sNameToken = *pName;
+-  zName = sqlite3NameFromToken(db, pName);
+   if( zName==0 ) return;
+   if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
+     goto begin_table_error;
+   }
+   if( db->init.iDb==1 ) isTemp = 1;
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+-  assert( (isTemp & 1)==isTemp );
++  assert( isTemp==0 || isTemp==1 );
++  assert( isView==0 || isView==1 );
+   {
+-    int code;
+-    char *zDb = db->aDb[iDb].zName;
++    static const u8 aCode[] = {
++       SQLITE_CREATE_TABLE,
++       SQLITE_CREATE_TEMP_TABLE,
++       SQLITE_CREATE_VIEW,
++       SQLITE_CREATE_TEMP_VIEW
++    };
++    char *zDb = db->aDb[iDb].zDbSName;
+     if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
+       goto begin_table_error;
+     }
+-    if( isView ){
+-      if( !OMIT_TEMPDB && isTemp ){
+-        code = SQLITE_CREATE_TEMP_VIEW;
+-      }else{
+-        code = SQLITE_CREATE_VIEW;
+-      }
+-    }else{
+-      if( !OMIT_TEMPDB && isTemp ){
+-        code = SQLITE_CREATE_TEMP_TABLE;
+-      }else{
+-        code = SQLITE_CREATE_TABLE;
+-      }
+-    }
+-    if( !isVirtual && sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){
++    if( !isVirtual && sqlite3AuthCheck(pParse, (int)aCode[isTemp+2*isView],
++                                       zName, 0, zDb) ){
+       goto begin_table_error;
+     }
+   }
+@@ -91721,7 +104638,7 @@
+   ** collisions.
+   */
+   if( !IN_DECLARE_VTAB ){
+-    char *zDb = db->aDb[iDb].zName;
++    char *zDb = db->aDb[iDb].zDbSName;
+     if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
+       goto begin_table_error;
+     }
+@@ -91743,16 +104660,20 @@
+ 
+   pTable = sqlite3DbMallocZero(db, sizeof(Table));
+   if( pTable==0 ){
+-    db->mallocFailed = 1;
+-    pParse->rc = SQLITE_NOMEM;
++    assert( db->mallocFailed );
++    pParse->rc = SQLITE_NOMEM_BKPT;
+     pParse->nErr++;
+     goto begin_table_error;
+   }
+   pTable->zName = zName;
+   pTable->iPKey = -1;
+   pTable->pSchema = db->aDb[iDb].pSchema;
+-  pTable->nRef = 1;
++  pTable->nTabRef = 1;
++#ifdef SQLITE_DEFAULT_ROWEST
++  pTable->nRowLogEst = sqlite3LogEst(SQLITE_DEFAULT_ROWEST);
++#else
+   pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
++#endif
+   assert( pParse->pNewTable==0 );
+   pParse->pNewTable = pTable;
+ 
+@@ -91776,10 +104697,12 @@
+   ** now.
+   */
+   if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
+-    int j1;
++    int addr1;
+     int fileFormat;
+     int reg1, reg2, reg3;
+-    sqlite3BeginWriteOperation(pParse, 0, iDb);
++    /* nullRow[] is an OP_Record encoding of a row containing 5 NULLs */
++    static const char nullRow[] = { 6, 0, 0, 0, 0, 0 };
++    sqlite3BeginWriteOperation(pParse, 1, iDb);
+ 
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+     if( isVirtual ){
+@@ -91795,14 +104718,12 @@
+     reg3 = ++pParse->nMem;
+     sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
+     sqlite3VdbeUsesBtree(v, iDb);
+-    j1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
++    addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
+     fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
+                   1 : SQLITE_MAX_FILE_FORMAT;
+-    sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
+-    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, reg3);
+-    sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3);
+-    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, reg3);
+-    sqlite3VdbeJumpHere(v, j1);
++    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat);
++    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db));
++    sqlite3VdbeJumpHere(v, addr1);
+ 
+     /* This just creates a place-holder record in the sqlite_master table.
+     ** The record created does not contain anything yet.  It will be replaced
+@@ -91823,7 +104744,7 @@
+     }
+     sqlite3OpenMasterTable(pParse, iDb);
+     sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
+-    sqlite3VdbeAddOp2(v, OP_Null, 0, reg3);
++    sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
+     sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
+     sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+     sqlite3VdbeAddOp0(v, OP_Close);
+@@ -91838,18 +104759,19 @@
+   return;
+ }
+ 
+-/*
+-** This macro is used to compare two strings in a case-insensitive manner.
+-** It is slightly faster than calling sqlite3StrICmp() directly, but
+-** produces larger code.
+-**
+-** WARNING: This macro is not compatible with the strcmp() family. It
+-** returns true if the two strings are equal, otherwise false.
+-*/
+-#define STRICMP(x, y) (\
+-sqlite3UpperToLower[*(unsigned char *)(x)]==   \
+-sqlite3UpperToLower[*(unsigned char *)(y)]     \
+-&& sqlite3StrICmp((x)+1,(y)+1)==0 )
++/* Set properties of a table column based on the (magical)
++** name of the column.
++*/
++#if SQLITE_ENABLE_HIDDEN_COLUMNS
++SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){
++  if( sqlite3_strnicmp(pCol->zName, "__hidden__", 10)==0 ){
++    pCol->colFlags |= COLFLAG_HIDDEN;
++  }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){
++    pTab->tabFlags |= TF_OOOHidden;
++  }
 +}
++#endif
 +
-+int sqlcipher_codec_ctx_get_pagesize(codec_ctx *ctx) {
-+  return ctx->page_sz;
+ 
+ /*
+ ** Add a new column to the table currently being constructed.
+@@ -91859,10 +104781,11 @@
+ ** first to get things going.  Then this routine is called for each
+ ** column.
+ */
+-SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){
++SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
+   Table *p;
+   int i;
+   char *z;
++  char *zType;
+   Column *pCol;
+   sqlite3 *db = pParse->db;
+   if( (p = pParse->pNewTable)==0 ) return;
+@@ -91872,10 +104795,13 @@
+     return;
+   }
+ #endif
+-  z = sqlite3NameFromToken(db, pName);
++  z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
+   if( z==0 ) return;
++  memcpy(z, pName->z, pName->n);
++  z[pName->n] = 0;
++  sqlite3Dequote(z);
+   for(i=0; i<p->nCol; i++){
+-    if( STRICMP(z, p->aCol[i].zName) ){
++    if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){
+       sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
+       sqlite3DbFree(db, z);
+       return;
+@@ -91893,14 +104819,23 @@
+   pCol = &p->aCol[p->nCol];
+   memset(pCol, 0, sizeof(p->aCol[0]));
+   pCol->zName = z;
++  sqlite3ColumnPropertiesFromName(p, pCol);
+  
+-  /* If there is no type specified, columns have the default affinity
+-  ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will
+-  ** be called next to set pCol->affinity correctly.
+-  */
+-  pCol->affinity = SQLITE_AFF_NONE;
+-  pCol->szEst = 1;
++  if( pType->n==0 ){
++    /* If there is no type specified, columns have the default affinity
++    ** 'BLOB'. */
++    pCol->affinity = SQLITE_AFF_BLOB;
++    pCol->szEst = 1;
++  }else{
++    zType = z + sqlite3Strlen30(z) + 1;
++    memcpy(zType, pType->z, pType->n);
++    zType[pType->n] = 0;
++    sqlite3Dequote(zType);
++    pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst);
++    pCol->colFlags |= COLFLAG_HASTYPE;
++  }
+   p->nCol++;
++  pParse->constraintName.n = 0;
+ }
+ 
+ /*
+@@ -91914,6 +104849,7 @@
+   p = pParse->pNewTable;
+   if( p==0 || NEVER(p->nCol<1) ) return;
+   p->aCol[p->nCol-1].notNull = (u8)onError;
++  p->tabFlags |= TF_HasNotNull;
+ }
+ 
+ /*
+@@ -91933,7 +104869,7 @@
+ ** 'CHAR'        | SQLITE_AFF_TEXT
+ ** 'CLOB'        | SQLITE_AFF_TEXT
+ ** 'TEXT'        | SQLITE_AFF_TEXT
+-** 'BLOB'        | SQLITE_AFF_NONE
++** 'BLOB'        | SQLITE_AFF_BLOB
+ ** 'REAL'        | SQLITE_AFF_REAL
+ ** 'FLOA'        | SQLITE_AFF_REAL
+ ** 'DOUB'        | SQLITE_AFF_REAL
+@@ -91946,7 +104882,7 @@
+   char aff = SQLITE_AFF_NUMERIC;
+   const char *zChar = 0;
+ 
+-  if( zIn==0 ) return aff;
++  assert( zIn!=0 );
+   while( zIn[0] ){
+     h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff];
+     zIn++;
+@@ -91959,7 +104895,7 @@
+       aff = SQLITE_AFF_TEXT;
+     }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b')          /* BLOB */
+         && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){
+-      aff = SQLITE_AFF_NONE;
++      aff = SQLITE_AFF_BLOB;
+       if( zIn[0]=='(' ) zChar = zIn;
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+     }else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l')          /* REAL */
+@@ -92004,28 +104940,6 @@
+ }
+ 
+ /*
+-** This routine is called by the parser while in the middle of
+-** parsing a CREATE TABLE statement.  The pFirst token is the first
+-** token in the sequence of tokens that describe the type of the
+-** column currently under construction.   pLast is the last token
+-** in the sequence.  Use this information to construct a string
+-** that contains the typename of the column and store that string
+-** in zType.
+-*/ 
+-SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
+-  Table *p;
+-  Column *pCol;
+-
+-  p = pParse->pNewTable;
+-  if( p==0 || NEVER(p->nCol<1) ) return;
+-  pCol = &p->aCol[p->nCol-1];
+-  assert( pCol->zType==0 || CORRUPT_DB );
+-  sqlite3DbFree(pParse->db, pCol->zType);
+-  pCol->zType = sqlite3NameFromToken(pParse->db, pType);
+-  pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
+-}
+-
+-/*
+ ** The expression is the default value for the most recently added column
+ ** of the table currently under construction.
+ **
+@@ -92050,17 +104964,46 @@
+       ** tokens that point to volatile memory. The 'span' of the expression
+       ** is required by pragma table_info.
+       */
++      Expr x;
+       sqlite3ExprDelete(db, pCol->pDflt);
+-      pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE);
+-      sqlite3DbFree(db, pCol->zDflt);
+-      pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
+-                                     (int)(pSpan->zEnd - pSpan->zStart));
++      memset(&x, 0, sizeof(x));
++      x.op = TK_SPAN;
++      x.u.zToken = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
++                                    (int)(pSpan->zEnd - pSpan->zStart));
++      x.pLeft = pSpan->pExpr;
++      x.flags = EP_Skip;
++      pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
++      sqlite3DbFree(db, x.u.zToken);
+     }
+   }
+   sqlite3ExprDelete(db, pSpan->pExpr);
+ }
+ 
+ /*
++** Backwards Compatibility Hack:
++** 
++** Historical versions of SQLite accepted strings as column names in
++** indexes and PRIMARY KEY constraints and in UNIQUE constraints.  Example:
++**
++**     CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim)
++**     CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC);
++**
++** This is goofy.  But to preserve backwards compatibility we continue to
++** accept it.  This routine does the necessary conversion.  It converts
++** the expression given in its argument from a TK_STRING into a TK_ID
++** if the expression is just a TK_STRING with an optional COLLATE clause.
++** If the epxression is anything other than TK_STRING, the expression is
++** unchanged.
++*/
++static void sqlite3StringToId(Expr *p){
++  if( p->op==TK_STRING ){
++    p->op = TK_ID;
++  }else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){
++    p->pLeft->op = TK_ID;
++  }
 +}
 +
-+void sqlcipher_set_default_pagesize(int page_size) {
-+  default_page_size = page_size;
-+}
++/*
+ ** Designate the PRIMARY KEY for the table.  pList is a list of names 
+ ** of columns that form the primary key.  If pList is NULL, then the
+ ** most recently added column of the table is the primary key.
+@@ -92086,10 +105029,10 @@
+   int sortOrder     /* SQLITE_SO_ASC or SQLITE_SO_DESC */
+ ){
+   Table *pTab = pParse->pNewTable;
+-  char *zType = 0;
++  Column *pCol = 0;
+   int iCol = -1, i;
+   int nTerm;
+-  if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
++  if( pTab==0 ) goto primary_key_exit;
+   if( pTab->tabFlags & TF_HasPrimaryKey ){
+     sqlite3ErrorMsg(pParse, 
+       "table \"%s\" has more than one primary key", pTab->zName);
+@@ -92098,24 +105041,31 @@
+   pTab->tabFlags |= TF_HasPrimaryKey;
+   if( pList==0 ){
+     iCol = pTab->nCol - 1;
+-    pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
+-    zType = pTab->aCol[iCol].zType;
++    pCol = &pTab->aCol[iCol];
++    pCol->colFlags |= COLFLAG_PRIMKEY;
+     nTerm = 1;
+   }else{
+     nTerm = pList->nExpr;
+     for(i=0; i<nTerm; i++){
+-      for(iCol=0; iCol<pTab->nCol; iCol++){
+-        if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
+-          pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
+-          zType = pTab->aCol[iCol].zType;
+-          break;
++      Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
++      assert( pCExpr!=0 );
++      sqlite3StringToId(pCExpr);
++      if( pCExpr->op==TK_ID ){
++        const char *zCName = pCExpr->u.zToken;
++        for(iCol=0; iCol<pTab->nCol; iCol++){
++          if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){
++            pCol = &pTab->aCol[iCol];
++            pCol->colFlags |= COLFLAG_PRIMKEY;
++            break;
++          }
+         }
+       }
+     }
+   }
+   if( nTerm==1
+-   && zType && sqlite3StrICmp(zType, "INTEGER")==0
+-   && sortOrder==SQLITE_SO_ASC
++   && pCol
++   && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0
++   && sortOrder!=SQLITE_SO_DESC
+   ){
+     pTab->iPKey = iCol;
+     pTab->keyConf = (u8)onError;
+@@ -92128,15 +105078,8 @@
+        "INTEGER PRIMARY KEY");
+ #endif
+   }else{
+-    Vdbe *v = pParse->pVdbe;
+-    Index *p;
+-    if( v ) pParse->addrSkipPK = sqlite3VdbeAddOp0(v, OP_Noop);
+-    p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
+-                           0, sortOrder, 0);
+-    if( p ){
+-      p->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
+-      if( v ) sqlite3VdbeJumpHere(v, pParse->addrSkipPK);
+-    }
++    sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
++                           0, sortOrder, 0, SQLITE_IDXTYPE_PRIMARYKEY);
+     pList = 0;
+   }
+ 
+@@ -92255,15 +105198,16 @@
+ ** set back to prior value.  But schema changes are infrequent
+ ** and the probability of hitting the same cookie value is only
+ ** 1 chance in 2^32.  So we're safe enough.
++**
++** IMPLEMENTATION-OF: R-34230-56049 SQLite automatically increments
++** the schema-version whenever the schema changes.
+ */
+ SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){
+-  int r1 = sqlite3GetTempReg(pParse);
+   sqlite3 *db = pParse->db;
+   Vdbe *v = pParse->pVdbe;
+   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+-  sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1);
+-  sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, r1);
+-  sqlite3ReleaseTempReg(pParse, r1);
++  sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, 
++                    db->aDb[iDb].pSchema->schema_cookie+1);
+ }
+ 
+ /*
+@@ -92345,7 +105289,7 @@
+   n += 35 + 6*p->nCol;
+   zStmt = sqlite3DbMallocRaw(0, n);
+   if( zStmt==0 ){
+-    db->mallocFailed = 1;
++    sqlite3OomFault(db);
+     return 0;
+   }
+   sqlite3_snprintf(n, zStmt, "CREATE TABLE ");
+@@ -92354,7 +105298,7 @@
+   zStmt[k++] = '(';
+   for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
+     static const char * const azType[] = {
+-        /* SQLITE_AFF_NONE    */ "",
++        /* SQLITE_AFF_BLOB    */ "",
+         /* SQLITE_AFF_TEXT    */ " TEXT",
+         /* SQLITE_AFF_NUMERIC */ " NUM",
+         /* SQLITE_AFF_INTEGER */ " INT",
+@@ -92367,17 +105311,17 @@
+     k += sqlite3Strlen30(&zStmt[k]);
+     zSep = zSep2;
+     identPut(zStmt, &k, pCol->zName);
+-    assert( pCol->affinity-SQLITE_AFF_NONE >= 0 );
+-    assert( pCol->affinity-SQLITE_AFF_NONE < ArraySize(azType) );
+-    testcase( pCol->affinity==SQLITE_AFF_NONE );
++    assert( pCol->affinity-SQLITE_AFF_BLOB >= 0 );
++    assert( pCol->affinity-SQLITE_AFF_BLOB < ArraySize(azType) );
++    testcase( pCol->affinity==SQLITE_AFF_BLOB );
+     testcase( pCol->affinity==SQLITE_AFF_TEXT );
+     testcase( pCol->affinity==SQLITE_AFF_NUMERIC );
+     testcase( pCol->affinity==SQLITE_AFF_INTEGER );
+     testcase( pCol->affinity==SQLITE_AFF_REAL );
+     
+-    zType = azType[pCol->affinity - SQLITE_AFF_NONE];
++    zType = azType[pCol->affinity - SQLITE_AFF_BLOB];
+     len = sqlite3Strlen30(zType);
+-    assert( pCol->affinity==SQLITE_AFF_NONE 
++    assert( pCol->affinity==SQLITE_AFF_BLOB 
+             || pCol->affinity==sqlite3AffinityType(zType, 0) );
+     memcpy(&zStmt[k], zType, len);
+     k += len;
+@@ -92398,9 +105342,9 @@
+   assert( pIdx->isResized==0 );
+   nByte = (sizeof(char*) + sizeof(i16) + 1)*N;
+   zExtra = sqlite3DbMallocZero(db, nByte);
+-  if( zExtra==0 ) return SQLITE_NOMEM;
++  if( zExtra==0 ) return SQLITE_NOMEM_BKPT;
+   memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
+-  pIdx->azColl = (char**)zExtra;
++  pIdx->azColl = (const char**)zExtra;
+   zExtra += sizeof(char*)*N;
+   memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn);
+   pIdx->aiColumn = (i16*)zExtra;
+@@ -92455,21 +105399,23 @@
+ ** are appropriate for a WITHOUT ROWID table instead of a rowid table.
+ ** Changes include:
+ **
+-**     (1)  Convert the OP_CreateTable into an OP_CreateIndex.  There is
++**     (1)  Set all columns of the PRIMARY KEY schema object to be NOT NULL.
++**     (2)  Convert the OP_CreateTable into an OP_CreateIndex.  There is
+ **          no rowid btree for a WITHOUT ROWID.  Instead, the canonical
+ **          data storage is a covering index btree.
+-**     (2)  Bypass the creation of the sqlite_master table entry
++**     (3)  Bypass the creation of the sqlite_master table entry
+ **          for the PRIMARY KEY as the primary key index is now
+ **          identified by the sqlite_master table entry of the table itself.
+-**     (3)  Set the Index.tnum of the PRIMARY KEY Index object in the
++**     (4)  Set the Index.tnum of the PRIMARY KEY Index object in the
+ **          schema to the rootpage from the main table.
+-**     (4)  Set all columns of the PRIMARY KEY schema object to be NOT NULL.
+ **     (5)  Add all table columns to the PRIMARY KEY Index object
+ **          so that the PRIMARY KEY is a covering index.  The surplus
+ **          columns are part of KeyInfo.nXField and are not used for
+ **          sorting or lookup or uniqueness checks.
+ **     (6)  Replace the rowid tail on all automatically generated UNIQUE
+ **          indices with the PRIMARY KEY columns.
++**
++** For virtual tables, only (1) is performed.
+ */
+ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
+   Index *pIdx;
+@@ -92479,21 +105425,27 @@
+   sqlite3 *db = pParse->db;
+   Vdbe *v = pParse->pVdbe;
+ 
++  /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
++  */
++  if( !db->init.imposterTable ){
++    for(i=0; i<pTab->nCol; i++){
++      if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 ){
++        pTab->aCol[i].notNull = OE_Abort;
++      }
++    }
++  }
 +
-+int sqlcipher_get_default_pagesize() {
-+  return default_page_size;
-+}
++  /* The remaining transformations only apply to b-tree tables, not to
++  ** virtual tables */
++  if( IN_DECLARE_VTAB ) return;
 +
-+int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_file *fd, const void *zKey, 
int nKey) {
-+  int rc;
-+  codec_ctx *ctx;
-+  *iCtx = sqlcipher_malloc(sizeof(codec_ctx));
-+  ctx = *iCtx;
+   /* Convert the OP_CreateTable opcode that would normally create the
+   ** root-page for the table into an OP_CreateIndex opcode.  The index
+   ** created will become the PRIMARY KEY index.
+   */
+   if( pParse->addrCrTab ){
+     assert( v );
+-    sqlite3VdbeGetOp(v, pParse->addrCrTab)->opcode = OP_CreateIndex;
+-  }
+-
+-  /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
+-  ** table entry.
+-  */
+-  if( pParse->addrSkipPK ){
+-    assert( v );
+-    sqlite3VdbeGetOp(v, pParse->addrSkipPK)->opcode = OP_Goto;
++    sqlite3VdbeChangeOpcode(v, pParse->addrCrTab, OP_CreateIndex);
+   }
+ 
+   /* Locate the PRIMARY KEY index.  Or, if this table was originally
+@@ -92501,18 +105453,21 @@
+   */
+   if( pTab->iPKey>=0 ){
+     ExprList *pList;
+-    pList = sqlite3ExprListAppend(pParse, 0, 0);
++    Token ipkToken;
++    sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName);
++    pList = sqlite3ExprListAppend(pParse, 0, 
++                  sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
+     if( pList==0 ) return;
+-    pList->a[0].zName = sqlite3DbStrDup(pParse->db,
+-                                        pTab->aCol[pTab->iPKey].zName);
+     pList->a[0].sortOrder = pParse->iPkSortOrder;
+     assert( pParse->pNewTable==pTab );
+-    pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0);
+-    if( pPk==0 ) return;
+-    pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
++    sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
++                       SQLITE_IDXTYPE_PRIMARYKEY);
++    if( db->mallocFailed ) return;
++    pPk = sqlite3PrimaryKeyIndex(pTab);
+     pTab->iPKey = -1;
+   }else{
+     pPk = sqlite3PrimaryKeyIndex(pTab);
 +
-+  if(ctx == NULL) return SQLITE_NOMEM;
+     /*
+     ** Remove all redundant columns from the PRIMARY KEY.  For example, change
+     ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)".  Later
+@@ -92527,17 +105482,18 @@
+     }
+     pPk->nKeyCol = j;
+   }
+-  pPk->isCovering = 1;
+   assert( pPk!=0 );
++  pPk->isCovering = 1;
++  if( !db->init.imposterTable ) pPk->uniqNotNull = 1;
+   nPk = pPk->nKeyCol;
+ 
+-  /* Make sure every column of the PRIMARY KEY is NOT NULL.  (Except,
+-  ** do not enforce this for imposter tables.) */
+-  if( !db->init.imposterTable ){
+-    for(i=0; i<nPk; i++){
+-      pTab->aCol[pPk->aiColumn[i]].notNull = 1;
+-    }
+-    pPk->uniqNotNull = 1;
++  /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
++  ** table entry. This is only required if currently generating VDBE
++  ** code for a CREATE TABLE (not when parsing one as part of reading
++  ** a database schema).  */
++  if( v && pPk->tnum>0 ){
++    assert( db->init.busy==0 );
++    sqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto);
+   }
+ 
+   /* The root page of the PRIMARY KEY is the table root page */
+@@ -92577,7 +105533,7 @@
+       if( !hasColumn(pPk->aiColumn, j, i) ){
+         assert( j<pPk->nColumn );
+         pPk->aiColumn[j] = i;
+-        pPk->azColl[j] = "BINARY";
++        pPk->azColl[j] = sqlite3StrBINARY;
+         j++;
+       }
+     }
+@@ -92620,9 +105576,10 @@
+   int iDb;                  /* Database in which the table lives */
+   Index *pIdx;              /* An implied index of the table */
+ 
+-  if( (pEnd==0 && pSelect==0) || db->mallocFailed ){
++  if( pEnd==0 && pSelect==0 ){
+     return;
+   }
++  assert( !db->mallocFailed );
+   p = pParse->pNewTable;
+   if( p==0 ) return;
+ 
+@@ -92633,9 +105590,13 @@
+   ** So do not write to the disk again.  Extract the root page number
+   ** for the table from the db->init.newTnum field.  (The page number
+   ** should have been put there by the sqliteOpenCb routine.)
++  **
++  ** If the root page number is 1, that means this is the sqlite_master
++  ** table itself.  So mark it read-only.
+   */
+   if( db->init.busy ){
+     p->tnum = db->init.newTnum;
++    if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
+   }
+ 
+   /* Special processing for WITHOUT ROWID Tables */
+@@ -92648,7 +105609,7 @@
+     if( (p->tabFlags & TF_HasPrimaryKey)==0 ){
+       sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName);
+     }else{
+-      p->tabFlags |= TF_WithoutRowid;
++      p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid;
+       convertToWithoutRowidTable(pParse, p);
+     }
+   }
+@@ -92716,26 +105677,46 @@
+     ** be redundant.
+     */
+     if( pSelect ){
+-      SelectDest dest;
+-      Table *pSelTab;
++      SelectDest dest;    /* Where the SELECT should store results */
++      int regYield;       /* Register holding co-routine entry-point */
++      int addrTop;        /* Top of the co-routine */
++      int regRec;         /* A record to be insert into the new table */
++      int regRowid;       /* Rowid of the next row to insert */
++      int addrInsLoop;    /* Top of the loop for inserting rows */
++      Table *pSelTab;     /* A table that describes the SELECT results */
+ 
++      regYield = ++pParse->nMem;
++      regRec = ++pParse->nMem;
++      regRowid = ++pParse->nMem;
+       assert(pParse->nTab==1);
++      sqlite3MayAbort(pParse);
+       sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
+       sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
+       pParse->nTab = 2;
+-      sqlite3SelectDestInit(&dest, SRT_Table, 1);
++      addrTop = sqlite3VdbeCurrentAddr(v) + 1;
++      sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
++      sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
+       sqlite3Select(pParse, pSelect, &dest);
++      sqlite3VdbeEndCoroutine(v, regYield);
++      sqlite3VdbeJumpHere(v, addrTop - 1);
++      if( pParse->nErr ) return;
++      pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
++      if( pSelTab==0 ) return;
++      assert( p->aCol==0 );
++      p->nCol = pSelTab->nCol;
++      p->aCol = pSelTab->aCol;
++      pSelTab->nCol = 0;
++      pSelTab->aCol = 0;
++      sqlite3DeleteTable(db, pSelTab);
++      addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec);
++      sqlite3TableAffinity(v, p, 0);
++      sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid);
++      sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid);
++      sqlite3VdbeGoto(v, addrInsLoop);
++      sqlite3VdbeJumpHere(v, addrInsLoop);
+       sqlite3VdbeAddOp1(v, OP_Close, 1);
+-      if( pParse->nErr==0 ){
+-        pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
+-        if( pSelTab==0 ) return;
+-        assert( p->aCol==0 );
+-        p->nCol = pSelTab->nCol;
+-        p->aCol = pSelTab->aCol;
+-        pSelTab->nCol = 0;
+-        pSelTab->aCol = 0;
+-        sqlite3DeleteTable(db, pSelTab);
+-      }
+     }
+ 
+     /* Compute the complete text of the CREATE statement */
+@@ -92758,7 +105739,7 @@
+       "UPDATE %Q.%s "
+          "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q "
+        "WHERE rowid=#%d",
+-      db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
++      db->aDb[iDb].zDbSName, MASTER_NAME,
+       zType,
+       p->zName,
+       p->zName,
+@@ -92773,13 +105754,13 @@
+     /* Check to see if we need to create an sqlite_sequence table for
+     ** keeping track of autoincrement keys.
+     */
+-    if( p->tabFlags & TF_Autoincrement ){
++    if( (p->tabFlags & TF_Autoincrement)!=0 ){
+       Db *pDb = &db->aDb[iDb];
+       assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+       if( pDb->pSchema->pSeqTab==0 ){
+         sqlite3NestedParse(pParse,
+           "CREATE TABLE %Q.sqlite_sequence(name,seq)",
+-          pDb->zName
++          pDb->zDbSName
+         );
+       }
+     }
+@@ -92800,7 +105781,7 @@
+     pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p);
+     if( pOld ){
+       assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
+-      db->mallocFailed = 1;
++      sqlite3OomFault(db);
+       return;
+     }
+     pParse->pNewTable = 0;
+@@ -92830,6 +105811,7 @@
+   Token *pBegin,     /* The CREATE token that begins the statement */
+   Token *pName1,     /* The token that holds the name of the view */
+   Token *pName2,     /* The token that holds the name of the view */
++  ExprList *pCNames, /* Optional list of view column names */
+   Select *pSelect,   /* A SELECT statement that will become the new view */
+   int isTemp,        /* TRUE for a TEMPORARY view */
+   int noErr          /* Suppress error messages if VIEW already exists */
+@@ -92845,22 +105827,15 @@
+ 
+   if( pParse->nVar>0 ){
+     sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
+-    sqlite3SelectDelete(db, pSelect);
+-    return;
++    goto create_view_fail;
+   }
+   sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
+   p = pParse->pNewTable;
+-  if( p==0 || pParse->nErr ){
+-    sqlite3SelectDelete(db, pSelect);
+-    return;
+-  }
++  if( p==0 || pParse->nErr ) goto create_view_fail;
+   sqlite3TwoPartName(pParse, pName1, pName2, &pName);
+   iDb = sqlite3SchemaToIndex(db, p->pSchema);
+   sqlite3FixInit(&sFix, pParse, iDb, "view", pName);
+-  if( sqlite3FixSelect(&sFix, pSelect) ){
+-    sqlite3SelectDelete(db, pSelect);
+-    return;
+-  }
++  if( sqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail;
+ 
+   /* Make a copy of the entire SELECT statement that defines the view.
+   ** This will force all the Expr.token.z values to be dynamically
+@@ -92868,30 +105843,31 @@
+   ** they will persist after the current sqlite3_exec() call returns.
+   */
+   p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
+-  sqlite3SelectDelete(db, pSelect);
+-  if( db->mallocFailed ){
+-    return;
+-  }
+-  if( !db->init.busy ){
+-    sqlite3ViewGetColumnNames(pParse, p);
+-  }
++  p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE);
++  if( db->mallocFailed ) goto create_view_fail;
+ 
+   /* Locate the end of the CREATE VIEW statement.  Make sEnd point to
+   ** the end.
+   */
+   sEnd = pParse->sLastToken;
+-  if( ALWAYS(sEnd.z[0]!=0) && sEnd.z[0]!=';' ){
++  assert( sEnd.z[0]!=0 );
++  if( sEnd.z[0]!=';' ){
+     sEnd.z += sEnd.n;
+   }
+   sEnd.n = 0;
+   n = (int)(sEnd.z - pBegin->z);
++  assert( n>0 );
+   z = pBegin->z;
+-  while( ALWAYS(n>0) && sqlite3Isspace(z[n-1]) ){ n--; }
++  while( sqlite3Isspace(z[n-1]) ){ n--; }
+   sEnd.z = &z[n-1];
+   sEnd.n = 1;
+ 
+   /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
+   sqlite3EndTable(pParse, 0, &sEnd, 0, 0);
++
++create_view_fail:
++  sqlite3SelectDelete(db, pSelect);
++  sqlite3ExprListDelete(db, pCNames);
+   return;
+ }
+ #endif /* SQLITE_OMIT_VIEW */
+@@ -92908,7 +105884,9 @@
+   int nErr = 0;     /* Number of errors encountered */
+   int n;            /* Temporarily holds the number of cursors assigned */
+   sqlite3 *db = pParse->db;  /* Database connection for malloc errors */
++#ifndef SQLITE_OMIT_AUTHORIZATION
+   sqlite3_xauth xAuth;       /* Saved xAuth pointer */
++#endif
+ 
+   assert( pTable );
+ 
+@@ -92956,11 +105934,10 @@
+   assert( pTable->pSelect );
+   pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
+   if( pSel ){
+-    u8 enableLookaside = db->lookaside.bEnabled;
+     n = pParse->nTab;
+     sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
+     pTable->nCol = -1;
+-    db->lookaside.bEnabled = 0;
++    db->lookaside.bDisable++;
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+     xAuth = db->xAuth;
+     db->xAuth = 0;
+@@ -92969,25 +105946,43 @@
+ #else
+     pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
+ #endif
+-    db->lookaside.bEnabled = enableLookaside;
+     pParse->nTab = n;
+-    if( pSelTab ){
++    if( pTable->pCheck ){
++      /* CREATE VIEW name(arglist) AS ...
++      ** The names of the columns in the table are taken from
++      ** arglist which is stored in pTable->pCheck.  The pCheck field
++      ** normally holds CHECK constraints on an ordinary table, but for
++      ** a VIEW it holds the list of column names.
++      */
++      sqlite3ColumnsFromExprList(pParse, pTable->pCheck, 
++                                 &pTable->nCol, &pTable->aCol);
++      if( db->mallocFailed==0 
++       && pParse->nErr==0
++       && pTable->nCol==pSel->pEList->nExpr
++      ){
++        sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel);
++      }
++    }else if( pSelTab ){
++      /* CREATE VIEW name AS...  without an argument list.  Construct
++      ** the column names from the SELECT statement that defines the view.
++      */
+       assert( pTable->aCol==0 );
+       pTable->nCol = pSelTab->nCol;
+       pTable->aCol = pSelTab->aCol;
+       pSelTab->nCol = 0;
+       pSelTab->aCol = 0;
+-      sqlite3DeleteTable(db, pSelTab);
+       assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
+-      pTable->pSchema->schemaFlags |= DB_UnresetViews;
+     }else{
+       pTable->nCol = 0;
+       nErr++;
+     }
++    sqlite3DeleteTable(db, pSelTab);
+     sqlite3SelectDelete(db, pSel);
++    db->lookaside.bDisable--;
+   } else {
+     nErr++;
+   }
++  pTable->pSchema->schemaFlags |= DB_UnresetViews;
+ #endif /* SQLITE_OMIT_VIEW */
+   return nErr;  
+ }
+@@ -93004,7 +105999,7 @@
+   for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){
+     Table *pTab = sqliteHashData(i);
+     if( pTab->pSelect ){
+-      sqliteDeleteColumnNames(db, pTab);
++      sqlite3DeleteColumnNames(db, pTab);
+       pTab->aCol = 0;
+       pTab->nCol = 0;
+     }
+@@ -93066,6 +106061,7 @@
+ static void destroyRootPage(Parse *pParse, int iTable, int iDb){
+   Vdbe *v = sqlite3GetVdbe(pParse);
+   int r1 = sqlite3GetTempReg(pParse);
++  assert( iTable>1 );
+   sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
+   sqlite3MayAbort(pParse);
+ #ifndef SQLITE_OMIT_AUTOVACUUM
+@@ -93080,7 +106076,7 @@
+   */
+   sqlite3NestedParse(pParse, 
+      "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
+-     pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1);
++     pParse->db->aDb[iDb].zDbSName, MASTER_NAME, iTable, r1, r1);
+ #endif
+   sqlite3ReleaseTempReg(pParse, r1);
+ }
+@@ -93156,7 +106152,7 @@
+   const char *zName      /* Name of index or table */
+ ){
+   int i;
+-  const char *zDbName = pParse->db->aDb[iDb].zName;
++  const char *zDbName = pParse->db->aDb[iDb].zDbSName;
+   for(i=1; i<=4; i++){
+     char zTab[24];
+     sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i);
+@@ -93209,7 +106205,7 @@
+   if( pTab->tabFlags & TF_Autoincrement ){
+     sqlite3NestedParse(pParse,
+       "DELETE FROM %Q.sqlite_sequence WHERE name=%Q",
+-      pDb->zName, pTab->zName
++      pDb->zDbSName, pTab->zName
+     );
+   }
+ #endif
+@@ -93223,7 +106219,7 @@
+   */
+   sqlite3NestedParse(pParse, 
+       "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
+-      pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
++      pDb->zDbSName, MASTER_NAME, pTab->zName);
+   if( !isView && !IsVirtual(pTab) ){
+     destroyTable(pParse, pTab);
+   }
+@@ -93256,6 +106252,7 @@
+   assert( pName->nSrc==1 );
+   if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
+   if( noErr ) db->suppressErr++;
++  assert( isView==0 || isView==LOCATE_VIEW );
+   pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
+   if( noErr ) db->suppressErr--;
+ 
+@@ -93276,7 +106273,7 @@
+   {
+     int code;
+     const char *zTab = SCHEMA_TABLE(iDb);
+-    const char *zDb = db->aDb[iDb].zName;
++    const char *zDb = db->aDb[iDb].zDbSName;
+     const char *zArg2 = 0;
+     if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
+       goto exit_drop_table;
+@@ -93451,7 +106448,7 @@
+       pFKey->zTo, (void *)pFKey
+   );
+   if( pNextTo==pFKey ){
+-    db->mallocFailed = 1;
++    sqlite3OomFault(db);
+     goto fk_end;
+   }
+   if( pNextTo ){
+@@ -93517,7 +106514,7 @@
+ 
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+   if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
+-      db->aDb[iDb].zName ) ){
++      db->aDb[iDb].zDbSName ) ){
+     return;
+   }
+ #endif
+@@ -93533,6 +106530,7 @@
+     tnum = pIndex->tnum;
+   }
+   pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
++  assert( pKey!=0 || db->mallocFailed || pParse->nErr );
+ 
+   /* Open the sorter cursor if we are to use one. */
+   iSorter = pParse->nTab++;
+@@ -93556,10 +106554,9 @@
+   sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
+ 
+   addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
+-  assert( pKey!=0 || db->mallocFailed || pParse->nErr );
+-  if( IsUniqueIndex(pIndex) && pKey!=0 ){
++  if( IsUniqueIndex(pIndex) ){
+     int j2 = sqlite3VdbeCurrentAddr(v) + 3;
+-    sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
++    sqlite3VdbeGoto(v, j2);
+     addr2 = sqlite3VdbeCurrentAddr(v);
+     sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
+                          pIndex->nKeyCol); VdbeCoverage(v);
+@@ -93569,7 +106566,7 @@
+   }
+   sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
+   sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1);
+-  sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
++  sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
+   sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+   sqlite3ReleaseTempReg(pParse, regRecord);
+   sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
+@@ -93604,7 +106601,7 @@
+   p = sqlite3DbMallocZero(db, nByte + nExtra);
+   if( p ){
+     char *pExtra = ((char*)p)+ROUND8(sizeof(Index));
+-    p->azColl = (char**)pExtra;       pExtra += ROUND8(sizeof(char*)*nCol);
++    p->azColl = (const char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
+     p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1);
+     p->aiColumn = (i16*)pExtra;       pExtra += sizeof(i16)*nCol;
+     p->aSortOrder = (u8*)pExtra;
+@@ -93626,12 +106623,8 @@
+ ** pList is a list of columns to be indexed.  pList will be NULL if this
+ ** is a primary key or unique-constraint on the most recent column added
+ ** to the table currently under construction.  
+-**
+-** If the index is created successfully, return a pointer to the new Index
+-** structure. This is used by sqlite3AddPrimaryKey() to mark the index
+-** as the tables primary key (Index.idxType==SQLITE_IDXTYPE_PRIMARYKEY)
+ */
+-SQLITE_PRIVATE Index *sqlite3CreateIndex(
++SQLITE_PRIVATE void sqlite3CreateIndex(
+   Parse *pParse,     /* All information about this parse */
+   Token *pName1,     /* First part of index name. May be NULL */
+   Token *pName2,     /* Second part of index name. May be NULL */
+@@ -93641,9 +106634,9 @@
+   Token *pStart,     /* The CREATE token that begins this statement */
+   Expr *pPIWhere,    /* WHERE clause for partial indices */
+   int sortOrder,     /* Sort order of primary key when pList==NULL */
+-  int ifNotExist     /* Omit error if index already exists */
++  int ifNotExist,    /* Omit error if index already exists */
++  u8 idxType         /* The index type */
+ ){
+-  Index *pRet = 0;     /* Pointer to return */
+   Table *pTab = 0;     /* Table to be indexed */
+   Index *pIndex = 0;   /* The index to be created */
+   char *zName = 0;     /* Name of the index */
+@@ -93656,13 +106649,15 @@
+   int iDb;             /* Index of the database that is being written */
+   Token *pName = 0;    /* Unqualified name of the index to create */
+   struct ExprList_item *pListItem; /* For looping over pList */
+-  const Column *pTabCol;           /* A column in the table */
+   int nExtra = 0;                  /* Space allocated for zExtra[] */
+   int nExtraCol;                   /* Number of extra columns needed */
+   char *zExtra = 0;                /* Extra space after the Index object */
+   Index *pPk = 0;      /* PRIMARY KEY index for WITHOUT ROWID tables */
+ 
+-  if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){
++  if( db->mallocFailed || pParse->nErr>0 ){
++    goto exit_create_index;
++  }
++  if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){
+     goto exit_create_index;
+   }
+   if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
+@@ -93771,7 +106766,7 @@
+         goto exit_create_index;
+       }
+     }
+-    if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
++    if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){
+       if( !ifNotExist ){
+         sqlite3ErrorMsg(pParse, "index %s already exists", zName);
+       }else{
+@@ -93788,13 +106783,20 @@
+     if( zName==0 ){
+       goto exit_create_index;
+     }
 +
-+  ctx->pBt = pDb->pBt; /* assign pointer to database btree structure */
++    /* Automatic index names generated from within sqlite3_declare_vtab()
++    ** must have names that are distinct from normal automatic index names.
++    ** The following statement converts "sqlite3_autoindex..." into
++    ** "sqlite3_butoindex..." in order to make the names distinct.
++    ** The "vtab_err.test" test demonstrates the need of this statement. */
++    if( IN_DECLARE_VTAB ) zName[7]++;
+   }
+ 
+   /* Check for authorization to create an index.
+   */
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+   {
+-    const char *zDb = pDb->zName;
++    const char *zDb = pDb->zDbSName;
+     if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
+       goto exit_create_index;
+     }
+@@ -93811,11 +106813,15 @@
+   ** So create a fake list to simulate this.
+   */
+   if( pList==0 ){
+-    pList = sqlite3ExprListAppend(pParse, 0, 0);
++    Token prevCol;
++    sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName);
++    pList = sqlite3ExprListAppend(pParse, 0,
++              sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
+     if( pList==0 ) goto exit_create_index;
+-    pList->a[0].zName = sqlite3DbStrDup(pParse->db,
+-                                        pTab->aCol[pTab->nCol-1].zName);
+-    pList->a[0].sortOrder = (u8)sortOrder;
++    assert( pList->nExpr==1 );
++    sqlite3ExprListSetSortOrder(pList, sortOrder);
++  }else{
++    sqlite3ExprListCheckLength(pParse, pList, "index");
+   }
+ 
+   /* Figure out how many bytes of space are required to store explicitly
+@@ -93823,8 +106829,8 @@
+   */
+   for(i=0; i<pList->nExpr; i++){
+     Expr *pExpr = pList->a[i].pExpr;
+-    if( pExpr ){
+-      assert( pExpr->op==TK_COLLATE );
++    assert( pExpr!=0 );
++    if( pExpr->op==TK_COLLATE ){
+       nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken));
+     }
+   }
+@@ -93847,7 +106853,7 @@
+   pIndex->pTable = pTab;
+   pIndex->onError = (u8)onError;
+   pIndex->uniqNotNull = onError!=OE_None;
+-  pIndex->idxType = pName ? SQLITE_IDXTYPE_APPDEF : SQLITE_IDXTYPE_UNIQUE;
++  pIndex->idxType = idxType;
+   pIndex->pSchema = db->aDb[iDb].pSchema;
+   pIndex->nKeyCol = pList->nExpr;
+   if( pPIWhere ){
+@@ -93865,35 +106871,54 @@
+     sortOrderMask = 0;    /* Ignore DESC */
+   }
+ 
+-  /* Scan the names of the columns of the table to be indexed and
+-  ** load the column indices into the Index structure.  Report an error
+-  ** if any column is not found.
+-  **
+-  ** TODO:  Add a test to make sure that the same column is not named
+-  ** more than once within the same index.  Only the first instance of
+-  ** the column will ever be used by the optimizer.  Note that using the
+-  ** same column more than once cannot be an error because that would 
+-  ** break backwards compatibility - it needs to be a warning.
++  /* Analyze the list of expressions that form the terms of the index and
++  ** report any errors.  In the common case where the expression is exactly
++  ** a table column, store that column in aiColumn[].  For general expressions,
++  ** populate pIndex->aColExpr and store XN_EXPR (-2) in aiColumn[].
++  **
++  ** TODO: Issue a warning if two or more columns of the index are identical.
++  ** TODO: Issue a warning if the table primary key is used as part of the
++  ** index key.
+   */
+   for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
+-    const char *zColName = pListItem->zName;
+-    int requestedSortOrder;
+-    char *zColl;                   /* Collation sequence name */
+-
+-    for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
+-      if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
+-    }
+-    if( j>=pTab->nCol ){
+-      sqlite3ErrorMsg(pParse, "table %s has no column named %s",
+-        pTab->zName, zColName);
+-      pParse->checkSchema = 1;
+-      goto exit_create_index;
++    Expr *pCExpr;                  /* The i-th index expression */
++    int requestedSortOrder;        /* ASC or DESC on the i-th expression */
++    const char *zColl;             /* Collation sequence name */
++
++    sqlite3StringToId(pListItem->pExpr);
++    sqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0);
++    if( pParse->nErr ) goto exit_create_index;
++    pCExpr = sqlite3ExprSkipCollate(pListItem->pExpr);
++    if( pCExpr->op!=TK_COLUMN ){
++      if( pTab==pParse->pNewTable ){
++        sqlite3ErrorMsg(pParse, "expressions prohibited in PRIMARY KEY and "
++                                "UNIQUE constraints");
++        goto exit_create_index;
++      }
++      if( pIndex->aColExpr==0 ){
++        ExprList *pCopy = sqlite3ExprListDup(db, pList, 0);
++        pIndex->aColExpr = pCopy;
++        if( !db->mallocFailed ){
++          assert( pCopy!=0 );
++          pListItem = &pCopy->a[i];
++        }
++      }
++      j = XN_EXPR;
++      pIndex->aiColumn[i] = XN_EXPR;
++      pIndex->uniqNotNull = 0;
++    }else{
++      j = pCExpr->iColumn;
++      assert( j<=0x7fff );
++      if( j<0 ){
++        j = pTab->iPKey;
++      }else if( pTab->aCol[j].notNull==0 ){
++        pIndex->uniqNotNull = 0;
++      }
++      pIndex->aiColumn[i] = (i16)j;
+     }
+-    assert( j<=0x7fff );
+-    pIndex->aiColumn[i] = (i16)j;
+-    if( pListItem->pExpr ){
++    zColl = 0;
++    if( pListItem->pExpr->op==TK_COLLATE ){
+       int nColl;
+-      assert( pListItem->pExpr->op==TK_COLLATE );
+       zColl = pListItem->pExpr->u.zToken;
+       nColl = sqlite3Strlen30(zColl) + 1;
+       assert( nExtra>=nColl );
+@@ -93901,21 +106926,26 @@
+       zColl = zExtra;
+       zExtra += nColl;
+       nExtra -= nColl;
+-    }else{
++    }else if( j>=0 ){
+       zColl = pTab->aCol[j].zColl;
+-      if( !zColl ) zColl = "BINARY";
+     }
++    if( !zColl ) zColl = sqlite3StrBINARY;
+     if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
+       goto exit_create_index;
+     }
+     pIndex->azColl[i] = zColl;
+     requestedSortOrder = pListItem->sortOrder & sortOrderMask;
+     pIndex->aSortOrder[i] = (u8)requestedSortOrder;
+-    if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0;
+   }
 +
-+  /* allocate space for salt data. Then read the first 16 bytes 
-+       directly off the database file. This is the salt for the
-+       key derivation function. If we get a short read allocate
-+       a new random salt value */
-+  ctx->kdf_salt_sz = FILE_HEADER_SZ;
-+  ctx->kdf_salt = sqlcipher_malloc(ctx->kdf_salt_sz);
-+  if(ctx->kdf_salt == NULL) return SQLITE_NOMEM;
++  /* Append the table key to the end of the index.  For WITHOUT ROWID
++  ** tables (when pPk!=0) this will be the declared PRIMARY KEY.  For
++  ** normal tables (when pPk==0) this will be the rowid.
++  */
+   if( pPk ){
+     for(j=0; j<pPk->nKeyCol; j++){
+       int x = pPk->aiColumn[j];
++      assert( x>=0 );
+       if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
+         pIndex->nColumn--; 
+       }else{
+@@ -93927,12 +106957,26 @@
+     }
+     assert( i==pIndex->nColumn );
+   }else{
+-    pIndex->aiColumn[i] = -1;
+-    pIndex->azColl[i] = "BINARY";
++    pIndex->aiColumn[i] = XN_ROWID;
++    pIndex->azColl[i] = sqlite3StrBINARY;
+   }
+   sqlite3DefaultRowEst(pIndex);
+   if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
+ 
++  /* If this index contains every column of its table, then mark
++  ** it as a covering index */
++  assert( HasRowid(pTab) 
++      || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 );
++  if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
++    pIndex->isCovering = 1;
++    for(j=0; j<pTab->nCol; j++){
++      if( j==pTab->iPKey ) continue;
++      if( sqlite3ColumnOfIndex(pIndex,j)>=0 ) continue;
++      pIndex->isCovering = 0;
++      break;
++    }
++  }
 +
-+  /* allocate space for separate hmac salt data. We want the
-+     HMAC derivation salt to be different than the encryption
-+     key derivation salt */
-+  ctx->hmac_kdf_salt = sqlcipher_malloc(ctx->kdf_salt_sz);
-+  if(ctx->hmac_kdf_salt == NULL) return SQLITE_NOMEM;
+   if( pTab==pParse->pNewTable ){
+     /* This routine has been called to create an automatic index as a
+     ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
+@@ -93966,10 +107010,11 @@
+       for(k=0; k<pIdx->nKeyCol; k++){
+         const char *z1;
+         const char *z2;
++        assert( pIdx->aiColumn[k]>=0 );
+         if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
+         z1 = pIdx->azColl[k];
+         z2 = pIndex->azColl[k];
+-        if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
++        if( sqlite3StrICmp(z1, z2) ) break;
+       }
+       if( k==pIdx->nKeyCol ){
+         if( pIdx->onError!=pIndex->onError ){
+@@ -93988,7 +107033,7 @@
+             pIdx->onError = pIndex->onError;
+           }
+         }
+-        pRet = pIdx;
++        if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType;
+         goto exit_create_index;
+       }
+     }
+@@ -93997,14 +107042,16 @@
+   /* Link the new Index structure to its table and to the other
+   ** in-memory database structures. 
+   */
++  assert( pParse->nErr==0 );
+   if( db->init.busy ){
+     Index *p;
++    assert( !IN_DECLARE_VTAB );
+     assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
+     p = sqlite3HashInsert(&pIndex->pSchema->idxHash, 
+                           pIndex->zName, pIndex);
+     if( p ){
+       assert( p==pIndex );  /* Malloc must have failed */
+-      db->mallocFailed = 1;
++      sqlite3OomFault(db);
+       goto exit_create_index;
+     }
+     db->flags |= SQLITE_InternChanges;
+@@ -94026,7 +107073,7 @@
+   ** has just been created, it contains no data and the index initialization
+   ** step can be skipped.
+   */
+-  else if( pParse->nErr==0 && (HasRowid(pTab) || pTblName!=0) ){
++  else if( HasRowid(pTab) || pTblName!=0 ){
+     Vdbe *v;
+     char *zStmt;
+     int iMem = ++pParse->nMem;
+@@ -94034,10 +107081,15 @@
+     v = sqlite3GetVdbe(pParse);
+     if( v==0 ) goto exit_create_index;
+ 
+-
+-    /* Create the rootpage for the index
+-    */
+     sqlite3BeginWriteOperation(pParse, 1, iDb);
++
++    /* Create the rootpage for the index using CreateIndex. But before
++    ** doing so, code a Noop instruction and store its address in 
++    ** Index.tnum. This is required in case this index is actually a 
++    ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In 
++    ** that case the convertToWithoutRowidTable() routine will replace
++    ** the Noop with a Goto to jump over the VDBE code generated below. */
++    pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop);
+     sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);
+ 
+     /* Gather the complete text of the CREATE INDEX statement into
+@@ -94059,7 +107111,7 @@
+     */
+     sqlite3NestedParse(pParse, 
+         "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
+-        db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
++        db->aDb[iDb].zDbSName, MASTER_NAME,
+         pIndex->zName,
+         pTab->zName,
+         iMem,
+@@ -94075,8 +107127,10 @@
+       sqlite3ChangeCookie(pParse, iDb);
+       sqlite3VdbeAddParseSchemaOp(v, iDb,
+          sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
+-      sqlite3VdbeAddOp1(v, OP_Expire, 0);
++      sqlite3VdbeAddOp0(v, OP_Expire);
+     }
 +
++    sqlite3VdbeJumpHere(v, pIndex->tnum);
+   }
+ 
+   /* When adding an index to the list of indices for a table, make
+@@ -94098,7 +107152,6 @@
+       pIndex->pNext = pOther->pNext;
+       pOther->pNext = pIndex;
+     }
+-    pRet = pIndex;
+     pIndex = 0;
+   }
+ 
+@@ -94109,7 +107162,6 @@
+   sqlite3ExprListDelete(db, pList);
+   sqlite3SrcListDelete(db, pTblName);
+   sqlite3DbFree(db, zName);
+-  return pRet;
+ }
+ 
+ /*
+@@ -94137,11 +107189,15 @@
+   int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol);
+   int i;
+ 
++  /* Indexes with default row estimates should not have stat1 data */
++  assert( !pIdx->hasStat1 );
++
+   /* Set the first entry (number of rows in the index) to the estimated 
+-  ** number of rows in the table. Or 10, if the estimated number of rows 
+-  ** in the table is less than that.  */
++  ** number of rows in the table, or half the number of rows in the table
++  ** for a partial index.   But do not let the estimate drop below 10. */
+   a[0] = pIdx->pTable->nRowLogEst;
+-  if( a[0]<33 ) a[0] = 33;        assert( 33==sqlite3LogEst(10) );
++  if( pIdx->pPartIdxWhere!=0 ) a[0] -= 10;  assert( 10==sqlite3LogEst(2) );
++  if( a[0]<33 ) a[0] = 33;                  assert( 33==sqlite3LogEst(10) );
+ 
+   /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is
+   ** 6 and each subsequent value (if any) is 5.  */
+@@ -94192,7 +107248,7 @@
+   {
+     int code = SQLITE_DROP_INDEX;
+     Table *pTab = pIndex->pTable;
+-    const char *zDb = db->aDb[iDb].zName;
++    const char *zDb = db->aDb[iDb].zDbSName;
+     const char *zTab = SCHEMA_TABLE(iDb);
+     if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
+       goto exit_drop_index;
+@@ -94210,7 +107266,7 @@
+     sqlite3BeginWriteOperation(pParse, 1, iDb);
+     sqlite3NestedParse(pParse,
+        "DELETE FROM %Q.%s WHERE name=%Q AND type='index'",
+-       db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName
++       db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName
+     );
+     sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
+     sqlite3ChangeCookie(pParse, iDb);
+@@ -94301,7 +107357,7 @@
+     sqlite3DbFree(db, pList->a[i].zName);
+   }
+   sqlite3DbFree(db, pList->a);
+-  sqlite3DbFree(db, pList);
++  sqlite3DbFreeNN(db, pList);
+ }
+ 
+ /*
+@@ -94353,7 +107409,7 @@
+   /* Allocate additional space if needed */
+   if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){
+     SrcList *pNew;
+-    int nAlloc = pSrc->nSrc+nExtra;
++    int nAlloc = pSrc->nSrc*2+nExtra;
+     int nGot;
+     pNew = sqlite3DbRealloc(db, pSrc,
+                sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) );
+@@ -94426,12 +107482,17 @@
+ ){
+   struct SrcList_item *pItem;
+   assert( pDatabase==0 || pTable!=0 );  /* Cannot have C without B */
++  assert( db!=0 );
+   if( pList==0 ){
+-    pList = sqlite3DbMallocZero(db, sizeof(SrcList) );
++    pList = sqlite3DbMallocRawNN(db, sizeof(SrcList) );
+     if( pList==0 ) return 0;
+     pList->nAlloc = 1;
++    pList->nSrc = 1;
++    memset(&pList->a[0], 0, sizeof(pList->a[0]));
++    pList->a[0].iCursor = -1;
++  }else{
++    pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc);
+   }
+-  pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc);
+   if( db->mallocFailed ){
+     sqlite3SrcListDelete(db, pList);
+     return 0;
+@@ -94441,12 +107502,12 @@
+     pDatabase = 0;
+   }
+   if( pDatabase ){
+-    Token *pTemp = pDatabase;
+-    pDatabase = pTable;
+-    pTable = pTemp;
++    pItem->zName = sqlite3NameFromToken(db, pDatabase);
++    pItem->zDatabase = sqlite3NameFromToken(db, pTable);
++  }else{
++    pItem->zName = sqlite3NameFromToken(db, pTable);
++    pItem->zDatabase = 0;
+   }
+-  pItem->zName = sqlite3NameFromToken(db, pTable);
+-  pItem->zDatabase = sqlite3NameFromToken(db, pDatabase);
+   return pList;
+ }
+ 
+@@ -94479,13 +107540,14 @@
+     sqlite3DbFree(db, pItem->zDatabase);
+     sqlite3DbFree(db, pItem->zName);
+     sqlite3DbFree(db, pItem->zAlias);
+-    sqlite3DbFree(db, pItem->zIndex);
++    if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
++    if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
+     sqlite3DeleteTable(db, pItem->pTab);
+     sqlite3SelectDelete(db, pItem->pSelect);
+     sqlite3ExprDelete(db, pItem->pOn);
+     sqlite3IdListDelete(db, pItem->pUsing);
+   }
+-  sqlite3DbFree(db, pList);
++  sqlite3DbFreeNN(db, pList);
+ }
+ 
+ /*
+@@ -94552,18 +107614,38 @@
+   assert( pIndexedBy!=0 );
+   if( p && ALWAYS(p->nSrc>0) ){
+     struct SrcList_item *pItem = &p->a[p->nSrc-1];
+-    assert( pItem->notIndexed==0 && pItem->zIndex==0 );
++    assert( pItem->fg.notIndexed==0 );
++    assert( pItem->fg.isIndexedBy==0 );
++    assert( pItem->fg.isTabFunc==0 );
+     if( pIndexedBy->n==1 && !pIndexedBy->z ){
+       /* A "NOT INDEXED" clause was supplied. See parse.y 
+       ** construct "indexed_opt" for details. */
+-      pItem->notIndexed = 1;
++      pItem->fg.notIndexed = 1;
+     }else{
+-      pItem->zIndex = sqlite3NameFromToken(pParse->db, pIndexedBy);
++      pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy);
++      pItem->fg.isIndexedBy = (pItem->u1.zIndexedBy!=0);
+     }
+   }
+ }
+ 
+ /*
++** Add the list of function arguments to the SrcList entry for a
++** table-valued-function.
++*/
++SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){
++  if( p ){
++    struct SrcList_item *pItem = &p->a[p->nSrc-1];
++    assert( pItem->fg.notIndexed==0 );
++    assert( pItem->fg.isIndexedBy==0 );
++    assert( pItem->fg.isTabFunc==0 );
++    pItem->u1.pFuncArg = pList;
++    pItem->fg.isTabFunc = 1;
++  }else{
++    sqlite3ExprListDelete(pParse->db, pList);
++  }
++}
 +
-+  /*
-+     Always overwrite page size and set to the default because the first page of the database
-+     in encrypted and thus sqlite can't effectively determine the pagesize. this causes an issue in 
-+     cases where bytes 16 & 17 of the page header are a power of 2 as reported by John Lehman
++/*
+ ** When building up a FROM clause in the parser, the join operator
+ ** is initially attached to the left operand.  But the code generator
+ ** expects the join operator to be on the right operand.  This routine
+@@ -94582,14 +107664,14 @@
+   if( p ){
+     int i;
+     for(i=p->nSrc-1; i>0; i--){
+-      p->a[i].jointype = p->a[i-1].jointype;
++      p->a[i].fg.jointype = p->a[i-1].fg.jointype;
+     }
+-    p->a[0].jointype = 0;
++    p->a[0].fg.jointype = 0;
+   }
+ }
+ 
+ /*
+-** Begin a transaction
++** Generate VDBE code for a BEGIN statement.
+ */
+ SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){
+   sqlite3 *db;
+@@ -94599,7 +107681,6 @@
+   assert( pParse!=0 );
+   db = pParse->db;
+   assert( db!=0 );
+-/*  if( db->aDb[0].pBt==0 ) return; */
+   if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){
+     return;
+   }
+@@ -94611,40 +107692,29 @@
+       sqlite3VdbeUsesBtree(v, i);
+     }
+   }
+-  sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0);
+-}
+-
+-/*
+-** Commit a transaction
+-*/
+-SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){
+-  Vdbe *v;
+-
+-  assert( pParse!=0 );
+-  assert( pParse->db!=0 );
+-  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
+-    return;
+-  }
+-  v = sqlite3GetVdbe(pParse);
+-  if( v ){
+-    sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0);
+-  }
++  sqlite3VdbeAddOp0(v, OP_AutoCommit);
+ }
+ 
+ /*
+-** Rollback a transaction
++** Generate VDBE code for a COMMIT or ROLLBACK statement.
++** Code for ROLLBACK is generated if eType==TK_ROLLBACK.  Otherwise
++** code is generated for a COMMIT.
+ */
+-SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){
++SQLITE_PRIVATE void sqlite3EndTransaction(Parse *pParse, int eType){
+   Vdbe *v;
++  int isRollback;
+ 
+   assert( pParse!=0 );
+   assert( pParse->db!=0 );
+-  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
++  assert( eType==TK_COMMIT || eType==TK_END || eType==TK_ROLLBACK );
++  isRollback = eType==TK_ROLLBACK;
++  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, 
++       isRollback ? "ROLLBACK" : "COMMIT", 0, 0) ){
+     return;
+   }
+   v = sqlite3GetVdbe(pParse);
+   if( v ){
+-    sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1);
++    sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, isRollback);
+   }
+ }
+ 
+@@ -94694,7 +107764,7 @@
+     db->aDb[1].pBt = pBt;
+     assert( db->aDb[1].pSchema );
+     if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
+-      db->mallocFailed = 1;
++      sqlite3OomFault(db);
+       return 1;
+     }
+   }
+@@ -94709,15 +107779,13 @@
+ */
+ SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
+   Parse *pToplevel = sqlite3ParseToplevel(pParse);
+-  sqlite3 *db = pToplevel->db;
+ 
+-  assert( iDb>=0 && iDb<db->nDb );
+-  assert( db->aDb[iDb].pBt!=0 || iDb==1 );
++  assert( iDb>=0 && iDb<pParse->db->nDb );
++  assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 );
+   assert( iDb<SQLITE_MAX_ATTACHED+2 );
+-  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
++  assert( sqlite3SchemaMutexHeld(pParse->db, iDb, 0) );
+   if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
+     DbMaskSet(pToplevel->cookieMask, iDb);
+-    pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
+     if( !OMIT_TEMPDB && iDb==1 ){
+       sqlite3OpenTempDatabase(pToplevel);
+     }
+@@ -94733,7 +107801,7 @@
+   int i;
+   for(i=0; i<db->nDb; i++){
+     Db *pDb = &db->aDb[i];
+-    if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){
++    if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zDbSName)) ){
+       sqlite3CodeVerifySchema(pParse, i);
+     }
+   }
+@@ -94811,7 +107879,7 @@
+     sqlite3MayAbort(pParse);
+   }
+   sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
+-  if( p5Errmsg ) sqlite3VdbeChangeP5(v, p5Errmsg);
++  sqlite3VdbeChangeP5(v, p5Errmsg);
+ }
+ 
+ /*
+@@ -94828,12 +107896,18 @@
+   Table *pTab = pIdx->pTable;
+ 
+   sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
+-  for(j=0; j<pIdx->nKeyCol; j++){
+-    char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
+-    if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
+-    sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
+-    sqlite3StrAccumAppend(&errMsg, ".", 1);
+-    sqlite3StrAccumAppendAll(&errMsg, zCol);
++  if( pIdx->aColExpr ){
++    sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);
++  }else{
++    for(j=0; j<pIdx->nKeyCol; j++){
++      char *zCol;
++      assert( pIdx->aiColumn[j]>=0 );
++      zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
++      if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
++      sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
++      sqlite3StrAccumAppend(&errMsg, ".", 1);
++      sqlite3StrAccumAppendAll(&errMsg, zCol);
++    }
+   }
+   zErr = sqlite3StrAccumFinish(&errMsg);
+   sqlite3HaltConstraint(pParse, 
+@@ -94976,7 +108050,7 @@
+   if( iDb<0 ) return;
+   z = sqlite3NameFromToken(db, pObjName);
+   if( z==0 ) return;
+-  zDb = db->aDb[iDb].zName;
++  zDb = db->aDb[iDb].zDbSName;
+   pTab = sqlite3FindTable(db, z, zDb);
+   if( pTab ){
+     reindexTable(pParse, pTab, 0);
+@@ -94997,10 +108071,6 @@
+ /*
+ ** Return a KeyInfo structure that is appropriate for the given Index.
+ **
+-** The KeyInfo structure for an index is cached in the Index object.
+-** So there might be multiple references to the returned pointer.  The
+-** caller should not try to modify the KeyInfo object.
+-**
+ ** The caller should invoke sqlite3KeyInfoUnref() on the returned object
+ ** when it has finished using it.
+ */
+@@ -95018,9 +108088,8 @@
+   if( pKey ){
+     assert( sqlite3KeyInfoIsWriteable(pKey) );
+     for(i=0; i<nCol; i++){
+-      char *zColl = pIdx->azColl[i];
+-      assert( zColl!=0 );
+-      pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 :
++      const char *zColl = pIdx->azColl[i];
++      pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 :
+                         sqlite3LocateCollSeq(pParse, zColl);
+       pKey->aSortOrder[i] = pIdx->aSortOrder[i];
+     }
+@@ -95066,10 +108135,9 @@
+   }else{
+     pNew = sqlite3DbMallocZero(db, sizeof(*pWith));
+   }
+-  assert( zName!=0 || pNew==0 );
+-  assert( db->mallocFailed==0 || pNew==0 );
++  assert( (pNew!=0 && zName!=0) || db->mallocFailed );
+ 
+-  if( pNew==0 ){
++  if( db->mallocFailed ){
+     sqlite3ExprListDelete(db, pArglist);
+     sqlite3SelectDelete(db, pQuery);
+     sqlite3DbFree(db, zName);
+@@ -95078,7 +108146,7 @@
+     pNew->a[pNew->nCte].pSelect = pQuery;
+     pNew->a[pNew->nCte].pCols = pArglist;
+     pNew->a[pNew->nCte].zName = zName;
+-    pNew->a[pNew->nCte].zErr = 0;
++    pNew->a[pNew->nCte].zCteErr = 0;
+     pNew->nCte++;
+   }
+ 
+@@ -95120,6 +108188,7 @@
+ ** of user defined functions and collation sequences.
+ */
+ 
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** Invoke the 'collation needed' callback to request a collation sequence
+@@ -95226,7 +108295,7 @@
+ ** from the main database is substituted, if one is available.
+ */
+ SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
+-  if( pColl ){
++  if( pColl && pColl->xCmp==0 ){
+     const char *zName = pColl->zName;
+     sqlite3 *db = pParse->db;
+     CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName);
+@@ -95262,8 +108331,8 @@
+   pColl = sqlite3HashFind(&db->aCollSeq, zName);
+ 
+   if( 0==pColl && create ){
+-    int nName = sqlite3Strlen30(zName);
+-    pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1);
++    int nName = sqlite3Strlen30(zName) + 1;
++    pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName);
+     if( pColl ){
+       CollSeq *pDel = 0;
+       pColl[0].zName = (char*)&pColl[3];
+@@ -95273,7 +108342,6 @@
+       pColl[2].zName = (char*)&pColl[3];
+       pColl[2].enc = SQLITE_UTF16BE;
+       memcpy(pColl[0].zName, zName, nName);
+-      pColl[0].zName[nName] = 0;
+       pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, pColl);
+ 
+       /* If a malloc() failure occurred in sqlite3HashInsert(), it will 
+@@ -95282,7 +108350,7 @@
+       */
+       assert( pDel==0 || pDel==pColl );
+       if( pDel!=0 ){
+-        db->mallocFailed = 1;
++        sqlite3OomFault(db);
+         sqlite3DbFree(db, pDel);
+         pColl = 0;
+       }
+@@ -95348,8 +108416,8 @@
+ ** 5: UTF16 byte order conversion required - argument count matches exactly
+ ** 6: Perfect match:  encoding and argument count match exactly.
+ **
+-** If nArg==(-2) then any function with a non-null xStep or xFunc is
+-** a perfect match and any function with both xStep and xFunc NULL is
++** If nArg==(-2) then any function with a non-null xSFunc is
++** a perfect match and any function with xSFunc NULL is
+ ** a non-match.
+ */
+ #define FUNC_PERFECT_MATCH 6  /* The score for a perfect match */
+@@ -95361,7 +108429,7 @@
+   int match;
+ 
+   /* nArg of -2 is a special case */
+-  if( nArg==(-2) ) return (p->xFunc==0 && p->xStep==0) ? 0 : FUNC_PERFECT_MATCH;
++  if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH;
+ 
+   /* Wrong number of arguments means "no match" */
+   if( p->nArg!=nArg && p->nArg>=0 ) return 0;
+@@ -95389,14 +108457,12 @@
+ ** a pointer to the matching FuncDef if found, or 0 if there is no match.
+ */
+ static FuncDef *functionSearch(
+-  FuncDefHash *pHash,  /* Hash table to search */
+   int h,               /* Hash of the name */
+-  const char *zFunc,   /* Name of function */
+-  int nFunc            /* Number of bytes in zFunc */
++  const char *zFunc    /* Name of function */
+ ){
+   FuncDef *p;
+-  for(p=pHash->a[h]; p; p=p->pHash){
+-    if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){
++  for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
++    if( sqlite3StrICmp(p->zName, zFunc)==0 ){
+       return p;
+     }
+   }
+@@ -95406,23 +108472,27 @@
+ /*
+ ** Insert a new FuncDef into a FuncDefHash hash table.
+ */
+-SQLITE_PRIVATE void sqlite3FuncDefInsert(
+-  FuncDefHash *pHash,  /* The hash table into which to insert */
+-  FuncDef *pDef        /* The function definition to insert */
+-){
+-  FuncDef *pOther;
+-  int nName = sqlite3Strlen30(pDef->zName);
+-  u8 c1 = (u8)pDef->zName[0];
+-  int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
+-  pOther = functionSearch(pHash, h, pDef->zName, nName);
+-  if( pOther ){
+-    assert( pOther!=pDef && pOther->pNext!=pDef );
+-    pDef->pNext = pOther->pNext;
+-    pOther->pNext = pDef;
+-  }else{
+-    pDef->pNext = 0;
+-    pDef->pHash = pHash->a[h];
+-    pHash->a[h] = pDef;
++SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
++  FuncDef *aDef,      /* List of global functions to be inserted */
++  int nDef            /* Length of the apDef[] list */
++){
++  int i;
++  for(i=0; i<nDef; i++){
++    FuncDef *pOther;
++    const char *zName = aDef[i].zName;
++    int nName = sqlite3Strlen30(zName);
++    int h = (zName[0] + nName) % SQLITE_FUNC_HASH_SZ;
++    assert( zName[0]>='a' && zName[0]<='z' );
++    pOther = functionSearch(h, zName);
++    if( pOther ){
++      assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
++      aDef[i].pNext = pOther->pNext;
++      pOther->pNext = &aDef[i];
++    }else{
++      aDef[i].pNext = 0;
++      aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h];
++      sqlite3BuiltinFunctions.a[h] = &aDef[i];
++    }
+   }
+ }
+   
+@@ -95439,7 +108509,7 @@
+ ** no matching function previously existed.
+ **
+ ** If nArg is -2, then the first valid function found is returned.  A
+-** function is valid if either xFunc or xStep is non-zero.  The nArg==(-2)
++** function is valid if xSFunc is non-zero.  The nArg==(-2)
+ ** case is used to see if zName is a valid function name for some number
+ ** of arguments.  If nArg is -2, then createFlag must be 0.
+ **
+@@ -95449,8 +108519,7 @@
+ */
+ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
+   sqlite3 *db,       /* An open database */
+-  const char *zName, /* Name of the function.  Not null-terminated */
+-  int nName,         /* Number of characters in the name */
++  const char *zName, /* Name of the function.  zero-terminated */
+   int nArg,          /* Number of arguments.  -1 means any number */
+   u8 enc,            /* Preferred text encoding */
+   u8 createFlag      /* Create new entry if true and does not otherwise exist */
+@@ -95459,14 +108528,15 @@
+   FuncDef *pBest = 0; /* Best match found so far */
+   int bestScore = 0;  /* Score of best match */
+   int h;              /* Hash value */
++  int nName;          /* Length of the name */
+ 
+   assert( nArg>=(-2) );
+   assert( nArg>=(-1) || createFlag==0 );
+-  h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
++  nName = sqlite3Strlen30(zName);
+ 
+   /* First search for a match amongst the application-defined functions.
+   */
+-  p = functionSearch(&db->aFunc, h, zName, nName);
++  p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName);
+   while( p ){
+     int score = matchQuality(p, nArg, enc);
+     if( score>bestScore ){
+@@ -95489,9 +108559,9 @@
+   ** So we must not search for built-ins when creating a new function.
+   */ 
+   if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
+-    FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
+     bestScore = 0;
+-    p = functionSearch(pHash, h, zName, nName);
++    h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
++    p = functionSearch(h, zName);
+     while( p ){
+       int score = matchQuality(p, nArg, enc);
+       if( score>bestScore ){
+@@ -95508,15 +108578,22 @@
+   */
+   if( createFlag && bestScore<FUNC_PERFECT_MATCH && 
+       (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
+-    pBest->zName = (char *)&pBest[1];
++    FuncDef *pOther;
++    pBest->zName = (const char*)&pBest[1];
+     pBest->nArg = (u16)nArg;
+     pBest->funcFlags = enc;
+-    memcpy(pBest->zName, zName, nName);
+-    pBest->zName[nName] = 0;
+-    sqlite3FuncDefInsert(&db->aFunc, pBest);
++    memcpy((char*)&pBest[1], zName, nName+1);
++    pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
++    if( pOther==pBest ){
++      sqlite3DbFree(db, pBest);
++      sqlite3OomFault(db);
++      return 0;
++    }else{
++      pBest->pNext = pOther;
++    }
+   }
+ 
+-  if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
++  if( pBest && (pBest->xSFunc || createFlag) ){
+     return pBest;
+   }
+   return 0;
+@@ -95570,7 +108647,7 @@
+     p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema));
+   }
+   if( !p ){
+-    db->mallocFailed = 1;
++    sqlite3OomFault(db);
+   }else if ( 0==p->file_format ){
+     sqlite3HashInit(&p->tblHash);
+     sqlite3HashInit(&p->idxHash);
+@@ -95597,6 +108674,7 @@
+ ** This file contains C code routines that are called by the parser
+ ** in order to generate code for DELETE FROM statements.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** While a SrcList can in general represent multiple tables and subqueries
+@@ -95620,7 +108698,7 @@
+   sqlite3DeleteTable(pParse->db, pItem->pTab);
+   pItem->pTab = pTab;
+   if( pTab ){
+-    pTab->nRef++;
++    pTab->nTabRef++;
+   }
+   if( sqlite3IndexedByLookup(pParse, pItem) ){
+     pTab = 0;
+@@ -95686,11 +108764,12 @@
+   if( pFrom ){
+     assert( pFrom->nSrc==1 );
+     pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
+-    pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
++    pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
+     assert( pFrom->a[0].pOn==0 );
+     assert( pFrom->a[0].pUsing==0 );
+   }
+-  pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
++  pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 
++                          SF_IncludeHidden, 0, 0);
+   sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
+   sqlite3Select(pParse, pSel, &dest);
+   sqlite3SelectDelete(db, pSel);
+@@ -95726,7 +108805,7 @@
+   */
+   if( pOrderBy && (pLimit == 0) ) {
+     sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
+-    goto limit_where_cleanup_2;
++    goto limit_where_cleanup;
+   }
+ 
+   /* We only need to generate a select expression if there
+@@ -95747,17 +108826,17 @@
+   **   );
+   */
+ 
+-  pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
+-  if( pSelectRowid == 0 ) goto limit_where_cleanup_2;
++  pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0);
++  if( pSelectRowid == 0 ) goto limit_where_cleanup;
+   pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
+-  if( pEList == 0 ) goto limit_where_cleanup_2;
++  if( pEList == 0 ) goto limit_where_cleanup;
+ 
+   /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
+   ** and the SELECT subtree. */
+   pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
+   if( pSelectSrc == 0 ) {
+     sqlite3ExprListDelete(pParse->db, pEList);
+-    goto limit_where_cleanup_2;
++    goto limit_where_cleanup;
+   }
+ 
+   /* generate the SELECT expression tree. */
+@@ -95766,22 +108845,12 @@
+   if( pSelect == 0 ) return 0;
+ 
+   /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
+-  pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
+-  if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
+-  pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
+-  if( pInClause == 0 ) goto limit_where_cleanup_1;
+-
+-  pInClause->x.pSelect = pSelect;
+-  pInClause->flags |= EP_xIsSelect;
+-  sqlite3ExprSetHeightAndFlags(pParse, pInClause);
++  pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0);
++  pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0) : 0;
++  sqlite3PExprAddSelect(pParse, pInClause, pSelect);
+   return pInClause;
+ 
+-  /* something went wrong. clean up anything allocated. */
+-limit_where_cleanup_1:
+-  sqlite3SelectDelete(pParse->db, pSelect);
+-  return 0;
+-
+-limit_where_cleanup_2:
++limit_where_cleanup:
+   sqlite3ExprDelete(pParse->db, pWhere);
+   sqlite3ExprListDelete(pParse->db, pOrderBy);
+   sqlite3ExprDelete(pParse->db, pLimit);
+@@ -95805,7 +108874,6 @@
+ ){
+   Vdbe *v;               /* The virtual database engine */
+   Table *pTab;           /* The table from which records will be deleted */
+-  const char *zDb;       /* Name of database holding pTab */
+   int i;                 /* Loop counter */
+   WhereInfo *pWInfo;     /* Information about the WHERE clause */
+   Index *pIdx;           /* For looping over indices of the table */
+@@ -95819,7 +108887,7 @@
+   int iDb;               /* Database number */
+   int memCnt = -1;       /* Memory cell used for change counting */
+   int rcauth;            /* Value returned by authorization callback */
+-  int okOnePass;         /* True for one-pass algorithm without the FIFO */
++  int eOnePass;          /* ONEPASS_OFF or _SINGLE or _MULTI */
+   int aiCurOnePass[2];   /* The write cursors opened by WHERE_ONEPASS */
+   u8 *aToOpen = 0;       /* Open cursor iTabCur+j if aToOpen[j] is true */
+   Index *pPk;            /* The PRIMARY KEY index on the table */
+@@ -95831,8 +108899,9 @@
+   int iRowSet = 0;       /* Register for rowset of rows to delete */
+   int addrBypass = 0;    /* Address of jump over the delete logic */
+   int addrLoop = 0;      /* Top of the delete loop */
+-  int addrDelete = 0;    /* Jump directly to the delete logic */
+   int addrEphOpen = 0;   /* Instruction to open the Ephemeral table */
++  int bComplex;          /* True if there are triggers or FKs or
++                         ** subqueries in the WHERE clause */
+  
+ #ifndef SQLITE_OMIT_TRIGGER
+   int isView;                  /* True if attempting to delete from a view */
+@@ -95860,6 +108929,7 @@
+ #ifndef SQLITE_OMIT_TRIGGER
+   pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
+   isView = pTab->pSelect!=0;
++  bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
+ #else
+ # define pTrigger 0
+ # define isView 0
+@@ -95880,8 +108950,8 @@
+   }
+   iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+   assert( iDb<db->nDb );
+-  zDb = db->aDb[iDb].zName;
+-  rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb);
++  rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, 
++                            db->aDb[iDb].zDbSName);
+   assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
+   if( rcauth==SQLITE_DENY ){
+     goto delete_from_cleanup;
+@@ -95942,9 +109012,21 @@
+   /* Special case: A DELETE without a WHERE clause deletes everything.
+   ** It is easier just to erase the whole table. Prior to version 3.6.5,
+   ** this optimization caused the row change count (the value returned by 
+-  ** API function sqlite3_count_changes) to be set incorrectly.  */
+-  if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) 
+-   && 0==sqlite3FkRequired(pParse, pTab, 0, 0)
++  ** API function sqlite3_count_changes) to be set incorrectly.
++  **
++  ** The "rcauth==SQLITE_OK" terms is the
++  ** IMPLEMENTATION-OF: R-17228-37124 If the action code is SQLITE_DELETE and
++  ** the callback returns SQLITE_IGNORE then the DELETE operation proceeds but
++  ** the truncate optimization is disabled and all rows are deleted
++  ** individually.
 +  */
-+  if((rc = sqlcipher_codec_ctx_set_pagesize(ctx, default_page_size)) != SQLITE_OK) return rc;
-+
-+  if((rc = sqlcipher_cipher_ctx_init(&ctx->read_ctx)) != SQLITE_OK) return rc; 
-+  if((rc = sqlcipher_cipher_ctx_init(&ctx->write_ctx)) != SQLITE_OK) return rc; 
-+
-+  if(fd == NULL || sqlite3OsRead(fd, ctx->kdf_salt, FILE_HEADER_SZ, 0) != SQLITE_OK) {
-+    ctx->need_kdf_salt = 1;
++  if( rcauth==SQLITE_OK
++   && pWhere==0
++   && !bComplex
++   && !IsVirtual(pTab)
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++   && db->xPreUpdateCallback==0
++#endif
+   ){
+     assert( !isView );
+     sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
+@@ -95959,6 +109041,9 @@
+   }else
+ #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
+   {
++    u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK|WHERE_SEEK_TABLE;
++    if( sNC.ncFlags & NC_VarSelect ) bComplex = 1;
++    wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);
+     if( HasRowid(pTab) ){
+       /* For a rowid table, initialize the RowSet to an empty set */
+       pPk = 0;
+@@ -95979,13 +109064,18 @@
+     }
+   
+     /* Construct a query to find the rowid or primary key for every row
+-    ** to be deleted, based on the WHERE clause.
++    ** to be deleted, based on the WHERE clause. Set variable eOnePass
++    ** to indicate the strategy used to implement this delete:
++    **
++    **  ONEPASS_OFF:    Two-pass approach - use a FIFO for rowids/PK values.
++    **  ONEPASS_SINGLE: One-pass approach - at most one row deleted.
++    **  ONEPASS_MULTI:  One-pass approach - any number of rows may be deleted.
+     */
+-    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 
+-                               WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK,
+-                               iTabCur+1);
++    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
+     if( pWInfo==0 ) goto delete_from_cleanup;
+-    okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
++    eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
++    assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
++    assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
+   
+     /* Keep track of the number of rows to be deleted */
+     if( db->flags & SQLITE_CountRows ){
+@@ -95995,6 +109085,7 @@
+     /* Extract the rowid or primary key for the current row */
+     if( pPk ){
+       for(i=0; i<nPk; i++){
++        assert( pPk->aiColumn[i]>=0 );
+         sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
+                                         pPk->aiColumn[i], iPk+i);
+       }
+@@ -96005,13 +109096,12 @@
+       if( iKey>pParse->nMem ) pParse->nMem = iKey;
+     }
+   
+-    if( okOnePass ){
+-      /* For ONEPASS, no need to store the rowid/primary-key.  There is only
++    if( eOnePass!=ONEPASS_OFF ){
++      /* For ONEPASS, no need to store the rowid/primary-key. There is only
+       ** one, so just keep it in its register(s) and fall through to the
+-      ** delete code.
+-      */
++      ** delete code.  */
+       nKey = nPk; /* OP_Found will use an unpacked key */
+-      aToOpen = sqlite3DbMallocRaw(db, nIdx+2);
++      aToOpen = sqlite3DbMallocRawNN(db, nIdx+2);
+       if( aToOpen==0 ){
+         sqlite3WhereEnd(pWInfo);
+         goto delete_from_cleanup;
+@@ -96021,27 +109111,27 @@
+       if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0;
+       if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0;
+       if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen);
+-      addrDelete = sqlite3VdbeAddOp0(v, OP_Goto); /* Jump to DELETE logic */
+-    }else if( pPk ){
+-      /* Construct a composite key for the row to be deleted and remember it */
+-      iKey = ++pParse->nMem;
+-      nKey = 0;   /* Zero tells OP_Found to use a composite key */
+-      sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
+-                        sqlite3IndexAffinityStr(v, pPk), nPk);
+-      sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey);
+-    }else{
+-      /* Get the rowid of the row to be deleted and remember it in the RowSet */
+-      nKey = 1;  /* OP_Seek always uses a single rowid */
+-      sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
++    }else{
++      if( pPk ){
++        /* Add the PK key for this row to the temporary table */
++        iKey = ++pParse->nMem;
++        nKey = 0;   /* Zero tells OP_Found to use a composite key */
++        sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
++            sqlite3IndexAffinityStr(pParse->db, pPk), nPk);
++        sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk);
++      }else{
++        /* Add the rowid of the row to be deleted to the RowSet */
++        nKey = 1;  /* OP_DeferredSeek always uses a single rowid */
++        sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
++      }
+     }
+   
+-    /* End of the WHERE loop */
+-    sqlite3WhereEnd(pWInfo);
+-    if( okOnePass ){
+-      /* Bypass the delete logic below if the WHERE loop found zero rows */
++    /* If this DELETE cannot use the ONEPASS strategy, this is the 
++    ** end of the WHERE loop */
++    if( eOnePass!=ONEPASS_OFF ){
+       addrBypass = sqlite3VdbeMakeLabel(v);
+-      sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBypass);
+-      sqlite3VdbeJumpHere(v, addrDelete);
++    }else{
++      sqlite3WhereEnd(pWInfo);
+     }
+   
+     /* Unless this is a view, open cursors for the table we are 
+@@ -96050,28 +109140,31 @@
+     ** triggers.
+     */
+     if( !isView ){
++      int iAddrOnce = 0;
++      if( eOnePass==ONEPASS_MULTI ){
++        iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
++      }
+       testcase( IsVirtual(pTab) );
+-      sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen,
+-                                 &iDataCur, &iIdxCur);
++      sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE,
++                                 iTabCur, aToOpen, &iDataCur, &iIdxCur);
+       assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
+       assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
++      if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
+     }
+   
+     /* Set up a loop over the rowids/primary-keys that were found in the
+     ** where-clause loop above.
+     */
+-    if( okOnePass ){
+-      /* Just one row.  Hence the top-of-loop is a no-op */
++    if( eOnePass!=ONEPASS_OFF ){
+       assert( nKey==nPk );  /* OP_Found will use an unpacked key */
+-      assert( !IsVirtual(pTab) );
+-      if( aToOpen[iDataCur-iTabCur] ){
++      if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){
+         assert( pPk!=0 || pTab->pSelect!=0 );
+         sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
+         VdbeCoverage(v);
+       }
+     }else if( pPk ){
+       addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
+-      sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
++      sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey);
+       assert( nKey==0 );  /* OP_Found will use a composite key */
+     }else{
+       addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);
+@@ -96086,33 +109179,30 @@
+       sqlite3VtabMakeWritable(pParse, pTab);
+       sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
+       sqlite3VdbeChangeP5(v, OE_Abort);
++      assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
+       sqlite3MayAbort(pParse);
++      if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){
++        pParse->isMultiWrite = 0;
++      }
+     }else
+ #endif
+     {
+       int count = (pParse->nested==0);    /* True to count changes */
+       sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+-                               iKey, nKey, count, OE_Default, okOnePass);
++          iKey, nKey, count, OE_Default, eOnePass, aiCurOnePass[1]);
+     }
+   
+     /* End of the loop over all rowids/primary-keys. */
+-    if( okOnePass ){
++    if( eOnePass!=ONEPASS_OFF ){
+       sqlite3VdbeResolveLabel(v, addrBypass);
++      sqlite3WhereEnd(pWInfo);
+     }else if( pPk ){
+       sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
+       sqlite3VdbeJumpHere(v, addrLoop);
+     }else{
+-      sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop);
++      sqlite3VdbeGoto(v, addrLoop);
+       sqlite3VdbeJumpHere(v, addrLoop);
+     }     
+-  
+-    /* Close the cursors open on the table and its indexes. */
+-    if( !isView && !IsVirtual(pTab) ){
+-      if( !pPk ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur);
+-      for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+-        sqlite3VdbeAddOp1(v, OP_Close, iIdxCur + i);
+-      }
+-    }
+   } /* End non-truncate path */
+ 
+   /* Update the sqlite_sequence table by storing the content of the
+@@ -96169,6 +109259,27 @@
+ **       sequence of nPk memory cells starting at iPk.  If nPk==0 that means
+ **       that a search record formed from OP_MakeRecord is contained in the
+ **       single memory location iPk.
++**
++** eMode:
++**   Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or
++**   ONEPASS_MULTI.  If eMode is not ONEPASS_OFF, then the cursor
++**   iDataCur already points to the row to delete. If eMode is ONEPASS_OFF
++**   then this function must seek iDataCur to the entry identified by iPk
++**   and nPk before reading from it.
++**
++**   If eMode is ONEPASS_MULTI, then this call is being made as part
++**   of a ONEPASS delete that affects multiple rows. In this case, if 
++**   iIdxNoSeek is a valid cursor number (>=0) and is not the same as
++**   iDataCur, then its position should be preserved following the delete
++**   operation. Or, if iIdxNoSeek is not a valid cursor number, the
++**   position of iDataCur should be preserved instead.
++**
++** iIdxNoSeek:
++**   If iIdxNoSeek is a valid cursor number (>=0) not equal to iDataCur,
++**   then it identifies an index cursor (from within array of cursors
++**   starting at iIdxCur) that already points to the index entry to be deleted.
++**   Except, this optimization is disabled if there are BEFORE triggers since
++**   the trigger body might have moved the cursor.
+ */
+ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
+   Parse *pParse,     /* Parsing context */
+@@ -96180,7 +109291,8 @@
+   i16 nPk,           /* Number of PRIMARY KEY memory cells */
+   u8 count,          /* If non-zero, increment the row change counter */
+   u8 onconf,         /* Default ON CONFLICT policy for triggers */
+-  u8 bNoSeek         /* iDataCur is already pointing to the row to delete */
++  u8 eMode,          /* ONEPASS_OFF, _SINGLE, or _MULTI.  See above */
++  int iIdxNoSeek     /* Cursor number of cursor that does not need seeking */
+ ){
+   Vdbe *v = pParse->pVdbe;        /* Vdbe */
+   int iOld = 0;                   /* First register in OLD.* array */
+@@ -96197,7 +109309,7 @@
+   ** not attempt to delete it or fire any DELETE triggers.  */
+   iLabel = sqlite3VdbeMakeLabel(v);
+   opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
+-  if( !bNoSeek ){
++  if( eMode==ONEPASS_OFF ){
+     sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+     VdbeCoverageIf(v, opSeek==OP_NotExists);
+     VdbeCoverageIf(v, opSeek==OP_NotFound);
+@@ -96238,13 +109350,18 @@
+ 
+     /* If any BEFORE triggers were coded, then seek the cursor to the 
+     ** row to be deleted again. It may be that the BEFORE triggers moved
+-    ** the cursor or of already deleted the row that the cursor was
++    ** the cursor or already deleted the row that the cursor was
+     ** pointing to.
++    **
++    ** Also disable the iIdxNoSeek optimization since the BEFORE trigger
++    ** may have moved that cursor.
+     */
+     if( addrStart<sqlite3VdbeCurrentAddr(v) ){
+       sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+       VdbeCoverageIf(v, opSeek==OP_NotExists);
+       VdbeCoverageIf(v, opSeek==OP_NotFound);
++      testcase( iIdxNoSeek>=0 );
++      iIdxNoSeek = -1;
+     }
+ 
+     /* Do FK processing. This call checks that any FK constraints that
+@@ -96255,13 +109372,29 @@
+ 
+   /* Delete the index and table entries. Skip this step if pTab is really
+   ** a view (in which case the only effect of the DELETE statement is to
+-  ** fire the INSTEAD OF triggers).  */ 
++  ** fire the INSTEAD OF triggers).  
++  **
++  ** If variable 'count' is non-zero, then this OP_Delete instruction should
++  ** invoke the update-hook. The pre-update-hook, on the other hand should
++  ** be invoked unless table pTab is a system table. The difference is that
++  ** the update-hook is not invoked for rows removed by REPLACE, but the 
++  ** pre-update-hook is.
++  */ 
+   if( pTab->pSelect==0 ){
+-    sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0);
++    u8 p5 = 0;
++    sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
+     sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
+-    if( count ){
+-      sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
++    if( pParse->nested==0 ){
++      sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE);
++    }
++    if( eMode!=ONEPASS_OFF ){
++      sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE);
++    }
++    if( iIdxNoSeek>=0 && iIdxNoSeek!=iDataCur ){
++      sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);
+     }
++    if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION;
++    sqlite3VdbeChangeP5(v, p5);
    }
--  return rc;
-+
-+  if((rc = sqlcipher_codec_ctx_set_cipher(ctx, CIPHER, 0)) != SQLITE_OK) return rc;
-+  if((rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, default_kdf_iter, 0)) != SQLITE_OK) return rc;
-+  if((rc = sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, FAST_PBKDF2_ITER, 0)) != SQLITE_OK) return rc;
-+  if((rc = sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, 0)) != SQLITE_OK) return rc;
-+
-+  /* Note that use_hmac is a special case that requires recalculation of page size
-+     so we call set_use_hmac to perform setup */
-+  if((rc = sqlcipher_codec_ctx_set_use_hmac(ctx, default_flags & CIPHER_FLAG_HMAC)) != SQLITE_OK) return rc;
-+
-+  if((rc = sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx)) != SQLITE_OK) return rc;
-+
-+  return SQLITE_OK;
-+}
+ 
+   /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
+@@ -96304,7 +109437,8 @@
+   Table *pTab,       /* Table containing the row to be deleted */
+   int iDataCur,      /* Cursor of table holding data. */
+   int iIdxCur,       /* First index cursor */
+-  int *aRegIdx       /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
++  int *aRegIdx,      /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
++  int iIdxNoSeek     /* Do not delete from this cursor */
+ ){
+   int i;             /* Index loop counter */
+   int r1 = -1;       /* Register holding an index key */
+@@ -96320,11 +109454,12 @@
+     assert( iIdxCur+i!=iDataCur || pPk==pIdx );
+     if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
+     if( pIdx==pPk ) continue;
++    if( iIdxCur+i==iIdxNoSeek ) continue;
+     VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
+     r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
+-                                 &iPartIdxLabel, pPrior, r1);
++        &iPartIdxLabel, pPrior, r1);
+     sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
+-                      pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
++        pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
+     sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
+     pPrior = pIdx;
+   }
+@@ -96373,17 +109508,17 @@
+ ){
+   Vdbe *v = pParse->pVdbe;
+   int j;
+-  Table *pTab = pIdx->pTable;
+   int regBase;
+   int nCol;
+ 
+   if( piPartIdxLabel ){
+     if( pIdx->pPartIdxWhere ){
+       *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
+-      pParse->iPartIdxTab = iDataCur;
++      pParse->iSelfTab = iDataCur + 1;
+       sqlite3ExprCachePush(pParse);
+-      sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
+-                         SQLITE_JUMPIFNULL);
++      sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
++                            SQLITE_JUMPIFNULL);
++      pParse->iSelfTab = 0;
+     }else{
+       *piPartIdxLabel = 0;
+     }
+@@ -96392,9 +109527,14 @@
+   regBase = sqlite3GetTempRange(pParse, nCol);
+   if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;
+   for(j=0; j<nCol; j++){
+-    if( pPrior && pPrior->aiColumn[j]==pIdx->aiColumn[j] ) continue;
+-    sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pIdx->aiColumn[j],
+-                                    regBase+j);
++    if( pPrior
++     && pPrior->aiColumn[j]==pIdx->aiColumn[j]
++     && pPrior->aiColumn[j]!=XN_EXPR
++    ){
++      /* This column was already computed by the previous index */
++      continue;
++    }
++    sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j);
+     /* If the column affinity is REAL but the number is an integer, then it
+     ** might be stored in the table as an integer (using a compact
+     ** representation) then converted to REAL by an OP_RealAffinity opcode.
+@@ -96405,6 +109545,10 @@
+   }
+   if( regOut ){
+     sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
++    if( pIdx->pTable->pSelect ){
++      const char *zAff = sqlite3IndexAffinityStr(pParse->db, pIdx);
++      sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
++    }
+   }
+   sqlite3ReleaseTempRange(pParse, regBase, nCol);
+   return regBase;
+@@ -96439,8 +109583,10 @@
+ ** functions of SQLite.  (Some function, and in particular the date and
+ ** time functions, are implemented separately.)
+ */
++/* #include "sqliteInt.h" */
+ /* #include <stdlib.h> */
+ /* #include <assert.h> */
++/* #include "vdbeInt.h" */
+ 
+ /*
+ ** Return the collating function associated with a function.
+@@ -96500,16 +109646,20 @@
+   int NotUsed,
+   sqlite3_value **argv
+ ){
+-  const char *z = 0;
++  static const char *azType[] = { "integer", "real", "text", "blob", "null" };
++  int i = sqlite3_value_type(argv[0]) - 1;
+   UNUSED_PARAMETER(NotUsed);
+-  switch( sqlite3_value_type(argv[0]) ){
+-    case SQLITE_INTEGER: z = "integer"; break;
+-    case SQLITE_TEXT:    z = "text";    break;
+-    case SQLITE_FLOAT:   z = "real";    break;
+-    case SQLITE_BLOB:    z = "blob";    break;
+-    default:             z = "null";    break;
+-  }
+-  sqlite3_result_text(context, z, -1, SQLITE_STATIC);
++  assert( i>=0 && i<ArraySize(azType) );
++  assert( SQLITE_INTEGER==1 );
++  assert( SQLITE_FLOAT==2 );
++  assert( SQLITE_TEXT==3 );
++  assert( SQLITE_BLOB==4 );
++  assert( SQLITE_NULL==5 );
++  /* EVIDENCE-OF: R-01470-60482 The sqlite3_value_type(V) interface returns
++  ** the datatype code for the initial datatype of the sqlite3_value object
++  ** V. The returned value is one of SQLITE_INTEGER, SQLITE_FLOAT,
++  ** SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL. */
++  sqlite3_result_text(context, azType[i], -1, SQLITE_STATIC);
+ }
+ 
+ 
+@@ -96624,23 +109774,26 @@
+   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>0 ){
++    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;
++    }
++    if( zNeedle==0 || (nHaystack && zHaystack==0) ) return;
++    while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
++      N++;
++      do{
++        nHaystack--;
++        zHaystack++;
++      }while( isText && (zHaystack[0]&0xc0)==0x80 );
++    }
++    if( nNeedle>nHaystack ) N = 0;
+   }
+-  if( nNeedle>nHaystack ) N = 0;
+   sqlite3_result_int(context, N);
+ }
+ 
+@@ -96663,7 +109816,8 @@
+     x.nUsed = 0;
+     x.apArg = argv+1;
+     sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
+-    sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
++    str.printfFlags = SQLITE_PRINTF_SQLFUNC;
++    sqlite3XPrintf(&str, zFormat, &x);
+     n = str.nChar;
+     sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
+                         SQLITE_DYNAMIC);
+@@ -96991,25 +110145,23 @@
+ ** A structure defining how to do GLOB-style comparisons.
+ */
+ struct compareInfo {
+-  u8 matchAll;
+-  u8 matchOne;
+-  u8 matchSet;
+-  u8 noCase;
++  u8 matchAll;          /* "*" or "%" */
++  u8 matchOne;          /* "?" or "_" */
++  u8 matchSet;          /* "[" or 0 */
++  u8 noCase;            /* true to ignore case differences */
+ };
+ 
+ /*
+ ** For LIKE and GLOB matching on EBCDIC machines, assume that every
+-** character is exactly one byte in size.  Also, all characters are
+-** able to participate in upper-case-to-lower-case mappings in EBCDIC
+-** whereas only characters less than 0x80 do in ASCII.
++** character is exactly one byte in size.  Also, provde the Utf8Read()
++** macro for fast reading of the next character in the common case where
++** the next character is ASCII.
+ */
+ #if defined(SQLITE_EBCDIC)
+ # define sqlite3Utf8Read(A)        (*((*A)++))
+-# define GlobUpperToLower(A)       A = sqlite3UpperToLower[A]
+-# define GlobUpperToLowerAscii(A)  A = sqlite3UpperToLower[A]
++# define Utf8Read(A)               (*(A++))
+ #else
+-# define GlobUpperToLower(A)       if( A<=0x7f ){ A = sqlite3UpperToLower[A]; }
+-# define GlobUpperToLowerAscii(A)  A = sqlite3UpperToLower[A]
++# define Utf8Read(A)               (A[0]<0x80?*(A++):sqlite3Utf8Read(&A))
+ #endif
+ 
+ static const struct compareInfo globInfo = { '*', '?', '[', 0 };
+@@ -97021,9 +110173,19 @@
+ static const struct compareInfo likeInfoAlt = { '%', '_',   0, 0 };
+ 
+ /*
+-** Compare two UTF-8 strings for equality where the first string can
+-** potentially be a "glob" or "like" expression.  Return true (1) if they
+-** are the same and false (0) if they are different.
++** Possible error returns from patternMatch()
++*/
++#define SQLITE_MATCH             0
++#define SQLITE_NOMATCH           1
++#define SQLITE_NOWILDCARDMATCH   2
 +
-+/**
-+  * Free and wipe memory associated with a cipher_ctx, including the allocated
-+  * read_ctx and write_ctx.
-+  */
-+void sqlcipher_codec_ctx_free(codec_ctx **iCtx) {
-+  codec_ctx *ctx = *iCtx;
-+  CODEC_TRACE(("codec_ctx_free: entered iCtx=%p\n", iCtx));
-+  sqlcipher_free(ctx->kdf_salt, ctx->kdf_salt_sz);
-+  sqlcipher_free(ctx->hmac_kdf_salt, ctx->kdf_salt_sz);
-+  sqlcipher_free(ctx->buffer, 0);
-+  sqlcipher_cipher_ctx_free(&ctx->read_ctx);
-+  sqlcipher_cipher_ctx_free(&ctx->write_ctx);
-+  sqlcipher_free(ctx, sizeof(codec_ctx)); 
++/*
++** Compare two UTF-8 strings for equality where the first string is
++** a GLOB or LIKE expression.  Return values:
++**
++**    SQLITE_MATCH:            Match
++**    SQLITE_NOMATCH:          No match
++**    SQLITE_NOWILDCARDMATCH:  No match in spite of having * or % wildcards.
+ **
+ ** Globbing rules:
+ **
+@@ -97051,7 +110213,7 @@
+ **      Ec        Where E is the "esc" character and c is any other
+ **                character, including '%', '_', and esc, match exactly c.
+ **
+-** The comments through this routine usually assume glob matching.
++** The comments within this routine usually assume glob matching.
+ **
+ ** This routine is usually quick, but can be N**2 in the worst case.
+ */
+@@ -97059,54 +110221,46 @@
+   const u8 *zPattern,              /* The glob pattern */
+   const u8 *zString,               /* The string to compare against the glob */
+   const struct compareInfo *pInfo, /* Information about how to do the compare */
+-  u32 esc                          /* The escape character */
++  u32 matchOther                   /* The escape char (LIKE) or '[' (GLOB) */
+ ){
+   u32 c, c2;                       /* Next pattern and input string chars */
+   u32 matchOne = pInfo->matchOne;  /* "?" or "_" */
+   u32 matchAll = pInfo->matchAll;  /* "*" or "%" */
+-  u32 matchOther;                  /* "[" or the escape character */
+   u8 noCase = pInfo->noCase;       /* True if uppercase==lowercase */
+   const u8 *zEscaped = 0;          /* One past the last escaped input char */
+   
+-  /* The GLOB operator does not have an ESCAPE clause.  And LIKE does not
+-  ** have the matchSet operator.  So we either have to look for one or
+-  ** the other, never both.  Hence the single variable matchOther is used
+-  ** to store the one we have to look for.
+-  */
+-  matchOther = esc ? esc : pInfo->matchSet;
+-
+-  while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
++  while( (c = Utf8Read(zPattern))!=0 ){
+     if( c==matchAll ){  /* Match "*" */
+       /* Skip over multiple "*" characters in the pattern.  If there
+       ** are also "?" characters, skip those as well, but consume a
+       ** single character of the input string for each "?" skipped */
+-      while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
+-               || c == matchOne ){
++      while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){
+         if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
+-          return 0;
++          return SQLITE_NOWILDCARDMATCH;
+         }
+       }
+       if( c==0 ){
+-        return 1;   /* "*" at the end of the pattern matches */
++        return SQLITE_MATCH;   /* "*" at the end of the pattern matches */
+       }else if( c==matchOther ){
+-        if( esc ){
++        if( pInfo->matchSet==0 ){
+           c = sqlite3Utf8Read(&zPattern);
+-          if( c==0 ) return 0;
++          if( c==0 ) return SQLITE_NOWILDCARDMATCH;
+         }else{
+           /* "[...]" immediately follows the "*".  We have to do a slow
+           ** recursive search in this case, but it is an unusual case. */
+           assert( matchOther<0x80 );  /* '[' is a single-byte character */
+-          while( *zString
+-                 && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
++          while( *zString ){
++            int bMatch = patternCompare(&zPattern[-1],zString,pInfo,matchOther);
++            if( bMatch!=SQLITE_NOMATCH ) return bMatch;
+             SQLITE_SKIP_UTF8(zString);
+           }
+-          return *zString!=0;
++          return SQLITE_NOWILDCARDMATCH;
+         }
+       }
+ 
+       /* At this point variable c contains the first character of the
+       ** pattern string past the "*".  Search in the input string for the
+-      ** first matching character and recursively contine the match from
++      ** first matching character and recursively continue the match from
+       ** that point.
+       **
+       ** For a case-insensitive search, set variable cx to be the same as
+@@ -97115,6 +110269,7 @@
+       */
+       if( c<=0x80 ){
+         u32 cx;
++        int bMatch;
+         if( noCase ){
+           cx = sqlite3Toupper(c);
+           c = sqlite3Tolower(c);
+@@ -97123,27 +110278,30 @@
+         }
+         while( (c2 = *(zString++))!=0 ){
+           if( c2!=c && c2!=cx ) continue;
+-          if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
++          bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
++          if( bMatch!=SQLITE_NOMATCH ) return bMatch;
+         }
+       }else{
+-        while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
++        int bMatch;
++        while( (c2 = Utf8Read(zString))!=0 ){
+           if( c2!=c ) continue;
+-          if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
++          bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
++          if( bMatch!=SQLITE_NOMATCH ) return bMatch;
+         }
+       }
+-      return 0;
++      return SQLITE_NOWILDCARDMATCH;
+     }
+     if( c==matchOther ){
+-      if( esc ){
++      if( pInfo->matchSet==0 ){
+         c = sqlite3Utf8Read(&zPattern);
+-        if( c==0 ) return 0;
++        if( c==0 ) return SQLITE_NOMATCH;
+         zEscaped = zPattern;
+       }else{
+         u32 prior_c = 0;
+         int seen = 0;
+         int invert = 0;
+         c = sqlite3Utf8Read(&zString);
+-        if( c==0 ) return 0;
++        if( c==0 ) return SQLITE_NOMATCH;
+         c2 = sqlite3Utf8Read(&zPattern);
+         if( c2=='^' ){
+           invert = 1;
+@@ -97167,27 +110325,36 @@
+           c2 = sqlite3Utf8Read(&zPattern);
+         }
+         if( c2==0 || (seen ^ invert)==0 ){
+-          return 0;
++          return SQLITE_NOMATCH;
+         }
+         continue;
+       }
+     }
+-    c2 = sqlite3Utf8Read(&zString);
++    c2 = Utf8Read(zString);
+     if( c==c2 ) continue;
+-    if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
++    if( noCase  && sqlite3Tolower(c)==sqlite3Tolower(c2) && c<0x80 && c2<0x80 ){
+       continue;
+     }
+     if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
+-    return 0;
++    return SQLITE_NOMATCH;
+   }
+-  return *zString==0;
++  return *zString==0 ? SQLITE_MATCH : SQLITE_NOMATCH;
 +}
 +
-+/** convert a 32bit unsigned integer to little endian byte ordering */
-+static void sqlcipher_put4byte_le(unsigned char *p, u32 v) { 
-+  p[0] = (u8)v;
-+  p[1] = (u8)(v>>8);
-+  p[2] = (u8)(v>>16);
-+  p[3] = (u8)(v>>24);
++/*
++** The sqlite3_strglob() interface.  Return 0 on a match (like strcmp()) and
++** non-zero if there is no match.
++*/
++SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){
++  return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[');
+ }
+ 
+ /*
+-** The sqlite3_strglob() interface.
++** The sqlite3_strlike() interface.  Return 0 on a match and non-zero for
++** a miss - like strcmp().
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlobPattern, const char *zString){
+-  return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0;
++SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
++  return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc);
+ }
+ 
+ /*
+@@ -97218,10 +110385,22 @@
+   sqlite3_value **argv
+ ){
+   const unsigned char *zA, *zB;
+-  u32 escape = 0;
++  u32 escape;
+   int nPat;
+   sqlite3 *db = sqlite3_context_db_handle(context);
++  struct compareInfo *pInfo = sqlite3_user_data(context);
+ 
++#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
++  if( sqlite3_value_type(argv[0])==SQLITE_BLOB
++   || sqlite3_value_type(argv[1])==SQLITE_BLOB
++  ){
++#ifdef SQLITE_TEST
++    sqlite3_like_count++;
++#endif
++    sqlite3_result_int(context, 0);
++    return;
++  }
++#endif
+   zB = sqlite3_value_text(argv[0]);
+   zA = sqlite3_value_text(argv[1]);
+ 
+@@ -97249,14 +110428,14 @@
+       return;
+     }
+     escape = sqlite3Utf8Read(&zEsc);
++  }else{
++    escape = pInfo->matchSet;
+   }
+   if( zA && zB ){
+-    struct compareInfo *pInfo = sqlite3_user_data(context);
+ #ifdef SQLITE_TEST
+     sqlite3_like_count++;
+ #endif
+-    
+-    sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape));
++    sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH);
+   }
+ }
+ 
+@@ -97549,16 +110728,14 @@
+   sqlite3_value **argv
+ ){
+   i64 n;
+-  sqlite3 *db = sqlite3_context_db_handle(context);
++  int rc;
+   assert( argc==1 );
+   UNUSED_PARAMETER(argc);
+   n = sqlite3_value_int64(argv[0]);
+-  testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH] );
+-  testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
+-  if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+-    sqlite3_result_error_toobig(context);
+-  }else{
+-    sqlite3_result_zeroblob(context, (int)n); /* IMP: R-00293-64994 */
++  if( n<0 ) n = 0;
++  rc = sqlite3_result_zeroblob64(context, n); /* IMP: R-00293-64994 */
++  if( rc ){
++    sqlite3_result_error_code(context, rc);
+   }
+ }
+ 
+@@ -97733,6 +110910,26 @@
+ }
+ 
+ 
++#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
++/*
++** The "unknown" function is automatically substituted in place of
++** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN
++** when the SQLITE_ENABLE_UNKNOWN_FUNCTION compile-time option is used.
++** When the "sqlite3" command-line shell is built using this functionality,
++** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries
++** involving application-defined functions to be examined in a generic
++** sqlite3 shell.
++*/
++static void unknownFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  /* no-op */
 +}
++#endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/
 +
-+static int sqlcipher_page_hmac(cipher_ctx *ctx, Pgno pgno, unsigned char *in, int in_sz, unsigned char 
*out) {
-+  unsigned char pgno_raw[sizeof(pgno)];
-+  /* we may convert page number to consistent representation before calculating MAC for
-+     compatibility across big-endian and little-endian platforms. 
-+
-+     Note: The public release of sqlcipher 2.0.0 to 2.0.6 had a bug where the bytes of pgno 
-+     were used directly in the MAC. SQLCipher convert's to little endian by default to preserve
-+     backwards compatibility on the most popular platforms, but can optionally be configured
-+     to use either big endian or native byte ordering via pragma. */
 +
-+  if(ctx->flags & CIPHER_FLAG_LE_PGNO) { /* compute hmac using little endian pgno*/
-+    sqlcipher_put4byte_le(pgno_raw, pgno);
-+  } else if(ctx->flags & CIPHER_FLAG_BE_PGNO) { /* compute hmac using big endian pgno */
-+    sqlite3Put4byte(pgno_raw, pgno); /* sqlite3Put4byte converts 32bit uint to big endian  */
-+  } else { /* use native byte ordering */
-+    memcpy(pgno_raw, &pgno, sizeof(pgno));
+ /* IMP: R-25361-16150 This function is omitted from SQLite by default. It
+ ** is only available if the SQLITE_SOUNDEX compile-time option is used
+ ** when SQLite is built.
+@@ -97803,6 +111000,14 @@
+   sqlite3 *db = sqlite3_context_db_handle(context);
+   char *zErrMsg = 0;
+ 
++  /* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc
++  ** flag is set.  See the sqlite3_enable_load_extension() API.
++  */
++  if( (db->flags & SQLITE_LoadExtFunc)==0 ){
++    sqlite3_result_error(context, "not authorized", -1);
++    return;
 +  }
 +
-+  /* include the encrypted page data,  initialization vector, and page number in HMAC. This will 
-+     prevent both tampering with the ciphertext, manipulation of the IV, or resequencing otherwise
-+     valid pages out of order in a database */ 
-+  ctx->provider->hmac(
-+    ctx->provider_ctx, ctx->hmac_key,
-+    ctx->key_sz, in,
-+    in_sz, (unsigned char*) &pgno_raw,
-+    sizeof(pgno), out);
-+  return SQLITE_OK; 
+   if( argc==2 ){
+     zProc = (const char *)sqlite3_value_text(argv[1]);
+   }else{
+@@ -98001,7 +111206,7 @@
+         zSep = ",";
+         nSep = 1;
+       }
+-      if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
++      if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
+     }
+     zVal = (char*)sqlite3_value_text(argv[0]);
+     nVal = sqlite3_value_bytes(argv[0]);
+@@ -98028,12 +111233,26 @@
+ ** of the built-in functions above are part of the global function set.
+ ** This routine only deals with those that are not global.
+ */
+-SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
++SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
+   int rc = sqlite3_overload_function(db, "MATCH", 2);
++/* BEGIN SQLCIPHER */
++#ifdef SQLITE_HAS_CODEC
++#ifndef OMIT_EXPORT
++  extern void sqlcipher_exportFunc(sqlite3_context *, int, sqlite3_value **);
++#endif
++#endif
++/* END SQLCIPHER */
+   assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
+   if( rc==SQLITE_NOMEM ){
+-    db->mallocFailed = 1;
++    sqlite3OomFault(db);
+   }
++/* BEGIN SQLCIPHER */
++#ifdef SQLITE_HAS_CODEC
++#ifndef OMIT_EXPORT
++  sqlite3CreateFunc(db, "sqlcipher_export", 1, SQLITE_TEXT, 0, sqlcipher_exportFunc, 0, 0, 0);
++#endif
++#endif
++/* END SQLCIPHER */
  }
  
  /*
--** Query status information for a single database connection
--*/
--SQLITE_API int SQLITE_STDCALL sqlite3_db_status(
--  sqlite3 *db,          /* The database connection whose status is desired */
--  int op,               /* Status verb */
--  int *pCurrent,        /* Write current value here */
--  int *pHighwater,      /* Write high-water mark here */
--  int resetFlag         /* Reset high-water mark if true */
--){
--  int rc = SQLITE_OK;   /* Return code */
--#ifdef SQLITE_ENABLE_API_ARMOR
--  if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){
--    return SQLITE_MISUSE_BKPT;
--  }
+@@ -98041,8 +111260,7 @@
+ */
+ static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
+   FuncDef *pDef;
+-  pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName),
+-                             2, SQLITE_UTF8, 0);
++  pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
+   if( ALWAYS(pDef) ){
+     pDef->funcFlags |= flagVal;
+   }
+@@ -98090,9 +111308,7 @@
+     return 0;
+   }
+   assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+-  pDef = sqlite3FindFunction(db, pExpr->u.zToken, 
+-                             sqlite3Strlen30(pExpr->u.zToken),
+-                             2, SQLITE_UTF8, 0);
++  pDef = sqlite3FindFunction(db, pExpr->u.zToken, 2, SQLITE_UTF8, 0);
+   if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
+     return 0;
+   }
+@@ -98116,7 +111332,7 @@
+ **
+ ** After this routine runs
+ */
+-SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
++SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
+   /*
+   ** The following array holds FuncDef structures for all of the functions
+   ** defined in this file.
+@@ -98124,8 +111340,30 @@
+   ** The array cannot be constant since changes are made to the
+   ** FuncDef.pHash elements at start-time.  The elements of this array
+   ** are read-only after initialization is complete.
++  **
++  ** For peak efficiency, put the most frequently used function last.
+   */
+-  static SQLITE_WSD FuncDef aBuiltinFunc[] = {
++  static FuncDef aBuiltinFunc[] = {
++#ifdef SQLITE_SOUNDEX
++    FUNCTION(soundex,            1, 0, 0, soundexFunc      ),
++#endif
++#ifndef SQLITE_OMIT_LOAD_EXTENSION
++    VFUNCTION(load_extension,    1, 0, 0, loadExt          ),
++    VFUNCTION(load_extension,    2, 0, 0, loadExt          ),
++#endif
++#if SQLITE_USER_AUTHENTICATION
++    FUNCTION(sqlite_crypt,       2, 0, 0, sqlite3CryptFunc ),
++#endif
++#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
++    DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc  ),
++    DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc  ),
++#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
++    FUNCTION2(unlikely,          1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
++    FUNCTION2(likelihood,        2, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
++    FUNCTION2(likely,            1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
++#ifdef SQLITE_DEBUG
++    FUNCTION2(affinity,          1, 0, 0, noopFunc,  SQLITE_FUNC_AFFINITY),
++#endif
+     FUNCTION(ltrim,              1, 1, 0, trimFunc         ),
+     FUNCTION(ltrim,              2, 1, 0, trimFunc         ),
+     FUNCTION(rtrim,              1, 2, 0, trimFunc         ),
+@@ -98143,8 +111381,6 @@
+     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(printf,            -1, 0, 0, printfFunc       ),
+     FUNCTION(unicode,            1, 0, 0, unicodeFunc      ),
+     FUNCTION(char,              -1, 0, 0, charFunc         ),
+@@ -98155,40 +111391,22 @@
+ #endif
+     FUNCTION(upper,              1, 0, 0, upperFunc        ),
+     FUNCTION(lower,              1, 0, 0, lowerFunc        ),
+-    FUNCTION(coalesce,           1, 0, 0, 0                ),
+-    FUNCTION(coalesce,           0, 0, 0, 0                ),
+-    FUNCTION2(coalesce,         -1, 0, 0, noopFunc,  SQLITE_FUNC_COALESCE),
+     FUNCTION(hex,                1, 0, 0, hexFunc          ),
+     FUNCTION2(ifnull,            2, 0, 0, noopFunc,  SQLITE_FUNC_COALESCE),
+-    FUNCTION2(unlikely,          1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
+-    FUNCTION2(likelihood,        2, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
+-    FUNCTION2(likely,            1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
+     VFUNCTION(random,            0, 0, 0, randomFunc       ),
+     VFUNCTION(randomblob,        1, 0, 0, randomBlob       ),
+     FUNCTION(nullif,             2, 0, 1, nullifFunc       ),
+-    FUNCTION(sqlite_version,     0, 0, 0, versionFunc      ),
+-    FUNCTION(sqlite_source_id,   0, 0, 0, sourceidFunc     ),
++    DFUNCTION(sqlite_version,    0, 0, 0, versionFunc      ),
++    DFUNCTION(sqlite_source_id,  0, 0, 0, sourceidFunc     ),
+     FUNCTION(sqlite_log,         2, 0, 0, errlogFunc       ),
+-#if SQLITE_USER_AUTHENTICATION
+-    FUNCTION(sqlite_crypt,       2, 0, 0, sqlite3CryptFunc ),
 -#endif
--  sqlite3_mutex_enter(db->mutex);
--  switch( op ){
--    case SQLITE_DBSTATUS_LOOKASIDE_USED: {
--      *pCurrent = db->lookaside.nOut;
--      *pHighwater = db->lookaside.mxOut;
--      if( resetFlag ){
--        db->lookaside.mxOut = db->lookaside.nOut;
--      }
--      break;
-+ * ctx - codec context
-+ * pgno - page number in database
-+ * size - size in bytes of input and output buffers
-+ * mode - 1 to encrypt, 0 to decrypt
-+ * in - pointer to input bytes
-+ * out - pouter to output bytes
-+ */
-+int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int page_sz, unsigned char *in, 
unsigned char *out) {
-+  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
-+  unsigned char *iv_in, *iv_out, *hmac_in, *hmac_out, *out_start;
-+  int size;
-+
-+  /* calculate some required positions into various buffers */
-+  size = page_sz - c_ctx->reserve_sz; /* adjust size to useable size and memset reserve at end of page */
-+  iv_out = out + size;
-+  iv_in = in + size;
-+
-+  /* hmac will be written immediately after the initialization vector. the remainder of the page reserve 
will contain
-+     random bytes. note, these pointers are only valid when using hmac */
-+  hmac_in = in + size + c_ctx->iv_sz; 
-+  hmac_out = out + size + c_ctx->iv_sz;
-+  out_start = out; /* note the original position of the output buffer pointer, as out will be rewritten 
during encryption */
-+
-+  CODEC_TRACE(("codec_cipher:entered pgno=%d, mode=%d, size=%d\n", pgno, mode, size));
-+  CODEC_HEXDUMP("codec_cipher: input page data", in, page_sz);
-+
-+  /* the key size should never be zero. If it is, error out. */
-+  if(c_ctx->key_sz == 0) {
-+    CODEC_TRACE(("codec_cipher: error possible context corruption, key_sz is zero for pgno=%d\n", pgno));
-+    sqlcipher_memset(out, 0, page_sz); 
-+    return SQLITE_ERROR;
-+  } 
-+
-+  if(mode == CIPHER_ENCRYPT) {
-+    /* start at front of the reserve block, write random data to the end */
-+    if(c_ctx->provider->random(c_ctx->provider_ctx, iv_out, c_ctx->reserve_sz) != SQLITE_OK) return 
SQLITE_ERROR; 
-+  } else { /* CIPHER_DECRYPT */
-+    memcpy(iv_out, iv_in, c_ctx->iv_sz); /* copy the iv from the input to output buffer */
-+  } 
+-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+-    FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc  ),
+-    FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc  ),
+-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
+     FUNCTION(quote,              1, 0, 0, quoteFunc        ),
+     VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
+     VFUNCTION(changes,           0, 0, 0, changes          ),
+     VFUNCTION(total_changes,     0, 0, 0, total_changes    ),
+     FUNCTION(replace,            3, 0, 0, replaceFunc      ),
+     FUNCTION(zeroblob,           1, 0, 0, zeroblobFunc     ),
+-  #ifdef SQLITE_SOUNDEX
+-    FUNCTION(soundex,            1, 0, 0, soundexFunc      ),
+-  #endif
+-  #ifndef SQLITE_OMIT_LOAD_EXTENSION
+-    FUNCTION(load_extension,     1, 0, 0, loadExt          ),
+-    FUNCTION(load_extension,     2, 0, 0, loadExt          ),
+-  #endif
++    FUNCTION(substr,             2, 0, 0, substrFunc       ),
++    FUNCTION(substr,             3, 0, 0, substrFunc       ),
+     AGGREGATE(sum,               1, 0, 0, sumStep,         sumFinalize    ),
+     AGGREGATE(total,             1, 0, 0, sumStep,         totalFinalize    ),
+     AGGREGATE(avg,               1, 0, 0, sumStep,         avgFinalize    ),
+@@ -98199,29 +111417,44 @@
+     AGGREGATE(group_concat,      2, 0, 0, groupConcatStep, groupConcatFinalize),
+   
+     LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
+-  #ifdef SQLITE_CASE_SENSITIVE_LIKE
++#ifdef SQLITE_CASE_SENSITIVE_LIKE
+     LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
+     LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
+-  #else
++#else
+     LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
+     LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
+-  #endif
++#endif
++#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
++    FUNCTION(unknown,           -1, 0, 0, unknownFunc      ),
++#endif
++    FUNCTION(coalesce,           1, 0, 0, 0                ),
++    FUNCTION(coalesce,           0, 0, 0, 0                ),
++    FUNCTION2(coalesce,         -1, 0, 0, noopFunc,  SQLITE_FUNC_COALESCE),
+   };
+-
+-  int i;
+-  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
+-  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aBuiltinFunc);
+-
+-  for(i=0; i<ArraySize(aBuiltinFunc); i++){
+-    sqlite3FuncDefInsert(pHash, &aFunc[i]);
+-  }
+-  sqlite3RegisterDateTimeFunctions();
+ #ifndef SQLITE_OMIT_ALTERTABLE
+   sqlite3AlterFunctions();
+ #endif
+ #if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
+   sqlite3AnalyzeFunctions();
+ #endif
++  sqlite3RegisterDateTimeFunctions();
++  sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc));
 +
-+  if((c_ctx->flags & CIPHER_FLAG_HMAC) && (mode == CIPHER_DECRYPT) && !ctx->skip_read_hmac) {
-+    if(sqlcipher_page_hmac(c_ctx, pgno, in, size + c_ctx->iv_sz, hmac_out) != SQLITE_OK) {
-+      sqlcipher_memset(out, 0, page_sz); 
-+      CODEC_TRACE(("codec_cipher: hmac operations failed for pgno=%d\n", pgno));
-+      return SQLITE_ERROR;
-     }
++#if 0  /* Enable to print out how the built-in functions are hashed */
++  {
++    int i;
++    FuncDef *p;
++    for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
++      printf("FUNC-HASH %02d:", i);
++      for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){
++        int n = sqlite3Strlen30(p->zName);
++        int h = p->zName[0] + n;
++        printf(" %s(%d)", p->zName, h);
++      }
++      printf("\n");
++    }
++  }
++#endif
+ }
  
--    case SQLITE_DBSTATUS_LOOKASIDE_HIT:
--    case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE:
--    case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: {
--      testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT );
--      testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE );
--      testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL );
--      assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 );
--      assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 );
--      *pCurrent = 0;
--      *pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT];
--      if( resetFlag ){
--        db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0;
-+    CODEC_TRACE(("codec_cipher: comparing hmac on in=%p out=%p hmac_sz=%d\n", hmac_in, hmac_out, 
c_ctx->hmac_sz));
-+    if(sqlcipher_memcmp(hmac_in, hmac_out, c_ctx->hmac_sz) != 0) { /* the hmac check failed */ 
-+      if(sqlcipher_ismemset(in, 0, page_sz) == 0) {
-+        /* first check if the entire contents of the page is zeros. If so, this page 
-+           resulted from a short read (i.e. sqlite attempted to pull a page after the end of the file. 
these 
-+           short read failures must be ignored for autovaccum mode to work so wipe the output buffer 
-+           and return SQLITE_OK to skip the decryption step. */
-+        CODEC_TRACE(("codec_cipher: zeroed page (short read) for pgno %d, encryption but returning 
SQLITE_OK\n", pgno));
-+        sqlcipher_memset(out, 0, page_sz); 
-+      return SQLITE_OK;
-+      } else {
-+      /* if the page memory is not all zeros, it means the there was data and a hmac on the page. 
-+           since the check failed, the page was either tampered with or corrupted. wipe the output buffer,
-+           and return SQLITE_ERROR to the caller */
-+              CODEC_TRACE(("codec_cipher: hmac check failed for pgno=%d returning SQLITE_ERROR\n", pgno));
-+        sqlcipher_memset(out, 0, page_sz); 
-+              return SQLITE_ERROR;
-       }
--      break;
-     }
-+  } 
-+  
-+  c_ctx->provider->cipher(c_ctx->provider_ctx, mode, c_ctx->key, c_ctx->key_sz, iv_out, in, size, out);
+ /************** End of func.c ************************************************/
+@@ -98239,6 +111472,7 @@
+ ** This file contains code used by the compiler to add foreign key
+ ** support to compiled SQL statements.
+ */
++/* #include "sqliteInt.h" */
  
--    /* 
--    ** Return an approximation for the amount of memory currently used
--    ** by all pagers associated with the given database connection.  The
--    ** highwater mark is meaningless and is returned as zero.
--    */
--    case SQLITE_DBSTATUS_CACHE_USED: {
--      int totalUsed = 0;
-+  if((c_ctx->flags & CIPHER_FLAG_HMAC) && (mode == CIPHER_ENCRYPT)) {
-+    sqlcipher_page_hmac(c_ctx, pgno, out_start, size + c_ctx->iv_sz, hmac_out); 
-+  }
-+
-+  CODEC_HEXDUMP("codec_cipher: output page data", out_start, page_sz);
-+
-+  return SQLITE_OK;
-+}
-+
-+/**
-+  * Derive an encryption key for a cipher contex key based on the raw password.
-+  *
-+  * If the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
-+  * the key (i.e 64 hex chars for a 256 bit key) then the key data will be used directly. 
-+
-+  * Else, if the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
-+  * the key and the salt (i.e 92 hex chars for a 256 bit key and 16 byte salt) then it will be unpacked
-+  * as the key followed by the salt.
-+  * 
-+  * Otherwise, a key data will be derived using PBKDF2
-+  * 
-+  * returns SQLITE_OK if initialization was successful
-+  * returns SQLITE_ERROR if the key could't be derived (for instance if pass is NULL or pass_sz is 0)
-+  */
-+static int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
-+  int rc;
-+  CODEC_TRACE(("cipher_ctx_key_derive: entered c_ctx->pass=%s, c_ctx->pass_sz=%d \
-+                ctx->kdf_salt=%p ctx->kdf_salt_sz=%d c_ctx->kdf_iter=%d \
-+                ctx->hmac_kdf_salt=%p, c_ctx->fast_kdf_iter=%d c_ctx->key_sz=%d\n", 
-+                c_ctx->pass, c_ctx->pass_sz, ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter, 
-+                ctx->hmac_kdf_salt, c_ctx->fast_kdf_iter, c_ctx->key_sz)); 
-+                
-+  
-+  if(c_ctx->pass && c_ctx->pass_sz) { // if pass is not null
-+
-+    if(ctx->need_kdf_salt) {
-+      if(ctx->read_ctx->provider->random(ctx->read_ctx->provider_ctx, ctx->kdf_salt, FILE_HEADER_SZ) != 
SQLITE_OK) return SQLITE_ERROR;
-+      ctx->need_kdf_salt = 0;
-+    }
-+    if (c_ctx->pass_sz == ((c_ctx->key_sz * 2) + 3) && sqlite3StrNICmp((const char *)c_ctx->pass ,"x'", 2) 
== 0) { 
-+      int n = c_ctx->pass_sz - 3; /* adjust for leading x' and tailing ' */
-+      const unsigned char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
-+      CODEC_TRACE(("cipher_ctx_key_derive: using raw key from hex\n")); 
-+      cipher_hex2bin(z, n, c_ctx->key);
-+    } else if (c_ctx->pass_sz == (((c_ctx->key_sz + ctx->kdf_salt_sz) * 2) + 3) && sqlite3StrNICmp((const 
char *)c_ctx->pass ,"x'", 2) == 0) { 
-+      const unsigned char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
-+      CODEC_TRACE(("cipher_ctx_key_derive: using raw key from hex\n")); 
-+      cipher_hex2bin(z, (c_ctx->key_sz * 2), c_ctx->key);
-+      cipher_hex2bin(z + (c_ctx->key_sz * 2), (ctx->kdf_salt_sz * 2), ctx->kdf_salt);
-+    } else { 
-+      CODEC_TRACE(("cipher_ctx_key_derive: deriving key using full PBKDF2 with %d iterations\n", 
c_ctx->kdf_iter)); 
-+      c_ctx->provider->kdf(c_ctx->provider_ctx, c_ctx->pass, c_ctx->pass_sz, 
-+                    ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter,
-+                    c_ctx->key_sz, c_ctx->key);
-+    }
-+
-+    /* set the context "keyspec" containing the hex-formatted key and salt to be used when attaching 
databases */
-+    if((rc = sqlcipher_cipher_ctx_set_keyspec(c_ctx, c_ctx->key, c_ctx->key_sz, ctx->kdf_salt, 
ctx->kdf_salt_sz)) != SQLITE_OK) return rc;
-+
-+    /* if this context is setup to use hmac checks, generate a seperate and different 
-+       key for HMAC. In this case, we use the output of the previous KDF as the input to 
-+       this KDF run. This ensures a distinct but predictable HMAC key. */
-+    if(c_ctx->flags & CIPHER_FLAG_HMAC) {
-       int i;
--      sqlite3BtreeEnterAll(db);
--      for(i=0; i<db->nDb; i++){
--        Btree *pBt = db->aDb[i].pBt;
--        if( pBt ){
--          Pager *pPager = sqlite3BtreePager(pBt);
--          totalUsed += sqlite3PagerMemUsed(pPager);
--        }
--      }
--      sqlite3BtreeLeaveAll(db);
--      *pCurrent = totalUsed;
--      *pHighwater = 0;
--      break;
--    }
+ #ifndef SQLITE_OMIT_FOREIGN_KEY
+ #ifndef SQLITE_OMIT_TRIGGER
+@@ -98446,13 +111680,13 @@
+     }
+   }else if( paiCol ){
+     assert( nCol>1 );
+-    aiCol = (int *)sqlite3DbMallocRaw(pParse->db, nCol*sizeof(int));
++    aiCol = (int *)sqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int));
+     if( !aiCol ) return 1;
+     *paiCol = aiCol;
+   }
  
--    /*
--    ** *pCurrent gets an accurate estimate of the amount of memory used
--    ** to store the schema for all databases (main, temp, and any ATTACHed
--    ** databases.  *pHighwater is set to zero.
--    */
--    case SQLITE_DBSTATUS_SCHEMA_USED: {
--      int i;                      /* Used to iterate through schemas */
--      int nByte = 0;              /* Used to accumulate return value */
-+      /* start by copying the kdf key into the hmac salt slot
-+         then XOR it with the fixed hmac salt defined at compile time
-+         this ensures that the salt passed in to derive the hmac key, while 
-+         easy to derive and publically known, is not the same as the salt used 
-+         to generate the encryption key */ 
-+      memcpy(ctx->hmac_kdf_salt, ctx->kdf_salt, ctx->kdf_salt_sz);
-+      for(i = 0; i < ctx->kdf_salt_sz; i++) {
-+        ctx->hmac_kdf_salt[i] ^= hmac_salt_mask;
-+      } 
+   for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){
+-    if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) ){ 
++    if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) && pIdx->pPartIdxWhere==0 ){ 
+       /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
+       ** of columns. If each indexed column corresponds to a foreign key
+       ** column of pFKey, then this index is a winner.  */
+@@ -98476,16 +111710,16 @@
+         int i, j;
+         for(i=0; i<nCol; i++){
+           i16 iCol = pIdx->aiColumn[i];     /* Index of column in parent tbl */
+-          char *zDfltColl;                  /* Def. collation for column */
++          const char *zDfltColl;            /* Def. collation for column */
+           char *zIdxCol;                    /* Name of indexed column */
+ 
++          if( iCol<0 ) break; /* No foreign keys against expression indexes */
++
+           /* If the index uses a collation sequence that is different from
+           ** the default collation sequence for the column, this index is
+           ** unusable. Bail out early in this case.  */
+           zDfltColl = pParent->aCol[iCol].zColl;
+-          if( !zDfltColl ){
+-            zDfltColl = "BINARY";
+-          }
++          if( !zDfltColl ) zDfltColl = sqlite3StrBINARY;
+           if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break;
  
--      sqlite3BtreeEnterAll(db);
--      db->pnBytesFreed = &nByte;
--      for(i=0; i<db->nDb; i++){
--        Schema *pSchema = db->aDb[i].pSchema;
--        if( ALWAYS(pSchema!=0) ){
--          HashElem *p;
-+      CODEC_TRACE(("cipher_ctx_key_derive: deriving hmac key from encryption key using PBKDF2 with %d 
iterations\n", 
-+        c_ctx->fast_kdf_iter)); 
- 
--          nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * (
--              pSchema->tblHash.count 
--            + pSchema->trigHash.count
--            + pSchema->idxHash.count
--            + pSchema->fkeyHash.count
--          );
--          nByte += sqlite3MallocSize(pSchema->tblHash.ht);
--          nByte += sqlite3MallocSize(pSchema->trigHash.ht);
--          nByte += sqlite3MallocSize(pSchema->idxHash.ht);
--          nByte += sqlite3MallocSize(pSchema->fkeyHash.ht);
-+      
-+      c_ctx->provider->kdf(c_ctx->provider_ctx, c_ctx->key, c_ctx->key_sz, 
-+                    ctx->hmac_kdf_salt, ctx->kdf_salt_sz, c_ctx->fast_kdf_iter,
-+                    c_ctx->key_sz, c_ctx->hmac_key); 
+           zIdxCol = pParent->aCol[iCol].zName;
+@@ -98601,7 +111835,7 @@
+   
+       sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
+       sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v);
+-      sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
++      sqlite3VdbeGoto(v, iOk);
+       sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
+       sqlite3VdbeJumpHere(v, iMustBeInt);
+       sqlite3ReleaseTempReg(pParse, regTemp);
+@@ -98631,6 +111865,7 @@
+         for(i=0; i<nCol; i++){
+           int iChild = aiCol[i]+1+regData;
+           int iParent = pIdx->aiColumn[i]+1+regData;
++          assert( pIdx->aiColumn[i]>=0 );
+           assert( aiCol[i]!=pTab->iPKey );
+           if( pIdx->aiColumn[i]==pTab->iPKey ){
+             /* The parent key is a composite key that includes the IPK column */
+@@ -98639,11 +111874,11 @@
+           sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v);
+           sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
+         }
+-        sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
++        sqlite3VdbeGoto(v, iOk);
+       }
+   
+       sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
+-                        sqlite3IndexAffinityStr(v,pIdx), nCol);
++                        sqlite3IndexAffinityStr(pParse->db,pIdx), nCol);
+       sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v);
+   
+       sqlite3ReleaseTempReg(pParse, regRec);
+@@ -98810,7 +112045,7 @@
+     assert( iCol>=0 );
+     zCol = pFKey->pFrom->aCol[iCol].zName;
+     pRight = sqlite3Expr(db, TK_ID, zCol);
+-    pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
++    pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
+     pWhere = sqlite3ExprAnd(db, pWhere, pEq);
+   }
+ 
+@@ -98832,19 +112067,20 @@
+     if( HasRowid(pTab) ){
+       pLeft = exprTableRegister(pParse, pTab, regData, -1);
+       pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1);
+-      pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0);
++      pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight);
+     }else{
+       Expr *pEq, *pAll = 0;
+       Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+       assert( pIdx!=0 );
+       for(i=0; i<pPk->nKeyCol; i++){
+         i16 iCol = pIdx->aiColumn[i];
++        assert( iCol>=0 );
+         pLeft = exprTableRegister(pParse, pTab, regData, iCol);
+         pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
+-        pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
++        pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
+         pAll = sqlite3ExprAnd(db, pAll, pEq);
+       }
+-      pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0);
++      pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
+     }
+     pWhere = sqlite3ExprAnd(db, pWhere, pNe);
+   }
+@@ -98858,10 +112094,12 @@
+   /* Create VDBE to loop through the entries in pSrc that match the WHERE
+   ** clause. For each row found, increment either the deferred or immediate
+   ** foreign key constraint counter. */
+-  pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
+-  sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
+-  if( pWInfo ){
+-    sqlite3WhereEnd(pWInfo);
++  if( pParse->nErr==0 ){
++    pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
++    sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
++    if( pWInfo ){
++      sqlite3WhereEnd(pWInfo);
 +    }
+   }
  
--          for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
--            sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
--          }
--          for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
--            sqlite3DeleteTable(db, (Table *)sqliteHashData(p));
--          }
--        }
--      }
--      db->pnBytesFreed = 0;
--      sqlite3BtreeLeaveAll(db);
-+    c_ctx->derive_key = 0;
-+    return SQLITE_OK;
-+  };
-+  return SQLITE_ERROR;
-+}
+   /* Clean up the WHERE clause constructed above. */
+@@ -99096,7 +112334,7 @@
+   if( (db->flags&SQLITE_ForeignKeys)==0 ) return;
  
--      *pHighwater = 0;
--      *pCurrent = nByte;
--      break;
-+int sqlcipher_codec_key_derive(codec_ctx *ctx) {
-+  /* derive key on first use if necessary */
-+  if(ctx->read_ctx->derive_key) {
-+    if(sqlcipher_cipher_ctx_key_derive(ctx, ctx->read_ctx) != SQLITE_OK) return SQLITE_ERROR;
-+  }
-+
-+  if(ctx->write_ctx->derive_key) {
-+    if(sqlcipher_cipher_ctx_cmp(ctx->write_ctx, ctx->read_ctx) == 0) {
-+      /* the relevant parameters are the same, just copy read key */
-+      if(sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx) != SQLITE_OK) return SQLITE_ERROR;
-+    } else {
-+      if(sqlcipher_cipher_ctx_key_derive(ctx, ctx->write_ctx) != SQLITE_OK) return SQLITE_ERROR;
+   iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+-  zDb = db->aDb[iDb].zName;
++  zDb = db->aDb[iDb].zDbSName;
+ 
+   /* Loop through all the foreign key constraints for which pTab is the
+   ** child table (the table that the foreign key definition is part of).  */
+@@ -99158,6 +112396,7 @@
+       if( aiCol[i]==pTab->iPKey ){
+         aiCol[i] = -1;
+       }
++      assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+       /* Request permission to read the parent key columns. If the 
+       ** authorization callback returns SQLITE_IGNORE, behave as if any
+@@ -99231,7 +112470,7 @@
+       struct SrcList_item *pItem = pSrc->a;
+       pItem->pTab = pFKey->pFrom;
+       pItem->zName = pFKey->pFrom->zName;
+-      pItem->pTab->nRef++;
++      pItem->pTab->nTabRef++;
+       pItem->iCursor = pParse->nTab++;
+   
+       if( regNew!=0 ){
+@@ -99289,7 +112528,10 @@
+       Index *pIdx = 0;
+       sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
+       if( pIdx ){
+-        for(i=0; i<pIdx->nKeyCol; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
++        for(i=0; i<pIdx->nKeyCol; i++){
++          assert( pIdx->aiColumn[i]>=0 );
++          mask |= COLUMN_MASK(pIdx->aiColumn[i]);
++        }
+       }
      }
-+  }
+   }
+@@ -99308,8 +112550,16 @@
+ ** UPDATE statement modifies the rowid fields of the table.
+ **
+ ** If any foreign key processing will be required, this function returns
+-** true. If there is no foreign key related processing, this function 
+-** returns false.
++** non-zero. If there is no foreign key related processing, this function 
++** returns zero.
++**
++** For an UPDATE, this function returns 2 if:
++**
++**   * There are any FKs for which pTab is the child and the parent table, or
++**   * the UPDATE modifies one or more parent keys for which the action is
++**     not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL).
++**
++** Or, assuming some other foreign key processing is required, 1.
+ */
+ SQLITE_PRIVATE int sqlite3FkRequired(
+   Parse *pParse,                  /* Parse context */
+@@ -99317,12 +112567,13 @@
+   int *aChange,                   /* Non-NULL for UPDATE operations */
+   int chngRowid                   /* True for UPDATE that affects rowid */
+ ){
++  int eRet = 0;
+   if( pParse->db->flags&SQLITE_ForeignKeys ){
+     if( !aChange ){
+       /* A DELETE operation. Foreign key processing is required if the 
+       ** table in question is either the child or parent table for any 
+       ** foreign key constraint.  */
+-      return (sqlite3FkReferences(pTab) || pTab->pFKey);
++      eRet = (sqlite3FkReferences(pTab) || pTab->pFKey);
+     }else{
+       /* This is an UPDATE. Foreign key processing is only required if the
+       ** operation modifies one or more child or parent key columns. */
+@@ -99330,16 +112581,22 @@
+ 
+       /* Check if any child key columns are being modified. */
+       for(p=pTab->pFKey; p; p=p->pNextFrom){
+-        if( fkChildIsModified(pTab, p, aChange, chngRowid) ) return 1;
++        if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) return 2;
++        if( fkChildIsModified(pTab, p, aChange, chngRowid) ){
++          eRet = 1;
++        }
+       }
  
--    /*
--    ** *pCurrent gets an accurate estimate of the amount of memory used
--    ** to store all prepared statements.
--    ** *pHighwater is set to zero.
--    */
--    case SQLITE_DBSTATUS_STMT_USED: {
--      struct Vdbe *pVdbe;         /* Used to iterate through VMs */
--      int nByte = 0;              /* Used to accumulate return value */
-+  /* TODO: wipe and free passphrase after key derivation */
-+  if(ctx->read_ctx->store_pass  != 1) {
-+    sqlcipher_cipher_ctx_set_pass(ctx->read_ctx, NULL, 0);
-+    sqlcipher_cipher_ctx_set_pass(ctx->write_ctx, NULL, 0);
-+  }
+       /* Check if any parent key columns are being modified. */
+       for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
+-        if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1;
++        if( fkParentIsModified(pTab, p, aChange, chngRowid) ){
++          if( p->aAction[1]!=OE_None ) return 2;
++          eRet = 1;
++        }
+       }
+     }
+   }
+-  return 0;
++  return eRet;
+ }
  
--      db->pnBytesFreed = &nByte;
--      for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
--        sqlite3VdbeClearObject(db, pVdbe);
--        sqlite3DbFree(db, pVdbe);
--      }
--      db->pnBytesFreed = 0;
-+  return SQLITE_OK; 
-+}
+ /*
+@@ -99383,10 +112640,12 @@
+   int iAction = (pChanges!=0);    /* 1 for UPDATE, 0 for DELETE */
  
--      *pHighwater = 0;  /* IMP: R-64479-57858 */
--      *pCurrent = nByte;
-+int sqlcipher_codec_key_copy(codec_ctx *ctx, int source) {
-+  if(source == CIPHER_READ_CTX) { 
-+      return sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx); 
-+  } else {
-+      return sqlcipher_cipher_ctx_copy(ctx->read_ctx, ctx->write_ctx); 
+   action = pFKey->aAction[iAction];
++  if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){
++    return 0;
 +  }
-+}
+   pTrigger = pFKey->apTrigger[iAction];
+ 
+   if( action!=OE_None && !pTrigger ){
+-    u8 enableLookaside;           /* Copy of db->lookaside.bEnabled */
+     char const *zFrom;            /* Name of child table */
+     int nFrom;                    /* Length in bytes of zFrom */
+     Index *pIdx = 0;              /* Parent key index for this FK */
+@@ -99412,11 +112671,10 @@
+       iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
+       assert( iFromCol>=0 );
+       assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
+-      tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
+-      tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
+-
+-      tToCol.n = sqlite3Strlen30(tToCol.z);
+-      tFromCol.n = sqlite3Strlen30(tFromCol.z);
++      assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
++      sqlite3TokenInit(&tToCol,
++                   pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName);
++      sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName);
+ 
+       /* Create the expression "OLD.zToCol = zFromCol". It is important
+       ** that the "OLD.zToCol" term is on the LHS of the = operator, so
+@@ -99425,10 +112683,9 @@
+       pEq = sqlite3PExpr(pParse, TK_EQ,
+           sqlite3PExpr(pParse, TK_DOT, 
+             sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+-            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
+-          , 0),
++            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
+           sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
+-      , 0);
++      );
+       pWhere = sqlite3ExprAnd(db, pWhere, pEq);
+ 
+       /* For ON UPDATE, construct the next term of the WHEN clause.
+@@ -99440,13 +112697,11 @@
+         pEq = sqlite3PExpr(pParse, TK_IS,
+             sqlite3PExpr(pParse, TK_DOT, 
+               sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+-              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
+-              0),
++              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
+             sqlite3PExpr(pParse, TK_DOT, 
+               sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+-              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
+-              0),
+-            0);
++              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
++            );
+         pWhen = sqlite3ExprAnd(db, pWhen, pEq);
+       }
+   
+@@ -99455,17 +112710,16 @@
+         if( action==OE_Cascade ){
+           pNew = sqlite3PExpr(pParse, TK_DOT, 
+             sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+-            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
+-          , 0);
++            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0));
+         }else if( action==OE_SetDflt ){
+           Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
+           if( pDflt ){
+             pNew = sqlite3ExprDup(db, pDflt, 0);
+           }else{
+-            pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
++            pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
+           }
+         }else{
+-          pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
++          pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
+         }
+         pList = sqlite3ExprListAppend(pParse, pList, pNew);
+         sqlite3ExprListSetName(pParse, pList, &tFromCol, 0);
+@@ -99496,8 +112750,7 @@
+     }
  
--      break;
--    }
-+const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx) {
-+  return ctx->read_ctx->provider->get_provider_name(ctx->read_ctx);
-+}
+     /* Disable lookaside memory allocation */
+-    enableLookaside = db->lookaside.bEnabled;
+-    db->lookaside.bEnabled = 0;
++    db->lookaside.bDisable++;
+ 
+     pTrigger = (Trigger *)sqlite3DbMallocZero(db, 
+         sizeof(Trigger) +         /* struct Trigger */
+@@ -99513,13 +112766,13 @@
+       pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
+       pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
+       if( pWhen ){
+-        pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0);
++        pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0);
+         pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
+       }
+     }
  
--    /*
--    ** Set *pCurrent to the total cache hits or misses encountered by all
--    ** pagers the database handle is connected to. *pHighwater is always set 
--    ** to zero.
--    */
--    case SQLITE_DBSTATUS_CACHE_HIT:
--    case SQLITE_DBSTATUS_CACHE_MISS:
--    case SQLITE_DBSTATUS_CACHE_WRITE:{
--      int i;
--      int nRet = 0;
--      assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
--      assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 );
- 
--      for(i=0; i<db->nDb; i++){
--        if( db->aDb[i].pBt ){
--          Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
--          sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
--        }
-+static int sqlcipher_check_connection(const char *filename, char *key, int key_sz, char *sql, int 
*user_version) {
-+  int rc;
-+  sqlite3 *db = NULL;
-+  sqlite3_stmt *statement = NULL;
-+  char *query_user_version = "PRAGMA user_version;";
-+  
-+  rc = sqlite3_open(filename, &db);
-+  if(rc != SQLITE_OK){
-+    goto cleanup;
-+  }
-+  rc = sqlite3_key(db, key, key_sz);
-+  if(rc != SQLITE_OK){
-+    goto cleanup;
-+  }
-+  rc = sqlite3_exec(db, sql, NULL, NULL, NULL);
-+  if(rc != SQLITE_OK){
-+    goto cleanup;
-+  }
-+  rc = sqlite3_prepare(db, query_user_version, -1, &statement, NULL);
-+  if(rc != SQLITE_OK){
-+    goto cleanup;
-+  }
-+  rc = sqlite3_step(statement);
-+  if(rc == SQLITE_ROW){
-+    *user_version = sqlite3_column_int(statement, 0);
-+    rc = SQLITE_OK;
-+  }
-+  
-+cleanup:
-+  if(statement){
-+    sqlite3_finalize(statement);
-+  }
-+  if(db){
-+    sqlite3_close(db);
-+  }
-+  return rc;
-+}
-+
-+int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
-+  u32 meta;
-+  int rc = 0;
-+  int command_idx = 0;
-+  int password_sz;
-+  int saved_flags;
-+  int saved_nChange;
-+  int saved_nTotalChange;
-+  void (*saved_xTrace)(void*,const char*);
-+  Db *pDb = 0;
-+  sqlite3 *db = ctx->pBt->db;
-+  const char *db_filename = sqlite3_db_filename(db, "main");
-+  char *migrated_db_filename = sqlite3_mprintf("%s-migrated", db_filename);
-+  char *pragma_hmac_off = "PRAGMA cipher_use_hmac = OFF;";
-+  char *pragma_4k_kdf_iter = "PRAGMA kdf_iter = 4000;";
-+  char *pragma_1x_and_4k;
-+  char *set_user_version;
-+  char *key;
-+  int key_sz;
-+  int user_version = 0;
-+  int upgrade_1x_format = 0;
-+  int upgrade_4k_format = 0;
-+  static const unsigned char aCopy[] = {
-+    BTREE_SCHEMA_VERSION,     1,  /* Add one to the old schema cookie */
-+    BTREE_DEFAULT_CACHE_SIZE, 0,  /* Preserve the default page cache size */
-+    BTREE_TEXT_ENCODING,      0,  /* Preserve the text encoding */
-+    BTREE_USER_VERSION,       0,  /* Preserve the user version */
-+    BTREE_APPLICATION_ID,     0,  /* Preserve the application id */
-+  };
-+
-+
-+  key_sz = ctx->read_ctx->pass_sz + 1;
-+  key = sqlcipher_malloc(key_sz);
-+  memset(key, 0, key_sz);
-+  memcpy(key, ctx->read_ctx->pass, ctx->read_ctx->pass_sz);
-+
-+  if(db_filename){
-+    const char* commands[5];
-+    char *attach_command = sqlite3_mprintf("ATTACH DATABASE '%s-migrated' as migrate KEY '%q';",
-+                                            db_filename, key);
-+
-+    int rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, "", &user_version);
-+    if(rc == SQLITE_OK){
-+      CODEC_TRACE(("No upgrade required - exiting\n"));
-+      goto exit;
-+    }
-+    
-+    // Version 2 - check for 4k with hmac format 
-+    rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, pragma_4k_kdf_iter, 
&user_version);
-+    if(rc == SQLITE_OK) {
-+      CODEC_TRACE(("Version 2 format found\n"));
-+      upgrade_4k_format = 1;
-+    }
-+
-+    // Version 1 - check both no hmac and 4k together
-+    pragma_1x_and_4k = sqlite3_mprintf("%s%s", pragma_hmac_off,
-+                                             pragma_4k_kdf_iter);
-+    rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, pragma_1x_and_4k, 
&user_version);
-+    sqlite3_free(pragma_1x_and_4k);
-+    if(rc == SQLITE_OK) {
-+      CODEC_TRACE(("Version 1 format found\n"));
-+      upgrade_1x_format = 1;
-+      upgrade_4k_format = 1;
-+    }
-+
-+    if(upgrade_1x_format == 0 && upgrade_4k_format == 0) {
-+      CODEC_TRACE(("Upgrade format not determined\n"));
-+      goto handle_error;
-+    }
-+
-+    set_user_version = sqlite3_mprintf("PRAGMA migrate.user_version = %d;", user_version);
-+    commands[0] = upgrade_4k_format == 1 ? pragma_4k_kdf_iter : "";
-+    commands[1] = upgrade_1x_format == 1 ? pragma_hmac_off : "";
-+    commands[2] = attach_command;
-+    commands[3] = "SELECT sqlcipher_export('migrate');";
-+    commands[4] = set_user_version;
-+      
-+    for(command_idx = 0; command_idx < ArraySize(commands); command_idx++){
-+      const char *command = commands[command_idx];
-+      if(strcmp(command, "") == 0){
-+        continue;
+     /* Re-enable the lookaside buffer, if it was disabled earlier. */
+-    db->lookaside.bEnabled = enableLookaside;
++    db->lookaside.bDisable--;
+ 
+     sqlite3ExprDelete(db, pWhere);
+     sqlite3ExprDelete(db, pWhen);
+@@ -99593,7 +112846,8 @@
+   FKey *pFKey;                    /* Iterator variable */
+   FKey *pNext;                    /* Copy of pFKey->pNextFrom */
+ 
+-  assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) );
++  assert( db==0 || IsVirtual(pTab)
++         || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) );
+   for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){
+ 
+     /* Remove the FK from the fkeyHash hash table. */
+@@ -99643,6 +112897,7 @@
+ ** This file contains C code routines that are called by the parser
+ ** to handle INSERT statements in SQLite.
+ */
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** Generate code that will 
+@@ -99672,7 +112927,7 @@
+   }else{
+     Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+     assert( pPk!=0 );
+-    assert( pPk->tnum=pTab->tnum );
++    assert( pPk->tnum==pTab->tnum );
+     sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
+     sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+     VdbeComment((v, "%s", pTab->zName));
+@@ -99686,7 +112941,7 @@
+ **
+ **  Character      Column affinity
+ **  ------------------------------
+-**  'A'            NONE
++**  'A'            BLOB
+ **  'B'            TEXT
+ **  'C'            NUMERIC
+ **  'D'            INTEGER
+@@ -99699,7 +112954,7 @@
+ ** is managed along with the rest of the Index structure. It will be
+ ** released when sqlite3DeleteIndex() is called.
+ */
+-SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
++SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
+   if( !pIdx->zColAff ){
+     /* The first time a column affinity string for a particular index is
+     ** required, it is allocated and populated here. It is then stored as
+@@ -99711,15 +112966,25 @@
+     */
+     int n;
+     Table *pTab = pIdx->pTable;
+-    sqlite3 *db = sqlite3VdbeDb(v);
+     pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1);
+     if( !pIdx->zColAff ){
+-      db->mallocFailed = 1;
++      sqlite3OomFault(db);
+       return 0;
+     }
+     for(n=0; n<pIdx->nColumn; n++){
+       i16 x = pIdx->aiColumn[n];
+-      pIdx->zColAff[n] = x<0 ? SQLITE_AFF_INTEGER : pTab->aCol[x].affinity;
++      if( x>=0 ){
++        pIdx->zColAff[n] = pTab->aCol[x].affinity;
++      }else if( x==XN_ROWID ){
++        pIdx->zColAff[n] = SQLITE_AFF_INTEGER;
++      }else{
++        char aff;
++        assert( x==XN_EXPR );
++        assert( pIdx->aColExpr!=0 );
++        aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
++        if( aff==0 ) aff = SQLITE_AFF_BLOB;
++        pIdx->zColAff[n] = aff;
 +      }
-+      rc = sqlite3_exec(db, command, NULL, NULL, NULL);
-+      if(rc != SQLITE_OK){
-+        break;
+     }
+     pIdx->zColAff[n] = 0;
+   }
+@@ -99729,9 +112994,9 @@
+ 
+ /*
+ ** Compute the affinity string for table pTab, if it has not already been
+-** computed.  As an optimization, omit trailing SQLITE_AFF_NONE affinities.
++** computed.  As an optimization, omit trailing SQLITE_AFF_BLOB affinities.
+ **
+-** If the affinity exists (if it is no entirely SQLITE_AFF_NONE values) and
++** If the affinity exists (if it is no entirely SQLITE_AFF_BLOB values) and
+ ** if iReg>0 then code an OP_Affinity opcode that will set the affinities
+ ** for register iReg and following.  Or if affinities exists and iReg==0,
+ ** then just set the P4 operand of the previous opcode (which should  be
+@@ -99741,7 +113006,7 @@
+ **
+ **  Character      Column affinity
+ **  ------------------------------
+-**  'A'            NONE
++**  'A'            BLOB
+ **  'B'            TEXT
+ **  'C'            NUMERIC
+ **  'D'            INTEGER
+@@ -99754,7 +113019,7 @@
+     sqlite3 *db = sqlite3VdbeDb(v);
+     zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
+     if( !zColAff ){
+-      db->mallocFailed = 1;
++      sqlite3OomFault(db);
+       return;
+     }
+ 
+@@ -99763,7 +113028,7 @@
+     }
+     do{
+       zColAff[i--] = 0;
+-    }while( i>=0 && zColAff[i]==SQLITE_AFF_NONE );
++    }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
+     pTab->zColAff = zColAff;
+   }
+   i = sqlite3Strlen30(zColAff);
+@@ -99820,7 +113085,9 @@
+ /*
+ ** Locate or create an AutoincInfo structure associated with table pTab
+ ** which is in database iDb.  Return the register number for the register
+-** that holds the maximum rowid.
++** that holds the maximum rowid.  Return zero if pTab is not an AUTOINCREMENT
++** table.  (Also return zero when doing a VACUUM since we do not want to
++** update the AUTOINCREMENT counters during a VACUUM.)
+ **
+ ** There is at most one AutoincInfo structure per table even if the
+ ** same table is autoincremented multiple times due to inserts within
+@@ -99843,14 +113110,16 @@
+   Table *pTab         /* The table we are writing to */
+ ){
+   int memId = 0;      /* Register holding maximum rowid */
+-  if( pTab->tabFlags & TF_Autoincrement ){
++  if( (pTab->tabFlags & TF_Autoincrement)!=0
++   && (pParse->db->flags & SQLITE_Vacuum)==0
++  ){
+     Parse *pToplevel = sqlite3ParseToplevel(pParse);
+     AutoincInfo *pInfo;
+ 
+     pInfo = pToplevel->pAinc;
+     while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
+     if( pInfo==0 ){
+-      pInfo = sqlite3DbMallocRaw(pParse->db, sizeof(*pInfo));
++      pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo));
+       if( pInfo==0 ) return 0;
+       pInfo->pNext = pToplevel->pAinc;
+       pToplevel->pAinc = pInfo;
+@@ -99874,43 +113143,55 @@
+   sqlite3 *db = pParse->db;  /* The database connection */
+   Db *pDb;                   /* Database only autoinc table */
+   int memId;                 /* Register holding max rowid */
+-  int addr;                  /* A VDBE address */
+   Vdbe *v = pParse->pVdbe;   /* VDBE under construction */
+ 
+   /* This routine is never called during trigger-generation.  It is
+   ** only called from the top-level */
+   assert( pParse->pTriggerTab==0 );
+-  assert( pParse==sqlite3ParseToplevel(pParse) );
++  assert( sqlite3IsToplevel(pParse) );
+ 
+   assert( v );   /* We failed long ago if this is not so */
+   for(p = pParse->pAinc; p; p = p->pNext){
++    static const int iLn = VDBE_OFFSET_LINENO(2);
++    static const VdbeOpList autoInc[] = {
++      /* 0  */ {OP_Null,    0,  0, 0},
++      /* 1  */ {OP_Rewind,  0,  9, 0},
++      /* 2  */ {OP_Column,  0,  0, 0},
++      /* 3  */ {OP_Ne,      0,  7, 0},
++      /* 4  */ {OP_Rowid,   0,  0, 0},
++      /* 5  */ {OP_Column,  0,  1, 0},
++      /* 6  */ {OP_Goto,    0,  9, 0},
++      /* 7  */ {OP_Next,    0,  2, 0},
++      /* 8  */ {OP_Integer, 0,  0, 0},
++      /* 9  */ {OP_Close,   0,  0, 0} 
++    };
++    VdbeOp *aOp;
+     pDb = &db->aDb[p->iDb];
+     memId = p->regCtr;
+     assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
+     sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
+-    sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1);
+-    addr = sqlite3VdbeCurrentAddr(v);
+-    sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
+-    sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); VdbeCoverage(v);
+-    sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);
+-    sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); VdbeCoverage(v);
+-    sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
+-    sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
+-    sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId);
+-    sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9);
+-    sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); VdbeCoverage(v);
+-    sqlite3VdbeAddOp2(v, OP_Integer, 0, memId);
+-    sqlite3VdbeAddOp0(v, OP_Close);
++    sqlite3VdbeLoadString(v, memId-1, p->pTab->zName);
++    aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn);
++    if( aOp==0 ) break;
++    aOp[0].p2 = memId;
++    aOp[0].p3 = memId+1;
++    aOp[2].p3 = memId;
++    aOp[3].p1 = memId-1;
++    aOp[3].p3 = memId;
++    aOp[3].p5 = SQLITE_JUMPIFNULL;
++    aOp[4].p2 = memId+1;
++    aOp[5].p3 = memId;
++    aOp[8].p2 = memId;
+   }
+ }
+ 
+ /*
+ ** Update the maximum rowid for an autoincrement calculation.
+ **
+-** This routine should be called when the top of the stack holds a
++** This routine should be called when the regRowid register holds a
+ ** new rowid that is about to be inserted.  If that new rowid is
+ ** larger than the maximum rowid in the memId memory cell, then the
+-** memory cell is updated.  The stack is unchanged.
++** memory cell is updated.
+ */
+ static void autoIncStep(Parse *pParse, int memId, int regRowid){
+   if( memId>0 ){
+@@ -99925,31 +113206,44 @@
+ ** table (either directly or through triggers) needs to call this
+ ** routine just before the "exit" code.
+ */
+-SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
++static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){
+   AutoincInfo *p;
+   Vdbe *v = pParse->pVdbe;
+   sqlite3 *db = pParse->db;
+ 
+   assert( v );
+   for(p = pParse->pAinc; p; p = p->pNext){
++    static const int iLn = VDBE_OFFSET_LINENO(2);
++    static const VdbeOpList autoIncEnd[] = {
++      /* 0 */ {OP_NotNull,     0, 2, 0},
++      /* 1 */ {OP_NewRowid,    0, 0, 0},
++      /* 2 */ {OP_MakeRecord,  0, 2, 0},
++      /* 3 */ {OP_Insert,      0, 0, 0},
++      /* 4 */ {OP_Close,       0, 0, 0}
++    };
++    VdbeOp *aOp;
+     Db *pDb = &db->aDb[p->iDb];
+-    int j1;
+     int iRec;
+     int memId = p->regCtr;
+ 
+     iRec = sqlite3GetTempReg(pParse);
+     assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
+     sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
+-    j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v);
+-    sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1);
+-    sqlite3VdbeJumpHere(v, j1);
+-    sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
+-    sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);
+-    sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+-    sqlite3VdbeAddOp0(v, OP_Close);
++    aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn);
++    if( aOp==0 ) break;
++    aOp[0].p1 = memId+1;
++    aOp[1].p2 = memId+1;
++    aOp[2].p1 = memId-1;
++    aOp[2].p3 = iRec;
++    aOp[3].p2 = iRec;
++    aOp[3].p3 = memId+1;
++    aOp[3].p5 = OPFLAG_APPEND;
+     sqlite3ReleaseTempReg(pParse, iRec);
+   }
+ }
++SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
++  if( pParse->pAinc ) autoIncrementEnd(pParse);
++}
+ #else
+ /*
+ ** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines
+@@ -100076,8 +113370,7 @@
+   sqlite3 *db;          /* The main database structure */
+   Table *pTab;          /* The table to insert into.  aka TABLE */
+   char *zTab;           /* Name of the table into which we are inserting */
+-  const char *zDb;      /* Name of the database holding this table */
+-  int i, j, idx;        /* Loop counters */
++  int i, j;             /* Loop counters */
+   Vdbe *v;              /* Generate code into this virtual machine */
+   Index *pIdx;          /* For looping over indices of the table */
+   int nColumn;          /* Number of columns in the data */
+@@ -100091,7 +113384,6 @@
+   int addrCont = 0;     /* Top of insert loop. Label "C" in templates 3 and 4 */
+   SelectDest dest;      /* Destination for SELECT on rhs of INSERT */
+   int iDb;              /* Index of database holding TABLE */
+-  Db *pDb;              /* The database containing table being inserted into */
+   u8 useTempTable = 0;  /* Store SELECT results in intermediate table */
+   u8 appendFlag = 0;    /* True if the insert is likely to be an append */
+   u8 withoutRowid;      /* 0 for normal table.  1 for WITHOUT ROWID table */
+@@ -100114,10 +113406,10 @@
+ #endif
+ 
+   db = pParse->db;
+-  memset(&dest, 0, sizeof(dest));
+   if( pParse->nErr || db->mallocFailed ){
+     goto insert_cleanup;
+   }
++  dest.iSDParm = 0;  /* Suppress a harmless compiler warning */
+ 
+   /* If the Select object is really just a simple VALUES() list with a
+   ** single row (the common case) then keep that one row of values
+@@ -100141,9 +113433,8 @@
+   }
+   iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+   assert( iDb<db->nDb );
+-  pDb = &db->aDb[iDb];
+-  zDb = pDb->zName;
+-  if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
++  if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0,
++                       db->aDb[iDb].zDbSName) ){
+     goto insert_cleanup;
+   }
+   withoutRowid = !HasRowid(pTab);
+@@ -100280,7 +113571,7 @@
+     rc = sqlite3Select(pParse, pSelect, &dest);
+     regFromSelect = dest.iSdst;
+     if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
+-    sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
++    sqlite3VdbeEndCoroutine(v, regYield);
+     sqlite3VdbeJumpHere(v, addrTop - 1);                       /* label B: */
+     assert( pSelect->pEList );
+     nColumn = pSelect->pEList->nExpr;
+@@ -100321,7 +113612,7 @@
+       sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
+       sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
+       sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
+-      sqlite3VdbeAddOp2(v, OP_Goto, 0, addrL);
++      sqlite3VdbeGoto(v, addrL);
+       sqlite3VdbeJumpHere(v, addrL);
+       sqlite3ReleaseTempReg(pParse, regRec);
+       sqlite3ReleaseTempReg(pParse, regTempRowid);
+@@ -100335,11 +113626,13 @@
+     sNC.pParse = pParse;
+     srcTab = -1;
+     assert( useTempTable==0 );
+-    nColumn = pList ? pList->nExpr : 0;
+-    for(i=0; i<nColumn; i++){
+-      if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
++    if( pList ){
++      nColumn = pList->nExpr;
++      if( sqlite3ResolveExprListNames(&sNC, pList) ){
+         goto insert_cleanup;
+       }
++    }else{
++      nColumn = 0;
+     }
+   }
+ 
+@@ -100354,10 +113647,8 @@
+   /* Make sure the number of columns in the source data matches the number
+   ** of columns to be inserted into the table.
+   */
+-  if( IsVirtual(pTab) ){
+-    for(i=0; i<pTab->nCol; i++){
+-      nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0);
+-    }
++  for(i=0; i<pTab->nCol; i++){
++    nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0);
+   }
+   if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){
+     sqlite3ErrorMsg(pParse, 
+@@ -100380,14 +113671,16 @@
+   /* If this is not a view, open the table and and all indices */
+   if( !isView ){
+     int nIdx;
+-    nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, -1, 0,
++    nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
+                                       &iDataCur, &iIdxCur);
+-    aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1));
++    aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1));
+     if( aRegIdx==0 ){
+       goto insert_cleanup;
+     }
+-    for(i=0; i<nIdx; i++){
++    for(i=0, pIdx=pTab->pIndex; i<nIdx; pIdx=pIdx->pNext, i++){
++      assert( pIdx );
+       aRegIdx[i] = ++pParse->nMem;
++      pParse->nMem += pIdx->nColumn;
+     }
+   }
+ 
+@@ -100432,7 +113725,7 @@
+     if( ipkColumn<0 ){
+       sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
+     }else{
+-      int j1;
++      int addr1;
+       assert( !withoutRowid );
+       if( useTempTable ){
+         sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols);
+@@ -100440,9 +113733,9 @@
+         assert( pSelect==0 );  /* Otherwise useTempTable is true */
+         sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols);
        }
--      *pHighwater = 0; /* IMP: R-42420-56072 */
--                       /* IMP: R-54100-20147 */
--                       /* IMP: R-29431-39229 */
--      *pCurrent = nRet;
--      break;
+-      j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
++      addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
+       sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
+-      sqlite3VdbeJumpHere(v, j1);
++      sqlite3VdbeJumpHere(v, addr1);
+       sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v);
      }
-+    sqlite3_free(attach_command);
-+    sqlite3_free(set_user_version);
-+    sqlcipher_free(key, key_sz);
-+    
-+    if(rc == SQLITE_OK){
-+      Btree *pDest;
-+      Btree *pSrc;
-+      int i = 0;
  
--    /* Set *pCurrent to non-zero if there are unresolved deferred foreign
--    ** key constraints.  Set *pCurrent to zero if all foreign key constraints
--    ** have been satisfied.  The *pHighwater is always set to zero.
--    */
--    case SQLITE_DBSTATUS_DEFERRED_FKS: {
--      *pHighwater = 0;  /* IMP: R-11967-56545 */
--      *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
--      break;
+@@ -100453,15 +113746,14 @@
+ 
+     /* Create the new column data
+     */
+-    for(i=0; i<pTab->nCol; i++){
+-      if( pColumn==0 ){
+-        j = i;
+-      }else{
++    for(i=j=0; i<pTab->nCol; i++){
++      if( pColumn ){
+         for(j=0; j<pColumn->nId; j++){
+           if( pColumn->a[j].idx==i ) break;
+         }
+       }
+-      if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId) ){
++      if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId)
++            || (pColumn==0 && IsOrdinaryHiddenColumn(&pTab->aCol[i])) ){
+         sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1);
+       }else if( useTempTable ){
+         sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); 
+@@ -100469,6 +113761,7 @@
+         assert( pSelect==0 ); /* Otherwise useTempTable is true */
+         sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1);
+       }
++      if( pColumn==0 && !IsOrdinaryHiddenColumn(&pTab->aCol[i]) ) j++;
+     }
+ 
+     /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
+@@ -100516,14 +113809,14 @@
+       ** to generate a unique primary key value.
+       */
+       if( !appendFlag ){
+-        int j1;
++        int addr1;
+         if( !IsVirtual(pTab) ){
+-          j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
++          addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
+           sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
+-          sqlite3VdbeJumpHere(v, j1);
++          sqlite3VdbeJumpHere(v, addr1);
+         }else{
+-          j1 = sqlite3VdbeCurrentAddr(v);
+-          sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2); VdbeCoverage(v);
++          addr1 = sqlite3VdbeCurrentAddr(v);
++          sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v);
+         }
+         sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v);
+       }
+@@ -100552,7 +113845,6 @@
+       }
+       if( pColumn==0 ){
+         if( IsHiddenColumn(&pTab->aCol[i]) ){
+-          assert( IsVirtual(pTab) );
+           j = -1;
+           nHidden++;
+         }else{
+@@ -100590,12 +113882,26 @@
+ #endif
+     {
+       int isReplace;    /* Set to true if constraints may cause a replace */
++      int bUseSeek;     /* True to use OPFLAG_SEEKRESULT */
+       sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+-          regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace
++          regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0
+       );
+       sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
++
++      /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE
++      ** constraints or (b) there are no triggers and this table is not a
++      ** parent table in a foreign key constraint. It is safe to set the
++      ** flag in the second case as if any REPLACE constraint is hit, an
++      ** OP_Delete or OP_IdxDelete instruction will be executed on each 
++      ** cursor that is disturbed. And these instructions both clear the
++      ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT
++      ** functionality.  */
++      bUseSeek = (isReplace==0 || (pTrigger==0 &&
++          ((db->flags & SQLITE_ForeignKeys)==0 || sqlite3FkReferences(pTab)==0)
++      ));
+       sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
+-                               regIns, aRegIdx, 0, appendFlag, isReplace==0);
++          regIns, aRegIdx, 0, appendFlag, bUseSeek
++      );
+     }
+   }
+ 
+@@ -100620,18 +113926,10 @@
+     sqlite3VdbeJumpHere(v, addrInsTop);
+     sqlite3VdbeAddOp1(v, OP_Close, srcTab);
+   }else if( pSelect ){
+-    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrCont);
++    sqlite3VdbeGoto(v, addrCont);
+     sqlite3VdbeJumpHere(v, addrInsTop);
+   }
+ 
+-  if( !IsVirtual(pTab) && !isView ){
+-    /* Close all tables opened */
+-    if( iDataCur<iIdxCur ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur);
+-    for(idx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
+-      sqlite3VdbeAddOp1(v, OP_Close, idx+iIdxCur);
 -    }
-+      if( !db->autoCommit ){
-+        CODEC_TRACE(("cannot migrate from within a transaction"));
-+        goto handle_error;
-+      }
-+      if( db->nVdbeActive>1 ){
-+        CODEC_TRACE(("cannot migrate - SQL statements in progress"));
-+        goto handle_error;
-+      }
-+
-+      /* Save the current value of the database flags so that it can be
-+      ** restored before returning. Then set the writable-schema flag, and
-+      ** disable CHECK and foreign key constraints.  */
-+      saved_flags = db->flags;
-+      saved_nChange = db->nChange;
-+      saved_nTotalChange = db->nTotalChange;
-+      saved_xTrace = db->xTrace;
-+      db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
-+      db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
-+      db->xTrace = 0;
-+      
-+      pDest = db->aDb[0].pBt;
-+      pDb = &(db->aDb[db->nDb-1]);
-+      pSrc = pDb->pBt;
-+      
-+      rc = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
-+      rc = sqlite3BtreeBeginTrans(pSrc, 2);
-+      rc = sqlite3BtreeBeginTrans(pDest, 2);
-+      
-+      assert( 1==sqlite3BtreeIsInTrans(pDest) );
-+      assert( 1==sqlite3BtreeIsInTrans(pSrc) );
+-  }
+-
+ insert_end:
+   /* Update the sqlite_sequence table by storing the content of the
+   ** maximum rowid counter values recorded while inserting into
+@@ -100674,6 +113972,59 @@
+ #endif
  
--    default: {
--      rc = SQLITE_ERROR;
-+      sqlite3CodecGetKey(db, db->nDb - 1, (void**)&key, &password_sz);
-+      sqlite3CodecAttach(db, 0, key, password_sz);
-+      sqlite3pager_get_codec(pDest->pBt->pPager, (void**)&ctx);
-+      
-+      ctx->skip_read_hmac = 1;      
-+      for(i=0; i<ArraySize(aCopy); i+=2){
-+        sqlite3BtreeGetMeta(pSrc, aCopy[i], &meta);
-+        rc = sqlite3BtreeUpdateMeta(pDest, aCopy[i], meta+aCopy[i+1]);
-+        if( NEVER(rc!=SQLITE_OK) ) goto handle_error; 
+ /*
++** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged()
++*/
++#define CKCNSTRNT_COLUMN   0x01    /* CHECK constraint uses a changing column */
++#define CKCNSTRNT_ROWID    0x02    /* CHECK constraint references the ROWID */
++
++/* This is the Walker callback from checkConstraintUnchanged().  Set
++** bit 0x01 of pWalker->eCode if
++** pWalker->eCode to 0 if this expression node references any of the
++** columns that are being modifed by an UPDATE statement.
++*/
++static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
++  if( pExpr->op==TK_COLUMN ){
++    assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 );
++    if( pExpr->iColumn>=0 ){
++      if( pWalker->u.aiCol[pExpr->iColumn]>=0 ){
++        pWalker->eCode |= CKCNSTRNT_COLUMN;
 +      }
-+      rc = sqlite3BtreeCopyFile(pDest, pSrc);
-+      ctx->skip_read_hmac = 0;
-+      if( rc!=SQLITE_OK ) goto handle_error;
-+      rc = sqlite3BtreeCommit(pDest);
++    }else{
++      pWalker->eCode |= CKCNSTRNT_ROWID;
++    }
++  }
++  return WRC_Continue;
++}
 +
-+      db->flags = saved_flags;
-+      db->nChange = saved_nChange;
-+      db->nTotalChange = saved_nTotalChange;
-+      db->xTrace = saved_xTrace;
-+      db->autoCommit = 1;
-+      sqlite3BtreeClose(pDb->pBt);
-+      pDb->pBt = 0;
-+      pDb->pSchema = 0;
-+      sqlite3ResetAllSchemasOfConnection(db);
-+      remove(migrated_db_filename);
-+      sqlite3_free(migrated_db_filename);
-+    } else {
-+      CODEC_TRACE(("*** migration failure** \n\n"));
++/*
++** pExpr is a CHECK constraint on a row that is being UPDATE-ed.  The
++** only columns that are modified by the UPDATE are those for which
++** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
++**
++** Return true if CHECK constraint pExpr does not use any of the
++** changing columns (or the rowid if it is changing).  In other words,
++** return true if this CHECK constraint can be skipped when validating
++** the new row in the UPDATE statement.
++*/
++static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
++  Walker w;
++  memset(&w, 0, sizeof(w));
++  w.eCode = 0;
++  w.xExprCallback = checkConstraintExprNode;
++  w.u.aiCol = aiChng;
++  sqlite3WalkExpr(&w, pExpr);
++  if( !chngRowid ){
++    testcase( (w.eCode & CKCNSTRNT_ROWID)!=0 );
++    w.eCode &= ~CKCNSTRNT_ROWID;
++  }
++  testcase( w.eCode==0 );
++  testcase( w.eCode==CKCNSTRNT_COLUMN );
++  testcase( w.eCode==CKCNSTRNT_ROWID );
++  testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
++  return !w.eCode;
++}
++
++/*
+ ** Generate code to do constraint checks prior to an INSERT or an UPDATE
+ ** on table pTab.
+ **
+@@ -100767,7 +114118,8 @@
+   u8 pkChng,           /* Non-zero if the rowid or PRIMARY KEY changed */
+   u8 overrideError,    /* Override onError to this if not OE_Default */
+   int ignoreDest,      /* Jump to this label on an OE_Ignore resolution */
+-  int *pbMayReplace    /* OUT: Set to true if constraint may cause a replace */
++  int *pbMayReplace,   /* OUT: Set to true if constraint may cause a replace */
++  int *aiChng          /* column i is unchanged if aiChng[i]<0 */
+ ){
+   Vdbe *v;             /* VDBE under constrution */
+   Index *pIdx;         /* Pointer to one of the indices */
+@@ -100777,14 +114129,13 @@
+   int ix;              /* Index loop counter */
+   int nCol;            /* Number of columns */
+   int onError;         /* Conflict resolution strategy */
+-  int j1;              /* Address of jump instruction */
++  int addr1;           /* Address of jump instruction */
+   int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
+   int nPkField;        /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
+   int ipkTop = 0;      /* Top of the rowid change constraint check */
+   int ipkBottom = 0;   /* Bottom of the rowid change constraint check */
+   u8 isUpdate;         /* True if this is an UPDATE operation */
+   u8 bAffinityDone = 0;  /* True if the OP_Affinity operation has been run */
+-  int regRowid = -1;   /* Register holding ROWID value */
+ 
+   isUpdate = regOldData!=0;
+   db = pParse->db;
+@@ -100813,10 +114164,14 @@
+   */
+   for(i=0; i<nCol; i++){
+     if( i==pTab->iPKey ){
++      continue;        /* ROWID is never NULL */
++    }
++    if( aiChng && aiChng[i]<0 ){
++      /* Don't bother checking for NOT NULL on columns that do not change */
+       continue;
      }
-+    
+     onError = pTab->aCol[i].notNull;
+-    if( onError==OE_None ) continue;
++    if( onError==OE_None ) continue;  /* This column is allowed to be NULL */
+     if( overrideError!=OE_Default ){
+       onError = overrideError;
+     }else if( onError==OE_Default ){
+@@ -100835,8 +114190,9 @@
+       case OE_Fail: {
+         char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
+                                     pTab->aCol[i].zName);
+-        sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
+-                          regNewData+1+i, zMsg, P4_DYNAMIC);
++        sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
++                          regNewData+1+i);
++        sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
+         sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
+         VdbeCoverage(v);
+         break;
+@@ -100848,9 +114204,10 @@
+       }
+       default: {
+         assert( onError==OE_Replace );
+-        j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i); VdbeCoverage(v);
++        addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
++           VdbeCoverage(v);
+         sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
+-        sqlite3VdbeJumpHere(v, j1);
++        sqlite3VdbeJumpHere(v, addr1);
+         break;
+       }
+     }
+@@ -100861,13 +114218,16 @@
+ #ifndef SQLITE_OMIT_CHECK
+   if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
+     ExprList *pCheck = pTab->pCheck;
+-    pParse->ckBase = regNewData+1;
++    pParse->iSelfTab = -(regNewData+1);
+     onError = overrideError!=OE_Default ? overrideError : OE_Abort;
+     for(i=0; i<pCheck->nExpr; i++){
+-      int allOk = sqlite3VdbeMakeLabel(v);
+-      sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
++      int allOk;
++      Expr *pExpr = pCheck->a[i].pExpr;
++      if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
++      allOk = sqlite3VdbeMakeLabel(v);
++      sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
+       if( onError==OE_Ignore ){
+-        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
++        sqlite3VdbeGoto(v, ignoreDest);
+       }else{
+         char *zName = pCheck->a[i].zName;
+         if( zName==0 ) zName = pTab->zName;
+@@ -100878,6 +114238,7 @@
+       }
+       sqlite3VdbeResolveLabel(v, allOk);
+     }
++    pParse->iSelfTab = 0;
    }
--  sqlite3_mutex_leave(db->mutex);
-+  goto exit;
+ #endif /* !defined(SQLITE_OMIT_CHECK) */
+ 
+@@ -100896,7 +114257,7 @@
+     }
+ 
+     if( isUpdate ){
+-      /* pkChng!=0 does not mean that the rowid has change, only that
++      /* pkChng!=0 does not mean that the rowid has changed, only that
+       ** it might have changed.  Skip the conflict logic below if the rowid
+       ** is unchanged. */
+       sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
+@@ -100965,17 +114326,29 @@
+         if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
+           sqlite3MultiWrite(pParse);
+           sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+-                                   regNewData, 1, 0, OE_Replace, 1);
+-        }else if( pTab->pIndex ){
+-          sqlite3MultiWrite(pParse);
+-          sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0);
++                                   regNewData, 1, 0, OE_Replace, 1, -1);
++        }else{
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++          if( HasRowid(pTab) ){
++            /* This OP_Delete opcode fires the pre-update-hook only. It does
++            ** not modify the b-tree. It is more efficient to let the coming
++            ** OP_Insert replace the existing entry than it is to delete the
++            ** existing entry and then insert a new one. */
++            sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP);
++            sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
++          }
++#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
++          if( pTab->pIndex ){
++            sqlite3MultiWrite(pParse);
++            sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,-1);
++          }
+         }
+         seenReplace = 1;
+         break;
+       }
+       case OE_Ignore: {
+         /*assert( seenReplace==0 );*/
+-        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
++        sqlite3VdbeGoto(v, ignoreDest);
+         break;
+       }
+     }
+@@ -101010,32 +114383,39 @@
+     /* Skip partial indices for which the WHERE clause is not true */
+     if( pIdx->pPartIdxWhere ){
+       sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
+-      pParse->ckBase = regNewData+1;
+-      sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
+-                         SQLITE_JUMPIFNULL);
+-      pParse->ckBase = 0;
++      pParse->iSelfTab = -(regNewData+1);
++      sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
++                            SQLITE_JUMPIFNULL);
++      pParse->iSelfTab = 0;
+     }
+ 
+     /* Create a record for this index entry as it should appear after
+     ** the insert or update.  Store that record in the aRegIdx[ix] register
+     */
+-    regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn);
++    regIdx = aRegIdx[ix]+1;
+     for(i=0; i<pIdx->nColumn; i++){
+       int iField = pIdx->aiColumn[i];
+       int x;
+-      if( iField<0 || iField==pTab->iPKey ){
+-        if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */
+-        x = regNewData;
+-        regRowid =  pIdx->pPartIdxWhere ? -1 : regIdx+i;
++      if( iField==XN_EXPR ){
++        pParse->iSelfTab = -(regNewData+1);
++        sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
++        pParse->iSelfTab = 0;
++        VdbeComment((v, "%s column %d", pIdx->zName, i));
+       }else{
+-        x = iField + regNewData + 1;
++        if( iField==XN_ROWID || iField==pTab->iPKey ){
++          x = regNewData;
++        }else{
++          x = iField + regNewData + 1;
++        }
++        sqlite3VdbeAddOp2(v, iField<0 ? OP_IntCopy : OP_SCopy, x, regIdx+i);
++        VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
+       }
+-      sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i);
+-      VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
+     }
+     sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
+     VdbeComment((v, "for %s", pIdx->zName));
+-    sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn);
++#ifdef SQLITE_ENABLE_NULL_TRIM
++    if( pIdx->idxType==2 ) sqlite3SetMakeRecordP5(v, pIdx->pTable);
++#endif
+ 
+     /* In an UPDATE operation, if this index is the PRIMARY KEY index 
+     ** of a WITHOUT ROWID table and there has been no change the
+@@ -101049,7 +114429,6 @@
+     /* Find out what action to take in case there is a uniqueness conflict */
+     onError = pIdx->onError;
+     if( onError==OE_None ){ 
+-      sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
+       sqlite3VdbeResolveLabel(v, addrUniqueOk);
+       continue;  /* pIdx is not a UNIQUE index */
+     }
+@@ -101058,7 +114437,26 @@
+     }else if( onError==OE_Default ){
+       onError = OE_Abort;
+     }
+-    
 +
-+ handle_error:
-+  CODEC_TRACE(("An error occurred attempting to migrate the database\n"));
-+  rc = SQLITE_ERROR;
++    /* Collision detection may be omitted if all of the following are true:
++    **   (1) The conflict resolution algorithm is REPLACE
++    **   (2) The table is a WITHOUT ROWID table
++    **   (3) There are no secondary indexes on the table
++    **   (4) No delete triggers need to be fired if there is a conflict
++    **   (5) No FK constraint counters need to be updated if a conflict occurs.
++    */ 
++    if( (ix==0 && pIdx->pNext==0)                   /* Condition 3 */
++     && pPk==pIdx                                   /* Condition 2 */
++     && onError==OE_Replace                         /* Condition 1 */
++     && ( 0==(db->flags&SQLITE_RecTriggers) ||      /* Condition 4 */
++          0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0))
++     && ( 0==(db->flags&SQLITE_ForeignKeys) ||      /* Condition 5 */
++         (0==pTab->pFKey && 0==sqlite3FkReferences(pTab)))
++    ){
++      sqlite3VdbeResolveLabel(v, addrUniqueOk);
++      continue;
++    }
 +
-+ exit:
-   return rc;
+     /* Check to see if the new index entry will be unique */
+     sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
+                          regIdx, pIdx->nKeyCol); VdbeCoverage(v);
+@@ -101081,6 +114479,7 @@
+         ** store it in registers regR..regR+nPk-1 */
+         if( pIdx!=pPk ){
+           for(i=0; i<pPk->nKeyCol; i++){
++            assert( pPk->aiColumn[i]>=0 );
+             x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
+             sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
+             VdbeComment((v, "%s.%s", pTab->zName,
+@@ -101102,6 +114501,7 @@
+           for(i=0; i<pPk->nKeyCol; i++){
+             char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
+             x = pPk->aiColumn[i];
++            assert( x>=0 );
+             if( i==(pPk->nKeyCol-1) ){
+               addrJump = addrUniqueOk;
+               op = OP_Eq;
+@@ -101128,7 +114528,7 @@
+         break;
+       }
+       case OE_Ignore: {
+-        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
++        sqlite3VdbeGoto(v, ignoreDest);
+         break;
+       }
+       default: {
+@@ -101139,17 +114539,17 @@
+           pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
+         }
+         sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+-                                 regR, nPkField, 0, OE_Replace, pIdx==pPk);
++            regR, nPkField, 0, OE_Replace,
++            (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur);
+         seenReplace = 1;
+         break;
+       }
+     }
+     sqlite3VdbeResolveLabel(v, addrUniqueOk);
+-    sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
+     if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
+   }
+   if( ipkTop ){
+-    sqlite3VdbeAddOp2(v, OP_Goto, 0, ipkTop+1);
++    sqlite3VdbeGoto(v, ipkTop+1);
+     sqlite3VdbeJumpHere(v, ipkBottom);
+   }
+   
+@@ -101157,6 +114557,28 @@
+   VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
  }
  
--/************** End of status.c **********************************************/
--/************** Begin file date.c ********************************************/
-+int sqlcipher_codec_add_random(codec_ctx *ctx, const char *zRight, int random_sz){
-+  const char *suffix = &zRight[random_sz-1];
-+  int n = random_sz - 3; /* adjust for leading x' and tailing ' */
-+  if (n > 0 &&
-+      sqlite3StrNICmp((const char *)zRight ,"x'", 2) == 0 &&
-+      sqlite3StrNICmp(suffix, "'", 1) == 0 &&
-+      n % 2 == 0) {
-+    int rc = 0;
-+    int buffer_sz = n / 2;
-+    unsigned char *random;
-+    const unsigned char *z = (const unsigned char *)zRight + 2; /* adjust lead offset of x' */
-+    CODEC_TRACE(("sqlcipher_codec_add_random: using raw random blob from hex\n"));
-+    random = sqlcipher_malloc(buffer_sz);
-+    memset(random, 0, buffer_sz);
-+    cipher_hex2bin(z, n, random);
-+    rc = ctx->read_ctx->provider->add_random(ctx->read_ctx->provider_ctx, random, buffer_sz);
-+    sqlcipher_free(random, buffer_sz);
-+    return rc;
++#ifdef SQLITE_ENABLE_NULL_TRIM
++/*
++** Change the P5 operand on the last opcode (which should be an OP_MakeRecord)
++** to be the number of columns in table pTab that must not be NULL-trimmed.
++**
++** Or if no columns of pTab may be NULL-trimmed, leave P5 at zero.
++*/
++SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){
++  u16 i;
++
++  /* Records with omitted columns are only allowed for schema format
++  ** version 2 and later (SQLite version 3.1.4, 2005-02-20). */
++  if( pTab->pSchema->file_format<2 ) return;
++
++  for(i=pTab->nCol-1; i>0; i--){
++    if( pTab->aCol[i].pDflt!=0 ) break;
++    if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break;
 +  }
-+  return SQLITE_ERROR;
++  sqlite3VdbeChangeP5(v, i+1);
 +}
++#endif
 +
-+int sqlcipher_cipher_profile(sqlite3 *db, const char *destination){
-+  FILE *f;
-+  if( strcmp(destination,"stdout")==0 ){
-+    f = stdout;
-+  }else if( strcmp(destination, "stderr")==0 ){
-+    f = stderr;
-+  }else if( strcmp(destination, "off")==0 ){
-+    f = 0;
-+  }else{
-+    f = fopen(destination, "wb");
-+    if( f==0 ){
-+      return SQLITE_ERROR;
+ /*
+ ** This routine generates code to finish the INSERT or UPDATE operation
+ ** that was started by a prior call to sqlite3GenerateConstraintChecks.
+@@ -101173,7 +114595,7 @@
+   int iIdxCur,        /* First index cursor */
+   int regNewData,     /* Range of content */
+   int *aRegIdx,       /* Register used by each index.  0 for unused indices */
+-  int isUpdate,       /* True for UPDATE, False for INSERT */
++  int update_flags,   /* True for UPDATE, False for INSERT */
+   int appendBias,     /* True if this is likely to be an append */
+   int useSeekResult   /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
+ ){
+@@ -101185,6 +114607,11 @@
+   int i;              /* Loop counter */
+   u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
+ 
++  assert( update_flags==0
++       || update_flags==OPFLAG_ISUPDATE
++       || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION)
++  );
++
+   v = sqlite3GetVdbe(pParse);
+   assert( v!=0 );
+   assert( pTab->pSelect==0 );  /* This table is not a VIEW */
+@@ -101195,26 +114622,39 @@
+       sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
+       VdbeCoverage(v);
+     }
+-    sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]);
+-    pik_flags = 0;
+-    if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT;
++    pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0);
+     if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
+       assert( pParse->nested==0 );
+       pik_flags |= OPFLAG_NCHANGE;
++      pik_flags |= (update_flags & OPFLAG_SAVEPOSITION);
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++      if( update_flags==0 ){
++        sqlite3VdbeAddOp4(v, OP_InsertInt, 
++            iIdxCur+i, aRegIdx[i], 0, (char*)pTab, P4_TABLE
++        );
++        sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP);
++      }
++#endif
+     }
+-    if( pik_flags )  sqlite3VdbeChangeP5(v, pik_flags);
++    sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i],
++                         aRegIdx[i]+1,
++                         pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn);
++    sqlite3VdbeChangeP5(v, pik_flags);
+   }
+   if( !HasRowid(pTab) ) return;
+   regData = regNewData + 1;
+   regRec = sqlite3GetTempReg(pParse);
+   sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
+-  if( !bAffinityDone ) sqlite3TableAffinity(v, pTab, 0);
+-  sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
++  sqlite3SetMakeRecordP5(v, pTab);
++  if( !bAffinityDone ){
++    sqlite3TableAffinity(v, pTab, 0);
++    sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
++  }
+   if( pParse->nested ){
+     pik_flags = 0;
+   }else{
+     pik_flags = OPFLAG_NCHANGE;
+-    pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
++    pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID);
+   }
+   if( appendBias ){
+     pik_flags |= OPFLAG_APPEND;
+@@ -101224,7 +114664,7 @@
+   }
+   sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
+   if( !pParse->nested ){
+-    sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
++    sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
+   }
+   sqlite3VdbeChangeP5(v, pik_flags);
+ }
+@@ -101254,6 +114694,7 @@
+   Parse *pParse,   /* Parsing context */
+   Table *pTab,     /* Table to be opened */
+   int op,          /* OP_OpenRead or OP_OpenWrite */
++  u8 p5,           /* P5 value for OP_Open* opcodes (except on WITHOUT ROWID) */
+   int iBase,       /* Use this for the table cursor, if there is one */
+   u8 *aToOpen,     /* If not NULL: boolean for each table and index */
+   int *piDataCur,  /* Write the database source cursor number here */
+@@ -101266,6 +114707,7 @@
+   Vdbe *v;
+ 
+   assert( op==OP_OpenRead || op==OP_OpenWrite );
++  assert( op==OP_OpenWrite || p5==0 );
+   if( IsVirtual(pTab) ){
+     /* This routine is a no-op for virtual tables. Leave the output
+     ** variables *piDataCur and *piIdxCur uninitialized so that valgrind
+@@ -101287,12 +114729,14 @@
+   for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+     int iIdxCur = iBase++;
+     assert( pIdx->pSchema==pTab->pSchema );
+-    if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) && piDataCur ){
+-      *piDataCur = iIdxCur;
++    if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
++      if( piDataCur ) *piDataCur = iIdxCur;
++      p5 = 0;
+     }
+     if( aToOpen==0 || aToOpen[i+1] ){
+       sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb);
+       sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
++      sqlite3VdbeChangeP5(v, p5);
+       VdbeComment((v, "%s", pIdx->zName));
+     }
+   }
+@@ -101314,20 +114758,6 @@
+ 
+ #ifndef SQLITE_OMIT_XFER_OPT
+ /*
+-** Check to collation names to see if they are compatible.
+-*/
+-static int xferCompatibleCollation(const char *z1, const char *z2){
+-  if( z1==0 ){
+-    return z2==0;
+-  }
+-  if( z2==0 ){
+-    return 0;
+-  }
+-  return sqlite3StrICmp(z1, z2)==0;
+-}
+-
+-
+-/*
+ ** Check to see if index pSrc is compatible as a source of data
+ ** for index pDest in an insert transfer optimization.  The rules
+ ** for a compatible index:
+@@ -101352,14 +114782,21 @@
+     if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
+       return 0;   /* Different columns indexed */
+     }
++    if( pSrc->aiColumn[i]==XN_EXPR ){
++      assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 );
++      if( sqlite3ExprCompare(0, pSrc->aColExpr->a[i].pExpr,
++                             pDest->aColExpr->a[i].pExpr, -1)!=0 ){
++        return 0;   /* Different expressions in the index */
++      }
++    }
+     if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
+       return 0;   /* Different sort orders */
+     }
+-    if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
++    if( sqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){
+       return 0;   /* Different collating sequences */
+     }
+   }
+-  if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
++  if( sqlite3ExprCompare(0, pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
+     return 0;     /* Different WHERE clauses */
+   }
+ 
+@@ -101428,7 +114865,7 @@
+     return 0;   /* tab1 must not have triggers */
+   }
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-  if( pDest->tabFlags & TF_Virtual ){
++  if( IsVirtual(pDest) ){
+     return 0;   /* tab1 must not be a virtual table */
+   }
+ #endif
+@@ -101470,7 +114907,7 @@
+     return 0;   /* The result set must have exactly one column */
+   }
+   assert( pEList->a[0].pExpr );
+-  if( pEList->a[0].pExpr->op!=TK_ALL ){
++  if( pEList->a[0].pExpr->op!=TK_ASTERISK ){
+     return 0;   /* The result set must be the special operator "*" */
+   }
+ 
+@@ -101490,7 +114927,7 @@
+     return 0;   /* source and destination must both be WITHOUT ROWID or not */
+   }
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-  if( pSrc->tabFlags & TF_Virtual ){
++  if( IsVirtual(pSrc) ){
+     return 0;   /* tab2 must not be a virtual table */
+   }
+ #endif
+@@ -101506,21 +114943,32 @@
+   for(i=0; i<pDest->nCol; i++){
+     Column *pDestCol = &pDest->aCol[i];
+     Column *pSrcCol = &pSrc->aCol[i];
++#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS
++    if( (db->flags & SQLITE_Vacuum)==0 
++     && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN 
++    ){
++      return 0;    /* Neither table may have __hidden__ columns */
++    }
++#endif
+     if( pDestCol->affinity!=pSrcCol->affinity ){
+       return 0;    /* Affinity must be the same on all columns */
+     }
+-    if( !xferCompatibleCollation(pDestCol->zColl, pSrcCol->zColl) ){
++    if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){
+       return 0;    /* Collating sequence must be the same on all columns */
+     }
+     if( pDestCol->notNull && !pSrcCol->notNull ){
+       return 0;    /* tab2 must be NOT NULL if tab1 is */
+     }
+     /* Default values for second and subsequent columns need to match. */
+-    if( i>0
+-     && ((pDestCol->zDflt==0)!=(pSrcCol->zDflt==0) 
+-         || (pDestCol->zDflt && strcmp(pDestCol->zDflt, pSrcCol->zDflt)!=0))
+-    ){
+-      return 0;    /* Default values must be the same for all columns */
++    if( i>0 ){
++      assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN );
++      assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN );
++      if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0) 
++       || (pDestCol->pDflt && strcmp(pDestCol->pDflt->u.zToken,
++                                       pSrcCol->pDflt->u.zToken)!=0)
++      ){
++        return 0;    /* Default values must be the same for all columns */
++      }
+     }
+   }
+   for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
+@@ -101595,10 +115043,11 @@
+     ** (3) onError is something other than OE_Abort and OE_Rollback.
+     */
+     addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v);
+-    emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
++    emptyDestTest = sqlite3VdbeAddOp0(v, OP_Goto);
+     sqlite3VdbeJumpHere(v, addr1);
+   }
+   if( HasRowid(pSrc) ){
++    u8 insFlags;
+     sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
+     emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
+     if( pDest->iPKey>=0 ){
+@@ -101614,10 +115063,17 @@
+       addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
+       assert( (pDest->tabFlags & TF_Autoincrement)==0 );
+     }
+-    sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData);
+-    sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
+-    sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
+-    sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
++    sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
++    if( db->flags & SQLITE_Vacuum ){
++      sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
++      insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|
++                           OPFLAG_APPEND|OPFLAG_USESEEKRESULT;
++    }else{
++      insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND;
++    }
++    sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid,
++                      (char*)pDest, P4_TABLE);
++    sqlite3VdbeChangeP5(v, insFlags);
+     sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v);
+     sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
+     sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
+@@ -101626,7 +115082,7 @@
+     sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
+   }
+   for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
+-    u8 useSeekResult = 0;
++    u8 idxInsFlags = 0;
+     for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
+       if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
+     }
+@@ -101639,7 +115095,7 @@
+     sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
+     VdbeComment((v, "%s", pDestIdx->zName));
+     addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
+-    sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
++    sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
+     if( db->flags & SQLITE_Vacuum ){
+       /* This INSERT command is part of a VACUUM operation, which guarantees
+       ** that the destination table is empty. If all indexed columns use
+@@ -101656,17 +115112,19 @@
+       ** a VACUUM command. In that case keys may not be written in strictly
+       ** sorted order.  */
+       for(i=0; i<pSrcIdx->nColumn; i++){
+-        char *zColl = pSrcIdx->azColl[i];
+-        assert( zColl!=0 );
+-        if( sqlite3_stricmp("BINARY", zColl) ) break;
++        const char *zColl = pSrcIdx->azColl[i];
++        if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
+       }
+       if( i==pSrcIdx->nColumn ){
+-        useSeekResult = OPFLAG_USESEEKRESULT;
++        idxInsFlags = OPFLAG_USESEEKRESULT;
+         sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
+       }
+     }
+-    sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
+-    sqlite3VdbeChangeP5(v, useSeekResult);
++    if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){
++      idxInsFlags |= OPFLAG_NCHANGE;
 +    }
-+  }
-+  sqlite3_profile(db, sqlcipher_profile_callback, f);
-+  return SQLITE_OK;
-+}
-+
-+static void sqlcipher_profile_callback(void *file, const char *sql, sqlite3_uint64 run_time){
-+  FILE *f = (FILE*)file;
-+  double elapsed = run_time/1000000.0;
-+  if( f ) fprintf(f, "Elapsed time:%.3f ms - %s\n", elapsed, sql);
-+}
-+
-+int sqlcipher_codec_fips_status(codec_ctx *ctx) {
-+  return ctx->read_ctx->provider->fips_status(ctx->read_ctx);
-+}
++    sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData);
++    sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND);
+     sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
+     sqlite3VdbeJumpHere(v, addr1);
+     sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
+@@ -101676,6 +115134,7 @@
+   sqlite3ReleaseTempReg(pParse, regRowid);
+   sqlite3ReleaseTempReg(pParse, regData);
+   if( emptyDestTest ){
++    sqlite3AutoincrementEnd(pParse);
+     sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
+     sqlite3VdbeJumpHere(v, emptyDestTest);
+     sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
+@@ -101705,6 +115164,7 @@
+ ** accessed by users of the library.
+ */
+ 
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** Execute SQL code.  Return one of the SQLITE_ success/failure
+@@ -101716,7 +115176,7 @@
+ ** argument to xCallback().  If xCallback=NULL then no callback
+ ** is invoked, even for queries.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_exec(
++SQLITE_API int sqlite3_exec(
+   sqlite3 *db,                /* The database on which the SQL executes */
+   const char *zSql,           /* The SQL to be executed */
+   sqlite3_callback xCallback, /* Invoke this callback routine */
+@@ -101762,7 +115222,7 @@
+           (SQLITE_DONE==rc && !callbackIsInit
+                            && db->flags&SQLITE_NullCallback)) ){
+         if( !callbackIsInit ){
+-          azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
++          azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*));
+           if( azCols==0 ){
+             goto exec_out;
+           }
+@@ -101779,10 +115239,11 @@
+           for(i=0; i<nCol; i++){
+             azVals[i] = (char *)sqlite3_column_text(pStmt, i);
+             if( !azVals[i] && sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
+-              db->mallocFailed = 1;
++              sqlite3OomFault(db);
+               goto exec_out;
+             }
+           }
++          azVals[i] = 0;
+         }
+         if( xCallback(pArg, nCol, azVals, azCols) ){
+           /* EVIDENCE-OF: R-38229-40159 If the callback function to
+@@ -101815,12 +115276,9 @@
+ 
+   rc = sqlite3ApiExit(db, rc);
+   if( rc!=SQLITE_OK && pzErrMsg ){
+-    int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db));
+-    *pzErrMsg = sqlite3Malloc(nErrMsg);
+-    if( *pzErrMsg ){
+-      memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
+-    }else{
+-      rc = SQLITE_NOMEM;
++    *pzErrMsg = sqlite3DbStrDup(0, sqlite3_errmsg(db));
++    if( *pzErrMsg==0 ){
++      rc = SQLITE_NOMEM_BKPT;
+       sqlite3Error(db, SQLITE_NOMEM);
+     }
+   }else if( pzErrMsg ){
+@@ -101871,10 +115329,9 @@
+ ** as extensions by SQLite should #include this file instead of 
+ ** sqlite3.h.
+ */
+-#ifndef _SQLITE3EXT_H_
+-#define _SQLITE3EXT_H_
+-
+-typedef struct sqlite3_api_routines sqlite3_api_routines;
++#ifndef SQLITE3EXT_H
++#define SQLITE3EXT_H
++/* #include "sqlite3.h" */
+ 
+ /*
+ ** The following structure holds pointers to all of the SQLite API
+@@ -102122,9 +115579,46 @@
+   void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
+                          void(*)(void*), unsigned char);
+   int (*strglob)(const char*,const char*);
++  /* Version 3.8.11 and later */
++  sqlite3_value *(*value_dup)(const sqlite3_value*);
++  void (*value_free)(sqlite3_value*);
++  int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
++  int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
++  /* Version 3.9.0 and later */
++  unsigned int (*value_subtype)(sqlite3_value*);
++  void (*result_subtype)(sqlite3_context*,unsigned int);
++  /* Version 3.10.0 and later */
++  int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
++  int (*strlike)(const char*,const char*,unsigned int);
++  int (*db_cacheflush)(sqlite3*);
++  /* Version 3.12.0 and later */
++  int (*system_errno)(sqlite3*);
++  /* Version 3.14.0 and later */
++  int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
++  char *(*expanded_sql)(sqlite3_stmt*);
++  /* Version 3.18.0 and later */
++  void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
++  /* Version 3.20.0 and later */
++  int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
++                    sqlite3_stmt**,const char**);
++  int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
++                      sqlite3_stmt**,const void**);
++  int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
++  void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
++  void *(*value_pointer)(sqlite3_value*,const char*);
+ };
+ 
+ /*
++** This is the function signature used for all extension entry points.  It
++** is also defined in the file "loadext.c".
++*/
++typedef int (*sqlite3_loadext_entry)(
++  sqlite3 *db,                       /* Handle to the database. */
++  char **pzErrMsg,                   /* Used to set error string on failure. */
++  const sqlite3_api_routines *pThunk /* Extension API function pointers. */
++);
 +
++/*
+ ** The following macros redefine the API routines so that they are
+ ** redirected through the global sqlite3_api structure.
+ **
+@@ -102135,7 +115629,7 @@
+ ** the API.  So the redefinition macros are only valid if the
+ ** SQLITE_CORE macros is undefined.
+ */
+-#ifndef SQLITE_CORE
++#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+ #define sqlite3_aggregate_context      sqlite3_api->aggregate_context
+ #ifndef SQLITE_OMIT_DEPRECATED
+ #define sqlite3_aggregate_count        sqlite3_api->aggregate_count
+@@ -102262,6 +115756,7 @@
+ #define sqlite3_value_text16le         sqlite3_api->value_text16le
+ #define sqlite3_value_type             sqlite3_api->value_type
+ #define sqlite3_vmprintf               sqlite3_api->vmprintf
++#define sqlite3_vsnprintf              sqlite3_api->vsnprintf
+ #define sqlite3_overload_function      sqlite3_api->overload_function
+ #define sqlite3_prepare_v2             sqlite3_api->prepare_v2
+ #define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2
+@@ -102352,9 +115847,34 @@
+ #define sqlite3_result_blob64          sqlite3_api->result_blob64
+ #define sqlite3_result_text64          sqlite3_api->result_text64
+ #define sqlite3_strglob                sqlite3_api->strglob
+-#endif /* SQLITE_CORE */
++/* Version 3.8.11 and later */
++#define sqlite3_value_dup              sqlite3_api->value_dup
++#define sqlite3_value_free             sqlite3_api->value_free
++#define sqlite3_result_zeroblob64      sqlite3_api->result_zeroblob64
++#define sqlite3_bind_zeroblob64        sqlite3_api->bind_zeroblob64
++/* Version 3.9.0 and later */
++#define sqlite3_value_subtype          sqlite3_api->value_subtype
++#define sqlite3_result_subtype         sqlite3_api->result_subtype
++/* Version 3.10.0 and later */
++#define sqlite3_status64               sqlite3_api->status64
++#define sqlite3_strlike                sqlite3_api->strlike
++#define sqlite3_db_cacheflush          sqlite3_api->db_cacheflush
++/* Version 3.12.0 and later */
++#define sqlite3_system_errno           sqlite3_api->system_errno
++/* Version 3.14.0 and later */
++#define sqlite3_trace_v2               sqlite3_api->trace_v2
++#define sqlite3_expanded_sql           sqlite3_api->expanded_sql
++/* Version 3.18.0 and later */
++#define sqlite3_set_last_insert_rowid  sqlite3_api->set_last_insert_rowid
++/* Version 3.20.0 and later */
++#define sqlite3_prepare_v3             sqlite3_api->prepare_v3
++#define sqlite3_prepare16_v3           sqlite3_api->prepare16_v3
++#define sqlite3_bind_pointer           sqlite3_api->bind_pointer
++#define sqlite3_result_pointer         sqlite3_api->result_pointer
++#define sqlite3_value_pointer          sqlite3_api->value_pointer
++#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
+ 
+-#ifndef SQLITE_CORE
++#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+   /* This case when the file really is being compiled as a loadable 
+   ** extension */
+ # define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
+@@ -102369,14 +115889,13 @@
+ # define SQLITE_EXTENSION_INIT3     /*no-op*/
+ #endif
+ 
+-#endif /* _SQLITE3EXT_H_ */
++#endif /* SQLITE3EXT_H */
+ 
+ /************** End of sqlite3ext.h ******************************************/
+ /************** Continuing where we left off in loadext.c ********************/
+-/* #include <string.h> */
++/* #include "sqliteInt.h" */
+ 
+ #ifndef SQLITE_OMIT_LOAD_EXTENSION
+-
+ /*
+ ** Some API routines are omitted when various features are
+ ** excluded from a build of SQLite.  Substitute a NULL pointer
+@@ -102408,6 +115927,7 @@
+ # define sqlite3_open16                 0
+ # define sqlite3_prepare16              0
+ # define sqlite3_prepare16_v2           0
++# define sqlite3_prepare16_v3           0
+ # define sqlite3_result_error16         0
+ # define sqlite3_result_text16          0
+ # define sqlite3_result_text16be        0
+@@ -102446,7 +115966,7 @@
+ # define sqlite3_enable_shared_cache 0
+ #endif
+ 
+-#ifdef SQLITE_OMIT_TRACE
++#if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED)
+ # define sqlite3_profile       0
+ # define sqlite3_trace         0
+ #endif
+@@ -102466,6 +115986,10 @@
+ #define sqlite3_blob_reopen    0
+ #endif
+ 
++#if defined(SQLITE_OMIT_TRACE)
++# define sqlite3_trace_v2      0
 +#endif
-+/* END SQLCIPHER */
 +
-+/************** End of crypto_impl.c *****************************************/
-+/************** Begin file crypto_libtomcrypt.c ******************************/
  /*
--** 2003 October 31
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
-+** SQLCipher
-+** http://sqlcipher.net
- **
--**    May you do good and not evil.
--**    May you find forgiveness for yourself and forgive others.
--**    May you share freely, never taking more than you give.
--**
--*************************************************************************
--** This file contains the C functions that implement date and time
--** functions for SQLite.  
--**
--** There is only one exported symbol in this file - the function
--** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
--** All other code has file scope.
--**
--** SQLite processes all times and dates as julian day numbers.  The
--** dates and times are stored as the number of days since noon
--** in Greenwich on November 24, 4714 B.C. according to the Gregorian
--** calendar system. 
-+** Copyright (c) 2008 - 2013, ZETETIC LLC
-+** All rights reserved.
- **
--** 1970-01-01 00:00:00 is JD 2440587.5
--** 2000-01-01 00:00:00 is JD 2451544.5
--**
--** This implementation requires years to be expressed as a 4-digit number
--** which means that only dates between 0000-01-01 and 9999-12-31 can
--** be represented, even though julian day numbers allow a much wider
--** range of dates.
--**
--** The Gregorian calendar system is used for all dates and times,
--** even those that predate the Gregorian calendar.  Historians usually
--** use the julian calendar for dates prior to 1582-10-15 and for some
--** dates afterwards, depending on locale.  Beware of this difference.
-+** Redistribution and use in source and binary forms, with or without
-+** modification, are permitted provided that the following conditions are met:
-+**     * Redistributions of source code must retain the above copyright
-+**       notice, this list of conditions and the following disclaimer.
-+**     * Redistributions in binary form must reproduce the above copyright
-+**       notice, this list of conditions and the following disclaimer in the
-+**       documentation and/or other materials provided with the distribution.
-+**     * Neither the name of the ZETETIC LLC nor the
-+**       names of its contributors may be used to endorse or promote products
-+**       derived from this software without specific prior written permission.
- **
--** The conversion algorithms are implemented based on descriptions
--** in the following text:
-+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
-+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
-+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- **
--**      Jean Meeus
--**      Astronomical Algorithms, 2nd Edition, 1998
--**      ISBM 0-943396-61-1
--**      Willmann-Bell, Inc
--**      Richmond, Virginia (USA)
+ ** The following structure contains pointers to all SQLite API routines.
+ ** A pointer to this structure is passed into extensions when they are
+@@ -102757,7 +116281,32 @@
+   sqlite3_reset_auto_extension,
+   sqlite3_result_blob64,
+   sqlite3_result_text64,
+-  sqlite3_strglob
++  sqlite3_strglob,
++  /* Version 3.8.11 and later */
++  (sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup,
++  sqlite3_value_free,
++  sqlite3_result_zeroblob64,
++  sqlite3_bind_zeroblob64,
++  /* Version 3.9.0 and later */
++  sqlite3_value_subtype,
++  sqlite3_result_subtype,
++  /* Version 3.10.0 and later */
++  sqlite3_status64,
++  sqlite3_strlike,
++  sqlite3_db_cacheflush,
++  /* Version 3.12.0 and later */
++  sqlite3_system_errno,
++  /* Version 3.14.0 and later */
++  sqlite3_trace_v2,
++  sqlite3_expanded_sql,
++  /* Version 3.18.0 and later */
++  sqlite3_set_last_insert_rowid,
++  /* Version 3.20.0 and later */
++  sqlite3_prepare_v3,
++  sqlite3_prepare16_v3,
++  sqlite3_bind_pointer,
++  sqlite3_result_pointer,
++  sqlite3_value_pointer
+ };
+ 
+ /*
+@@ -102780,13 +116329,14 @@
+ ){
+   sqlite3_vfs *pVfs = db->pVfs;
+   void *handle;
+-  int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
++  sqlite3_loadext_entry xInit;
+   char *zErrmsg = 0;
+   const char *zEntry;
+   char *zAltEntry = 0;
+   void **aHandle;
+   u64 nMsg = 300 + sqlite3Strlen30(zFile);
+   int ii;
++  int rc;
+ 
+   /* Shared library endings to try if zFile cannot be loaded as written */
+   static const char *azEndings[] = {
+@@ -102805,8 +116355,9 @@
+   /* Ticket #1863.  To avoid a creating security problems for older
+   ** applications that relink against newer versions of SQLite, the
+   ** ability to run load_extension is turned off by default.  One
+-  ** must call sqlite3_enable_load_extension() to turn on extension
+-  ** loading.  Otherwise you get the following error.
++  ** must call either sqlite3_enable_load_extension(db) or
++  ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0)
++  ** to turn on extension loading.
+   */
+   if( (db->flags & SQLITE_LoadExtension)==0 ){
+     if( pzErrMsg ){
+@@ -102821,7 +116372,7 @@
+ #if SQLITE_OS_UNIX || SQLITE_OS_WIN
+   for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
+     char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
+-    if( zAltFile==0 ) return SQLITE_NOMEM;
++    if( zAltFile==0 ) return SQLITE_NOMEM_BKPT;
+     handle = sqlite3OsDlOpen(pVfs, zAltFile);
+     sqlite3_free(zAltFile);
+   }
+@@ -102837,8 +116388,7 @@
+     }
+     return SQLITE_ERROR;
+   }
+-  xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
+-                   sqlite3OsDlSym(pVfs, handle, zEntry);
++  xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);
+ 
+   /* If no entry point was specified and the default legacy
+   ** entry point name "sqlite3_extension_init" was not found, then
+@@ -102857,7 +116407,7 @@
+     zAltEntry = sqlite3_malloc64(ncFile+30);
+     if( zAltEntry==0 ){
+       sqlite3OsDlClose(pVfs, handle);
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     memcpy(zAltEntry, "sqlite3_", 8);
+     for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
+@@ -102870,8 +116420,7 @@
+     }
+     memcpy(zAltEntry+iEntry, "_init", 6);
+     zEntry = zAltEntry;
+-    xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
+-                     sqlite3OsDlSym(pVfs, handle, zEntry);
++    xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);
+   }
+   if( xInit==0 ){
+     if( pzErrMsg ){
+@@ -102888,7 +116437,9 @@
+     return SQLITE_ERROR;
+   }
+   sqlite3_free(zAltEntry);
+-  if( xInit(db, &zErrmsg, &sqlite3Apis) ){
++  rc = xInit(db, &zErrmsg, &sqlite3Apis);
++  if( rc ){
++    if( rc==SQLITE_OK_LOAD_PERMANENTLY ) return SQLITE_OK;
+     if( pzErrMsg ){
+       *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
+     }
+@@ -102900,7 +116451,7 @@
+   /* Append the new shared library handle to the db->aExtension array. */
+   aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1));
+   if( aHandle==0 ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   if( db->nExtension>0 ){
+     memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
+@@ -102911,7 +116462,7 @@
+   db->aExtension[db->nExtension++] = handle;
+   return SQLITE_OK;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
++SQLITE_API int sqlite3_load_extension(
+   sqlite3 *db,          /* Load the extension into this database connection */
+   const char *zFile,    /* Name of the shared library containing extension */
+   const char *zProc,    /* Entry point.  Use "sqlite3_extension_init" if 0 */
+@@ -102942,29 +116493,18 @@
+ ** Enable or disable extension loading.  Extension loading is disabled by
+ ** default so as not to open security holes in older applications.
  */
--/* #include <stdlib.h> */
--/* #include <assert.h> */
--#include <time.h>
--
--#ifndef SQLITE_OMIT_DATETIME_FUNCS
--
-+/* BEGIN SQLCIPHER */
-+#ifdef SQLITE_HAS_CODEC
-+#ifdef SQLCIPHER_CRYPTO_LIBTOMCRYPT
-+#include <tomcrypt.h>
+-SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff){
++SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
+   sqlite3_mutex_enter(db->mutex);
+   if( onoff ){
+-    db->flags |= SQLITE_LoadExtension;
++    db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
+   }else{
+-    db->flags &= ~SQLITE_LoadExtension;
++    db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
+   }
+   sqlite3_mutex_leave(db->mutex);
+   return SQLITE_OK;
+ }
  
+-#endif /* SQLITE_OMIT_LOAD_EXTENSION */
+-
 -/*
--** A structure for holding a single date and time.
+-** The auto-extension code added regardless of whether or not extension
+-** loading is supported.  We need a dummy sqlite3Apis pointer for that
+-** code if regular extension loading is not available.  This is that
+-** dummy pointer.
 -*/
--typedef struct DateTime DateTime;
--struct DateTime {
--  sqlite3_int64 iJD; /* The julian day number times 86400000 */
--  int Y, M, D;       /* Year, month, and day */
--  int h, m;          /* Hour and minutes */
--  int tz;            /* Timezone offset in minutes */
--  double s;          /* Seconds */
--  char validYMD;     /* True (1) if Y,M,D are valid */
--  char validHMS;     /* True (1) if h,m,s are valid */
--  char validJD;      /* True (1) if iJD is valid */
--  char validTZ;      /* True (1) if tz is valid */
--};
-+#define FORTUNA_MAX_SZ 32
-+static prng_state prng;
-+static unsigned int ltc_init = 0;
-+static unsigned int ltc_ref_count = 0;
-+static sqlite3_mutex* ltc_rand_mutex = NULL;
+-#ifdef SQLITE_OMIT_LOAD_EXTENSION
+-static const sqlite3_api_routines sqlite3Apis = { 0 };
+-#endif
+-
++#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */
  
-+static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
-+  int rc = 0;
-+  int data_to_read = length;
-+  int block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
-+  const unsigned char * data = (const unsigned char *)buffer;
-+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
-+  sqlite3_mutex_enter(ltc_rand_mutex);
-+#endif
-+    while(data_to_read > 0){
-+      rc = fortuna_add_entropy(data, block_sz, &prng);
-+      rc = rc != CRYPT_OK ? SQLITE_ERROR : SQLITE_OK;
-+      if(rc != SQLITE_OK){
-+        break;
-+      }
-+      data_to_read -= block_sz;
-+      data += block_sz;
-+      block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
-+    }
-+    fortuna_ready(&prng);
-+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
-+  sqlite3_mutex_leave(ltc_rand_mutex);
+ /*
+ ** The following object holds the list of automatically loaded
+@@ -102999,7 +116539,9 @@
+ ** Register a statically linked extension that is automatically
+ ** loaded by every new database connection.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xInit)(void)){
++SQLITE_API int sqlite3_auto_extension(
++  void (*xInit)(void)
++){
+   int rc = SQLITE_OK;
+ #ifndef SQLITE_OMIT_AUTOINIT
+   rc = sqlite3_initialize();
+@@ -103022,7 +116564,7 @@
+       void (**aNew)(void);
+       aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte);
+       if( aNew==0 ){
+-        rc = SQLITE_NOMEM;
++        rc = SQLITE_NOMEM_BKPT;
+       }else{
+         wsdAutoext.aExt = aNew;
+         wsdAutoext.aExt[wsdAutoext.nExt] = xInit;
+@@ -103044,7 +116586,9 @@
+ ** Return 1 if xInit was found on the list and removed.  Return 0 if xInit
+ ** was not on the list.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xInit)(void)){
++SQLITE_API int sqlite3_cancel_auto_extension(
++  void (*xInit)(void)
++){
+ #if SQLITE_THREADSAFE
+   sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+ #endif
+@@ -103067,7 +116611,7 @@
+ /*
+ ** Reset the automatic extension loading mechanism.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void){
++SQLITE_API void sqlite3_reset_auto_extension(void){
+ #ifndef SQLITE_OMIT_AUTOINIT
+   if( sqlite3_initialize()==SQLITE_OK )
+ #endif
+@@ -103093,7 +116637,7 @@
+   u32 i;
+   int go = 1;
+   int rc;
+-  int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
++  sqlite3_loadext_entry xInit;
+ 
+   wsdAutoextInit;
+   if( wsdAutoext.nExt==0 ){
+@@ -103105,17 +116649,21 @@
+ #if SQLITE_THREADSAFE
+     sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+ #endif
++#ifdef SQLITE_OMIT_LOAD_EXTENSION
++    const sqlite3_api_routines *pThunk = 0;
++#else
++    const sqlite3_api_routines *pThunk = &sqlite3Apis;
 +#endif
-+  return rc;
-+}
+     sqlite3_mutex_enter(mutex);
+     if( i>=wsdAutoext.nExt ){
+       xInit = 0;
+       go = 0;
+     }else{
+-      xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
+-              wsdAutoext.aExt[i];
++      xInit = (sqlite3_loadext_entry)wsdAutoext.aExt[i];
+     }
+     sqlite3_mutex_leave(mutex);
+     zErrmsg = 0;
+-    if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){
++    if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){
+       sqlite3ErrorWithMsg(db, rc,
+             "automatic extension loading failed: %s", zErrmsg);
+       go = 0;
+@@ -103139,6 +116687,7 @@
+ *************************************************************************
+ ** This file contains code used to implement the PRAGMA command.
+ */
++/* #include "sqliteInt.h" */
  
--/*
--** Convert zDate into one or more integers.  Additional arguments
--** come in groups of 5 as follows:
--**
--**       N       number of digits in the integer
--**       min     minimum allowed value of the integer
--**       max     maximum allowed value of the integer
--**       nextC   first character after the integer
--**       pVal    where to write the integers value.
--**
--** Conversions continue until one with nextC==0 is encountered.
--** The function returns the number of successful conversions.
--*/
--static int getDigits(const char *zDate, ...){
--  va_list ap;
--  int val;
--  int N;
--  int min;
--  int max;
--  int nextC;
--  int *pVal;
--  int cnt = 0;
--  va_start(ap, zDate);
--  do{
--    N = va_arg(ap, int);
--    min = va_arg(ap, int);
--    max = va_arg(ap, int);
--    nextC = va_arg(ap, int);
--    pVal = va_arg(ap, int*);
--    val = 0;
--    while( N-- ){
--      if( !sqlite3Isdigit(*zDate) ){
--        goto end_getDigits;
--      }
--      val = val*10 + *zDate - '0';
--      zDate++;
--    }
--    if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
--      goto end_getDigits;
-+static int sqlcipher_ltc_activate(void *ctx) {
-+  unsigned char random_buffer[FORTUNA_MAX_SZ];
-+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
-+  if(ltc_rand_mutex == NULL){
-+    ltc_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
-+  }
-+  sqlite3_mutex_enter(ltc_rand_mutex);
+ #if !defined(SQLITE_ENABLE_LOCKING_STYLE)
+ #  if defined(__APPLE__)
+@@ -103162,468 +116711,658 @@
+ ** ../tool/mkpragmatab.tcl.  To update the set of pragmas, edit
+ ** that script and rerun it.
+ */
++
++/* The various pragma types */
+ #define PragTyp_HEADER_VALUE                   0
+ #define PragTyp_AUTO_VACUUM                    1
+ #define PragTyp_FLAG                           2
+ #define PragTyp_BUSY_TIMEOUT                   3
+ #define PragTyp_CACHE_SIZE                     4
+-#define PragTyp_CASE_SENSITIVE_LIKE            5
+-#define PragTyp_COLLATION_LIST                 6
+-#define PragTyp_COMPILE_OPTIONS                7
+-#define PragTyp_DATA_STORE_DIRECTORY           8
+-#define PragTyp_DATABASE_LIST                  9
+-#define PragTyp_DEFAULT_CACHE_SIZE            10
+-#define PragTyp_ENCODING                      11
+-#define PragTyp_FOREIGN_KEY_CHECK             12
+-#define PragTyp_FOREIGN_KEY_LIST              13
+-#define PragTyp_INCREMENTAL_VACUUM            14
+-#define PragTyp_INDEX_INFO                    15
+-#define PragTyp_INDEX_LIST                    16
+-#define PragTyp_INTEGRITY_CHECK               17
+-#define PragTyp_JOURNAL_MODE                  18
+-#define PragTyp_JOURNAL_SIZE_LIMIT            19
+-#define PragTyp_LOCK_PROXY_FILE               20
+-#define PragTyp_LOCKING_MODE                  21
+-#define PragTyp_PAGE_COUNT                    22
+-#define PragTyp_MMAP_SIZE                     23
+-#define PragTyp_PAGE_SIZE                     24
+-#define PragTyp_SECURE_DELETE                 25
+-#define PragTyp_SHRINK_MEMORY                 26
+-#define PragTyp_SOFT_HEAP_LIMIT               27
+-#define PragTyp_STATS                         28
+-#define PragTyp_SYNCHRONOUS                   29
+-#define PragTyp_TABLE_INFO                    30
+-#define PragTyp_TEMP_STORE                    31
+-#define PragTyp_TEMP_STORE_DIRECTORY          32
+-#define PragTyp_THREADS                       33
+-#define PragTyp_WAL_AUTOCHECKPOINT            34
+-#define PragTyp_WAL_CHECKPOINT                35
+-#define PragTyp_ACTIVATE_EXTENSIONS           36
+-#define PragTyp_HEXKEY                        37
+-#define PragTyp_KEY                           38
+-#define PragTyp_REKEY                         39
+-#define PragTyp_LOCK_STATUS                   40
+-#define PragTyp_PARSER_TRACE                  41
+-#define PragFlag_NeedSchema           0x01
+-#define PragFlag_ReadOnly             0x02
+-static const struct sPragmaNames {
+-  const char *const zName;  /* Name of pragma */
+-  u8 ePragTyp;              /* PragTyp_XXX value */
+-  u8 mPragFlag;             /* Zero or more PragFlag_XXX values */
+-  u32 iArg;                 /* Extra argument */
+-} aPragmaNames[] = {
++#define PragTyp_CACHE_SPILL                    5
++#define PragTyp_CASE_SENSITIVE_LIKE            6
++#define PragTyp_COLLATION_LIST                 7
++#define PragTyp_COMPILE_OPTIONS                8
++#define PragTyp_DATA_STORE_DIRECTORY           9
++#define PragTyp_DATABASE_LIST                 10
++#define PragTyp_DEFAULT_CACHE_SIZE            11
++#define PragTyp_ENCODING                      12
++#define PragTyp_FOREIGN_KEY_CHECK             13
++#define PragTyp_FOREIGN_KEY_LIST              14
++#define PragTyp_FUNCTION_LIST                 15
++#define PragTyp_INCREMENTAL_VACUUM            16
++#define PragTyp_INDEX_INFO                    17
++#define PragTyp_INDEX_LIST                    18
++#define PragTyp_INTEGRITY_CHECK               19
++#define PragTyp_JOURNAL_MODE                  20
++#define PragTyp_JOURNAL_SIZE_LIMIT            21
++#define PragTyp_LOCK_PROXY_FILE               22
++#define PragTyp_LOCKING_MODE                  23
++#define PragTyp_PAGE_COUNT                    24
++#define PragTyp_MMAP_SIZE                     25
++#define PragTyp_MODULE_LIST                   26
++#define PragTyp_OPTIMIZE                      27
++#define PragTyp_PAGE_SIZE                     28
++#define PragTyp_PRAGMA_LIST                   29
++#define PragTyp_SECURE_DELETE                 30
++#define PragTyp_SHRINK_MEMORY                 31
++#define PragTyp_SOFT_HEAP_LIMIT               32
++#define PragTyp_SYNCHRONOUS                   33
++#define PragTyp_TABLE_INFO                    34
++#define PragTyp_TEMP_STORE                    35
++#define PragTyp_TEMP_STORE_DIRECTORY          36
++#define PragTyp_THREADS                       37
++#define PragTyp_WAL_AUTOCHECKPOINT            38
++#define PragTyp_WAL_CHECKPOINT                39
++#define PragTyp_ACTIVATE_EXTENSIONS           40
++#define PragTyp_HEXKEY                        41
++#define PragTyp_KEY                           42
++#define PragTyp_REKEY                         43
++#define PragTyp_LOCK_STATUS                   44
++#define PragTyp_PARSER_TRACE                  45
++#define PragTyp_STATS                         46
++
++/* Property flags associated with various pragma. */
++#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
++#define PragFlg_NoColumns  0x02 /* OP_ResultRow called with zero columns */
++#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
++#define PragFlg_ReadOnly   0x08 /* Read-only HEADER_VALUE */
++#define PragFlg_Result0    0x10 /* Acts as query when no argument */
++#define PragFlg_Result1    0x20 /* Acts as query when has one argument */
++#define PragFlg_SchemaOpt  0x40 /* Schema restricts name search if present */
++#define PragFlg_SchemaReq  0x80 /* Schema required - "main" is default */
++
++/* Names of columns for pragmas that return multi-column result
++** or that return single-column results where the name of the
++** result column is different from the name of the pragma
++*/
++static const char *const pragCName[] = {
++  /*   0 */ "cache_size",  /* Used by: default_cache_size */
++  /*   1 */ "cid",         /* Used by: table_info */
++  /*   2 */ "name",       
++  /*   3 */ "type",       
++  /*   4 */ "notnull",    
++  /*   5 */ "dflt_value", 
++  /*   6 */ "pk",         
++  /*   7 */ "tbl",         /* Used by: stats */
++  /*   8 */ "idx",        
++  /*   9 */ "wdth",       
++  /*  10 */ "hght",       
++  /*  11 */ "flgs",       
++  /*  12 */ "seqno",       /* Used by: index_info */
++  /*  13 */ "cid",        
++  /*  14 */ "name",       
++  /*  15 */ "seqno",       /* Used by: index_xinfo */
++  /*  16 */ "cid",        
++  /*  17 */ "name",       
++  /*  18 */ "desc",       
++  /*  19 */ "coll",       
++  /*  20 */ "key",        
++  /*  21 */ "seq",         /* Used by: index_list */
++  /*  22 */ "name",       
++  /*  23 */ "unique",     
++  /*  24 */ "origin",     
++  /*  25 */ "partial",    
++  /*  26 */ "seq",         /* Used by: database_list */
++  /*  27 */ "name",       
++  /*  28 */ "file",       
++  /*  29 */ "name",        /* Used by: function_list */
++  /*  30 */ "builtin",    
++  /*  31 */ "name",        /* Used by: module_list pragma_list */
++  /*  32 */ "seq",         /* Used by: collation_list */
++  /*  33 */ "name",       
++  /*  34 */ "id",          /* Used by: foreign_key_list */
++  /*  35 */ "seq",        
++  /*  36 */ "table",      
++  /*  37 */ "from",       
++  /*  38 */ "to",         
++  /*  39 */ "on_update",  
++  /*  40 */ "on_delete",  
++  /*  41 */ "match",      
++  /*  42 */ "table",       /* Used by: foreign_key_check */
++  /*  43 */ "rowid",      
++  /*  44 */ "parent",     
++  /*  45 */ "fkid",       
++  /*  46 */ "busy",        /* Used by: wal_checkpoint */
++  /*  47 */ "log",        
++  /*  48 */ "checkpointed",
++  /*  49 */ "timeout",     /* Used by: busy_timeout */
++  /*  50 */ "database",    /* Used by: lock_status */
++  /*  51 */ "status",     
++};
++
++/* Definitions of all built-in pragmas */
++typedef struct PragmaName {
++  const char *const zName; /* Name of pragma */
++  u8 ePragTyp;             /* PragTyp_XXX value */
++  u8 mPragFlg;             /* Zero or more PragFlg_XXX values */
++  u8 iPragCName;           /* Start of column names in pragCName[] */
++  u8 nPragCName;           /* Num of col names. 0 means use pragma name */
++  u32 iArg;                /* Extra argument */
++} PragmaName;
++static const PragmaName aPragmaName[] = {
+ #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
+-  { /* zName:     */ "activate_extensions",
+-    /* ePragTyp:  */ PragTyp_ACTIVATE_EXTENSIONS,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "activate_extensions",
++  /* ePragTyp:  */ PragTyp_ACTIVATE_EXTENSIONS,
++  /* ePragFlg:  */ 0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+-  { /* zName:     */ "application_id",
+-    /* ePragTyp:  */ PragTyp_HEADER_VALUE,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ BTREE_APPLICATION_ID },
++ {/* zName:     */ "application_id",
++  /* ePragTyp:  */ PragTyp_HEADER_VALUE,
++  /* ePragFlg:  */ PragFlg_NoColumns1|PragFlg_Result0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ BTREE_APPLICATION_ID },
+ #endif
+ #if !defined(SQLITE_OMIT_AUTOVACUUM)
+-  { /* zName:     */ "auto_vacuum",
+-    /* ePragTyp:  */ PragTyp_AUTO_VACUUM,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "auto_vacuum",
++  /* ePragTyp:  */ PragTyp_AUTO_VACUUM,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ #if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
+-  { /* zName:     */ "automatic_index",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_AutoIndex },
++ {/* zName:     */ "automatic_index",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_AutoIndex },
+ #endif
+ #endif
+-  { /* zName:     */ "busy_timeout",
+-    /* ePragTyp:  */ PragTyp_BUSY_TIMEOUT,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "busy_timeout",
++  /* ePragTyp:  */ PragTyp_BUSY_TIMEOUT,
++  /* ePragFlg:  */ PragFlg_Result0,
++  /* ColNames:  */ 49, 1,
++  /* iArg:      */ 0 },
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+-  { /* zName:     */ "cache_size",
+-    /* ePragTyp:  */ PragTyp_CACHE_SIZE,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "cache_size",
++  /* ePragTyp:  */ PragTyp_CACHE_SIZE,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+-  { /* zName:     */ "cache_spill",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_CacheSpill },
+-#endif
+-  { /* zName:     */ "case_sensitive_like",
+-    /* ePragTyp:  */ PragTyp_CASE_SENSITIVE_LIKE,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "cache_spill",
++  /* ePragTyp:  */ PragTyp_CACHE_SPILL,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
++#endif
++ {/* zName:     */ "case_sensitive_like",
++  /* ePragTyp:  */ PragTyp_CASE_SENSITIVE_LIKE,
++  /* ePragFlg:  */ PragFlg_NoColumns,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
++ {/* zName:     */ "cell_size_check",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_CellSizeCk },
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+-  { /* zName:     */ "checkpoint_fullfsync",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_CkptFullFSync },
++ {/* zName:     */ "checkpoint_fullfsync",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_CkptFullFSync },
+ #endif
+ #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+-  { /* zName:     */ "collation_list",
+-    /* ePragTyp:  */ PragTyp_COLLATION_LIST,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "collation_list",
++  /* ePragTyp:  */ PragTyp_COLLATION_LIST,
++  /* ePragFlg:  */ PragFlg_Result0,
++  /* ColNames:  */ 32, 2,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
+-  { /* zName:     */ "compile_options",
+-    /* ePragTyp:  */ PragTyp_COMPILE_OPTIONS,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "compile_options",
++  /* ePragTyp:  */ PragTyp_COMPILE_OPTIONS,
++  /* ePragFlg:  */ PragFlg_Result0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+-  { /* zName:     */ "count_changes",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_CountRows },
++ {/* zName:     */ "count_changes",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_CountRows },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
+-  { /* zName:     */ "data_store_directory",
+-    /* ePragTyp:  */ PragTyp_DATA_STORE_DIRECTORY,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "data_store_directory",
++  /* ePragTyp:  */ PragTyp_DATA_STORE_DIRECTORY,
++  /* ePragFlg:  */ PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+-  { /* zName:     */ "data_version",
+-    /* ePragTyp:  */ PragTyp_HEADER_VALUE,
+-    /* ePragFlag: */ PragFlag_ReadOnly,
+-    /* iArg:      */ BTREE_DATA_VERSION },
++ {/* zName:     */ "data_version",
++  /* ePragTyp:  */ PragTyp_HEADER_VALUE,
++  /* ePragFlg:  */ PragFlg_ReadOnly|PragFlg_Result0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ BTREE_DATA_VERSION },
+ #endif
+ #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+-  { /* zName:     */ "database_list",
+-    /* ePragTyp:  */ PragTyp_DATABASE_LIST,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "database_list",
++  /* ePragTyp:  */ PragTyp_DATABASE_LIST,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
++  /* ColNames:  */ 26, 3,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
+-  { /* zName:     */ "default_cache_size",
+-    /* ePragTyp:  */ PragTyp_DEFAULT_CACHE_SIZE,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "default_cache_size",
++  /* ePragTyp:  */ PragTyp_DEFAULT_CACHE_SIZE,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 1,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+-  { /* zName:     */ "defer_foreign_keys",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_DeferFKs },
++ {/* zName:     */ "defer_foreign_keys",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_DeferFKs },
+ #endif
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+-  { /* zName:     */ "empty_result_callbacks",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_NullCallback },
++ {/* zName:     */ "empty_result_callbacks",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_NullCallback },
+ #endif
+ #if !defined(SQLITE_OMIT_UTF16)
+-  { /* zName:     */ "encoding",
+-    /* ePragTyp:  */ PragTyp_ENCODING,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "encoding",
++  /* ePragTyp:  */ PragTyp_ENCODING,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+-  { /* zName:     */ "foreign_key_check",
+-    /* ePragTyp:  */ PragTyp_FOREIGN_KEY_CHECK,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "foreign_key_check",
++  /* ePragTyp:  */ PragTyp_FOREIGN_KEY_CHECK,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
++  /* ColNames:  */ 42, 4,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FOREIGN_KEY)
+-  { /* zName:     */ "foreign_key_list",
+-    /* ePragTyp:  */ PragTyp_FOREIGN_KEY_LIST,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "foreign_key_list",
++  /* ePragTyp:  */ PragTyp_FOREIGN_KEY_LIST,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
++  /* ColNames:  */ 34, 8,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+-  { /* zName:     */ "foreign_keys",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_ForeignKeys },
++ {/* zName:     */ "foreign_keys",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_ForeignKeys },
+ #endif
+ #endif
+ #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+-  { /* zName:     */ "freelist_count",
+-    /* ePragTyp:  */ PragTyp_HEADER_VALUE,
+-    /* ePragFlag: */ PragFlag_ReadOnly,
+-    /* iArg:      */ BTREE_FREE_PAGE_COUNT },
++ {/* zName:     */ "freelist_count",
++  /* ePragTyp:  */ PragTyp_HEADER_VALUE,
++  /* ePragFlg:  */ PragFlg_ReadOnly|PragFlg_Result0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ BTREE_FREE_PAGE_COUNT },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+-  { /* zName:     */ "full_column_names",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_FullColNames },
+-  { /* zName:     */ "fullfsync",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_FullFSync },
++ {/* zName:     */ "full_column_names",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_FullColNames },
++ {/* zName:     */ "fullfsync",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_FullFSync },
++#endif
++#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
++#if defined(SQLITE_INTROSPECTION_PRAGMAS)
++ {/* zName:     */ "function_list",
++  /* ePragTyp:  */ PragTyp_FUNCTION_LIST,
++  /* ePragFlg:  */ PragFlg_Result0,
++  /* ColNames:  */ 29, 2,
++  /* iArg:      */ 0 },
++#endif
+ #endif
+ #if defined(SQLITE_HAS_CODEC)
+-  { /* zName:     */ "hexkey",
+-    /* ePragTyp:  */ PragTyp_HEXKEY,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
+-  { /* zName:     */ "hexrekey",
+-    /* ePragTyp:  */ PragTyp_HEXKEY,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "hexkey",
++  /* ePragTyp:  */ PragTyp_HEXKEY,
++  /* ePragFlg:  */ 0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
++ {/* zName:     */ "hexrekey",
++  /* ePragTyp:  */ PragTyp_HEXKEY,
++  /* ePragFlg:  */ 0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ #if !defined(SQLITE_OMIT_CHECK)
+-  { /* zName:     */ "ignore_check_constraints",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_IgnoreChecks },
++ {/* zName:     */ "ignore_check_constraints",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_IgnoreChecks },
+ #endif
+ #endif
+ #if !defined(SQLITE_OMIT_AUTOVACUUM)
+-  { /* zName:     */ "incremental_vacuum",
+-    /* ePragTyp:  */ PragTyp_INCREMENTAL_VACUUM,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "incremental_vacuum",
++  /* ePragTyp:  */ PragTyp_INCREMENTAL_VACUUM,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_NoColumns,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+-  { /* zName:     */ "index_info",
+-    /* ePragTyp:  */ PragTyp_INDEX_INFO,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
+-  { /* zName:     */ "index_list",
+-    /* ePragTyp:  */ PragTyp_INDEX_LIST,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
+-  { /* zName:     */ "index_xinfo",
+-    /* ePragTyp:  */ PragTyp_INDEX_INFO,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 1 },
++ {/* zName:     */ "index_info",
++  /* ePragTyp:  */ PragTyp_INDEX_INFO,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
++  /* ColNames:  */ 12, 3,
++  /* iArg:      */ 0 },
++ {/* zName:     */ "index_list",
++  /* ePragTyp:  */ PragTyp_INDEX_LIST,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
++  /* ColNames:  */ 21, 5,
++  /* iArg:      */ 0 },
++ {/* zName:     */ "index_xinfo",
++  /* ePragTyp:  */ PragTyp_INDEX_INFO,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
++  /* ColNames:  */ 15, 6,
++  /* iArg:      */ 1 },
+ #endif
+ #if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
+-  { /* zName:     */ "integrity_check",
+-    /* ePragTyp:  */ PragTyp_INTEGRITY_CHECK,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "integrity_check",
++  /* ePragTyp:  */ PragTyp_INTEGRITY_CHECK,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+-  { /* zName:     */ "journal_mode",
+-    /* ePragTyp:  */ PragTyp_JOURNAL_MODE,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
+-  { /* zName:     */ "journal_size_limit",
+-    /* ePragTyp:  */ PragTyp_JOURNAL_SIZE_LIMIT,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "journal_mode",
++  /* ePragTyp:  */ PragTyp_JOURNAL_MODE,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
++ {/* zName:     */ "journal_size_limit",
++  /* ePragTyp:  */ PragTyp_JOURNAL_SIZE_LIMIT,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_SchemaReq,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if defined(SQLITE_HAS_CODEC)
+-  { /* zName:     */ "key",
+-    /* ePragTyp:  */ PragTyp_KEY,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "key",
++  /* ePragTyp:  */ PragTyp_KEY,
++  /* ePragFlg:  */ 0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+-  { /* zName:     */ "legacy_file_format",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_LegacyFileFmt },
++ {/* zName:     */ "legacy_file_format",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_LegacyFileFmt },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
+-  { /* zName:     */ "lock_proxy_file",
+-    /* ePragTyp:  */ PragTyp_LOCK_PROXY_FILE,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "lock_proxy_file",
++  /* ePragTyp:  */ PragTyp_LOCK_PROXY_FILE,
++  /* ePragFlg:  */ PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+-  { /* zName:     */ "lock_status",
+-    /* ePragTyp:  */ PragTyp_LOCK_STATUS,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "lock_status",
++  /* ePragTyp:  */ PragTyp_LOCK_STATUS,
++  /* ePragFlg:  */ PragFlg_Result0,
++  /* ColNames:  */ 50, 2,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+-  { /* zName:     */ "locking_mode",
+-    /* ePragTyp:  */ PragTyp_LOCKING_MODE,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
+-  { /* zName:     */ "max_page_count",
+-    /* ePragTyp:  */ PragTyp_PAGE_COUNT,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
+-  { /* zName:     */ "mmap_size",
+-    /* ePragTyp:  */ PragTyp_MMAP_SIZE,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
+-  { /* zName:     */ "page_count",
+-    /* ePragTyp:  */ PragTyp_PAGE_COUNT,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
+-  { /* zName:     */ "page_size",
+-    /* ePragTyp:  */ PragTyp_PAGE_SIZE,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "locking_mode",
++  /* ePragTyp:  */ PragTyp_LOCKING_MODE,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_SchemaReq,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
++ {/* zName:     */ "max_page_count",
++  /* ePragTyp:  */ PragTyp_PAGE_COUNT,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
++ {/* zName:     */ "mmap_size",
++  /* ePragTyp:  */ PragTyp_MMAP_SIZE,
++  /* ePragFlg:  */ 0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
 +#endif
-+  sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
-+  if(ltc_init == 0) {
-+    if(register_prng(&fortuna_desc) != CRYPT_OK) return SQLITE_ERROR;
-+    if(register_cipher(&rijndael_desc) != CRYPT_OK) return SQLITE_ERROR;
-+    if(register_hash(&sha1_desc) != CRYPT_OK) return SQLITE_ERROR;
-+    if(fortuna_start(&prng) != CRYPT_OK) {
-+      return SQLITE_ERROR;
-     }
--    *pVal = val;
--    zDate++;
--    cnt++;
--  }while( nextC );
--end_getDigits:
--  va_end(ap);
--  return cnt;
-+    ltc_init = 1;
-+  }
-+  ltc_ref_count++;
-+#ifndef SQLCIPHER_TEST
-+  sqlite3_randomness(FORTUNA_MAX_SZ, random_buffer);
++#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
++#if !defined(SQLITE_OMIT_VIRTUALTABLE)
++#if defined(SQLITE_INTROSPECTION_PRAGMAS)
++ {/* zName:     */ "module_list",
++  /* ePragTyp:  */ PragTyp_MODULE_LIST,
++  /* ePragFlg:  */ PragFlg_Result0,
++  /* ColNames:  */ 31, 1,
++  /* iArg:      */ 0 },
+ #endif
+-#if defined(SQLITE_DEBUG)
+-  { /* zName:     */ "parser_trace",
+-    /* ePragTyp:  */ PragTyp_PARSER_TRACE,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
 +#endif
-+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
-+  sqlite3_mutex_leave(ltc_rand_mutex);
 +#endif
-+  if(sqlcipher_ltc_add_random(ctx, random_buffer, FORTUNA_MAX_SZ) != SQLITE_OK) {
-+    return SQLITE_ERROR;
-+  }
-+  sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
-+  return SQLITE_OK;
- }
- 
--/*
--** Parse a timezone extension on the end of a date-time.
--** The extension is of the form:
--**
--**        (+/-)HH:MM
--**
--** Or the "zulu" notation:
--**
--**        Z
--**
--** If the parse is successful, write the number of minutes
--** of change in p->tz and return 0.  If a parser error occurs,
--** return non-zero.
--**
--** A missing specifier is not considered an error.
--*/
--static int parseTimezone(const char *zDate, DateTime *p){
--  int sgn = 0;
--  int nHr, nMn;
--  int c;
--  while( sqlite3Isspace(*zDate) ){ zDate++; }
--  p->tz = 0;
--  c = *zDate;
--  if( c=='-' ){
--    sgn = -1;
--  }else if( c=='+' ){
--    sgn = +1;
--  }else if( c=='Z' || c=='z' ){
--    zDate++;
--    goto zulu_time;
--  }else{
--    return c!=0;
--  }
--  zDate++;
--  if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
--    return 1;
-+static int sqlcipher_ltc_deactivate(void *ctx) {
-+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
-+  sqlite3_mutex_enter(ltc_rand_mutex);
++ {/* zName:     */ "optimize",
++  /* ePragTyp:  */ PragTyp_OPTIMIZE,
++  /* ePragFlg:  */ PragFlg_Result1|PragFlg_NeedSchema,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
++#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
++ {/* zName:     */ "page_count",
++  /* ePragTyp:  */ PragTyp_PAGE_COUNT,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
++ {/* zName:     */ "page_size",
++  /* ePragTyp:  */ PragTyp_PAGE_SIZE,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
 +#endif
-+  ltc_ref_count--;
-+  if(ltc_ref_count == 0){
-+    fortuna_done(&prng);
-+    sqlcipher_memset((void *)&prng, 0, sizeof(prng));
-+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
-+    sqlite3_mutex_leave(ltc_rand_mutex);
-+    sqlite3_mutex_free(ltc_rand_mutex);
-+    ltc_rand_mutex = NULL;
++#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE)
++ {/* zName:     */ "parser_trace",
++  /* ePragTyp:  */ PragTyp_PARSER_TRACE,
++  /* ePragFlg:  */ 0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
 +#endif
-+  }
-+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
-+  else {
-+    sqlite3_mutex_leave(ltc_rand_mutex);
-   }
--  zDate += 5;
--  p->tz = sgn*(nMn + nHr*60);
--zulu_time:
--  while( sqlite3Isspace(*zDate) ){ zDate++; }
--  return *zDate!=0;
-+#endif    
-+  return SQLITE_OK;
- }
- 
--/*
--** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
--** The HH, MM, and SS must each be exactly 2 digits.  The
--** fractional seconds FFFF can be one or more digits.
--**
--** Return 1 if there is a parsing error and 0 on success.
--*/
--static int parseHhMmSs(const char *zDate, DateTime *p){
--  int h, m, s;
--  double ms = 0.0;
--  if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
--    return 1;
-+static const char* sqlcipher_ltc_get_provider_name(void *ctx) {
-+  return "libtomcrypt";
-+}
-+
-+static int sqlcipher_ltc_random(void *ctx, void *buffer, int length) {
-+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
-+  sqlite3_mutex_enter(ltc_rand_mutex);
++#if defined(SQLITE_INTROSPECTION_PRAGMAS)
++ {/* zName:     */ "pragma_list",
++  /* ePragTyp:  */ PragTyp_PRAGMA_LIST,
++  /* ePragFlg:  */ PragFlg_Result0,
++  /* ColNames:  */ 31, 1,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+-  { /* zName:     */ "query_only",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_QueryOnly },
++ {/* zName:     */ "query_only",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_QueryOnly },
+ #endif
+ #if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
+-  { /* zName:     */ "quick_check",
+-    /* ePragTyp:  */ PragTyp_INTEGRITY_CHECK,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "quick_check",
++  /* ePragTyp:  */ PragTyp_INTEGRITY_CHECK,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+-  { /* zName:     */ "read_uncommitted",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_ReadUncommitted },
+-  { /* zName:     */ "recursive_triggers",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_RecTriggers },
++ {/* zName:     */ "read_uncommitted",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_ReadUncommit },
++ {/* zName:     */ "recursive_triggers",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_RecTriggers },
+ #endif
+ #if defined(SQLITE_HAS_CODEC)
+-  { /* zName:     */ "rekey",
+-    /* ePragTyp:  */ PragTyp_REKEY,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "rekey",
++  /* ePragTyp:  */ PragTyp_REKEY,
++  /* ePragFlg:  */ 0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+-  { /* zName:     */ "reverse_unordered_selects",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_ReverseOrder },
++ {/* zName:     */ "reverse_unordered_selects",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_ReverseOrder },
+ #endif
+ #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+-  { /* zName:     */ "schema_version",
+-    /* ePragTyp:  */ PragTyp_HEADER_VALUE,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ BTREE_SCHEMA_VERSION },
++ {/* zName:     */ "schema_version",
++  /* ePragTyp:  */ PragTyp_HEADER_VALUE,
++  /* ePragFlg:  */ PragFlg_NoColumns1|PragFlg_Result0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ BTREE_SCHEMA_VERSION },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+-  { /* zName:     */ "secure_delete",
+-    /* ePragTyp:  */ PragTyp_SECURE_DELETE,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "secure_delete",
++  /* ePragTyp:  */ PragTyp_SECURE_DELETE,
++  /* ePragFlg:  */ PragFlg_Result0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+-  { /* zName:     */ "short_column_names",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_ShortColNames },
+-#endif
+-  { /* zName:     */ "shrink_memory",
+-    /* ePragTyp:  */ PragTyp_SHRINK_MEMORY,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
+-  { /* zName:     */ "soft_heap_limit",
+-    /* ePragTyp:  */ PragTyp_SOFT_HEAP_LIMIT,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "short_column_names",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_ShortColNames },
 +#endif
-+  fortuna_read(buffer, length, &prng);
-+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
-+  sqlite3_mutex_leave(ltc_rand_mutex);
++ {/* zName:     */ "shrink_memory",
++  /* ePragTyp:  */ PragTyp_SHRINK_MEMORY,
++  /* ePragFlg:  */ PragFlg_NoColumns,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
++ {/* zName:     */ "soft_heap_limit",
++  /* ePragTyp:  */ PragTyp_SOFT_HEAP_LIMIT,
++  /* ePragFlg:  */ PragFlg_Result0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ #if defined(SQLITE_DEBUG)
+-  { /* zName:     */ "sql_trace",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_SqlTrace },
++ {/* zName:     */ "sql_trace",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_SqlTrace },
+ #endif
+ #endif
+-#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+-  { /* zName:     */ "stats",
+-    /* ePragTyp:  */ PragTyp_STATS,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
++ {/* zName:     */ "stats",
++  /* ePragTyp:  */ PragTyp_STATS,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
++  /* ColNames:  */ 7, 5,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+-  { /* zName:     */ "synchronous",
+-    /* ePragTyp:  */ PragTyp_SYNCHRONOUS,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "synchronous",
++  /* ePragTyp:  */ PragTyp_SYNCHRONOUS,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+-  { /* zName:     */ "table_info",
+-    /* ePragTyp:  */ PragTyp_TABLE_INFO,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "table_info",
++  /* ePragTyp:  */ PragTyp_TABLE_INFO,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
++  /* ColNames:  */ 1, 6,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+-  { /* zName:     */ "temp_store",
+-    /* ePragTyp:  */ PragTyp_TEMP_STORE,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
+-  { /* zName:     */ "temp_store_directory",
+-    /* ePragTyp:  */ PragTyp_TEMP_STORE_DIRECTORY,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
+-#endif
+-  { /* zName:     */ "threads",
+-    /* ePragTyp:  */ PragTyp_THREADS,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "temp_store",
++  /* ePragTyp:  */ PragTyp_TEMP_STORE,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
++ {/* zName:     */ "temp_store_directory",
++  /* ePragTyp:  */ PragTyp_TEMP_STORE_DIRECTORY,
++  /* ePragFlg:  */ PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
 +#endif
-+  return SQLITE_OK;
-+}
-+
-+static int sqlcipher_ltc_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, 
unsigned char *in2, int in2_sz, unsigned char *out) {
-+  int rc, hash_idx;
-+  hmac_state hmac;
-+  unsigned long outlen = key_sz;
-+
-+  hash_idx = find_hash("sha1");
-+  if((rc = hmac_init(&hmac, hash_idx, hmac_key, key_sz)) != CRYPT_OK) return SQLITE_ERROR;
-+  if((rc = hmac_process(&hmac, in, in_sz)) != CRYPT_OK) return SQLITE_ERROR;
-+  if((rc = hmac_process(&hmac, in2, in2_sz)) != CRYPT_OK) return SQLITE_ERROR;
-+  if((rc = hmac_done(&hmac, out, &outlen)) != CRYPT_OK) return SQLITE_ERROR;
-+  return SQLITE_OK;
-+}
-+
-+static int sqlcipher_ltc_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int 
salt_sz, int workfactor, int key_sz, unsigned char *key) {
-+  int rc, hash_idx;
-+  unsigned long outlen = key_sz;
-+  unsigned long random_buffer_sz = sizeof(char) * 256;
-+  unsigned char *random_buffer = sqlcipher_malloc(random_buffer_sz);
-+  sqlcipher_memset(random_buffer, 0, random_buffer_sz);
-+
-+  hash_idx = find_hash("sha1");
-+  if((rc = pkcs_5_alg2(pass, pass_sz, salt, salt_sz,
-+                       workfactor, hash_idx, key, &outlen)) != CRYPT_OK) {
-+    return SQLITE_ERROR;
++ {/* zName:     */ "threads",
++  /* ePragTyp:  */ PragTyp_THREADS,
++  /* ePragFlg:  */ PragFlg_Result0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
+ #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+-  { /* zName:     */ "user_version",
+-    /* ePragTyp:  */ PragTyp_HEADER_VALUE,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ BTREE_USER_VERSION },
++ {/* zName:     */ "user_version",
++  /* ePragTyp:  */ PragTyp_HEADER_VALUE,
++  /* ePragFlg:  */ PragFlg_NoColumns1|PragFlg_Result0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ BTREE_USER_VERSION },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ #if defined(SQLITE_DEBUG)
+-  { /* zName:     */ "vdbe_addoptrace",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_VdbeAddopTrace },
+-  { /* zName:     */ "vdbe_debug",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
+-  { /* zName:     */ "vdbe_eqp",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_VdbeEQP },
+-  { /* zName:     */ "vdbe_listing",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_VdbeListing },
+-  { /* zName:     */ "vdbe_trace",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_VdbeTrace },
++ {/* zName:     */ "vdbe_addoptrace",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_VdbeAddopTrace },
++ {/* zName:     */ "vdbe_debug",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
++ {/* zName:     */ "vdbe_eqp",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_VdbeEQP },
++ {/* zName:     */ "vdbe_listing",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_VdbeListing },
++ {/* zName:     */ "vdbe_trace",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_VdbeTrace },
+ #endif
+ #endif
+ #if !defined(SQLITE_OMIT_WAL)
+-  { /* zName:     */ "wal_autocheckpoint",
+-    /* ePragTyp:  */ PragTyp_WAL_AUTOCHECKPOINT,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ 0 },
+-  { /* zName:     */ "wal_checkpoint",
+-    /* ePragTyp:  */ PragTyp_WAL_CHECKPOINT,
+-    /* ePragFlag: */ PragFlag_NeedSchema,
+-    /* iArg:      */ 0 },
++ {/* zName:     */ "wal_autocheckpoint",
++  /* ePragTyp:  */ PragTyp_WAL_AUTOCHECKPOINT,
++  /* ePragFlg:  */ 0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 0 },
++ {/* zName:     */ "wal_checkpoint",
++  /* ePragTyp:  */ PragTyp_WAL_CHECKPOINT,
++  /* ePragFlg:  */ PragFlg_NeedSchema,
++  /* ColNames:  */ 46, 3,
++  /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+-  { /* zName:     */ "writable_schema",
+-    /* ePragTyp:  */ PragTyp_FLAG,
+-    /* ePragFlag: */ 0,
+-    /* iArg:      */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
++ {/* zName:     */ "writable_schema",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_WriteSchema },
+ #endif
+ };
+-/* Number of pragmas: 59 on by default, 72 total. */
++/* Number of pragmas: 60 on by default, 77 total. */
+ 
+ /************** End of pragma.h **********************************************/
+ /************** Continuing where we left off in pragma.c *********************/
+ 
+ /*
+ ** Interpret the given string as a safety level.  Return 0 for OFF,
+-** 1 for ON or NORMAL and 2 for FULL.  Return 1 for an empty or 
+-** unrecognized string argument.  The FULL option is disallowed
++** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA.  Return 1 for an empty or 
++** unrecognized string argument.  The FULL and EXTRA option is disallowed
+ ** if the omitFull parameter it 1.
+ **
+ ** Note that the values returned are one less that the values that
+@@ -103632,18 +117371,21 @@
+ ** and older scripts may have used numbers 0 for OFF and 1 for ON.
+ */
+ static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){
+-                             /* 123456789 123456789 */
+-  static const char zText[] = "onoffalseyestruefull";
+-  static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
+-  static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
+-  static const u8 iValue[] =  {1, 0, 0, 0, 1, 1, 2};
++                             /* 123456789 123456789 123 */
++  static const char zText[] = "onoffalseyestruextrafull";
++  static const u8 iOffset[] = {0, 1, 2,  4,    9,  12,  15,   20};
++  static const u8 iLength[] = {2, 2, 3,  5,    3,   4,   5,    4};
++  static const u8 iValue[] =  {1, 0, 0,  0,    1,   1,   3,    2};
++                            /* on no off false yes true extra full */
+   int i, n;
+   if( sqlite3Isdigit(*z) ){
+     return (u8)sqlite3Atoi(z);
    }
--  zDate += 5;
--  if( *zDate==':' ){
--    zDate++;
--    if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
--      return 1;
--    }
--    zDate += 2;
--    if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){
--      double rScale = 1.0;
--      zDate++;
--      while( sqlite3Isdigit(*zDate) ){
--        ms = ms*10.0 + *zDate - '0';
--        rScale *= 10.0;
--        zDate++;
--      }
--      ms /= rScale;
--    }
--  }else{
--    s = 0;
-+  if((rc = pkcs_5_alg2(key, key_sz, salt, salt_sz,
-+                       1, hash_idx, random_buffer, &random_buffer_sz)) != CRYPT_OK) {
-+    return SQLITE_ERROR;
+   n = sqlite3Strlen30(z);
+-  for(i=0; i<ArraySize(iLength)-omitFull; i++){
+-    if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){
++  for(i=0; i<ArraySize(iLength); i++){
++    if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0
++     && (!omitFull || iValue[i]<=1)
++    ){
+       return iValue[i];
+     }
    }
--  p->validJD = 0;
--  p->validHMS = 1;
--  p->h = h;
--  p->m = m;
--  p->s = s + ms;
--  if( parseTimezone(zDate, p) ) return 1;
--  p->validTZ = (p->tz!=0)?1:0;
-+  sqlcipher_ltc_add_random(ctx, random_buffer, random_buffer_sz);
-+  sqlcipher_free(random_buffer, random_buffer_sz);
-+  return SQLITE_OK;
-+}
-+
-+static const char* sqlcipher_ltc_get_cipher(void *ctx) {
-+  return "rijndael";
-+}
-+
-+static int sqlcipher_ltc_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, 
unsigned char *in, int in_sz, unsigned char *out) {
-+  int rc, cipher_idx;
-+  symmetric_CBC cbc;
-+
-+  if((cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx))) == -1) return SQLITE_ERROR;
-+  if((rc = cbc_start(cipher_idx, iv, key, key_sz, 0, &cbc)) != CRYPT_OK) return SQLITE_ERROR;
-+  rc = mode == 1 ? cbc_encrypt(in, out, in_sz, &cbc) : cbc_decrypt(in, out, in_sz, &cbc);
-+  if(rc != CRYPT_OK) return SQLITE_ERROR;
-+  cbc_done(&cbc);
-+  return SQLITE_OK;
-+}
-+
-+static int sqlcipher_ltc_set_cipher(void *ctx, const char *cipher_name) {
-+  return SQLITE_OK;
-+}
-+
-+static int sqlcipher_ltc_get_key_sz(void *ctx) {
-+  int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
-+  return cipher_descriptor[cipher_idx].max_key_length;
-+}
-+
-+static int sqlcipher_ltc_get_iv_sz(void *ctx) {
-+  int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
-+  return cipher_descriptor[cipher_idx].block_length;
-+}
-+
-+static int sqlcipher_ltc_get_block_sz(void *ctx) {
-+  int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
-+  return cipher_descriptor[cipher_idx].block_length;
-+}
-+
-+static int sqlcipher_ltc_get_hmac_sz(void *ctx) {
-+  int hash_idx = find_hash("sha1");
-+  return hash_descriptor[hash_idx].hashsize;
-+}
-+
-+static int sqlcipher_ltc_ctx_copy(void *target_ctx, void *source_ctx) {
-+  return SQLITE_OK;
-+}
-+
-+static int sqlcipher_ltc_ctx_cmp(void *c1, void *c2) {
-+  return 1;
-+}
-+
-+static int sqlcipher_ltc_ctx_init(void **ctx) {
-+  sqlcipher_ltc_activate(NULL);
-+  return SQLITE_OK;
+@@ -103750,19 +117492,43 @@
+ #endif /* SQLITE_PAGER_PRAGMAS */
+ 
+ /*
++** Set result column names for a pragma.
++*/
++static void setPragmaResultColumnNames(
++  Vdbe *v,                     /* The query under construction */
++  const PragmaName *pPragma    /* The pragma */
++){
++  u8 n = pPragma->nPragCName;
++  sqlite3VdbeSetNumCols(v, n==0 ? 1 : n);
++  if( n==0 ){
++    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC);
++  }else{
++    int i, j;
++    for(i=0, j=pPragma->iPragCName; i<n; i++, j++){
++      sqlite3VdbeSetColName(v, i, COLNAME_NAME, pragCName[j], SQLITE_STATIC);
++    }
++  }
 +}
 +
-+static int sqlcipher_ltc_ctx_free(void **ctx) {
-+  sqlcipher_ltc_deactivate(&ctx);
-+  return SQLITE_OK;
++/*
+ ** Generate code to return a single integer value.
+ */
+-static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
+-  Vdbe *v = sqlite3GetVdbe(pParse);
+-  int nMem = ++pParse->nMem;
+-  i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
+-  if( pI64 ){
+-    memcpy(pI64, &value, sizeof(value));
++static void returnSingleInt(Vdbe *v, i64 value){
++  sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, 1, 0, (const u8*)&value, P4_INT64);
++  sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
 +}
 +
-+static int sqlcipher_ltc_fips_status(void *ctx) {
-   return 0;
++/*
++** Generate code to return a single text value.
++*/
++static void returnSingleText(
++  Vdbe *v,                /* Prepared statement under construction */
++  const char *zValue      /* Value to be returned */
++){
++  if( zValue ){
++    sqlite3VdbeLoadString(v, 1, (const char*)zValue);
++    sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+   }
+-  sqlite3VdbeAddOp4(v, OP_Int64, 0, nMem, 0, (char*)pI64, P4_INT64);
+-  sqlite3VdbeSetNumCols(v, 1);
+-  sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
+-  sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
  }
  
-+int sqlcipher_ltc_setup(sqlcipher_provider *p) {
-+  p->activate = sqlcipher_ltc_activate;
-+  p->deactivate = sqlcipher_ltc_deactivate;
-+  p->get_provider_name = sqlcipher_ltc_get_provider_name;
-+  p->random = sqlcipher_ltc_random;
-+  p->hmac = sqlcipher_ltc_hmac;
-+  p->kdf = sqlcipher_ltc_kdf;
-+  p->cipher = sqlcipher_ltc_cipher;
-+  p->set_cipher = sqlcipher_ltc_set_cipher;
-+  p->get_cipher = sqlcipher_ltc_get_cipher;
-+  p->get_key_sz = sqlcipher_ltc_get_key_sz;
-+  p->get_iv_sz = sqlcipher_ltc_get_iv_sz;
-+  p->get_block_sz = sqlcipher_ltc_get_block_sz;
-+  p->get_hmac_sz = sqlcipher_ltc_get_hmac_sz;
-+  p->ctx_copy = sqlcipher_ltc_ctx_copy;
-+  p->ctx_cmp = sqlcipher_ltc_ctx_cmp;
-+  p->ctx_init = sqlcipher_ltc_ctx_init;
-+  p->ctx_free = sqlcipher_ltc_ctx_free;
-+  p->add_random = sqlcipher_ltc_add_random;
-+  p->fips_status = sqlcipher_ltc_fips_status;
-+  return SQLITE_OK;
+ 
+@@ -103838,22 +117604,40 @@
+   return azModeName[eMode];
+ }
+ 
+-static char *gdauniqueFuncName (FuncDef *func)
+-{
+-      char *sname;
+-      unsigned int order = 0;
+-      FuncDef *n;
+-      int size;
+-      for (n = func->pNext; n; n = n->pNext)
+-              order++;
+-
+-      size = strlen (func->zName) + 25;
+-      sname = sqlite3_malloc (sizeof (char) * size);
+-      if (func->nArg < 0)
+-              snprintf (sname, size-1, "%s_ANY_%u", func->zName, order);
+-      else
+-              snprintf (sname, size-1, "%s_%d_%u", func->zName, func->nArg, order);
+-      return sname;
++/*
++** Locate a pragma in the aPragmaName[] array.
++*/
++static const PragmaName *pragmaLocate(const char *zName){
++  int upr, lwr, mid = 0, rc;
++  lwr = 0;
++  upr = ArraySize(aPragmaName)-1;
++  while( lwr<=upr ){
++    mid = (lwr+upr)/2;
++    rc = sqlite3_stricmp(zName, aPragmaName[mid].zName);
++    if( rc==0 ) break;
++    if( rc<0 ){
++      upr = mid - 1;
++    }else{
++      lwr = mid + 1;
++    }
++  }
++  return lwr>upr ? 0 : &aPragmaName[mid];
 +}
 +
-+#endif
-+#endif
-+/* END SQLCIPHER */
-+
-+/************** End of crypto_libtomcrypt.c **********************************/
-+/************** Begin file crypto_openssl.c **********************************/
- /*
--** Convert from YYYY-MM-DD HH:MM:SS to julian day.  We always assume
--** that the YYYY-MM-DD is according to the Gregorian calendar.
-+** SQLCipher
-+** http://sqlcipher.net
-+**
-+** Copyright (c) 2008 - 2013, ZETETIC LLC
-+** All rights reserved.
-+**
-+** Redistribution and use in source and binary forms, with or without
-+** modification, are permitted provided that the following conditions are met:
-+**     * Redistributions of source code must retain the above copyright
-+**       notice, this list of conditions and the following disclaimer.
-+**     * Redistributions in binary form must reproduce the above copyright
-+**       notice, this list of conditions and the following disclaimer in the
-+**       documentation and/or other materials provided with the distribution.
-+**     * Neither the name of the ZETETIC LLC nor the
-+**       names of its contributors may be used to endorse or promote products
-+**       derived from this software without specific prior written permission.
++/*
++** Helper subroutine for PRAGMA integrity_check:
 +**
-+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
-+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
-+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++** Generate code to output a single-column result row with the result
++** held in register regResult.  Decrement the result count and halt if
++** the maximum number of result rows have been issued.
++*/
++static int integrityCheckResultRow(Vdbe *v, int regResult){
++  int addr;
++  sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1);
++  addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
++  return addr;
+ }
+ 
+ /*
+@@ -103861,7 +117645,7 @@
+ **
+ ** Pragmas are of this form:
  **
--** Reference:  Meeus page 61
+-**      PRAGMA [database.]id [= value]
++**      PRAGMA [schema.]id [= value]
+ **
+ ** The identifier might also be a string.  The value is a string, and
+ ** identifier, or a number.  If minusFlag is true, then the value is
+@@ -103873,8 +117657,8 @@
  */
--static void computeJD(DateTime *p){
--  int Y, M, D, A, B, X1, X2;
+ SQLITE_PRIVATE void sqlite3Pragma(
+   Parse *pParse, 
+-  Token *pId1,        /* First part of [database.]id field */
+-  Token *pId2,        /* Second part of [database.]id field, or NULL */
++  Token *pId1,        /* First part of [schema.]id field */
++  Token *pId2,        /* Second part of [schema.]id field, or NULL */
+   Token *pValue,      /* Token for <value>, or NULL */
+   int minusFlag       /* True if a '-' sign preceded <value> */
+ ){
+@@ -103884,18 +117668,22 @@
+   Token *pId;            /* Pointer to <id> token */
+   char *aFcntl[4];       /* Argument to SQLITE_FCNTL_PRAGMA */
+   int iDb;               /* Database index for <database> */
+-  int lwr, upr, mid = 0;       /* Binary search bounds */
+   int rc;                      /* return value form SQLITE_FCNTL_PRAGMA */
+   sqlite3 *db = pParse->db;    /* The database connection */
+   Db *pDb;                     /* The specific database being pragmaed */
+   Vdbe *v = sqlite3GetVdbe(pParse);  /* Prepared statement */
+-  const struct sPragmaNames *pPragma;
++  const PragmaName *pPragma;   /* The pragma */
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
-+#ifdef SQLCIPHER_CRYPTO_OPENSSL
-+#include <openssl/rand.h>
-+#include <openssl/evp.h>
-+#include <openssl/hmac.h>
++  extern int sqlcipher_codec_pragma(sqlite3*, int, Parse *, const char *, const char *);
++#endif
++/* END SQLCIPHER */
+ 
+   if( v==0 ) return;
+   sqlite3VdbeRunOnlyOnce(v);
+   pParse->nMem = 2;
+ 
+-  /* Interpret the [database.] part of the pragma statement. iDb is the
++  /* Interpret the [schema.] part of the pragma statement. iDb is the
+   ** index of the database this pragma is being applied to in db.aDb[]. */
+   iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
+   if( iDb<0 ) return;
+@@ -103917,7 +117705,7 @@
+   }
+ 
+   assert( pId2 );
+-  zDb = pId2->n>0 ? pDb->zName : 0;
++  zDb = pId2->n>0 ? pDb->zDbSName : 0;
+   if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
+     goto pragma_out;
+   }
+@@ -103944,14 +117732,10 @@
+   db->busyHandler.nBusy = 0;
+   rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
+   if( rc==SQLITE_OK ){
+-    if( aFcntl[0] ){
+-      int nMem = ++pParse->nMem;
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, nMem, 0, aFcntl[0], 0);
+-      sqlite3VdbeSetNumCols(v, 1);
+-      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
+-      sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
+-      sqlite3_free(aFcntl[0]);
+-    }
++    sqlite3VdbeSetNumCols(v, 1);
++    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, aFcntl[0], SQLITE_TRANSIENT);
++    returnSingleText(v, aFcntl[0]);
++    sqlite3_free(aFcntl[0]);
+     goto pragma_out;
+   }
+   if( rc!=SQLITE_NOTFOUND ){
+@@ -103961,37 +117745,42 @@
+     }
+     pParse->nErr++;
+     pParse->rc = rc;
 +
-+typedef struct {
-+  EVP_CIPHER *evp_cipher;
-+} openssl_ctx;
+     goto pragma_out;
+   }
+ 
+-  /* Locate the pragma in the lookup table */
+-  lwr = 0;
+-  upr = ArraySize(aPragmaNames)-1;
+-  while( lwr<=upr ){
+-    mid = (lwr+upr)/2;
+-    rc = sqlite3_stricmp(zLeft, aPragmaNames[mid].zName);
+-    if( rc==0 ) break;
+-    if( rc<0 ){
+-      upr = mid - 1;
+-    }else{
+-      lwr = mid + 1;
+-    }
++/* BEGIN SQLCIPHER */
++#ifdef SQLITE_HAS_CODEC
++  if(sqlcipher_codec_pragma(db, iDb, pParse, zLeft, zRight)) { 
++    /* sqlcipher_codec_pragma executes internal */
++    goto pragma_out;
+   }
+-  if( lwr>upr ) goto pragma_out;
+-  pPragma = &aPragmaNames[mid];
++#endif
++/* END SQLCIPHER */  
 +
-+static unsigned int openssl_external_init = 0;
-+static unsigned int openssl_init_count = 0;
-+static sqlite3_mutex* openssl_rand_mutex = NULL;
++  /* Locate the pragma in the lookup table */
++  pPragma = pragmaLocate(zLeft);
++  if( pPragma==0 ) goto pragma_out;
+ 
+   /* Make sure the database schema is loaded if the pragma requires that */
+-  if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){
++  if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){
+     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+   }
+ 
++  /* Register the result column names for pragmas that return results */
++  if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 
++   && ((pPragma->mPragFlg & PragFlg_NoColumns1)==0 || zRight==0)
++  ){
++    setPragmaResultColumnNames(v, pPragma);
++  }
 +
-+static int sqlcipher_openssl_add_random(void *ctx, void *buffer, int length) {
-+#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
-+  sqlite3_mutex_enter(openssl_rand_mutex);
-+#endif
-+  RAND_add(buffer, length, 0);
-+#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
-+  sqlite3_mutex_leave(openssl_rand_mutex);
-+#endif
-+  return SQLITE_OK;
-+}
+   /* Jump to the appropriate pragma handler */
+   switch( pPragma->ePragTyp ){
+   
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
+   /*
+-  **  PRAGMA [database.]default_cache_size
+-  **  PRAGMA [database.]default_cache_size=N
++  **  PRAGMA [schema.]default_cache_size
++  **  PRAGMA [schema.]default_cache_size=N
+   **
+   ** The first form reports the current persistent setting for the
+   ** page cache size.  The value returned is the maximum number of
+@@ -104018,21 +117807,20 @@
+       { OP_Noop,        0, 0,        0},
+       { OP_ResultRow,   1, 1,        0},
+     };
+-    int addr;
++    VdbeOp *aOp;
+     sqlite3VdbeUsesBtree(v, iDb);
+     if( !zRight ){
+-      sqlite3VdbeSetNumCols(v, 1);
+-      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC);
+       pParse->nMem += 2;
+-      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize,iLn);
+-      sqlite3VdbeChangeP1(v, addr, iDb);
+-      sqlite3VdbeChangeP1(v, addr+1, iDb);
+-      sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
++      sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize));
++      aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn);
++      if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
++      aOp[0].p1 = iDb;
++      aOp[1].p1 = iDb;
++      aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE;
+     }else{
+       int size = sqlite3AbsInt32(sqlite3Atoi(zRight));
+       sqlite3BeginWriteOperation(pParse, 0, iDb);
+-      sqlite3VdbeAddOp2(v, OP_Integer, size, 1);
+-      sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1);
++      sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, size);
+       assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+       pDb->pSchema->cache_size = size;
+       sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
+@@ -104043,8 +117831,8 @@
+ 
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+   /*
+-  **  PRAGMA [database.]page_size
+-  **  PRAGMA [database.]page_size=N
++  **  PRAGMA [schema.]page_size
++  **  PRAGMA [schema.]page_size=N
+   **
+   ** The first form reports the current setting for the
+   ** database page size in bytes.  The second form sets the
+@@ -104056,33 +117844,37 @@
+     assert( pBt!=0 );
+     if( !zRight ){
+       int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
+-      returnSingleInt(pParse, "page_size", size);
++      returnSingleInt(v, size);
+     }else{
+       /* Malloc may fail when setting the page-size, as there is an internal
+       ** buffer that the pager module resizes using sqlite3_realloc().
+       */
+       db->nextPagesize = sqlite3Atoi(zRight);
+       if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){
+-        db->mallocFailed = 1;
++        sqlite3OomFault(db);
+       }
+     }
+     break;
+   }
  
--  if( p->validJD ) return;
--  if( p->validYMD ){
--    Y = p->Y;
--    M = p->M;
--    D = p->D;
--  }else{
--    Y = 2000;  /* If no YMD specified, assume 2000-Jan-01 */
--    M = 1;
--    D = 1;
--  }
--  if( M<=2 ){
--    Y--;
--    M += 12;
-+/* activate and initialize sqlcipher. Most importantly, this will automatically
-+   intialize OpenSSL's EVP system if it hasn't already be externally. Note that 
-+   this function may be called multiple times as new codecs are intiialized. 
-+   Thus it performs some basic counting to ensure that only the last and final
-+   sqlcipher_openssl_deactivate() will free the EVP structures. 
-+*/
-+static int sqlcipher_openssl_activate(void *ctx) {
-+  /* initialize openssl and increment the internal init counter
-+     but only if it hasn't been initalized outside of SQLCipher by this program 
-+     e.g. on startup */
-+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+   /*
+-  **  PRAGMA [database.]secure_delete
+-  **  PRAGMA [database.]secure_delete=ON/OFF
++  **  PRAGMA [schema.]secure_delete
++  **  PRAGMA [schema.]secure_delete=ON/OFF/FAST
+   **
+   ** The first form reports the current setting for the
+   ** secure_delete flag.  The second form changes the secure_delete
+-  ** flag setting and reports thenew value.
++  ** flag setting and reports the new value.
+   */
+   case PragTyp_SECURE_DELETE: {
+     Btree *pBt = pDb->pBt;
+     int b = -1;
+     assert( pBt!=0 );
+     if( zRight ){
+-      b = sqlite3GetBoolean(zRight, 0);
++      if( sqlite3_stricmp(zRight, "fast")==0 ){
++        b = 2;
++      }else{
++        b = sqlite3GetBoolean(zRight, 0);
++      }
+     }
+     if( pId2->n==0 && b>=0 ){
+       int ii;
+@@ -104091,13 +117883,13 @@
+       }
+     }
+     b = sqlite3BtreeSecureDelete(pBt, b);
+-    returnSingleInt(pParse, "secure_delete", b);
++    returnSingleInt(v, b);
+     break;
+   }
+ 
+   /*
+-  **  PRAGMA [database.]max_page_count
+-  **  PRAGMA [database.]max_page_count=N
++  **  PRAGMA [schema.]max_page_count
++  **  PRAGMA [schema.]max_page_count=N
+   **
+   ** The first form reports the current setting for the
+   ** maximum number of pages in the database file.  The 
+@@ -104108,7 +117900,7 @@
+   ** change.  The only purpose is to provide an easy way to test
+   ** the sqlite3AbsInt32() function.
+   **
+-  **  PRAGMA [database.]page_count
++  **  PRAGMA [schema.]page_count
+   **
+   ** Return the number of pages in the specified database.
+   */
+@@ -104123,14 +117915,12 @@
+                         sqlite3AbsInt32(sqlite3Atoi(zRight)));
+     }
+     sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
+-    sqlite3VdbeSetNumCols(v, 1);
+-    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
+     break;
+   }
+ 
+   /*
+-  **  PRAGMA [database.]locking_mode
+-  **  PRAGMA [database.]locking_mode = (normal|exclusive)
++  **  PRAGMA [schema.]locking_mode
++  **  PRAGMA [schema.]locking_mode = (normal|exclusive)
+   */
+   case PragTyp_LOCKING_MODE: {
+     const char *zRet = "normal";
+@@ -104170,25 +117960,19 @@
+     if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){
+       zRet = "exclusive";
+     }
+-    sqlite3VdbeSetNumCols(v, 1);
+-    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", SQLITE_STATIC);
+-    sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zRet, 0);
+-    sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
++    returnSingleText(v, zRet);
+     break;
+   }
+ 
+   /*
+-  **  PRAGMA [database.]journal_mode
+-  **  PRAGMA [database.]journal_mode =
++  **  PRAGMA [schema.]journal_mode
++  **  PRAGMA [schema.]journal_mode =
+   **                      (delete|persist|off|truncate|memory|wal|off)
+   */
+   case PragTyp_JOURNAL_MODE: {
+     int eMode;        /* One of the PAGER_JOURNALMODE_XXX symbols */
+     int ii;           /* Loop counter */
+ 
+-    sqlite3VdbeSetNumCols(v, 1);
+-    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC);
+-
+     if( zRight==0 ){
+       /* If there is no "=MODE" part of the pragma, do a query for the
+       ** current mode */
+@@ -104221,8 +118005,8 @@
+   }
+ 
+   /*
+-  **  PRAGMA [database.]journal_size_limit
+-  **  PRAGMA [database.]journal_size_limit=N
++  **  PRAGMA [schema.]journal_size_limit
++  **  PRAGMA [schema.]journal_size_limit=N
+   **
+   ** Get or set the size limit on rollback journal files.
+   */
+@@ -104234,15 +118018,15 @@
+       if( iLimit<-1 ) iLimit = -1;
+     }
+     iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
+-    returnSingleInt(pParse, "journal_size_limit", iLimit);
++    returnSingleInt(v, iLimit);
+     break;
+   }
+ 
+ #endif /* SQLITE_OMIT_PAGER_PRAGMAS */
+ 
+   /*
+-  **  PRAGMA [database.]auto_vacuum
+-  **  PRAGMA [database.]auto_vacuum=N
++  **  PRAGMA [schema.]auto_vacuum
++  **  PRAGMA [schema.]auto_vacuum=N
+   **
+   ** Get or set the value of the database 'auto-vacuum' parameter.
+   ** The value is one of:  0 NONE 1 FULL 2 INCREMENTAL
+@@ -104252,7 +118036,7 @@
+     Btree *pBt = pDb->pBt;
+     assert( pBt!=0 );
+     if( !zRight ){
+-      returnSingleInt(pParse, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt));
++      returnSingleInt(v, sqlite3BtreeGetAutoVacuum(pBt));
+     }else{
+       int eAuto = getAutoVacuum(zRight);
+       assert( eAuto>=0 && eAuto<=2 );
+@@ -104275,16 +118059,18 @@
+           { OP_ReadCookie,     0,         1,         BTREE_LARGEST_ROOT_PAGE},
+           { OP_If,             1,         0,                 0},    /* 2 */
+           { OP_Halt,           SQLITE_OK, OE_Abort,          0},    /* 3 */
+-          { OP_Integer,        0,         1,                 0},    /* 4 */
+-          { OP_SetCookie,      0,         BTREE_INCR_VACUUM, 1},    /* 5 */
++          { OP_SetCookie,      0,         BTREE_INCR_VACUUM, 0},    /* 4 */
+         };
+-        int iAddr;
+-        iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn);
+-        sqlite3VdbeChangeP1(v, iAddr, iDb);
+-        sqlite3VdbeChangeP1(v, iAddr+1, iDb);
+-        sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4);
+-        sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1);
+-        sqlite3VdbeChangeP1(v, iAddr+5, iDb);
++        VdbeOp *aOp;
++        int iAddr = sqlite3VdbeCurrentAddr(v);
++        sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6));
++        aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn);
++        if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
++        aOp[0].p1 = iDb;
++        aOp[1].p1 = iDb;
++        aOp[2].p2 = iAddr+4;
++        aOp[4].p1 = iDb;
++        aOp[4].p3 = eAuto - 1;
+         sqlite3VdbeUsesBtree(v, iDb);
+       }
+     }
+@@ -104293,7 +118079,7 @@
+ #endif
+ 
+   /*
+-  **  PRAGMA [database.]incremental_vacuum(N)
++  **  PRAGMA [schema.]incremental_vacuum(N)
+   **
+   ** Do N steps of incremental vacuuming on a database.
+   */
+@@ -104316,8 +118102,8 @@
+ 
+ #ifndef SQLITE_OMIT_PAGER_PRAGMAS
+   /*
+-  **  PRAGMA [database.]cache_size
+-  **  PRAGMA [database.]cache_size=N
++  **  PRAGMA [schema.]cache_size
++  **  PRAGMA [schema.]cache_size=N
+   **
+   ** The first form reports the current local setting for the
+   ** page cache size. The second form sets the local
+@@ -104329,7 +118115,7 @@
+   case PragTyp_CACHE_SIZE: {
+     assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+     if( !zRight ){
+-      returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
++      returnSingleInt(v, pDb->pSchema->cache_size);
+     }else{
+       int size = sqlite3Atoi(zRight);
+       pDb->pSchema->cache_size = size;
+@@ -104339,7 +118125,50 @@
+   }
+ 
+   /*
+-  **  PRAGMA [database.]mmap_size(N)
++  **  PRAGMA [schema.]cache_spill
++  **  PRAGMA cache_spill=BOOLEAN
++  **  PRAGMA [schema.]cache_spill=N
++  **
++  ** The first form reports the current local setting for the
++  ** page cache spill size. The second form turns cache spill on
++  ** or off.  When turnning cache spill on, the size is set to the
++  ** current cache_size.  The third form sets a spill size that
++  ** may be different form the cache size.
++  ** If N is positive then that is the
++  ** number of pages in the cache.  If N is negative, then the
++  ** number of pages is adjusted so that the cache uses -N kibibytes
++  ** of memory.
++  **
++  ** If the number of cache_spill pages is less then the number of
++  ** cache_size pages, no spilling occurs until the page count exceeds
++  ** the number of cache_size pages.
++  **
++  ** The cache_spill=BOOLEAN setting applies to all attached schemas,
++  ** not just the schema specified.
++  */
++  case PragTyp_CACHE_SPILL: {
++    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
++    if( !zRight ){
++      returnSingleInt(v,
++         (db->flags & SQLITE_CacheSpill)==0 ? 0 : 
++            sqlite3BtreeSetSpillSize(pDb->pBt,0));
++    }else{
++      int size = 1;
++      if( sqlite3GetInt32(zRight, &size) ){
++        sqlite3BtreeSetSpillSize(pDb->pBt, size);
++      }
++      if( sqlite3GetBoolean(zRight, size!=0) ){
++        db->flags |= SQLITE_CacheSpill;
++      }else{
++        db->flags &= ~SQLITE_CacheSpill;
++      }
++      setAllPagerFlags(db);
++    }
++    break;
++  }
 +
-+  if(openssl_init_count == 0 && EVP_get_cipherbyname(CIPHER) != NULL) {
-+    /* if openssl has not yet been initialized by this library, but 
-+       a call to get_cipherbyname works, then the openssl library
-+       has been initialized externally already. */
-+    openssl_external_init = 1;
++  /*
++  **  PRAGMA [schema.]mmap_size(N)
+   **
+   ** Used to set mapping size limit. The mapping size limit is
+   ** used to limit the aggregate size of all memory mapped regions of the
+@@ -104374,7 +118203,7 @@
+     rc = SQLITE_OK;
+ #endif
+     if( rc==SQLITE_OK ){
+-      returnSingleInt(pParse, "mmap_size", sz);
++      returnSingleInt(v, sz);
+     }else if( rc!=SQLITE_NOTFOUND ){
+       pParse->nErr++;
+       pParse->rc = rc;
+@@ -104395,7 +118224,7 @@
+   */
+   case PragTyp_TEMP_STORE: {
+     if( !zRight ){
+-      returnSingleInt(pParse, "temp_store", db->temp_store);
++      returnSingleInt(v, db->temp_store);
+     }else{
+       changeTempStorage(pParse, zRight);
+     }
+@@ -104414,13 +118243,7 @@
+   */
+   case PragTyp_TEMP_STORE_DIRECTORY: {
+     if( !zRight ){
+-      if( sqlite3_temp_directory ){
+-        sqlite3VdbeSetNumCols(v, 1);
+-        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, 
+-            "temp_store_directory", SQLITE_STATIC);
+-        sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_temp_directory, 0);
+-        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+-      }
++      returnSingleText(v, sqlite3_temp_directory);
+     }else{
+ #ifndef SQLITE_OMIT_WSD
+       if( zRight[0] ){
+@@ -104464,13 +118287,7 @@
+   */
+   case PragTyp_DATA_STORE_DIRECTORY: {
+     if( !zRight ){
+-      if( sqlite3_data_directory ){
+-        sqlite3VdbeSetNumCols(v, 1);
+-        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, 
+-            "data_store_directory", SQLITE_STATIC);
+-        sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_data_directory, 0);
+-        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+-      }
++      returnSingleText(v, sqlite3_data_directory);
+     }else{
+ #ifndef SQLITE_OMIT_WSD
+       if( zRight[0] ){
+@@ -104495,8 +118312,8 @@
+ 
+ #if SQLITE_ENABLE_LOCKING_STYLE
+   /*
+-  **   PRAGMA [database.]lock_proxy_file
+-  **   PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path"
++  **   PRAGMA [schema.]lock_proxy_file
++  **   PRAGMA [schema.]lock_proxy_file = ":auto:"|"lock_file_path"
+   **
+   ** Return or set the value of the lock_proxy_file flag.  Changing
+   ** the value sets a specific file to be used for database access locks.
+@@ -104509,14 +118326,7 @@
+       sqlite3_file *pFile = sqlite3PagerFile(pPager);
+       sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, 
+                            &proxy_file_path);
+-      
+-      if( proxy_file_path ){
+-        sqlite3VdbeSetNumCols(v, 1);
+-        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, 
+-                              "lock_proxy_file", SQLITE_STATIC);
+-        sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, proxy_file_path, 0);
+-        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+-      }
++      returnSingleText(v, proxy_file_path);
+     }else{
+       Pager *pPager = sqlite3BtreePager(pDb->pBt);
+       sqlite3_file *pFile = sqlite3PagerFile(pPager);
+@@ -104538,8 +118348,8 @@
+ #endif /* SQLITE_ENABLE_LOCKING_STYLE */      
+     
+   /*
+-  **   PRAGMA [database.]synchronous
+-  **   PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
++  **   PRAGMA [schema.]synchronous
++  **   PRAGMA [schema.]synchronous=OFF|ON|NORMAL|FULL|EXTRA
+   **
+   ** Return or set the local value of the synchronous flag.  Changing
+   ** the local value does not make changes to the disk file and the
+@@ -104548,15 +118358,16 @@
+   */
+   case PragTyp_SYNCHRONOUS: {
+     if( !zRight ){
+-      returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
++      returnSingleInt(v, pDb->safety_level-1);
+     }else{
+       if( !db->autoCommit ){
+         sqlite3ErrorMsg(pParse, 
+             "Safety level may not be changed inside a transaction");
+-      }else{
++      }else if( iDb!=1 ){
+         int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
+         if( iLevel==0 ) iLevel = 1;
+         pDb->safety_level = iLevel;
++        pDb->bSyncSet = 1;
+         setAllPagerFlags(db);
+       }
+     }
+@@ -104567,7 +118378,8 @@
+ #ifndef SQLITE_OMIT_FLAG_PRAGMAS
+   case PragTyp_FLAG: {
+     if( zRight==0 ){
+-      returnSingleInt(pParse, pPragma->zName, (db->flags & pPragma->iArg)!=0 );
++      setPragmaResultColumnNames(v, pPragma);
++      returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
+     }else{
+       int mask = pPragma->iArg;    /* Mask of bits to set or clear. */
+       if( db->autoCommit==0 ){
+@@ -104593,7 +118405,7 @@
+       ** compiler (eg. count_changes). So add an opcode to expire all
+       ** compiled SQL statements after modifying a pragma value.
+       */
+-      sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
++      sqlite3VdbeAddOp0(v, OP_Expire);
+       setAllPagerFlags(db);
+     }
+     break;
+@@ -104602,54 +118414,6 @@
+ 
+ #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
+   /*
+-  **   PRAGMA proc_list
+-  **
+-  ** Return a single row for each procedure, the returned data set are:
+-  **
+-  ** name:         Procedure name
+-  ** is_aggregate: True is procedure is an aggregate
+-  ** nargs:        Number of arguments of the procedure, or -1 if unlimited
+-  ** spe_name:     Specific name (unique procedure name)
+-  */
+-  if( sqlite3StrICmp(zLeft, "proc_list")==0 ){
+-    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+-
+-    sqlite3VdbeSetNumCols(v, 4);
+-    pParse->nMem = 4;
+-    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "name", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "is_aggregate", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "nargs", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "spe_name", SQLITE_STATIC);
+-    int j;
+-    for(j=0; j<ArraySize(db->aFunc.a); j++){
+-      FuncDef *func;
+-      for (func =db->aFunc.a[j]; func; func = func->pNext) {
+-      char *sname;
+-      sname = gdauniqueFuncName (func);
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
+-      sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
+-      sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, sname, 0);
+-      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+-      sqlite3_free (sname);
+-      }
+-    }
+-    for(j=0; j<ArraySize(sqlite3GlobalFunctions.a); j++){
+-      FuncDef *func;
+-      for (func =sqlite3GlobalFunctions.a[j]; func; func = func->pNext) {
+-      char *sname;
+-      sname = gdauniqueFuncName (func);
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
+-      sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
+-      sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, sname, 0);
+-      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+-      sqlite3_free (sname);
+-      }
+-    }
+-  }else
+-
+- /*
+   **   PRAGMA table_info(<table>)
+   **
+   ** Return a single row for each column of the named table. The columns of
+@@ -104663,37 +118427,20 @@
+   */
+   case PragTyp_TABLE_INFO: if( zRight ){
+     Table *pTab;
+-    pTab = sqlite3FindTable(db, zRight, zDb);
++    pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
+     if( pTab ){
+       int i, k;
+       int nHidden = 0;
+       Column *pCol;
+       Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+-      sqlite3VdbeSetNumCols(v, 6);
+       pParse->nMem = 6;
+       sqlite3CodeVerifySchema(pParse, iDb);
+-      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
+-      sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
+-      sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
+-      sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", SQLITE_STATIC);
+-      sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE_STATIC);
+-      sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", SQLITE_STATIC);
+       sqlite3ViewGetColumnNames(pParse, pTab);
+       for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
+         if( IsHiddenColumn(pCol) ){
+           nHidden++;
+           continue;
+         }
+-        sqlite3VdbeAddOp2(v, OP_Integer, i-nHidden, 1);
+-        sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pCol->zName, 0);
+-        sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
+-           pCol->zType ? pCol->zType : "", 0);
+-        sqlite3VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4);
+-        if( pCol->zDflt ){
+-          sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
+-        }else{
+-          sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
+-        }
+         if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
+           k = 0;
+         }else if( pPk==0 ){
+@@ -104701,44 +118448,45 @@
+         }else{
+           for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
+         }
+-        sqlite3VdbeAddOp2(v, OP_Integer, k, 6);
+-        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
++        assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
++        sqlite3VdbeMultiLoad(v, 1, "issisi",
++               i-nHidden,
++               pCol->zName,
++               sqlite3ColumnType(pCol,""),
++               pCol->notNull ? 1 : 0,
++               pCol->pDflt ? pCol->pDflt->u.zToken : 0,
++               k);
+       }
+     }
    }
--  A = Y/100;
--  B = 2 - A + (A/4);
--  X1 = 36525*(Y+4716)/100;
--  X2 = 306001*(M+1)/10000;
--  p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
--  p->validJD = 1;
--  if( p->validHMS ){
--    p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000);
--    if( p->validTZ ){
--      p->iJD -= p->tz*60000;
--      p->validYMD = 0;
--      p->validHMS = 0;
--      p->validTZ = 0;
-+
-+#ifdef SQLCIPHER_FIPS
-+  if(!FIPS_mode()){
-+    if(!FIPS_mode_set(1)){
-+      ERR_load_crypto_strings();
-+      ERR_print_errors_fp(stderr);
+   break;
+ 
++#ifdef SQLITE_DEBUG
+   case PragTyp_STATS: {
+     Index *pIdx;
+     HashElem *i;
+-    v = sqlite3GetVdbe(pParse);
+-    sqlite3VdbeSetNumCols(v, 4);
+-    pParse->nMem = 4;
++    pParse->nMem = 5;
+     sqlite3CodeVerifySchema(pParse, iDb);
+-    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "index", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "width", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "height", SQLITE_STATIC);
+     for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
+       Table *pTab = sqliteHashData(i);
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, pTab->zName, 0);
+-      sqlite3VdbeAddOp2(v, OP_Null, 0, 2);
+-      sqlite3VdbeAddOp2(v, OP_Integer,
+-                           (int)sqlite3LogEstToInt(pTab->szTabRow), 3);
+-      sqlite3VdbeAddOp2(v, OP_Integer, 
+-          (int)sqlite3LogEstToInt(pTab->nRowLogEst), 4);
+-      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
++      sqlite3VdbeMultiLoad(v, 1, "ssiii",
++           pTab->zName,
++           0,
++           pTab->szTabRow,
++           pTab->nRowLogEst,
++           pTab->tabFlags);
+       for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+-        sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
+-        sqlite3VdbeAddOp2(v, OP_Integer,
+-                             (int)sqlite3LogEstToInt(pIdx->szIdxRow), 3);
+-        sqlite3VdbeAddOp2(v, OP_Integer, 
+-            (int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]), 4);
+-        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
++        sqlite3VdbeMultiLoad(v, 2, "siiiX",
++           pIdx->zName,
++           pIdx->szIdxRow,
++           pIdx->aiRowLogEst[0],
++           pIdx->hasStat1);
++        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
+       }
      }
    }
--}
+   break;
 +#endif
  
--/*
--** Parse dates of the form
--**
--**     YYYY-MM-DD HH:MM:SS.FFF
--**     YYYY-MM-DD HH:MM:SS
--**     YYYY-MM-DD HH:MM
--**     YYYY-MM-DD
--**
--** Write the result into the DateTime structure and return 0
--** on success and 1 if the input string is not a well-formed
--** date.
--*/
--static int parseYyyyMmDd(const char *zDate, DateTime *p){
--  int Y, M, D, neg;
-+  if(openssl_init_count == 0 && openssl_external_init == 0)  {
-+    /* if the library was not externally initialized, then should be now */
-+    OpenSSL_add_all_algorithms();
-+  } 
- 
--  if( zDate[0]=='-' ){
--    zDate++;
--    neg = 1;
--  }else{
--    neg = 0;
--  }
--  if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
--    return 1;
-+#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
-+  if(openssl_rand_mutex == NULL) {
-+    /* allocate a mutex to guard against concurrent calls to RAND_bytes() */
-+    openssl_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+   case PragTyp_INDEX_INFO: if( zRight ){
+     Index *pIdx;
+@@ -104757,29 +118505,17 @@
+         pParse->nMem = 3;
+       }
+       pTab = pIdx->pTable;
+-      sqlite3VdbeSetNumCols(v, pParse->nMem);
+       sqlite3CodeVerifySchema(pParse, iDb);
+-      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
+-      sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
+-      sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
+-      if( pPragma->iArg ){
+-        sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "desc", SQLITE_STATIC);
+-        sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "coll", SQLITE_STATIC);
+-        sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "key", SQLITE_STATIC);
+-      }
++      assert( pParse->nMem<=pPragma->nPragCName );
+       for(i=0; i<mx; i++){
+         i16 cnum = pIdx->aiColumn[i];
+-        sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
+-        sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2);
+-        if( cnum<0 ){
+-          sqlite3VdbeAddOp2(v, OP_Null, 0, 3);
+-        }else{
+-          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
+-        }
++        sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum,
++                             cnum<0 ? 0 : pTab->aCol[cnum].zName);
+         if( pPragma->iArg ){
+-          sqlite3VdbeAddOp2(v, OP_Integer, pIdx->aSortOrder[i], 4);
+-          sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, pIdx->azColl[i], 0);
+-          sqlite3VdbeAddOp2(v, OP_Integer, i<pIdx->nKeyCol, 6);
++          sqlite3VdbeMultiLoad(v, 4, "isiX",
++            pIdx->aSortOrder[i],
++            pIdx->azColl[i],
++            i<pIdx->nKeyCol);
+         }
+         sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem);
+       }
+@@ -104793,23 +118529,16 @@
+     int i;
+     pTab = sqlite3FindTable(db, zRight, zDb);
+     if( pTab ){
+-      v = sqlite3GetVdbe(pParse);
+-      sqlite3VdbeSetNumCols(v, 5);
+       pParse->nMem = 5;
+       sqlite3CodeVerifySchema(pParse, iDb);
+-      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
+-      sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
+-      sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
+-      sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "origin", SQLITE_STATIC);
+-      sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "partial", SQLITE_STATIC);
+       for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
+         const char *azOrigin[] = { "c", "u", "pk" };
+-        sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
+-        sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
+-        sqlite3VdbeAddOp2(v, OP_Integer, IsUniqueIndex(pIdx), 3);
+-        sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, azOrigin[pIdx->idxType], 0);
+-        sqlite3VdbeAddOp2(v, OP_Integer, pIdx->pPartIdxWhere!=0, 5);
+-        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
++        sqlite3VdbeMultiLoad(v, 1, "isisi",
++           i,
++           pIdx->zName,
++           IsUniqueIndex(pIdx),
++           azOrigin[pIdx->idxType],
++           pIdx->pPartIdxWhere!=0);
+       }
+     }
    }
--  zDate += 10;
--  while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; }
--  if( parseHhMmSs(zDate, p)==0 ){
--    /* We got the time */
--  }else if( *zDate==0 ){
--    p->validHMS = 0;
--  }else{
--    return 1;
-+#endif
-+
-+  openssl_init_count++; 
-+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
-+  return SQLITE_OK;
-+}
-+
-+/* deactivate SQLCipher, most imporantly decremeting the activation count and
-+   freeing the EVP structures on the final deactivation to ensure that 
-+   OpenSSL memory is cleaned up */
-+static int sqlcipher_openssl_deactivate(void *ctx) {
-+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
-+  openssl_init_count--;
+@@ -104817,19 +118546,14 @@
+ 
+   case PragTyp_DATABASE_LIST: {
+     int i;
+-    sqlite3VdbeSetNumCols(v, 3);
+     pParse->nMem = 3;
+-    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", SQLITE_STATIC);
+     for(i=0; i<db->nDb; i++){
+       if( db->aDb[i].pBt==0 ) continue;
+-      assert( db->aDb[i].zName!=0 );
+-      sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, db->aDb[i].zName, 0);
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
+-           sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
+-      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
++      assert( db->aDb[i].zDbSName!=0 );
++      sqlite3VdbeMultiLoad(v, 1, "iss",
++         i,
++         db->aDb[i].zDbSName,
++         sqlite3BtreeGetFilename(db->aDb[i].pBt));
+     }
+   }
+   break;
+@@ -104837,18 +118561,57 @@
+   case PragTyp_COLLATION_LIST: {
+     int i = 0;
+     HashElem *p;
+-    sqlite3VdbeSetNumCols(v, 2);
+     pParse->nMem = 2;
+-    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
+     for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
+       CollSeq *pColl = (CollSeq *)sqliteHashData(p);
+-      sqlite3VdbeAddOp2(v, OP_Integer, i++, 1);
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pColl->zName, 0);
++      sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
++    }
++  }
++  break;
 +
-+  if(openssl_init_count == 0) {
-+    if(openssl_external_init == 0) {
-+    /* if OpenSSL hasn't be initialized externally, and the counter reaches zero 
-+       after it's decremented, release EVP memory
-+       Note: this code will only be reached if OpensSSL_add_all_algorithms()
-+       is called by SQLCipher internally. This should prevent SQLCipher from 
-+       "cleaning up" openssl when it was initialized externally by the program */
-+      EVP_cleanup();
++#ifdef SQLITE_INTROSPECTION_PRAGMAS
++  case PragTyp_FUNCTION_LIST: {
++    int i;
++    HashElem *j;
++    FuncDef *p;
++    pParse->nMem = 2;
++    for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
++      for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
++        sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
++        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
++      }
 +    }
-+#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
-+    sqlite3_mutex_free(openssl_rand_mutex);
-+    openssl_rand_mutex = NULL;
-+#endif
++    for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
++      p = (FuncDef*)sqliteHashData(j);
++      sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 0);
+       sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
+     }
    }
--  p->validJD = 0;
--  p->validYMD = 1;
--  p->Y = neg ? -Y : Y;
--  p->M = M;
--  p->D = D;
--  if( p->validTZ ){
--    computeJD(p);
-+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
-+  return SQLITE_OK;
-+}
-+
-+static const char* sqlcipher_openssl_get_provider_name(void *ctx) {
-+  return "openssl";
-+}
-+
-+/* generate a defined number of random bytes */
-+static int sqlcipher_openssl_random (void *ctx, void *buffer, int length) {
-+  int rc = 0;
-+  /* concurrent calls to RAND_bytes can cause a crash under some openssl versions when a 
-+     naive application doesn't use CRYPTO_set_locking_callback and
-+     CRYPTO_THREADID_set_callback to ensure openssl thread safety. 
-+     This is simple workaround to prevent this common crash
-+     but a more proper solution is that applications setup platform-appropriate
-+     thread saftey in openssl externally */
-+#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
-+  sqlite3_mutex_enter(openssl_rand_mutex);
-+#endif
-+  rc = RAND_bytes((unsigned char *)buffer, length);
-+#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
-+  sqlite3_mutex_leave(openssl_rand_mutex);
-+#endif
-+  return (rc == 1) ? SQLITE_OK : SQLITE_ERROR;
-+}
-+
-+static int sqlcipher_openssl_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int 
in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
-+  HMAC_CTX hctx;
-+  unsigned int outlen;
-+  HMAC_CTX_init(&hctx);
-+  HMAC_Init_ex(&hctx, hmac_key, key_sz, EVP_sha1(), NULL);
-+  HMAC_Update(&hctx, in, in_sz);
-+  HMAC_Update(&hctx, in2, in2_sz);
-+  HMAC_Final(&hctx, out, &outlen);
-+  HMAC_CTX_cleanup(&hctx);
-+  return SQLITE_OK; 
-+}
+   break;
++
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  case PragTyp_MODULE_LIST: {
++    HashElem *j;
++    pParse->nMem = 1;
++    for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){
++      Module *pMod = (Module*)sqliteHashData(j);
++      sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName);
++      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
++    }
++  }
++  break;
++#endif /* SQLITE_OMIT_VIRTUALTABLE */
 +
-+static int sqlcipher_openssl_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, 
int salt_sz, int workfactor, int key_sz, unsigned char *key) {
-+  PKCS5_PBKDF2_HMAC_SHA1((const char *)pass, pass_sz, salt, salt_sz, workfactor, key_sz, key);
-+  return SQLITE_OK; 
-+}
++  case PragTyp_PRAGMA_LIST: {
++    int i;
++    for(i=0; i<ArraySize(aPragmaName); i++){
++      sqlite3VdbeMultiLoad(v, 1, "s", aPragmaName[i].zName);
++      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
++    }
++  }
++  break;
++#endif /* SQLITE_INTROSPECTION_PRAGMAS */
++
+ #endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
+ 
+ #ifndef SQLITE_OMIT_FOREIGN_KEY
+@@ -104857,37 +118620,23 @@
+     Table *pTab;
+     pTab = sqlite3FindTable(db, zRight, zDb);
+     if( pTab ){
+-      v = sqlite3GetVdbe(pParse);
+       pFK = pTab->pFKey;
+       if( pFK ){
+         int i = 0; 
+-        sqlite3VdbeSetNumCols(v, 8);
+         pParse->nMem = 8;
+         sqlite3CodeVerifySchema(pParse, iDb);
+-        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC);
+-        sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE_STATIC);
+-        sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE_STATIC);
+-        sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", SQLITE_STATIC);
+-        sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", SQLITE_STATIC);
+-        sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "on_update", SQLITE_STATIC);
+-        sqlite3VdbeSetColName(v, 6, COLNAME_NAME, "on_delete", SQLITE_STATIC);
+-        sqlite3VdbeSetColName(v, 7, COLNAME_NAME, "match", SQLITE_STATIC);
+         while(pFK){
+           int j;
+           for(j=0; j<pFK->nCol; j++){
+-            char *zCol = pFK->aCol[j].zCol;
+-            char *zOnDelete = (char *)actionName(pFK->aAction[0]);
+-            char *zOnUpdate = (char *)actionName(pFK->aAction[1]);
+-            sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
+-            sqlite3VdbeAddOp2(v, OP_Integer, j, 2);
+-            sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pFK->zTo, 0);
+-            sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0,
+-                              pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
+-            sqlite3VdbeAddOp4(v, zCol ? OP_String8 : OP_Null, 0, 5, 0, zCol, 0);
+-            sqlite3VdbeAddOp4(v, OP_String8, 0, 6, 0, zOnUpdate, 0);
+-            sqlite3VdbeAddOp4(v, OP_String8, 0, 7, 0, zOnDelete, 0);
+-            sqlite3VdbeAddOp4(v, OP_String8, 0, 8, 0, "NONE", 0);
+-            sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 8);
++            sqlite3VdbeMultiLoad(v, 1, "iissssss",
++                   i,
++                   j,
++                   pFK->zTo,
++                   pTab->aCol[pFK->aCol[j].iFrom].zName,
++                   pFK->aCol[j].zCol,
++                   actionName(pFK->aAction[1]),  /* ON UPDATE */
++                   actionName(pFK->aAction[0]),  /* ON DELETE */
++                   "NONE");
+           }
+           ++i;
+           pFK = pFK->pNextFrom;
+@@ -104920,12 +118669,6 @@
+     pParse->nMem += 4;
+     regKey = ++pParse->nMem;
+     regRow = ++pParse->nMem;
+-    v = sqlite3GetVdbe(pParse);
+-    sqlite3VdbeSetNumCols(v, 4);
+-    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "rowid", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "parent", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "fkid", SQLITE_STATIC);
+     sqlite3CodeVerifySchema(pParse, iDb);
+     k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
+     while( k ){
+@@ -104940,8 +118683,7 @@
+       sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
+       if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
+       sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, regResult, 0, pTab->zName,
+-                        P4_TRANSIENT);
++      sqlite3VdbeLoadString(v, regResult, pTab->zName);
+       for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
+         pParent = sqlite3FindTable(db, pFK->zTo, zDb);
+         if( pParent==0 ) continue;
+@@ -104973,38 +118715,38 @@
+           assert( x==0 );
+         }
+         addrOk = sqlite3VdbeMakeLabel(v);
+-        if( pParent && pIdx==0 ){
+-          int iKey = pFK->aCol[0].iFrom;
+-          assert( iKey>=0 && iKey<pTab->nCol );
+-          if( iKey!=pTab->iPKey ){
+-            sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
+-            sqlite3ColumnDefault(v, pTab, iKey, regRow);
+-            sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v);
+-            sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow, 
+-               sqlite3VdbeCurrentAddr(v)+3); VdbeCoverage(v);
+-          }else{
+-            sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
+-          }
+-          sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v);
+-          sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
+-          sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
++
++        /* Generate code to read the child key values into registers
++        ** regRow..regRow+n. If any of the child key values are NULL, this 
++        ** row cannot cause an FK violation. Jump directly to addrOk in 
++        ** this case. */
++        for(j=0; j<pFK->nCol; j++){
++          int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom;
++          sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j);
++          sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
++        }
 +
-+static int sqlcipher_openssl_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, 
unsigned char *in, int in_sz, unsigned char *out) {
-+  EVP_CIPHER_CTX ectx;
-+  int tmp_csz, csz;
-+ 
-+  EVP_CipherInit(&ectx, ((openssl_ctx *)ctx)->evp_cipher, NULL, NULL, mode);
-+  EVP_CIPHER_CTX_set_padding(&ectx, 0); // no padding
-+  EVP_CipherInit(&ectx, NULL, key, iv, mode);
-+  EVP_CipherUpdate(&ectx, out, &tmp_csz, in, in_sz);
-+  csz = tmp_csz;  
-+  out += tmp_csz;
-+  EVP_CipherFinal(&ectx, out, &tmp_csz);
-+  csz += tmp_csz;
-+  EVP_CIPHER_CTX_cleanup(&ectx);
-+  assert(in_sz == csz);
-+  return SQLITE_OK; 
-+}
++        /* Generate code to query the parent index for a matching parent
++        ** key. If a match is found, jump to addrOk. */
++        if( pIdx ){
++          sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
++              sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
++          sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
++          VdbeCoverage(v);
++        }else if( pParent ){
++          int jmp = sqlite3VdbeCurrentAddr(v)+2;
++          sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v);
++          sqlite3VdbeGoto(v, addrOk);
++          assert( pFK->nCol==1 );
++        }
 +
-+static int sqlcipher_openssl_set_cipher(void *ctx, const char *cipher_name) {
-+  openssl_ctx *o_ctx = (openssl_ctx *)ctx;
-+  EVP_CIPHER* cipher = (EVP_CIPHER *) EVP_get_cipherbyname(cipher_name);
-+  if(cipher != NULL) {
-+    o_ctx->evp_cipher = cipher;
++        /* Generate code to report an FK violation to the caller. */
++        if( HasRowid(pTab) ){
++          sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
+         }else{
+-          for(j=0; j<pFK->nCol; j++){
+-            sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
+-                            aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j);
+-            sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
+-          }
+-          if( pParent ){
+-            sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
+-                              sqlite3IndexAffinityStr(v,pIdx), pFK->nCol);
+-            sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
+-            VdbeCoverage(v);
+-          }
++          sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1);
+         }
+-        sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
+-        sqlite3VdbeAddOp4(v, OP_String8, 0, regResult+2, 0, 
+-                          pFK->zTo, P4_TRANSIENT);
+-        sqlite3VdbeAddOp2(v, OP_Integer, i-1, regResult+3);
++        sqlite3VdbeMultiLoad(v, regResult+2, "siX", pFK->zTo, i-1);
+         sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
+         sqlite3VdbeResolveLabel(v, addrOk);
+         sqlite3DbFree(db, aiCols);
+@@ -105021,7 +118763,7 @@
+   case PragTyp_PARSER_TRACE: {
+     if( zRight ){
+       if( sqlite3GetBoolean(zRight, 0) ){
+-        sqlite3ParserTrace(stderr, "parser: ");
++        sqlite3ParserTrace(stdout, "parser: ");
+       }else{
+         sqlite3ParserTrace(0, 0);
+       }
+@@ -105045,24 +118787,21 @@
+ #endif
+ 
+ #ifndef SQLITE_OMIT_INTEGRITY_CHECK
+-  /* Pragma "quick_check" is reduced version of 
++  /*    PRAGMA integrity_check
++  **    PRAGMA integrity_check(N)
++  **    PRAGMA quick_check
++  **    PRAGMA quick_check(N)
++  **
++  ** Verify the integrity of the database.
++  **
++  ** The "quick_check" is reduced version of 
+   ** integrity_check designed to detect most database corruption
+-  ** without most of the overhead of a full integrity-check.
++  ** without the overhead of cross-checking indexes.  Quick_check
++  ** is linear time wherease integrity_check is O(NlogN).
+   */
+   case PragTyp_INTEGRITY_CHECK: {
+     int i, j, addr, mxErr;
+ 
+-    /* Code that appears at the end of the integrity check.  If no error
+-    ** messages have been generated, output OK.  Otherwise output the
+-    ** error message
+-    */
+-    static const int iLn = VDBE_OFFSET_LINENO(2);
+-    static const VdbeOpList endCode[] = {
+-      { OP_IfNeg,       1, 0,        0},    /* 0 */
+-      { OP_String8,     0, 3,        0},    /* 1 */
+-      { OP_ResultRow,   3, 1,        0},
+-    };
+-
+     int isQuick = (sqlite3Tolower(zLeft[0])=='q');
+ 
+     /* If the PRAGMA command was of the form "PRAGMA <db>.integrity_check",
+@@ -105080,8 +118819,6 @@
+ 
+     /* Initialize the VDBE program */
+     pParse->nMem = 6;
+-    sqlite3VdbeSetNumCols(v, 1);
+-    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC);
+ 
+     /* Set the maximum error count */
+     mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
+@@ -105091,63 +118828,67 @@
+         mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
+       }
+     }
+-    sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1);  /* reg[1] holds errors left */
++    sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */
+ 
+     /* Do an integrity check on each database file */
+     for(i=0; i<db->nDb; i++){
+       HashElem *x;
+       Hash *pTbls;
++      int *aRoot;
+       int cnt = 0;
++      int mxIdx = 0;
++      int nIdx;
+ 
+       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 */
+-      VdbeCoverage(v);
+-      sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
+-      sqlite3VdbeJumpHere(v, addr);
+ 
+       /* Do an integrity check of the B-Tree
+       **
+-      ** Begin by filling registers 2, 3, ... with the root pages numbers
++      ** Begin by finding the root pages numbers
+       ** for all tables and indices in the database.
+       */
+       assert( sqlite3SchemaMutexHeld(db, i, 0) );
+       pTbls = &db->aDb[i].pSchema->tblHash;
+-      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
++      for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
+         Table *pTab = sqliteHashData(x);
+         Index *pIdx;
+-        if( HasRowid(pTab) ){
+-          sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
+-          VdbeComment((v, "%s", pTab->zName));
+-          cnt++;
+-        }
++        if( HasRowid(pTab) ) cnt++;
++        for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
++        if( nIdx>mxIdx ) mxIdx = nIdx;
++      }
++      aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1));
++      if( aRoot==0 ) break;
++      for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
++        Table *pTab = sqliteHashData(x);
++        Index *pIdx;
++        if( HasRowid(pTab) ) aRoot[cnt++] = pTab->tnum;
+         for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+-          sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
+-          VdbeComment((v, "%s", pIdx->zName));
+-          cnt++;
++          aRoot[cnt++] = pIdx->tnum;
+         }
+       }
++      aRoot[cnt] = 0;
+ 
+       /* Make sure sufficient number of registers have been allocated */
+-      pParse->nMem = MAX( pParse->nMem, cnt+8 );
++      pParse->nMem = MAX( pParse->nMem, 8+mxIdx );
++      sqlite3ClearTempRegCache(pParse);
+ 
+       /* Do the b-tree integrity checks */
+-      sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
++      sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY);
+       sqlite3VdbeChangeP5(v, (u8)i);
+       addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
+       sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
+-         sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
++         sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName),
+          P4_DYNAMIC);
+       sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
+       sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
+-      sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
++      integrityCheckResultRow(v, 2);
+       sqlite3VdbeJumpHere(v, addr);
+ 
+       /* Make sure all the indices are constructed correctly.
+       */
+-      for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
++      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
+         Table *pTab = sqliteHashData(x);
+         Index *pIdx, *pPk;
+         Index *pPrior = 0;
+@@ -105155,43 +118896,68 @@
+         int iDataCur, iIdxCur;
+         int r1 = -1;
+ 
+-        if( pTab->pIndex==0 ) continue;
++        if( pTab->tnum<1 ) continue;  /* Skip VIEWs or VIRTUAL TABLEs */
++        if( pTab->pCheck==0
++         && (pTab->tabFlags & TF_HasNotNull)==0
++         && (pTab->pIndex==0 || isQuick)
++        ){
++          continue;  /* No additional checks needed for this table */
++        }
+         pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+-        addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);  /* Stop if out of errors */
+-        VdbeCoverage(v);
+-        sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
+-        sqlite3VdbeJumpHere(v, addr);
+         sqlite3ExprCacheClear(pParse);
+-        sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead,
++        sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
+                                    1, 0, &iDataCur, &iIdxCur);
+         sqlite3VdbeAddOp2(v, OP_Integer, 0, 7);
+         for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+           sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
+         }
+-        pParse->nMem = MAX(pParse->nMem, 8+j);
++        assert( pParse->nMem>=8+j );
++        assert( sqlite3NoTempsInRange(pParse,1,7+j) );
+         sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
+         loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
+         /* Verify that all NOT NULL columns really are NOT NULL */
+         for(j=0; j<pTab->nCol; j++){
+           char *zErr;
+-          int jmp2, jmp3;
++          int jmp2;
+           if( j==pTab->iPKey ) continue;
+           if( pTab->aCol[j].notNull==0 ) continue;
+           sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
+           sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
+           jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
+-          sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
+           zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
+                               pTab->aCol[j].zName);
+           sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
+-          sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
+-          jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
+-          sqlite3VdbeAddOp0(v, OP_Halt);
++          integrityCheckResultRow(v, 3);
+           sqlite3VdbeJumpHere(v, jmp2);
+-          sqlite3VdbeJumpHere(v, jmp3);
++        }
++        /* Verify CHECK constraints */
++        if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
++          ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
++          if( db->mallocFailed==0 ){
++            int addrCkFault = sqlite3VdbeMakeLabel(v);
++            int addrCkOk = sqlite3VdbeMakeLabel(v);
++            char *zErr;
++            int k;
++            pParse->iSelfTab = iDataCur + 1;
++            sqlite3ExprCachePush(pParse);
++            for(k=pCheck->nExpr-1; k>0; k--){
++              sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
++            }
++            sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, 
++                SQLITE_JUMPIFNULL);
++            sqlite3VdbeResolveLabel(v, addrCkFault);
++            pParse->iSelfTab = 0;
++            zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
++                pTab->zName);
++            sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
++            integrityCheckResultRow(v, 3);
++            sqlite3VdbeResolveLabel(v, addrCkOk);
++            sqlite3ExprCachePop(pParse);
++          }
++          sqlite3ExprListDelete(db, pCheck);
+         }
+         /* Validate index entries for the current row */
+-        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
++        for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){
+           int jmp2, jmp3, jmp4, jmp5;
+           int ckUniq = sqlite3VdbeMakeLabel(v);
+           if( pPk==pIdx ) continue;
+@@ -105202,18 +118968,13 @@
+           /* Verify that an index entry exists for the current table row */
+           jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
+                                       pIdx->nColumn); VdbeCoverage(v);
+-          sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
+-          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC);
++          sqlite3VdbeLoadString(v, 3, "row ");
+           sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
+-          sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, 
+-                            " missing from index ", P4_STATIC);
++          sqlite3VdbeLoadString(v, 4, " missing from index ");
+           sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
+-          jmp5 = sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0,
+-                                   pIdx->zName, P4_TRANSIENT);
++          jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
+           sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
+-          sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
+-          jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
+-          sqlite3VdbeAddOp0(v, OP_Halt);
++          jmp4 = integrityCheckResultRow(v, 3);
+           sqlite3VdbeJumpHere(v, jmp2);
+           /* For UNIQUE indexes, verify that only one entry exists with the
+           ** current key.  The entry is unique if (1) any column is NULL
+@@ -105224,20 +118985,18 @@
+             int kk;
+             for(kk=0; kk<pIdx->nKeyCol; kk++){
+               int iCol = pIdx->aiColumn[kk];
+-              assert( iCol>=0 && iCol<pTab->nCol );
+-              if( pTab->aCol[iCol].notNull ) continue;
++              assert( iCol!=XN_ROWID && iCol<pTab->nCol );
++              if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
+               sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
+               VdbeCoverage(v);
+             }
+             jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v);
+-            sqlite3VdbeAddOp2(v, OP_Goto, 0, uniqOk);
++            sqlite3VdbeGoto(v, uniqOk);
+             sqlite3VdbeJumpHere(v, jmp6);
+             sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
+                                  pIdx->nKeyCol); VdbeCoverage(v);
+-            sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
+-            sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
+-                              "non-unique entry in index ", P4_STATIC);
+-            sqlite3VdbeAddOp2(v, OP_Goto, 0, jmp5);
++            sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
++            sqlite3VdbeGoto(v, jmp5);
+             sqlite3VdbeResolveLabel(v, uniqOk);
+           }
+           sqlite3VdbeJumpHere(v, jmp4);
+@@ -105246,28 +119005,39 @@
+         sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
+         sqlite3VdbeJumpHere(v, loopTop-1);
+ #ifndef SQLITE_OMIT_BTREECOUNT
+-        sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, 
+-                     "wrong # of entries in index ", P4_STATIC);
+-        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+-          if( pPk==pIdx ) continue;
+-          addr = sqlite3VdbeCurrentAddr(v);
+-          sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
+-          sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
+-          sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
+-          sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
+-          sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+-          sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
+-          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
+-          sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
+-          sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
++        if( !isQuick ){
++          sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
++          for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
++            if( pPk==pIdx ) continue;
++            sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
++            addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v);
++            sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
++            sqlite3VdbeLoadString(v, 3, pIdx->zName);
++            sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
++            integrityCheckResultRow(v, 7);
++            sqlite3VdbeJumpHere(v, addr);
++          }
+         }
+ #endif /* SQLITE_OMIT_BTREECOUNT */
+       } 
+     }
+-    addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
+-    sqlite3VdbeChangeP3(v, addr, -mxErr);
+-    sqlite3VdbeJumpHere(v, addr);
+-    sqlite3VdbeChangeP4(v, addr+1, "ok", P4_STATIC);
++    {
++      static const int iLn = VDBE_OFFSET_LINENO(2);
++      static const VdbeOpList endCode[] = {
++        { OP_AddImm,      1, 0,        0},    /* 0 */
++        { OP_IfNotZero,   1, 4,        0},    /* 1 */
++        { OP_String8,     0, 3,        0},    /* 2 */
++        { OP_ResultRow,   3, 1,        0},    /* 3 */
++      };
++      VdbeOp *aOp;
++
++      aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
++      if( aOp ){
++        aOp[0].p2 = 1-mxErr;
++        aOp[2].p4type = P4_STATIC;
++        aOp[2].p4.z = "ok";
++      }
++    }
    }
-+  return cipher != NULL ? SQLITE_OK : SQLITE_ERROR;
-+}
-+
-+static const char* sqlcipher_openssl_get_cipher(void *ctx) {
-+  return EVP_CIPHER_name(((openssl_ctx *)ctx)->evp_cipher);
-+}
-+
-+static int sqlcipher_openssl_get_key_sz(void *ctx) {
-+  return EVP_CIPHER_key_length(((openssl_ctx *)ctx)->evp_cipher);
-+}
-+
-+static int sqlcipher_openssl_get_iv_sz(void *ctx) {
-+  return EVP_CIPHER_iv_length(((openssl_ctx *)ctx)->evp_cipher);
-+}
-+
-+static int sqlcipher_openssl_get_block_sz(void *ctx) {
-+  return EVP_CIPHER_block_size(((openssl_ctx *)ctx)->evp_cipher);
-+}
-+
-+static int sqlcipher_openssl_get_hmac_sz(void *ctx) {
-+  return EVP_MD_size(EVP_sha1());
-+}
-+
-+static int sqlcipher_openssl_ctx_copy(void *target_ctx, void *source_ctx) {
-+  memcpy(target_ctx, source_ctx, sizeof(openssl_ctx));
-+  return SQLITE_OK;
-+}
-+
-+static int sqlcipher_openssl_ctx_cmp(void *c1, void *c2) {
-+  return ((openssl_ctx *)c1)->evp_cipher == ((openssl_ctx *)c2)->evp_cipher;
-+}
-+
-+static int sqlcipher_openssl_ctx_init(void **ctx) {
-+  *ctx = sqlcipher_malloc(sizeof(openssl_ctx));
-+  if(*ctx == NULL) return SQLITE_NOMEM;
-+  sqlcipher_openssl_activate(*ctx);
-+  return SQLITE_OK;
-+}
-+
-+static int sqlcipher_openssl_ctx_free(void **ctx) {
-+  sqlcipher_openssl_deactivate(*ctx);
-+  sqlcipher_free(*ctx, sizeof(openssl_ctx));
-+  return SQLITE_OK;
-+}
-+
-+static int sqlcipher_openssl_fips_status(void *ctx) {
-+#ifdef SQLCIPHER_FIPS  
-+  return FIPS_mode();
-+#else
-   return 0;
-+#endif
- }
+   break;
+ #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+@@ -105313,14 +119083,10 @@
+     const struct EncName *pEnc;
+     if( !zRight ){    /* "PRAGMA encoding" */
+       if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+-      sqlite3VdbeSetNumCols(v, 1);
+-      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", SQLITE_STATIC);
+-      sqlite3VdbeAddOp2(v, OP_String8, 0, 1);
+       assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 );
+       assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE );
+       assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE );
+-      sqlite3VdbeChangeP4(v, -1, encnames[ENC(pParse->db)].zName, P4_STATIC);
+-      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
++      returnSingleText(v, encnames[ENC(pParse->db)].zName);
+     }else{                        /* "PRAGMA encoding = XXX" */
+       /* Only change the value of sqlite.enc if the database handle is not
+       ** initialized. If the main database exists, the new sqlite.enc value
+@@ -105349,16 +119115,18 @@
+ 
+ #ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
+   /*
+-  **   PRAGMA [database.]schema_version
+-  **   PRAGMA [database.]schema_version = <integer>
++  **   PRAGMA [schema.]schema_version
++  **   PRAGMA [schema.]schema_version = <integer>
+   **
+-  **   PRAGMA [database.]user_version
+-  **   PRAGMA [database.]user_version = <integer>
++  **   PRAGMA [schema.]user_version
++  **   PRAGMA [schema.]user_version = <integer>
+   **
+-  **   PRAGMA [database.]freelist_count = <integer>
++  **   PRAGMA [schema.]freelist_count
+   **
+-  **   PRAGMA [database.]application_id
+-  **   PRAGMA [database.]application_id = <integer>
++  **   PRAGMA [schema.]data_version
++  **
++  **   PRAGMA [schema.]application_id
++  **   PRAGMA [schema.]application_id = <integer>
+   **
+   ** The pragma's schema_version and user_version are used to set or get
+   ** the value of the schema-version and user-version, respectively. Both
+@@ -105381,18 +119149,20 @@
+   case PragTyp_HEADER_VALUE: {
+     int iCookie = pPragma->iArg;  /* Which cookie to read or write */
+     sqlite3VdbeUsesBtree(v, iDb);
+-    if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){
++    if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){
+       /* Write the specified cookie value */
+       static const VdbeOpList setCookie[] = {
+         { OP_Transaction,    0,  1,  0},    /* 0 */
+-        { OP_Integer,        0,  1,  0},    /* 1 */
+-        { OP_SetCookie,      0,  0,  1},    /* 2 */
++        { OP_SetCookie,      0,  0,  0},    /* 1 */
+       };
+-      int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0);
+-      sqlite3VdbeChangeP1(v, addr, iDb);
+-      sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight));
+-      sqlite3VdbeChangeP1(v, addr+2, iDb);
+-      sqlite3VdbeChangeP2(v, addr+2, iCookie);
++      VdbeOp *aOp;
++      sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie));
++      aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0);
++      if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
++      aOp[0].p1 = iDb;
++      aOp[1].p1 = iDb;
++      aOp[1].p2 = iCookie;
++      aOp[1].p3 = sqlite3Atoi(zRight);
+     }else{
+       /* Read the specified cookie value */
+       static const VdbeOpList readCookie[] = {
+@@ -105400,12 +119170,14 @@
+         { OP_ReadCookie,      0,  1,  0},    /* 1 */
+         { OP_ResultRow,       1,  1,  0}
+       };
+-      int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie, 0);
+-      sqlite3VdbeChangeP1(v, addr, iDb);
+-      sqlite3VdbeChangeP1(v, addr+1, iDb);
+-      sqlite3VdbeChangeP3(v, addr+1, iCookie);
+-      sqlite3VdbeSetNumCols(v, 1);
+-      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
++      VdbeOp *aOp;
++      sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(readCookie));
++      aOp = sqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0);
++      if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
++      aOp[0].p1 = iDb;
++      aOp[1].p1 = iDb;
++      aOp[1].p3 = iCookie;
++      sqlite3VdbeReusable(v);
+     }
+   }
+   break;
+@@ -105421,20 +119193,19 @@
+   case PragTyp_COMPILE_OPTIONS: {
+     int i = 0;
+     const char *zOpt;
+-    sqlite3VdbeSetNumCols(v, 1);
+     pParse->nMem = 1;
+-    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "compile_option", SQLITE_STATIC);
+     while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0);
++      sqlite3VdbeLoadString(v, 1, zOpt);
+       sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+     }
++    sqlite3VdbeReusable(v);
+   }
+   break;
+ #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
  
--/*
--** Set the time to the current time reported by the VFS.
--**
--** Return the number of errors.
--*/
--static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
--  p->iJD = sqlite3StmtCurrentTime(context);
--  if( p->iJD>0 ){
--    p->validJD = 1;
--    return 0;
--  }else{
--    return 1;
--  }
-+int sqlcipher_openssl_setup(sqlcipher_provider *p) {
-+  p->activate = sqlcipher_openssl_activate;  
-+  p->deactivate = sqlcipher_openssl_deactivate;
-+  p->get_provider_name = sqlcipher_openssl_get_provider_name;
-+  p->random = sqlcipher_openssl_random;
-+  p->hmac = sqlcipher_openssl_hmac;
-+  p->kdf = sqlcipher_openssl_kdf;
-+  p->cipher = sqlcipher_openssl_cipher;
-+  p->set_cipher = sqlcipher_openssl_set_cipher;
-+  p->get_cipher = sqlcipher_openssl_get_cipher;
-+  p->get_key_sz = sqlcipher_openssl_get_key_sz;
-+  p->get_iv_sz = sqlcipher_openssl_get_iv_sz;
-+  p->get_block_sz = sqlcipher_openssl_get_block_sz;
-+  p->get_hmac_sz = sqlcipher_openssl_get_hmac_sz;
-+  p->ctx_copy = sqlcipher_openssl_ctx_copy;
-+  p->ctx_cmp = sqlcipher_openssl_ctx_cmp;
-+  p->ctx_init = sqlcipher_openssl_ctx_init;
-+  p->ctx_free = sqlcipher_openssl_ctx_free;
-+  p->add_random = sqlcipher_openssl_add_random;
-+  p->fips_status = sqlcipher_openssl_fips_status;
-+  return SQLITE_OK;
- }
+ #ifndef SQLITE_OMIT_WAL
+   /*
+-  **   PRAGMA [database.]wal_checkpoint = passive|full|restart|truncate
++  **   PRAGMA [schema.]wal_checkpoint = passive|full|restart|truncate
+   **
+   ** Checkpoint the database.
+   */
+@@ -105450,12 +119221,7 @@
+         eMode = SQLITE_CHECKPOINT_TRUNCATE;
+       }
+     }
+-    sqlite3VdbeSetNumCols(v, 3);
+     pParse->nMem = 3;
+-    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "log", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "checkpointed", SQLITE_STATIC);
+-
+     sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1);
+     sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
+   }
+@@ -105473,7 +119239,7 @@
+     if( zRight ){
+       sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight));
+     }
+-    returnSingleInt(pParse, "wal_autocheckpoint", 
++    returnSingleInt(v, 
+        db->xWalCallback==sqlite3WalDefaultHook ? 
+            SQLITE_PTR_TO_INT(db->pWalArg) : 0);
+   }
+@@ -105493,6 +119259,119 @@
+   }
  
-+#endif
-+#endif
-+/* END SQLCIPHER */
-+
-+/************** End of crypto_openssl.c **************************************/
-+/************** Begin file crypto_cc.c ***************************************/
- /*
--** Attempt to parse the given string into a julian day number.  Return
--** the number of errors.
--**
--** The following are acceptable forms for the input string:
-+** SQLCipher
-+** http://sqlcipher.net
- **
--**      YYYY-MM-DD HH:MM:SS.FFF  +/-HH:MM
--**      DDDD.DD 
--**      now
-+** Copyright (c) 2008 - 2013, ZETETIC LLC
-+** All rights reserved.
-+**
-+** Redistribution and use in source and binary forms, with or without
-+** modification, are permitted provided that the following conditions are met:
-+**     * Redistributions of source code must retain the above copyright
-+**       notice, this list of conditions and the following disclaimer.
-+**     * Redistributions in binary form must reproduce the above copyright
-+**       notice, this list of conditions and the following disclaimer in the
-+**       documentation and/or other materials provided with the distribution.
-+**     * Neither the name of the ZETETIC LLC nor the
-+**       names of its contributors may be used to endorse or promote products
-+**       derived from this software without specific prior written permission.
-+**
-+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
-+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
-+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- **
--** In the first form, the +/-HH:MM is always optional.  The fractional
--** seconds extension (the ".FFF") is optional.  The seconds portion
--** (":SS.FFF") is option.  The year and date can be omitted as long
--** as there is a time string.  The time string can be omitted as long
--** as there is a year and date.
- */
--static int parseDateOrTime(
--  sqlite3_context *context, 
--  const char *zDate, 
--  DateTime *p
--){
--  double r;
--  if( parseYyyyMmDd(zDate,p)==0 ){
--    return 0;
--  }else if( parseHhMmSs(zDate, p)==0 ){
--    return 0;
--  }else if( sqlite3StrICmp(zDate,"now")==0){
--    return setDateTimeToCurrent(context, p);
--  }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
--    p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
--    p->validJD = 1;
--    return 0;
--  }
--  return 1;
-+/* BEGIN SQLCIPHER */
-+#ifdef SQLITE_HAS_CODEC
-+#ifdef SQLCIPHER_CRYPTO_CC
-+#include <CommonCrypto/CommonCrypto.h>
-+#include <Security/SecRandom.h>
+   /*
++  **  PRAGMA optimize
++  **  PRAGMA optimize(MASK)
++  **  PRAGMA schema.optimize
++  **  PRAGMA schema.optimize(MASK)
++  **
++  ** Attempt to optimize the database.  All schemas are optimized in the first
++  ** two forms, and only the specified schema is optimized in the latter two.
++  **
++  ** The details of optimizations performed by this pragma are expected
++  ** to change and improve over time.  Applications should anticipate that
++  ** this pragma will perform new optimizations in future releases.
++  **
++  ** The optional argument is a bitmask of optimizations to perform:
++  **
++  **    0x0001    Debugging mode.  Do not actually perform any optimizations
++  **              but instead return one line of text for each optimization
++  **              that would have been done.  Off by default.
++  **
++  **    0x0002    Run ANALYZE on tables that might benefit.  On by default.
++  **              See below for additional information.
++  **
++  **    0x0004    (Not yet implemented) Record usage and performance 
++  **              information from the current session in the
++  **              database file so that it will be available to "optimize"
++  **              pragmas run by future database connections.
++  **
++  **    0x0008    (Not yet implemented) Create indexes that might have
++  **              been helpful to recent queries
++  **
++  ** The default MASK is and always shall be 0xfffe.  0xfffe means perform all
++  ** of the optimizations listed above except Debug Mode, including new
++  ** optimizations that have not yet been invented.  If new optimizations are
++  ** ever added that should be off by default, those off-by-default 
++  ** optimizations will have bitmasks of 0x10000 or larger.
++  **
++  ** DETERMINATION OF WHEN TO RUN ANALYZE
++  **
++  ** In the current implementation, a table is analyzed if only if all of
++  ** the following are true:
++  **
++  ** (1) MASK bit 0x02 is set.
++  **
++  ** (2) The query planner used sqlite_stat1-style statistics for one or
++  **     more indexes of the table at some point during the lifetime of
++  **     the current connection.
++  **
++  ** (3) One or more indexes of the table are currently unanalyzed OR
++  **     the number of rows in the table has increased by 25 times or more
++  **     since the last time ANALYZE was run.
++  **
++  ** The rules for when tables are analyzed are likely to change in
++  ** future releases.
++  */
++  case PragTyp_OPTIMIZE: {
++    int iDbLast;           /* Loop termination point for the schema loop */
++    int iTabCur;           /* Cursor for a table whose size needs checking */
++    HashElem *k;           /* Loop over tables of a schema */
++    Schema *pSchema;       /* The current schema */
++    Table *pTab;           /* A table in the schema */
++    Index *pIdx;           /* An index of the table */
++    LogEst szThreshold;    /* Size threshold above which reanalysis is needd */
++    char *zSubSql;         /* SQL statement for the OP_SqlExec opcode */
++    u32 opMask;            /* Mask of operations to perform */
++
++    if( zRight ){
++      opMask = (u32)sqlite3Atoi(zRight);
++      if( (opMask & 0x02)==0 ) break;
++    }else{
++      opMask = 0xfffe;
++    }
++    iTabCur = pParse->nTab++;
++    for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){
++      if( iDb==1 ) continue;
++      sqlite3CodeVerifySchema(pParse, iDb);
++      pSchema = db->aDb[iDb].pSchema;
++      for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
++        pTab = (Table*)sqliteHashData(k);
++
++        /* If table pTab has not been used in a way that would benefit from
++        ** having analysis statistics during the current session, then skip it.
++        ** This also has the effect of skipping virtual tables and views */
++        if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue;
++
++        /* Reanalyze if the table is 25 times larger than the last analysis */
++        szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 );
++        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
++          if( !pIdx->hasStat1 ){
++            szThreshold = 0; /* Always analyze if any index lacks statistics */
++            break;
++          }
++        }
++        if( szThreshold ){
++          sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
++          sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, 
++                         sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold);
++          VdbeCoverage(v);
++        }
++        zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"",
++                                 db->aDb[iDb].zDbSName, pTab->zName);
++        if( opMask & 0x01 ){
++          int r1 = sqlite3GetTempReg(pParse);
++          sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC);
++          sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1);
++        }else{
++          sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC);
++        }
++      }
++    }
++    sqlite3VdbeAddOp0(v, OP_Expire);
++    break;
++  }
 +
-+static int sqlcipher_cc_add_random(void *ctx, void *buffer, int length) {
-+  return SQLITE_OK;
- }
++  /*
+   **   PRAGMA busy_timeout
+   **   PRAGMA busy_timeout = N
+   **
+@@ -105506,7 +119385,7 @@
+     if( zRight ){
+       sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
+     }
+-    returnSingleInt(pParse, "timeout",  db->busyTimeout);
++    returnSingleInt(v, db->busyTimeout);
+     break;
+   }
  
--/*
--** Compute the Year, Month, and Day from the julian day number.
--*/
--static void computeYMD(DateTime *p){
--  int Z, A, B, C, D, E, X1;
--  if( p->validYMD ) return;
--  if( !p->validJD ){
--    p->Y = 2000;
--    p->M = 1;
--    p->D = 1;
--  }else{
--    Z = (int)((p->iJD + 43200000)/86400000);
--    A = (int)((Z - 1867216.25)/36524.25);
--    A = Z + 1 + A - (A/4);
--    B = A + 1524;
--    C = (int)((B - 122.1)/365.25);
--    D = (36525*C)/100;
--    E = (int)((B-D)/30.6001);
--    X1 = (int)(30.6001*E);
--    p->D = B - D - X1;
--    p->M = E<14 ? E-1 : E-13;
--    p->Y = p->M>2 ? C - 4716 : C - 4715;
--  }
--  p->validYMD = 1;
-+/* generate a defined number of random bytes */
-+static int sqlcipher_cc_random (void *ctx, void *buffer, int length) {
-+  return (SecRandomCopyBytes(kSecRandomDefault, length, (uint8_t *)buffer) == 0) ? SQLITE_OK : SQLITE_ERROR;
- }
+@@ -105526,7 +119405,7 @@
+     if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
+       sqlite3_soft_heap_limit64(N);
+     }
+-    returnSingleInt(pParse, "soft_heap_limit",  sqlite3_soft_heap_limit64(-1));
++    returnSingleInt(v, sqlite3_soft_heap_limit64(-1));
+     break;
+   }
  
--/*
--** Compute the Hour, Minute, and Seconds from the julian day number.
--*/
--static void computeHMS(DateTime *p){
--  int s;
--  if( p->validHMS ) return;
--  computeJD(p);
--  s = (int)((p->iJD + 43200000) % 86400000);
--  p->s = s/1000.0;
--  s = (int)p->s;
--  p->s -= s;
--  p->h = s/3600;
--  s -= p->h*3600;
--  p->m = s/60;
--  p->s += s - p->m*60;
--  p->validHMS = 1;
-+static const char* sqlcipher_cc_get_provider_name(void *ctx) {
-+  return "commoncrypto";
- }
+@@ -105545,8 +119424,7 @@
+     ){
+       sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
+     }
+-    returnSingleInt(pParse, "threads",
+-                    sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
++    returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
+     break;
+   }
  
--/*
--** Compute both YMD and HMS
--*/
--static void computeYMD_HMS(DateTime *p){
--  computeYMD(p);
--  computeHMS(p);
-+static int sqlcipher_cc_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, 
unsigned char *in2, int in2_sz, unsigned char *out) {
-+  CCHmacContext hmac_context;
-+  CCHmacInit(&hmac_context, kCCHmacAlgSHA1, hmac_key, key_sz);
-+  CCHmacUpdate(&hmac_context, in, in_sz);
-+  CCHmacUpdate(&hmac_context, in2, in2_sz);
-+  CCHmacFinal(&hmac_context, out);
-+  return SQLITE_OK; 
- }
+@@ -105559,25 +119437,20 @@
+       "unlocked", "shared", "reserved", "pending", "exclusive"
+     };
+     int i;
+-    sqlite3VdbeSetNumCols(v, 2);
+     pParse->nMem = 2;
+-    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", SQLITE_STATIC);
+-    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC);
+     for(i=0; i<db->nDb; i++){
+       Btree *pBt;
+       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);
++      if( db->aDb[i].zDbSName==0 ) continue;
+       pBt = db->aDb[i].pBt;
+       if( pBt==0 || sqlite3BtreePager(pBt)==0 ){
+         zState = "closed";
+-      }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0, 
++      }else if( sqlite3_file_control(db, i ? db->aDb[i].zDbSName : 0, 
+                                      SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
+          zState = azLockName[j];
+       }
+-      sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC);
+-      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
++      sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState);
+     }
+     break;
+   }
+@@ -105628,10 +119501,329 @@
  
--/*
--** Clear the YMD and HMS and the TZ
--*/
--static void clearYMD_HMS_TZ(DateTime *p){
--  p->validYMD = 0;
--  p->validHMS = 0;
--  p->validTZ = 0;
-+static int sqlcipher_cc_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int 
salt_sz, int workfactor, int key_sz, unsigned char *key) {
-+  CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pass, pass_sz, salt, salt_sz, kCCPRFHmacAlgSHA1, 
workfactor, key, key_sz);
-+  return SQLITE_OK; 
-+}
+   } /* End of the PRAGMA switch */
+ 
++  /* The following block is a no-op unless SQLITE_DEBUG is defined. Its only
++  ** purpose is to execute assert() statements to verify that if the
++  ** PragFlg_NoColumns1 flag is set and the caller specified an argument
++  ** to the PRAGMA, the implementation has not added any OP_ResultRow 
++  ** instructions to the VM.  */
++  if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){
++    sqlite3VdbeVerifyNoResultRow(v);
++  }
 +
-+static int sqlcipher_cc_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, 
unsigned char *in, int in_sz, unsigned char *out) {
-+  CCCryptorRef cryptor;
-+  size_t tmp_csz, csz;
-+  CCOperation op = mode == CIPHER_ENCRYPT ? kCCEncrypt : kCCDecrypt;
+ pragma_out:
+   sqlite3DbFree(db, zLeft);
+   sqlite3DbFree(db, zRight);
+ }
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++/*****************************************************************************
++** Implementation of an eponymous virtual table that runs a pragma.
++**
++*/
++typedef struct PragmaVtab PragmaVtab;
++typedef struct PragmaVtabCursor PragmaVtabCursor;
++struct PragmaVtab {
++  sqlite3_vtab base;        /* Base class.  Must be first */
++  sqlite3 *db;              /* The database connection to which it belongs */
++  const PragmaName *pName;  /* Name of the pragma */
++  u8 nHidden;               /* Number of hidden columns */
++  u8 iHidden;               /* Index of the first hidden column */
++};
++struct PragmaVtabCursor {
++  sqlite3_vtab_cursor base; /* Base class.  Must be first */
++  sqlite3_stmt *pPragma;    /* The pragma statement to run */
++  sqlite_int64 iRowid;      /* Current rowid */
++  char *azArg[2];           /* Value of the argument and schema */
++};
 +
-+  CCCryptorCreate(op, kCCAlgorithmAES128, 0, key, kCCKeySizeAES256, iv, &cryptor);
-+  CCCryptorUpdate(cryptor, in, in_sz, out, in_sz, &tmp_csz);
-+  csz = tmp_csz;
-+  out += tmp_csz;
-+  CCCryptorFinal(cryptor, out, in_sz - csz, &tmp_csz);
-+  csz += tmp_csz;
-+  CCCryptorRelease(cryptor);
-+  assert(size == csz);
++/* 
++** Pragma virtual table module xConnect method.
++*/
++static int pragmaVtabConnect(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  const PragmaName *pPragma = (const PragmaName*)pAux;
++  PragmaVtab *pTab = 0;
++  int rc;
++  int i, j;
++  char cSep = '(';
++  StrAccum acc;
++  char zBuf[200];
 +
-+  return SQLITE_OK; 
++  UNUSED_PARAMETER(argc);
++  UNUSED_PARAMETER(argv);
++  sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
++  sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x");
++  for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
++    sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]);
++    cSep = ',';
++  }
++  if( i==0 ){
++    sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName);
++    cSep = ',';
++    i++;
++  }
++  j = 0;
++  if( pPragma->mPragFlg & PragFlg_Result1 ){
++    sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN");
++    j++;
++  }
++  if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
++    sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN");
++    j++;
++  }
++  sqlite3StrAccumAppend(&acc, ")", 1);
++  sqlite3StrAccumFinish(&acc);
++  assert( strlen(zBuf) < sizeof(zBuf)-1 );
++  rc = sqlite3_declare_vtab(db, zBuf);
++  if( rc==SQLITE_OK ){
++    pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab));
++    if( pTab==0 ){
++      rc = SQLITE_NOMEM;
++    }else{
++      memset(pTab, 0, sizeof(PragmaVtab));
++      pTab->pName = pPragma;
++      pTab->db = db;
++      pTab->iHidden = i;
++      pTab->nHidden = j;
++    }
++  }else{
++    *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++  }
++
++  *ppVtab = (sqlite3_vtab*)pTab;
++  return rc;
 +}
 +
-+static int sqlcipher_cc_set_cipher(void *ctx, const char *cipher_name) {
++/* 
++** Pragma virtual table module xDisconnect method.
++*/
++static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){
++  PragmaVtab *pTab = (PragmaVtab*)pVtab;
++  sqlite3_free(pTab);
 +  return SQLITE_OK;
 +}
 +
-+static const char* sqlcipher_cc_get_cipher(void *ctx) {
-+  return "aes-256-cbc";
++/* Figure out the best index to use to search a pragma virtual table.
++**
++** There are not really any index choices.  But we want to encourage the
++** query planner to give == constraints on as many hidden parameters as
++** possible, and especially on the first hidden parameter.  So return a
++** high cost if hidden parameters are unconstrained.
++*/
++static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
++  PragmaVtab *pTab = (PragmaVtab*)tab;
++  const struct sqlite3_index_constraint *pConstraint;
++  int i, j;
++  int seen[2];
++
++  pIdxInfo->estimatedCost = (double)1;
++  if( pTab->nHidden==0 ){ return SQLITE_OK; }
++  pConstraint = pIdxInfo->aConstraint;
++  seen[0] = 0;
++  seen[1] = 0;
++  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
++    if( pConstraint->usable==0 ) continue;
++    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
++    if( pConstraint->iColumn < pTab->iHidden ) continue;
++    j = pConstraint->iColumn - pTab->iHidden;
++    assert( j < 2 );
++    seen[j] = i+1;
++  }
++  if( seen[0]==0 ){
++    pIdxInfo->estimatedCost = (double)2147483647;
++    pIdxInfo->estimatedRows = 2147483647;
++    return SQLITE_OK;
++  }
++  j = seen[0]-1;
++  pIdxInfo->aConstraintUsage[j].argvIndex = 1;
++  pIdxInfo->aConstraintUsage[j].omit = 1;
++  if( seen[1]==0 ) return SQLITE_OK;
++  pIdxInfo->estimatedCost = (double)20;
++  pIdxInfo->estimatedRows = 20;
++  j = seen[1]-1;
++  pIdxInfo->aConstraintUsage[j].argvIndex = 2;
++  pIdxInfo->aConstraintUsage[j].omit = 1;
++  return SQLITE_OK;
 +}
 +
-+static int sqlcipher_cc_get_key_sz(void *ctx) {
-+  return kCCKeySizeAES256;
++/* Create a new cursor for the pragma virtual table */
++static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){
++  PragmaVtabCursor *pCsr;
++  pCsr = (PragmaVtabCursor*)sqlite3_malloc(sizeof(*pCsr));
++  if( pCsr==0 ) return SQLITE_NOMEM;
++  memset(pCsr, 0, sizeof(PragmaVtabCursor));
++  pCsr->base.pVtab = pVtab;
++  *ppCursor = &pCsr->base;
++  return SQLITE_OK;
 +}
 +
-+static int sqlcipher_cc_get_iv_sz(void *ctx) {
-+  return kCCBlockSizeAES128;
++/* Clear all content from pragma virtual table cursor. */
++static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){
++  int i;
++  sqlite3_finalize(pCsr->pPragma);
++  pCsr->pPragma = 0;
++  for(i=0; i<ArraySize(pCsr->azArg); i++){
++    sqlite3_free(pCsr->azArg[i]);
++    pCsr->azArg[i] = 0;
++  }
 +}
 +
-+static int sqlcipher_cc_get_block_sz(void *ctx) {
-+  return kCCBlockSizeAES128;
++/* Close a pragma virtual table cursor */
++static int pragmaVtabClose(sqlite3_vtab_cursor *cur){
++  PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur;
++  pragmaVtabCursorClear(pCsr);
++  sqlite3_free(pCsr);
++  return SQLITE_OK;
 +}
 +
-+static int sqlcipher_cc_get_hmac_sz(void *ctx) {
-+  return CC_SHA1_DIGEST_LENGTH;
++/* Advance the pragma virtual table cursor to the next row */
++static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){
++  PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
++  int rc = SQLITE_OK;
++
++  /* Increment the xRowid value */
++  pCsr->iRowid++;
++  assert( pCsr->pPragma );
++  if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){
++    rc = sqlite3_finalize(pCsr->pPragma);
++    pCsr->pPragma = 0;
++    pragmaVtabCursorClear(pCsr);
++  }
++  return rc;
 +}
 +
-+static int sqlcipher_cc_ctx_copy(void *target_ctx, void *source_ctx) {
-+  return SQLITE_OK;
++/* 
++** Pragma virtual table module xFilter method.
++*/
++static int pragmaVtabFilter(
++  sqlite3_vtab_cursor *pVtabCursor, 
++  int idxNum, const char *idxStr,
++  int argc, sqlite3_value **argv
++){
++  PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
++  PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab);
++  int rc;
++  int i, j;
++  StrAccum acc;
++  char *zSql;
++
++  UNUSED_PARAMETER(idxNum);
++  UNUSED_PARAMETER(idxStr);
++  pragmaVtabCursorClear(pCsr);
++  j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1;
++  for(i=0; i<argc; i++, j++){
++    const char *zText = (const char*)sqlite3_value_text(argv[i]);
++    assert( j<ArraySize(pCsr->azArg) );
++    assert( pCsr->azArg[j]==0 );
++    if( zText ){
++      pCsr->azArg[j] = sqlite3_mprintf("%s", zText);
++      if( pCsr->azArg[j]==0 ){
++        return SQLITE_NOMEM;
++      }
++    }
++  }
++  sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
++  sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
++  if( pCsr->azArg[1] ){
++    sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
++  }
++  sqlite3StrAccumAppendAll(&acc, pTab->pName->zName);
++  if( pCsr->azArg[0] ){
++    sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]);
++  }
++  zSql = sqlite3StrAccumFinish(&acc);
++  if( zSql==0 ) return SQLITE_NOMEM;
++  rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0);
++  sqlite3_free(zSql);
++  if( rc!=SQLITE_OK ){
++    pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
++    return rc;
++  }
++  return pragmaVtabNext(pVtabCursor);
 +}
 +
-+static int sqlcipher_cc_ctx_cmp(void *c1, void *c2) {
-+  return 1; /* always indicate contexts are the same */
++/*
++** Pragma virtual table module xEof method.
++*/
++static int pragmaVtabEof(sqlite3_vtab_cursor *pVtabCursor){
++  PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
++  return (pCsr->pPragma==0);
 +}
 +
-+static int sqlcipher_cc_ctx_init(void **ctx) {
++/* The xColumn method simply returns the corresponding column from
++** the PRAGMA.  
++*/
++static int pragmaVtabColumn(
++  sqlite3_vtab_cursor *pVtabCursor, 
++  sqlite3_context *ctx, 
++  int i
++){
++  PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
++  PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab);
++  if( i<pTab->iHidden ){
++    sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i));
++  }else{
++    sqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT);
++  }
 +  return SQLITE_OK;
 +}
 +
-+static int sqlcipher_cc_ctx_free(void **ctx) {
++/* 
++** Pragma virtual table module xRowid method.
++*/
++static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){
++  PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
++  *p = pCsr->iRowid;
 +  return SQLITE_OK;
 +}
 +
-+static int sqlcipher_cc_fips_status(void *ctx) {
-+  return 0;
-+}
++/* The pragma virtual table object */
++static const sqlite3_module pragmaVtabModule = {
++  0,                           /* iVersion */
++  0,                           /* xCreate - create a table */
++  pragmaVtabConnect,           /* xConnect - connect to an existing table */
++  pragmaVtabBestIndex,         /* xBestIndex - Determine search strategy */
++  pragmaVtabDisconnect,        /* xDisconnect - Disconnect from a table */
++  0,                           /* xDestroy - Drop a table */
++  pragmaVtabOpen,              /* xOpen - open a cursor */
++  pragmaVtabClose,             /* xClose - close a cursor */
++  pragmaVtabFilter,            /* xFilter - configure scan constraints */
++  pragmaVtabNext,              /* xNext - advance a cursor */
++  pragmaVtabEof,               /* xEof */
++  pragmaVtabColumn,            /* xColumn - read data */
++  pragmaVtabRowid,             /* xRowid - read data */
++  0,                           /* xUpdate - write data */
++  0,                           /* xBegin - begin transaction */
++  0,                           /* xSync - sync transaction */
++  0,                           /* xCommit - commit transaction */
++  0,                           /* xRollback - rollback transaction */
++  0,                           /* xFindFunction - function overloading */
++  0,                           /* xRename - rename the table */
++  0,                           /* xSavepoint */
++  0,                           /* xRelease */
++  0                            /* xRollbackTo */
++};
 +
-+int sqlcipher_cc_setup(sqlcipher_provider *p) {
-+  p->random = sqlcipher_cc_random;
-+  p->get_provider_name = sqlcipher_cc_get_provider_name;
-+  p->hmac = sqlcipher_cc_hmac;
-+  p->kdf = sqlcipher_cc_kdf;
-+  p->cipher = sqlcipher_cc_cipher;
-+  p->set_cipher = sqlcipher_cc_set_cipher;
-+  p->get_cipher = sqlcipher_cc_get_cipher;
-+  p->get_key_sz = sqlcipher_cc_get_key_sz;
-+  p->get_iv_sz = sqlcipher_cc_get_iv_sz;
-+  p->get_block_sz = sqlcipher_cc_get_block_sz;
-+  p->get_hmac_sz = sqlcipher_cc_get_hmac_sz;
-+  p->ctx_copy = sqlcipher_cc_ctx_copy;
-+  p->ctx_cmp = sqlcipher_cc_ctx_cmp;
-+  p->ctx_init = sqlcipher_cc_ctx_init;
-+  p->ctx_free = sqlcipher_cc_ctx_free;
-+  p->add_random = sqlcipher_cc_add_random;
-+  p->fips_status = sqlcipher_cc_fips_status;
-+  return SQLITE_OK;
- }
- 
-+#endif
-+#endif
-+/* END SQLCIPHER */
++/*
++** Check to see if zTabName is really the name of a pragma.  If it is,
++** then register an eponymous virtual table for that pragma and return
++** a pointer to the Module object for the new virtual table.
++*/
++SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){
++  const PragmaName *pName;
++  assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 );
++  pName = pragmaLocate(zName+7);
++  if( pName==0 ) return 0;
++  if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0;
++  assert( sqlite3HashFind(&db->aModule, zName)==0 );
++  return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0);
++}
 +
-+/************** End of crypto_cc.c *******************************************/
-+/************** Begin file global.c ******************************************/
- /*
--** On recent Windows platforms, the localtime_s() function is available
--** as part of the "Secure CRT". It is essentially equivalent to 
--** localtime_r() available under most POSIX platforms, except that the 
--** order of the parameters is reversed.
-+** 2008 June 13
- **
--** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx.
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
- **
--** If the user has not indicated to use localtime_r() or localtime_s()
--** already, check for an MSVC build environment that provides 
--** localtime_s().
-+**    May you do good and not evil.
-+**    May you find forgiveness for yourself and forgive others.
-+**    May you share freely, never taking more than you give.
-+**
-+*************************************************************************
-+**
-+** This file contains definitions of global variables and constants.
- */
--#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \
--    && defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
--#undef  HAVE_LOCALTIME_S
--#define HAVE_LOCALTIME_S 1
--#endif
- 
--#ifndef SQLITE_OMIT_LOCALTIME
--/*
--** The following routine implements the rough equivalent of localtime_r()
--** using whatever operating-system specific localtime facility that
--** is available.  This routine returns 0 on success and
--** non-zero on any kind of error.
--**
--** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
--** routine will always fail.
-+/* An array to map all upper-case characters into their corresponding
-+** lower-case character. 
- **
--** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
--** library function localtime_r() is used to assist in the calculation of
--** local time.
-+** SQLite only considers US-ASCII (or EBCDIC) characters.  We do not
-+** handle case conversions for the UTF character set since the tables
-+** involved are nearly as big or bigger than SQLite itself.
- */
--static int osLocaltime(time_t *t, struct tm *pTm){
--  int rc;
--#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S
--  struct tm *pX;
--#if SQLITE_THREADSAFE>0
--  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
--#endif
--  sqlite3_mutex_enter(mutex);
--  pX = localtime(t);
--#ifndef SQLITE_OMIT_BUILTIN_TEST
--  if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
--#endif
--  if( pX ) *pTm = *pX;
--  sqlite3_mutex_leave(mutex);
--  rc = pX==0;
--#else
--#ifndef SQLITE_OMIT_BUILTIN_TEST
--  if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
-+SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
-+#ifdef SQLITE_ASCII
-+      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
-+     18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
-+     36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
-+     54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
-+    104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
-+    122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
-+    108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
-+    126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
-+    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
-+    162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
-+    180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
-+    198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
-+    216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
-+    234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
-+    252,253,254,255
- #endif
--#if HAVE_LOCALTIME_R
--  rc = localtime_r(t, pTm)==0;
--#else
--  rc = localtime_s(pTm, t);
--#endif /* HAVE_LOCALTIME_R */
--#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */
--  return rc;
--}
--#endif /* SQLITE_OMIT_LOCALTIME */
--
-+#ifdef SQLITE_EBCDIC
-+      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 0x */
-+     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */
-+     32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 2x */
-+     48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
-+     64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
-+     80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
-+     96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */
-+    112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 7x */
-+    128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
-+    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, /* 9x */
-+    160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
-+    176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
-+    192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
-+    208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
-+    224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */
-+    240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */
-+#endif
-+};
++#endif /* SQLITE_OMIT_VIRTUALTABLE */
  
--#ifndef SQLITE_OMIT_LOCALTIME
- /*
--** Compute the difference (in milliseconds) between localtime and UTC
--** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
--** return this value and set *pRc to SQLITE_OK. 
-+** The following 256 byte lookup table is used to support SQLites built-in
-+** equivalents to the following standard library functions:
- **
--** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
--** is undefined in this case.
-+**   isspace()                        0x01
-+**   isalpha()                        0x02
-+**   isdigit()                        0x04
-+**   isalnum()                        0x06
-+**   isxdigit()                       0x08
-+**   toupper()                        0x20
-+**   SQLite identifier character      0x40
-+**
-+** Bit 0x20 is set if the mapped character requires translation to upper
-+** case. i.e. if the character is a lower-case ASCII character.
-+** If x is a lower-case ASCII character, then its upper-case equivalent
-+** is (x - 0x20). Therefore toupper() can be implemented as:
-+**
-+**   (x & ~(map[x]&0x20))
-+**
-+** Standard function tolower() is implemented using the sqlite3UpperToLower[]
-+** array. tolower() is used more often than toupper() by SQLite.
-+**
-+** Bit 0x40 is set if the character non-alphanumeric and can be used in an 
-+** SQLite identifier.  Identifiers are alphanumerics, "_", "$", and any
-+** non-ASCII UTF character. Hence the test for whether or not a character is
-+** part of an identifier is 0x46.
-+**
-+** SQLite's versions are identical to the standard versions assuming a
-+** locale of "C". They are implemented as macros in sqliteInt.h.
- */
--static sqlite3_int64 localtimeOffset(
--  DateTime *p,                    /* Date at which to calculate offset */
--  sqlite3_context *pCtx,          /* Write error here if one occurs */
--  int *pRc                        /* OUT: Error code. SQLITE_OK or ERROR */
--){
--  DateTime x, y;
--  time_t t;
--  struct tm sLocal;
-+#ifdef SQLITE_ASCII
-+SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
-+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 00..07    ........ */
-+  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,  /* 08..0f    ........ */
-+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 10..17    ........ */
-+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 18..1f    ........ */
-+  0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,  /* 20..27     !"#$%&' */
-+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 28..2f    ()*+,-./ */
-+  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,  /* 30..37    01234567 */
-+  0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 38..3f    89:;<=>? */
- 
--  /* Initialize the contents of sLocal to avoid a compiler warning. */
--  memset(&sLocal, 0, sizeof(sLocal));
-+  0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02,  /* 40..47    @ABCDEFG */
-+  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 48..4f    HIJKLMNO */
-+  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 50..57    PQRSTUVW */
-+  0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40,  /* 58..5f    XYZ[\]^_ */
-+  0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22,  /* 60..67    `abcdefg */
-+  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 68..6f    hijklmno */
-+  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 70..77    pqrstuvw */
-+  0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 78..7f    xyz{|}~. */
- 
--  x = *p;
--  computeYMD_HMS(&x);
--  if( x.Y<1971 || x.Y>=2038 ){
--    /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
--    ** works for years between 1970 and 2037. For dates outside this range,
--    ** SQLite attempts to map the year into an equivalent year within this
--    ** range, do the calculation, then map the year back.
--    */
--    x.Y = 2000;
--    x.M = 1;
--    x.D = 1;
--    x.h = 0;
--    x.m = 0;
--    x.s = 0.0;
--  } else {
--    int s = (int)(x.s + 0.5);
--    x.s = s;
--  }
--  x.tz = 0;
--  x.validJD = 0;
--  computeJD(&x);
--  t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
--  if( osLocaltime(&t, &sLocal) ){
--    sqlite3_result_error(pCtx, "local time unavailable", -1);
--    *pRc = SQLITE_ERROR;
--    return 0;
--  }
--  y.Y = sLocal.tm_year + 1900;
--  y.M = sLocal.tm_mon + 1;
--  y.D = sLocal.tm_mday;
--  y.h = sLocal.tm_hour;
--  y.m = sLocal.tm_min;
--  y.s = sLocal.tm_sec;
--  y.validYMD = 1;
--  y.validHMS = 1;
--  y.validJD = 0;
--  y.validTZ = 0;
--  computeJD(&y);
--  *pRc = SQLITE_OK;
--  return y.iJD - x.iJD;
--}
--#endif /* SQLITE_OMIT_LOCALTIME */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 80..87    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 88..8f    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 90..97    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 98..9f    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* a0..a7    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* a8..af    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* b0..b7    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* b8..bf    ........ */
+ #endif /* SQLITE_OMIT_PRAGMA */
  
--/*
--** Process a modifier to a date-time stamp.  The modifiers are
--** as follows:
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* c0..c7    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* c8..cf    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* d0..d7    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* d8..df    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e0..e7    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e8..ef    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* f0..f7    ........ */
-+  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40   /* f8..ff    ........ */
-+};
-+#endif
-+
-+/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
-+** compatibility for legacy applications, the URI filename capability is
-+** disabled by default.
- **
--**     NNN days
--**     NNN hours
--**     NNN minutes
--**     NNN.NNNN seconds
--**     NNN months
--**     NNN years
--**     start of month
--**     start of year
--**     start of week
--**     start of day
--**     weekday N
--**     unixepoch
--**     localtime
--**     utc
-+** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
-+** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
- **
--** Return 0 on success and 1 if there is any kind of error. If the error
--** is in a system call (i.e. localtime()), then an error message is written
--** to context pCtx. If the error is an unrecognized modifier, no error is
--** written to pCtx.
-+** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
-+** disabled. The default value may be changed by compiling with the
-+** SQLITE_USE_URI symbol defined.
+@@ -105652,6 +119844,7 @@
+ ** interface, and routines that contribute to loading the database schema
+ ** from disk.
  */
--static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
--  int rc = 1;
--  int n;
--  double r;
--  char *z, zBuf[30];
--  z = zBuf;
--  for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){
--    z[n] = (char)sqlite3UpperToLower[(u8)zMod[n]];
--  }
--  z[n] = 0;
--  switch( z[0] ){
--#ifndef SQLITE_OMIT_LOCALTIME
--    case 'l': {
--      /*    localtime
--      **
--      ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
--      ** show local time.
--      */
--      if( strcmp(z, "localtime")==0 ){
--        computeJD(p);
--        p->iJD += localtimeOffset(p, pCtx, &rc);
--        clearYMD_HMS_TZ(p);
--      }
--      break;
--    }
-+#ifndef SQLITE_USE_URI
-+# define  SQLITE_USE_URI 0
- #endif
--    case 'u': {
--      /*
--      **    unixepoch
--      **
--      ** Treat the current value of p->iJD as the number of
--      ** seconds since 1970.  Convert to a real julian day number.
--      */
--      if( strcmp(z, "unixepoch")==0 && p->validJD ){
--        p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000;
--        clearYMD_HMS_TZ(p);
--        rc = 0;
--      }
--#ifndef SQLITE_OMIT_LOCALTIME
--      else if( strcmp(z, "utc")==0 ){
--        sqlite3_int64 c1;
--        computeJD(p);
--        c1 = localtimeOffset(p, pCtx, &rc);
--        if( rc==SQLITE_OK ){
--          p->iJD -= c1;
--          clearYMD_HMS_TZ(p);
--          p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
--        }
--      }
-+
-+/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
-+** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
-+** that compile-time option is omitted.
-+*/
-+#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
-+# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
- #endif
--      break;
--    }
--    case 'w': {
--      /*
--      **    weekday N
--      **
--      ** Move the date to the same time on the next occurrence of
--      ** weekday N where 0==Sunday, 1==Monday, and so forth.  If the
--      ** date is already on the appropriate weekday, this is a no-op.
--      */
--      if( strncmp(z, "weekday ", 8)==0
--               && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
--               && (n=(int)r)==r && n>=0 && r<7 ){
--        sqlite3_int64 Z;
--        computeYMD_HMS(p);
--        p->validTZ = 0;
--        p->validJD = 0;
--        computeJD(p);
--        Z = ((p->iJD + 129600000)/86400000) % 7;
--        if( Z>n ) Z -= 7;
--        p->iJD += (n - Z)*86400000;
--        clearYMD_HMS_TZ(p);
--        rc = 0;
--      }
--      break;
--    }
--    case 's': {
--      /*
--      **    start of TTTTT
--      **
--      ** Move the date backwards to the beginning of the current day,
--      ** or month or year.
--      */
--      if( strncmp(z, "start of ", 9)!=0 ) break;
--      z += 9;
--      computeYMD(p);
--      p->validHMS = 1;
--      p->h = p->m = 0;
--      p->s = 0.0;
--      p->validTZ = 0;
--      p->validJD = 0;
--      if( strcmp(z,"month")==0 ){
--        p->D = 1;
--        rc = 0;
--      }else if( strcmp(z,"year")==0 ){
--        computeYMD(p);
--        p->M = 1;
--        p->D = 1;
--        rc = 0;
--      }else if( strcmp(z,"day")==0 ){
--        rc = 0;
--      }
--      break;
--    }
--    case '+':
--    case '-':
--    case '0':
--    case '1':
--    case '2':
--    case '3':
--    case '4':
--    case '5':
--    case '6':
--    case '7':
--    case '8':
--    case '9': {
--      double rRounder;
--      for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
--      if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
--        rc = 1;
--        break;
--      }
--      if( z[n]==':' ){
--        /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
--        ** specified number of hours, minutes, seconds, and fractional seconds
--        ** to the time.  The ".FFF" may be omitted.  The ":SS.FFF" may be
--        ** omitted.
--        */
--        const char *z2 = z;
--        DateTime tx;
--        sqlite3_int64 day;
--        if( !sqlite3Isdigit(*z2) ) z2++;
--        memset(&tx, 0, sizeof(tx));
--        if( parseHhMmSs(z2, &tx) ) break;
--        computeJD(&tx);
--        tx.iJD -= 43200000;
--        day = tx.iJD/86400000;
--        tx.iJD -= day*86400000;
--        if( z[0]=='-' ) tx.iJD = -tx.iJD;
--        computeJD(p);
--        clearYMD_HMS_TZ(p);
--        p->iJD += tx.iJD;
--        rc = 0;
--        break;
--      }
--      z += n;
--      while( sqlite3Isspace(*z) ) z++;
--      n = sqlite3Strlen30(z);
--      if( n>10 || n<3 ) break;
--      if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
--      computeJD(p);
--      rc = 0;
--      rRounder = r<0 ? -0.5 : +0.5;
--      if( n==3 && strcmp(z,"day")==0 ){
--        p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder);
--      }else if( n==4 && strcmp(z,"hour")==0 ){
--        p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder);
--      }else if( n==6 && strcmp(z,"minute")==0 ){
--        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder);
--      }else if( n==6 && strcmp(z,"second")==0 ){
--        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder);
--      }else if( n==5 && strcmp(z,"month")==0 ){
--        int x, y;
--        computeYMD_HMS(p);
--        p->M += (int)r;
--        x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
--        p->Y += x;
--        p->M -= x*12;
--        p->validJD = 0;
--        computeJD(p);
--        y = (int)r;
--        if( y!=r ){
--          p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder);
--        }
--      }else if( n==4 && strcmp(z,"year")==0 ){
--        int y = (int)r;
--        computeYMD_HMS(p);
--        p->Y += y;
--        p->validJD = 0;
--        computeJD(p);
--        if( y!=r ){
--          p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder);
--        }
--      }else{
--        rc = 1;
--      }
--      clearYMD_HMS_TZ(p);
--      break;
--    }
--    default: {
--      break;
--    }
--  }
--  return rc;
--}
- 
--/*
--** Process time function arguments.  argv[0] is a date-time stamp.
--** argv[1] and following are modifiers.  Parse them all and write
--** the resulting time into the DateTime structure p.  Return 0
--** on success and 1 if there are any errors.
--**
--** If there are zero parameters (if even argv[0] is undefined)
--** then assume a default value of "now" for argv[0].
-+/* The minimum PMA size is set to this value multiplied by the database
-+** page size in bytes.
- */
--static int isDate(
--  sqlite3_context *context, 
--  int argc, 
--  sqlite3_value **argv, 
--  DateTime *p
--){
--  int i;
--  const unsigned char *z;
--  int eType;
--  memset(p, 0, sizeof(*p));
--  if( argc==0 ){
--    return setDateTimeToCurrent(context, p);
--  }
--  if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
--                   || eType==SQLITE_INTEGER ){
--    p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
--    p->validJD = 1;
--  }else{
--    z = sqlite3_value_text(argv[0]);
--    if( !z || parseDateOrTime(context, (char*)z, p) ){
--      return 1;
--    }
--  }
--  for(i=1; i<argc; i++){
--    z = sqlite3_value_text(argv[i]);
--    if( z==0 || parseModifier(context, (char*)z, p) ) return 1;
--  }
--  return 0;
--}
-+#ifndef SQLITE_SORTER_PMASZ
-+# define SQLITE_SORTER_PMASZ 250
-+#endif
- 
-+/*
-+** The following singleton contains the global configuration for
-+** the SQLite library.
-+*/
-+SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
-+   SQLITE_DEFAULT_MEMSTATUS,  /* bMemstat */
-+   1,                         /* bCoreMutex */
-+   SQLITE_THREADSAFE==1,      /* bFullMutex */
-+   SQLITE_USE_URI,            /* bOpenUri */
-+   SQLITE_ALLOW_COVERING_INDEX_SCAN,   /* bUseCis */
-+   0x7ffffffe,                /* mxStrlen */
-+   0,                         /* neverCorrupt */
-+   128,                       /* szLookaside */
-+   500,                       /* nLookaside */
-+   {0,0,0,0,0,0,0,0},         /* m */
-+   {0,0,0,0,0,0,0,0,0},       /* mutex */
-+   {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
-+   (void*)0,                  /* pHeap */
-+   0,                         /* nHeap */
-+   0, 0,                      /* mnHeap, mxHeap */
-+   SQLITE_DEFAULT_MMAP_SIZE,  /* szMmap */
-+   SQLITE_MAX_MMAP_SIZE,      /* mxMmap */
-+   (void*)0,                  /* pScratch */
-+   0,                         /* szScratch */
-+   0,                         /* nScratch */
-+   (void*)0,                  /* pPage */
-+   0,                         /* szPage */
-+   0,                         /* nPage */
-+   0,                         /* mxParserStack */
-+   0,                         /* sharedCacheEnabled */
-+   SQLITE_SORTER_PMASZ,       /* szPma */
-+   /* All the rest should always be initialized to zero */
-+   0,                         /* isInit */
-+   0,                         /* inProgress */
-+   0,                         /* isMutexInit */
-+   0,                         /* isMallocInit */
-+   0,                         /* isPCacheInit */
-+   0,                         /* nRefInitMutex */
-+   0,                         /* pInitMutex */
-+   0,                         /* xLog */
-+   0,                         /* pLogArg */
-+#ifdef SQLITE_ENABLE_SQLLOG
-+   0,                         /* xSqllog */
-+   0,                         /* pSqllogArg */
-+#endif
-+#ifdef SQLITE_VDBE_COVERAGE
-+   0,                         /* xVdbeBranch */
-+   0,                         /* pVbeBranchArg */
-+#endif
-+#ifndef SQLITE_OMIT_BUILTIN_TEST
-+   0,                         /* xTestCallback */
-+#endif
-+   0                          /* bLocaltimeFault */
-+};
++/* #include "sqliteInt.h" */
  
  /*
--** The following routines implement the various date and time functions
--** of SQLite.
-+** Hash table for global functions - functions common to all
-+** database connections.  After initialization, this table is
-+** read-only.
- */
-+SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
+ ** Fill the InitData structure with an error message that indicates
+@@ -105663,16 +119856,15 @@
+   const char *zExtra   /* Error information */
+ ){
+   sqlite3 *db = pData->db;
+-  if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
++  if( !db->mallocFailed && (db->flags & SQLITE_WriteSchema)==0 ){
++    char *z;
+     if( zObj==0 ) zObj = "?";
+-    sqlite3SetString(pData->pzErrMsg, db,
+-      "malformed database schema (%s)", zObj);
+-    if( zExtra ){
+-      *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg, 
+-                                 "%s - %s", *pData->pzErrMsg, zExtra);
+-    }
++    z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
++    if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
++    sqlite3DbFree(db, *pData->pzErrMsg);
++    *pData->pzErrMsg = z;
+   }
+-  pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
++  pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT;
+ }
  
  /*
--**    julianday( TIMESTRING, MOD, MOD, ...)
--**
--** Return the julian day number of the date specified in the arguments
-+** Constant tokens for values 0 and 1.
- */
--static void juliandayFunc(
--  sqlite3_context *context,
--  int argc,
--  sqlite3_value **argv
--){
--  DateTime x;
--  if( isDate(context, argc, argv, &x)==0 ){
--    computeJD(&x);
--    sqlite3_result_double(context, x.iJD/86400000.0);
--  }
--}
--
--/*
--**    datetime( TIMESTRING, MOD, MOD, ...)
--**
--** Return YYYY-MM-DD HH:MM:SS
--*/
--static void datetimeFunc(
--  sqlite3_context *context,
--  int argc,
--  sqlite3_value **argv
--){
--  DateTime x;
--  if( isDate(context, argc, argv, &x)==0 ){
--    char zBuf[100];
--    computeYMD_HMS(&x);
--    sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d",
--                     x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
--    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
--  }
--}
--
--/*
--**    time( TIMESTRING, MOD, MOD, ...)
--**
--** Return HH:MM:SS
--*/
--static void timeFunc(
--  sqlite3_context *context,
--  int argc,
--  sqlite3_value **argv
--){
--  DateTime x;
--  if( isDate(context, argc, argv, &x)==0 ){
--    char zBuf[100];
--    computeHMS(&x);
--    sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
--    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
--  }
--}
+@@ -105712,6 +119904,7 @@
+     ** structures that describe the table, index, or view.
+     */
+     int rc;
++    u8 saved_iDb = db->init.iDb;
+     sqlite3_stmt *pStmt;
+     TESTONLY(int rcp);            /* Return code from sqlite3_prepare() */
+ 
+@@ -105722,14 +119915,15 @@
+     TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
+     rc = db->errCode;
+     assert( (rc&0xFF)==(rcp&0xFF) );
+-    db->init.iDb = 0;
++    db->init.iDb = saved_iDb;
++    assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 );
+     if( SQLITE_OK!=rc ){
+       if( db->init.orphanTrigger ){
+         assert( iDb==1 );
+       }else{
+         pData->rc = rc;
+         if( rc==SQLITE_NOMEM ){
+-          db->mallocFailed = 1;
++          sqlite3OomFault(db);
+         }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
+           corruptSchema(pData, argv[0], sqlite3_errmsg(db));
+         }
+@@ -105746,7 +119940,7 @@
+     ** to do here is record the root page number for that index.
+     */
+     Index *pIndex;
+-    pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName);
++    pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName);
+     if( pIndex==0 ){
+       /* This can occur if there exists an index on a TEMP table which
+       ** has the same name as another index on a permanent index.  Since
+@@ -105775,61 +119969,27 @@
+ #ifndef SQLITE_OMIT_DEPRECATED
+   int size;
+ #endif
+-  Table *pTab;
+   Db *pDb;
+   char const *azArg[4];
+   int meta[5];
+   InitData initData;
+-  char const *zMasterSchema;
+-  char const *zMasterName;
++  const char *zMasterName;
+   int openedTransaction = 0;
+ 
+-  /*
+-  ** The master database table has a structure like this
+-  */
+-  static const char master_schema[] = 
+-     "CREATE TABLE sqlite_master(\n"
+-     "  type text,\n"
+-     "  name text,\n"
+-     "  tbl_name text,\n"
+-     "  rootpage integer,\n"
+-     "  sql text\n"
+-     ")"
+-  ;
+-#ifndef SQLITE_OMIT_TEMPDB
+-  static const char temp_master_schema[] = 
+-     "CREATE TEMP TABLE sqlite_temp_master(\n"
+-     "  type text,\n"
+-     "  name text,\n"
+-     "  tbl_name text,\n"
+-     "  rootpage integer,\n"
+-     "  sql text\n"
+-     ")"
+-  ;
+-#else
+-  #define temp_master_schema 0
+-#endif
 -
--/*
--**    date( TIMESTRING, MOD, MOD, ...)
--**
--** Return YYYY-MM-DD
--*/
--static void dateFunc(
--  sqlite3_context *context,
--  int argc,
--  sqlite3_value **argv
--){
--  DateTime x;
--  if( isDate(context, argc, argv, &x)==0 ){
--    char zBuf[100];
--    computeYMD(&x);
--    sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
--    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+   assert( iDb>=0 && iDb<db->nDb );
+   assert( db->aDb[iDb].pSchema );
+   assert( sqlite3_mutex_held(db->mutex) );
+   assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
+ 
+-  /* zMasterSchema and zInitScript are set to point at the master schema
+-  ** and initialisation script appropriate for the database being
+-  ** initialized. zMasterName is the name of the master table.
+-  */
+-  if( !OMIT_TEMPDB && iDb==1 ){
+-    zMasterSchema = temp_master_schema;
+-  }else{
+-    zMasterSchema = master_schema;
 -  }
--}
+-  zMasterName = SCHEMA_TABLE(iDb);
 -
--/*
--**    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
--**
--** Return a string described by FORMAT.  Conversions as follows:
--**
--**   %d  day of month
--**   %f  ** fractional seconds  SS.SSS
--**   %H  hour 00-24
--**   %j  day of year 000-366
--**   %J  ** julian day number
--**   %m  month 01-12
--**   %M  minute 00-59
--**   %s  seconds since 1970-01-01
--**   %S  seconds 00-59
--**   %w  day of week 0-6  sunday==0
--**   %W  week of year 00-53
--**   %Y  year 0000-9999
--**   %%  %
--*/
--static void strftimeFunc(
--  sqlite3_context *context,
--  int argc,
--  sqlite3_value **argv
--){
--  DateTime x;
--  u64 n;
--  size_t i,j;
--  char *z;
--  sqlite3 *db;
--  const char *zFmt;
--  char zBuf[100];
--  if( argc==0 ) return;
--  zFmt = (const char*)sqlite3_value_text(argv[0]);
--  if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
--  db = sqlite3_context_db_handle(context);
--  for(i=0, n=1; zFmt[i]; i++, n++){
--    if( zFmt[i]=='%' ){
--      switch( zFmt[i+1] ){
--        case 'd':
--        case 'H':
--        case 'm':
--        case 'M':
--        case 'S':
--        case 'W':
--          n++;
--          /* fall thru */
--        case 'w':
--        case '%':
--          break;
--        case 'f':
--          n += 8;
--          break;
--        case 'j':
--          n += 3;
--          break;
--        case 'Y':
--          n += 8;
--          break;
--        case 's':
--        case 'J':
--          n += 50;
--          break;
--        default:
--          return;  /* ERROR.  return a NULL */
--      }
--      i++;
--    }
--  }
--  testcase( n==sizeof(zBuf)-1 );
--  testcase( n==sizeof(zBuf) );
--  testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
--  testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] );
--  if( n<sizeof(zBuf) ){
--    z = zBuf;
--  }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){
--    sqlite3_result_error_toobig(context);
--    return;
--  }else{
--    z = sqlite3DbMallocRaw(db, (int)n);
--    if( z==0 ){
--      sqlite3_result_error_nomem(context);
--      return;
--    }
+-  /* Construct the schema tables.  */
+-  azArg[0] = zMasterName;
++  /* Construct the in-memory representation schema tables (sqlite_master or
++  ** sqlite_temp_master) by invoking the parser directly.  The appropriate
++  ** table name will be inserted automatically by the parser so we can just
++  ** use the abbreviation "x" here.  The parser will also automatically tag
++  ** the schema table as read-only. */
++  azArg[0] = zMasterName = SCHEMA_TABLE(iDb);
+   azArg[1] = "1";
+-  azArg[2] = zMasterSchema;
++  azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text,"
++                            "rootpage integer,sql text)";
+   azArg[3] = 0;
+   initData.db = db;
+   initData.iDb = iDb;
+@@ -105840,10 +120000,6 @@
+     rc = initData.rc;
+     goto error_out;
+   }
+-  pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
+-  if( ALWAYS(pTab) ){
+-    pTab->tabFlags |= TF_Readonly;
 -  }
--  computeJD(&x);
--  computeYMD_HMS(&x);
--  for(i=j=0; zFmt[i]; i++){
--    if( zFmt[i]!='%' ){
--      z[j++] = zFmt[i];
--    }else{
--      i++;
--      switch( zFmt[i] ){
--        case 'd':  sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break;
--        case 'f': {
--          double s = x.s;
--          if( s>59.999 ) s = 59.999;
--          sqlite3_snprintf(7, &z[j],"%06.3f", s);
--          j += sqlite3Strlen30(&z[j]);
--          break;
--        }
--        case 'H':  sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break;
--        case 'W': /* Fall thru */
--        case 'j': {
--          int nDay;             /* Number of days since 1st day of year */
--          DateTime y = x;
--          y.validJD = 0;
--          y.M = 1;
--          y.D = 1;
--          computeJD(&y);
--          nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
--          if( zFmt[i]=='W' ){
--            int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
--            wd = (int)(((x.iJD+43200000)/86400000)%7);
--            sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7);
--            j += 2;
--          }else{
--            sqlite3_snprintf(4, &z[j],"%03d",nDay+1);
--            j += 3;
--          }
--          break;
--        }
--        case 'J': {
--          sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0);
--          j+=sqlite3Strlen30(&z[j]);
--          break;
--        }
--        case 'm':  sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break;
--        case 'M':  sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break;
--        case 's': {
--          sqlite3_snprintf(30,&z[j],"%lld",
--                           (i64)(x.iJD/1000 - 21086676*(i64)10000));
--          j += sqlite3Strlen30(&z[j]);
--          break;
--        }
--        case 'S':  sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break;
--        case 'w': {
--          z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
--          break;
--        }
--        case 'Y': {
--          sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]);
--          break;
--        }
--        default:   z[j++] = '%'; break;
--      }
--    }
+ 
+   /* Create a cursor to hold the database open
+   */
+@@ -105862,7 +120018,7 @@
+   if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
+     rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
+     if( rc!=SQLITE_OK ){
+-      sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
++      sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc));
+       goto initone_error_out;
+     }
+     openedTransaction = 1;
+@@ -105962,8 +120118,8 @@
+   {
+     char *zSql;
+     zSql = sqlite3MPrintf(db, 
+-        "SELECT name, rootpage, sql FROM '%q'.%s ORDER BY rowid",
+-        db->aDb[iDb].zName, zMasterName);
++        "SELECT name, rootpage, sql FROM \"%w\".%s ORDER BY rowid",
++        db->aDb[iDb].zDbSName, zMasterName);
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+     {
+       sqlite3_xauth xAuth;
+@@ -105984,11 +120140,11 @@
+ #endif
+   }
+   if( db->mallocFailed ){
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+     sqlite3ResetAllSchemasOfConnection(db);
+   }
+-  if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
+-    /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
++  if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){
++    /* Black magic: If the SQLITE_WriteSchema flag is set, then consider
+     ** the schema loaded, even if errors occurred. In this situation the 
+     ** current sqlite3_prepare() operation will fail, but the following one
+     ** will attempt to compile the supplied statement against whatever subset
+@@ -106012,7 +120168,7 @@
+ 
+ error_out:
+   if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+-    db->mallocFailed = 1;
++    sqlite3OomFault(db);
+   }
+   return rc;
+ }
+@@ -106110,7 +120266,7 @@
+     if( !sqlite3BtreeIsInReadTrans(pBt) ){
+       rc = sqlite3BtreeBeginTrans(pBt, 0);
+       if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+-        db->mallocFailed = 1;
++        sqlite3OomFault(db);
+       }
+       if( rc!=SQLITE_OK ) return;
+       openedTransaction = 1;
+@@ -106173,6 +120329,11 @@
+     sqlite3 *db = pParse->db;
+     sqlite3DbFree(db, pParse->aLabel);
+     sqlite3ExprListDelete(db, pParse->pConstExpr);
++    if( db ){
++      assert( db->lookaside.bDisable >= pParse->disableLookaside );
++      db->lookaside.bDisable -= pParse->disableLookaside;
++    }
++    pParse->disableLookaside = 0;
+   }
+ }
+ 
+@@ -106183,27 +120344,31 @@
+   sqlite3 *db,              /* Database handle. */
+   const char *zSql,         /* UTF-8 encoded SQL statement. */
+   int nBytes,               /* Length of zSql in bytes. */
+-  int saveSqlFlag,          /* True to copy SQL text into the sqlite3_stmt */
++  u32 prepFlags,            /* Zero or more SQLITE_PREPARE_* flags */
+   Vdbe *pReprepare,         /* VM being reprepared */
+   sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
+   const char **pzTail       /* OUT: End of parsed string */
+ ){
+-  Parse *pParse;            /* Parsing context */
+   char *zErrMsg = 0;        /* Error message */
+   int rc = SQLITE_OK;       /* Result code */
+   int i;                    /* Loop counter */
++  Parse sParse;             /* Parsing context */
+ 
+-  /* Allocate the parsing context */
+-  pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
+-  if( pParse==0 ){
+-    rc = SQLITE_NOMEM;
+-    goto end_prepare;
 -  }
--  z[j] = 0;
--  sqlite3_result_text(context, z, -1,
--                      z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
--}
--
--/*
--** current_time()
--**
--** This function returns the same value as time('now').
--*/
--static void ctimeFunc(
--  sqlite3_context *context,
--  int NotUsed,
--  sqlite3_value **NotUsed2
--){
--  UNUSED_PARAMETER2(NotUsed, NotUsed2);
--  timeFunc(context, 0, 0);
--}
-+SQLITE_PRIVATE const Token sqlite3IntTokens[] = {
-+   { "0", 1 },
-+   { "1", 1 }
-+};
+-  pParse->pReprepare = pReprepare;
++  memset(&sParse, 0, PARSE_HDR_SZ);
++  memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
++  sParse.pReprepare = pReprepare;
+   assert( ppStmt && *ppStmt==0 );
+-  assert( !db->mallocFailed );
++  /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
+   assert( sqlite3_mutex_held(db->mutex) );
+ 
++  /* For a long-term use prepared statement avoid the use of
++  ** lookaside memory.
++  */
++  if( prepFlags & SQLITE_PREPARE_PERSISTENT ){
++    sParse.disableLookaside++;
++    db->lookaside.bDisable++;
++  }
++
+   /* Check to verify that it is possible to get a read lock on all
+   ** database schemas.  The inability to get a read lock indicates that
+   ** some other database connection is holding a write-lock, which in
+@@ -106233,9 +120398,9 @@
+       assert( sqlite3BtreeHoldsMutex(pBt) );
+       rc = sqlite3BtreeSchemaLocked(pBt);
+       if( rc ){
+-        const char *zDb = db->aDb[i].zName;
++        const char *zDb = db->aDb[i].zDbSName;
+         sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
+-        testcase( db->flags & SQLITE_ReadUncommitted );
++        testcase( db->flags & SQLITE_ReadUncommit );
+         goto end_prepare;
+       }
+     }
+@@ -106243,8 +120408,7 @@
  
--/*
--** current_date()
--**
--** This function returns the same value as date('now').
--*/
--static void cdateFunc(
--  sqlite3_context *context,
--  int NotUsed,
--  sqlite3_value **NotUsed2
--){
--  UNUSED_PARAMETER2(NotUsed, NotUsed2);
--  dateFunc(context, 0, 0);
--}
+   sqlite3VtabUnlockList(db);
  
- /*
--** current_timestamp()
-+** The value of the "pending" byte must be 0x40000000 (1 byte past the
-+** 1-gibabyte boundary) in a compatible database.  SQLite never uses
-+** the database page that contains the pending byte.  It never attempts
-+** to read or write that page.  The pending byte page is set assign
-+** for use by the VFS layers as space for managing file locks.
- **
--** This function returns the same value as datetime('now').
--*/
--static void ctimestampFunc(
--  sqlite3_context *context,
--  int NotUsed,
--  sqlite3_value **NotUsed2
--){
--  UNUSED_PARAMETER2(NotUsed, NotUsed2);
--  datetimeFunc(context, 0, 0);
--}
--#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */
--
--#ifdef SQLITE_OMIT_DATETIME_FUNCS
--/*
--** If the library is compiled to omit the full-scale date and time
--** handling (to get a smaller binary), the following minimal version
--** of the functions current_time(), current_date() and current_timestamp()
--** are included instead. This is to support column declarations that
--** include "DEFAULT CURRENT_TIME" etc.
-+** During testing, it is often desirable to move the pending byte to
-+** a different position in the file.  This allows code that has to
-+** deal with the pending byte to run on files that are much smaller
-+** than 1 GiB.  The sqlite3_test_control() interface can be used to
-+** move the pending byte.
- **
--** This function uses the C-library functions time(), gmtime()
--** and strftime(). The format string to pass to strftime() is supplied
--** as the user-data for the function.
-+** IMPORTANT:  Changing the pending byte to any value other than
-+** 0x40000000 results in an incompatible database file format!
-+** Changing the pending byte during operation will result in undefined
-+** and incorrect behavior.
- */
--static void currentTimeFunc(
--  sqlite3_context *context,
--  int argc,
--  sqlite3_value **argv
--){
--  time_t t;
--  char *zFormat = (char *)sqlite3_user_data(context);
--  sqlite3 *db;
--  sqlite3_int64 iT;
--  struct tm *pTm;
--  struct tm sNow;
--  char zBuf[20];
--
--  UNUSED_PARAMETER(argc);
--  UNUSED_PARAMETER(argv);
--
--  iT = sqlite3StmtCurrentTime(context);
--  if( iT<=0 ) return;
--  t = iT/1000 - 10000*(sqlite3_int64)21086676;
--#if HAVE_GMTIME_R
--  pTm = gmtime_r(&t, &sNow);
--#else
--  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
--  pTm = gmtime(&t);
--  if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
--  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
--#endif
--  if( pTm ){
--    strftime(zBuf, 20, zFormat, &sNow);
--    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+-  pParse->db = db;
+-  pParse->nQueryLoop = 0;  /* Logarithmic, so 0 really means 1 */
++  sParse.db = db;
+   if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
+     char *zSqlCopy;
+     int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
+@@ -106257,64 +120421,60 @@
+     }
+     zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
+     if( zSqlCopy ){
+-      sqlite3RunParser(pParse, zSqlCopy, &zErrMsg);
++      sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
++      sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
+       sqlite3DbFree(db, zSqlCopy);
+-      pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
+     }else{
+-      pParse->zTail = &zSql[nBytes];
++      sParse.zTail = &zSql[nBytes];
+     }
+   }else{
+-    sqlite3RunParser(pParse, zSql, &zErrMsg);
++    sqlite3RunParser(&sParse, zSql, &zErrMsg);
+   }
+-  assert( 0==pParse->nQueryLoop );
++  assert( 0==sParse.nQueryLoop );
+ 
+-  if( db->mallocFailed ){
+-    pParse->rc = SQLITE_NOMEM;
 -  }
--}
-+#ifndef SQLITE_OMIT_WSD
-+SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
+-  if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
+-  if( pParse->checkSchema ){
+-    schemaIsValid(pParse);
++  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
++  if( sParse.checkSchema ){
++    schemaIsValid(&sParse);
+   }
+   if( db->mallocFailed ){
+-    pParse->rc = SQLITE_NOMEM;
++    sParse.rc = SQLITE_NOMEM_BKPT;
+   }
+   if( pzTail ){
+-    *pzTail = pParse->zTail;
++    *pzTail = sParse.zTail;
+   }
+-  rc = pParse->rc;
++  rc = sParse.rc;
+ 
+ #ifndef SQLITE_OMIT_EXPLAIN
+-  if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){
++  if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
+     static const char * const azColName[] = {
+        "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
+        "selectid", "order", "from", "detail"
+     };
+     int iFirst, mx;
+-    if( pParse->explain==2 ){
+-      sqlite3VdbeSetNumCols(pParse->pVdbe, 4);
++    if( sParse.explain==2 ){
++      sqlite3VdbeSetNumCols(sParse.pVdbe, 4);
+       iFirst = 8;
+       mx = 12;
+     }else{
+-      sqlite3VdbeSetNumCols(pParse->pVdbe, 8);
++      sqlite3VdbeSetNumCols(sParse.pVdbe, 8);
+       iFirst = 0;
+       mx = 8;
+     }
+     for(i=iFirst; i<mx; i++){
+-      sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME,
++      sqlite3VdbeSetColName(sParse.pVdbe, i-iFirst, COLNAME_NAME,
+                             azColName[i], SQLITE_STATIC);
+     }
+   }
  #endif
  
- /*
--** This function registered all of the above C functions as SQL
--** functions.  This should be the only routine in this file with
--** external linkage.
-+** Properties of opcodes.  The OPFLG_INITIALIZER macro is
-+** created by mkopcodeh.awk during compilation.  Data is obtained
-+** from the comments following the "case OP_xxxx:" statements in
-+** the vdbe.c file.  
+   if( db->init.busy==0 ){
+-    Vdbe *pVdbe = pParse->pVdbe;
+-    sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
++    sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags);
+   }
+-  if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
+-    sqlite3VdbeFinalize(pParse->pVdbe);
++  if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
++    sqlite3VdbeFinalize(sParse.pVdbe);
+     assert(!(*ppStmt));
+   }else{
+-    *ppStmt = (sqlite3_stmt*)pParse->pVdbe;
++    *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
+   }
+ 
+   if( zErrMsg ){
+@@ -106325,16 +120485,15 @@
+   }
+ 
+   /* Delete any TriggerPrg structures allocated while parsing this statement. */
+-  while( pParse->pTriggerPrg ){
+-    TriggerPrg *pT = pParse->pTriggerPrg;
+-    pParse->pTriggerPrg = pT->pNext;
++  while( sParse.pTriggerPrg ){
++    TriggerPrg *pT = sParse.pTriggerPrg;
++    sParse.pTriggerPrg = pT->pNext;
+     sqlite3DbFree(db, pT);
+   }
+ 
+ end_prepare:
+ 
+-  sqlite3ParserReset(pParse);
+-  sqlite3StackFree(db, pParse);
++  sqlite3ParserReset(&sParse);
+   rc = sqlite3ApiExit(db, rc);
+   assert( (rc&db->errMask)==rc );
+   return rc;
+@@ -106343,7 +120502,7 @@
+   sqlite3 *db,              /* Database handle. */
+   const char *zSql,         /* UTF-8 encoded SQL statement. */
+   int nBytes,               /* Length of zSql in bytes. */
+-  int saveSqlFlag,          /* True to copy SQL text into the sqlite3_stmt */
++  u32 prepFlags,            /* Zero or more SQLITE_PREPARE_* flags */
+   Vdbe *pOld,               /* VM being reprepared */
+   sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
+   const char **pzTail       /* OUT: End of parsed string */
+@@ -106359,10 +120518,10 @@
+   }
+   sqlite3_mutex_enter(db->mutex);
+   sqlite3BtreeEnterAll(db);
+-  rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
++  rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
+   if( rc==SQLITE_SCHEMA ){
+     sqlite3_finalize(*ppStmt);
+-    rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
++    rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
+   }
+   sqlite3BtreeLeaveAll(db);
+   sqlite3_mutex_leave(db->mutex);
+@@ -106383,16 +120542,18 @@
+   sqlite3_stmt *pNew;
+   const char *zSql;
+   sqlite3 *db;
++  u8 prepFlags;
+ 
+   assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) );
+   zSql = sqlite3_sql((sqlite3_stmt *)p);
+   assert( zSql!=0 );  /* Reprepare only called for prepare_v2() statements */
+   db = sqlite3VdbeDb(p);
+   assert( sqlite3_mutex_held(db->mutex) );
+-  rc = sqlite3LockAndPrepare(db, zSql, -1, 0, p, &pNew, 0);
++  prepFlags = sqlite3VdbePrepareFlags(p);
++  rc = sqlite3LockAndPrepare(db, zSql, -1, prepFlags, p, &pNew, 0);
+   if( rc ){
+     if( rc==SQLITE_NOMEM ){
+-      db->mallocFailed = 1;
++      sqlite3OomFault(db);
+     }
+     assert( pNew==0 );
+     return rc;
+@@ -106415,7 +120576,7 @@
+ ** and the statement is automatically recompiled if an schema change
+ ** occurs.
  */
--SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
--  static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
--#ifndef SQLITE_OMIT_DATETIME_FUNCS
--    FUNCTION(julianday,        -1, 0, 0, juliandayFunc ),
--    FUNCTION(date,             -1, 0, 0, dateFunc      ),
--    FUNCTION(time,             -1, 0, 0, timeFunc      ),
--    FUNCTION(datetime,         -1, 0, 0, datetimeFunc  ),
--    FUNCTION(strftime,         -1, 0, 0, strftimeFunc  ),
--    FUNCTION(current_time,      0, 0, 0, ctimeFunc     ),
--    FUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
--    FUNCTION(current_date,      0, 0, 0, cdateFunc     ),
--#else
--    STR_FUNCTION(current_time,      0, "%H:%M:%S",          0, currentTimeFunc),
--    STR_FUNCTION(current_date,      0, "%Y-%m-%d",          0, currentTimeFunc),
--    STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
--#endif
--  };
--  int i;
--  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
--  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs);
--
--  for(i=0; i<ArraySize(aDateTimeFuncs); i++){
--    sqlite3FuncDefInsert(pHash, &aFunc[i]);
--  }
--}
-+SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
+-SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
++SQLITE_API int sqlite3_prepare(
+   sqlite3 *db,              /* Database handle. */
+   const char *zSql,         /* UTF-8 encoded SQL statement. */
+   int nBytes,               /* Length of zSql in bytes. */
+@@ -106427,7 +120588,7 @@
+   assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
+   return rc;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
++SQLITE_API int sqlite3_prepare_v2(
+   sqlite3 *db,              /* Database handle. */
+   const char *zSql,         /* UTF-8 encoded SQL statement. */
+   int nBytes,               /* Length of zSql in bytes. */
+@@ -106435,8 +120596,36 @@
+   const char **pzTail       /* OUT: End of parsed string */
+ ){
+   int rc;
+-  rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,0,ppStmt,pzTail);
+-  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
++  /* EVIDENCE-OF: R-37923-12173 The sqlite3_prepare_v2() interface works
++  ** exactly the same as sqlite3_prepare_v3() with a zero prepFlags
++  ** parameter.
++  **
++  ** Proof in that the 5th parameter to sqlite3LockAndPrepare is 0 */
++  rc = sqlite3LockAndPrepare(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,0,
++                             ppStmt,pzTail);
++  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );
++  return rc;
++}
++SQLITE_API int sqlite3_prepare_v3(
++  sqlite3 *db,              /* Database handle. */
++  const char *zSql,         /* UTF-8 encoded SQL statement. */
++  int nBytes,               /* Length of zSql in bytes. */
++  unsigned int prepFlags,   /* Zero or more SQLITE_PREPARE_* flags */
++  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
++  const char **pzTail       /* OUT: End of parsed string */
++){
++  int rc;
++  /* EVIDENCE-OF: R-56861-42673 sqlite3_prepare_v3() differs from
++  ** sqlite3_prepare_v2() only in having the extra prepFlags parameter,
++  ** which is a bit array consisting of zero or more of the
++  ** SQLITE_PREPARE_* flags.
++  **
++  ** Proof by comparison to the implementation of sqlite3_prepare_v2()
++  ** directly above. */
++  rc = sqlite3LockAndPrepare(db,zSql,nBytes,
++                 SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK),
++                 0,ppStmt,pzTail);
++  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );
+   return rc;
+ }
+ 
+@@ -106449,7 +120638,7 @@
+   sqlite3 *db,              /* Database handle. */ 
+   const void *zSql,         /* UTF-16 encoded SQL statement. */
+   int nBytes,               /* Length of zSql in bytes. */
+-  int saveSqlFlag,          /* True to save SQL text into the sqlite3_stmt */
++  u32 prepFlags,            /* Zero or more SQLITE_PREPARE_* flags */
+   sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
+   const void **pzTail       /* OUT: End of parsed string */
+ ){
+@@ -106477,7 +120666,7 @@
+   sqlite3_mutex_enter(db->mutex);
+   zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
+   if( zSql8 ){
+-    rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8);
++    rc = sqlite3LockAndPrepare(db, zSql8, -1, prepFlags, 0, ppStmt, &zTail8);
+   }
+ 
+   if( zTail8 && pzTail ){
+@@ -106503,7 +120692,7 @@
+ ** and the statement is automatically recompiled if an schema change
+ ** occurs.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
++SQLITE_API int sqlite3_prepare16(
+   sqlite3 *db,              /* Database handle. */ 
+   const void *zSql,         /* UTF-16 encoded SQL statement. */
+   int nBytes,               /* Length of zSql in bytes. */
+@@ -106515,15 +120704,30 @@
+   assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
+   return rc;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
++SQLITE_API int sqlite3_prepare16_v2(
++  sqlite3 *db,              /* Database handle. */ 
++  const void *zSql,         /* UTF-16 encoded SQL statement. */
++  int nBytes,               /* Length of zSql in bytes. */
++  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
++  const void **pzTail       /* OUT: End of parsed string */
++){
++  int rc;
++  rc = sqlite3Prepare16(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,ppStmt,pzTail);
++  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
++  return rc;
++}
++SQLITE_API int sqlite3_prepare16_v3(
+   sqlite3 *db,              /* Database handle. */ 
+   const void *zSql,         /* UTF-16 encoded SQL statement. */
+   int nBytes,               /* Length of zSql in bytes. */
++  unsigned int prepFlags,   /* Zero or more SQLITE_PREPARE_* flags */
+   sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
+   const void **pzTail       /* OUT: End of parsed string */
+ ){
+   int rc;
+-  rc = sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail);
++  rc = sqlite3Prepare16(db,zSql,nBytes,
++         SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK),
++         ppStmt,pzTail);
+   assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
+   return rc;
+ }
+@@ -106546,6 +120750,7 @@
+ ** This file contains C code routines that are called by the parser
+ ** to handle SELECT statements in SQLite.
+ */
++/* #include "sqliteInt.h" */
  
--/************** End of date.c ************************************************/
--/************** Begin file os.c **********************************************/
-+/************** End of global.c **********************************************/
-+/************** Begin file ctime.c *******************************************/
  /*
--** 2005 November 29
-+** 2010 February 23
- **
- ** The author disclaims copyright to this source code.  In place of
- ** a legal notice, here is a blessing:
-@@ -16474,157 +17692,2571 @@
- **    May you find forgiveness for yourself and forgive others.
- **    May you share freely, never taking more than you give.
- **
--******************************************************************************
-+*************************************************************************
- **
--** This file contains OS interface code that is common to all
--** architectures.
-+** This file implements routines used to report what compile-time options
-+** SQLite was built with.
+ ** Trace output macros
+@@ -106554,7 +120759,8 @@
+ /***/ int sqlite3SelectTrace = 0;
+ # define SELECTTRACE(K,P,S,X)  \
+   if(sqlite3SelectTrace&(K))   \
+-    sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",(S)->zSelName,(S)),\
++    sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",\
++        (S)->zSelName,(S)),\
+     sqlite3DebugPrintf X
+ #else
+ # define SELECTTRACE(K,P,S,X)
+@@ -106586,7 +120792,9 @@
+   int regReturn;        /* Register holding block-output return address */
+   int labelBkOut;       /* Start label for the block-output subroutine */
+   int addrSortIndex;    /* Address of the OP_SorterOpen or OP_OpenEphemeral */
++  int labelDone;        /* Jump here when done, ex: LIMIT reached */
+   u8 sortFlags;         /* Zero or more SORTFLAG_* bits */
++  u8 bOrderedInnerLoop; /* ORDER BY correctly sorts the inner loop */
+ };
+ #define SORTFLAG_UseSorter  0x01   /* Use SorterOpen instead of OpenEphemeral */
+ 
+@@ -106605,8 +120813,8 @@
+     sqlite3ExprListDelete(db, p->pOrderBy);
+     sqlite3ExprDelete(db, p->pLimit);
+     sqlite3ExprDelete(db, p->pOffset);
+-    sqlite3WithDelete(db, p->pWith);
+-    if( bFree ) sqlite3DbFree(db, p);
++    if( p->pWith ) sqlite3WithDelete(db, p->pWith);
++    if( bFree ) sqlite3DbFreeNN(db, p);
+     p = pPrior;
+     bFree = 1;
+   }
+@@ -106618,7 +120826,7 @@
+ SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
+   pDest->eDest = (u8)eDest;
+   pDest->iSDParm = iParm;
+-  pDest->affSdst = 0;
++  pDest->zAffSdst = 0;
+   pDest->iSdst = 0;
+   pDest->nSdst = 0;
+ }
+@@ -106636,38 +120844,45 @@
+   ExprList *pGroupBy,   /* the GROUP BY clause */
+   Expr *pHaving,        /* the HAVING clause */
+   ExprList *pOrderBy,   /* the ORDER BY clause */
+-  u16 selFlags,         /* Flag parameters, such as SF_Distinct */
++  u32 selFlags,         /* Flag parameters, such as SF_Distinct */
+   Expr *pLimit,         /* LIMIT value.  NULL means not used */
+   Expr *pOffset         /* OFFSET value.  NULL means no offset */
+ ){
+   Select *pNew;
+   Select standin;
+-  sqlite3 *db = pParse->db;
+-  pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
++  pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) );
+   if( pNew==0 ){
+-    assert( db->mallocFailed );
++    assert( pParse->db->mallocFailed );
+     pNew = &standin;
+-    memset(pNew, 0, sizeof(*pNew));
+   }
+   if( pEList==0 ){
+-    pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0));
++    pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0));
+   }
+   pNew->pEList = pEList;
+-  if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
++  pNew->op = TK_SELECT;
++  pNew->selFlags = selFlags;
++  pNew->iLimit = 0;
++  pNew->iOffset = 0;
++#if SELECTTRACE_ENABLED
++  pNew->zSelName[0] = 0;
++#endif
++  pNew->addrOpenEphm[0] = -1;
++  pNew->addrOpenEphm[1] = -1;
++  pNew->nSelectRow = 0;
++  if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc));
+   pNew->pSrc = pSrc;
+   pNew->pWhere = pWhere;
+   pNew->pGroupBy = pGroupBy;
+   pNew->pHaving = pHaving;
+   pNew->pOrderBy = pOrderBy;
+-  pNew->selFlags = selFlags;
+-  pNew->op = TK_SELECT;
++  pNew->pPrior = 0;
++  pNew->pNext = 0;
+   pNew->pLimit = pLimit;
+   pNew->pOffset = pOffset;
+-  assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
+-  pNew->addrOpenEphm[0] = -1;
+-  pNew->addrOpenEphm[1] = -1;
+-  if( db->mallocFailed ) {
+-    clearSelect(db, pNew, pNew!=&standin);
++  pNew->pWith = 0;
++  assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || pParse->db->mallocFailed!=0 );
++  if( pParse->db->mallocFailed ) {
++    clearSelect(pParse->db, pNew, pNew!=&standin);
+     pNew = 0;
+   }else{
+     assert( pNew->pSrc!=0 || pParse->nErr>0 );
+@@ -106692,7 +120907,7 @@
+ ** Delete the given Select structure and all of its substructures.
  */
--#define _SQLITE_OS_C_ 1
--#undef _SQLITE_OS_C_
+ SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
+-  clearSelect(db, p, 1);
++  if( p ) clearSelect(db, p, 1);
+ }
  
--/*
--** The default SQLite sqlite3_vfs implementations do not allocate
--** memory (actually, os_unix.c allocates a small amount of memory
--** from within OsOpen()), but some third-party implementations may.
--** So we test the effects of a malloc() failing and the sqlite3OsXXX()
--** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
--**
--** The following functions are instrumented for malloc() failure 
--** testing:
--**
--**     sqlite3OsRead()
--**     sqlite3OsWrite()
--**     sqlite3OsSync()
--**     sqlite3OsFileSize()
--**     sqlite3OsLock()
--**     sqlite3OsCheckReservedLock()
--**     sqlite3OsFileControl()
--**     sqlite3OsShmMap()
--**     sqlite3OsOpen()
--**     sqlite3OsDelete()
--**     sqlite3OsAccess()
--**     sqlite3OsFullPathname()
--**
--*/
--#if defined(SQLITE_TEST)
--SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1;
--  #define DO_OS_MALLOC_TEST(x)                                       \
--  if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) {  \
--    void *pTstAlloc = sqlite3Malloc(10);                             \
--    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
--    sqlite3_free(pTstAlloc);                                         \
--  }
--#else
--  #define DO_OS_MALLOC_TEST(x)
--#endif
-+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+ /*
+@@ -106856,7 +121071,7 @@
+   pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft);
+   pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);
+ 
+-  pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0);
++  pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
+   if( pEq && isOuterJoin ){
+     ExprSetProperty(pEq, EP_FromJoin);
+     assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
+@@ -106898,6 +121113,12 @@
+     assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
+     ExprSetVVAProperty(p, EP_NoReduce);
+     p->iRightJoinTable = (i16)iTable;
++    if( p->op==TK_FUNCTION && p->x.pList ){
++      int i;
++      for(i=0; i<p->x.pList->nExpr; i++){
++        setJoinExpr(p->x.pList->a[i].pExpr, iTable);
++      }
++    }
+     setJoinExpr(p->pLeft, iTable);
+     p = p->pRight;
+   } 
+@@ -106932,12 +121153,12 @@
+     int isOuter;
+ 
+     if( NEVER(pLeftTab==0 || pRightTab==0) ) continue;
+-    isOuter = (pRight->jointype & JT_OUTER)!=0;
++    isOuter = (pRight->fg.jointype & JT_OUTER)!=0;
+ 
+     /* When the NATURAL keyword is present, add WHERE clause terms for
+     ** every column that the two tables have in common.
+     */
+-    if( pRight->jointype & JT_NATURAL ){
++    if( pRight->fg.jointype & JT_NATURAL ){
+       if( pRight->pOn || pRight->pUsing ){
+         sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
+            "an ON or USING clause", 0);
+@@ -107022,6 +121243,7 @@
+   SortCtx *pSort,        /* Information about the ORDER BY clause */
+   Select *pSelect,       /* The whole SELECT statement */
+   int regData,           /* First register holding data to be sorted */
++  int regOrigData,       /* First register holding data before packing */
+   int nData,             /* Number of elements in the data array */
+   int nPrefixReg         /* No. of reg prior to regData available for use */
+ ){
+@@ -107033,8 +121255,10 @@
+   int regRecord = ++pParse->nMem;                  /* Assembled sorter record */
+   int nOBSat = pSort->nOBSat;                      /* ORDER BY terms to skip */
+   int op;                            /* Opcode to add sorter record to sorter */
++  int iLimit;                        /* LIMIT counter */
+ 
+   assert( bSeq==0 || bSeq==1 );
++  assert( nData==1 || regData==regOrigData || regOrigData==0 );
+   if( nPrefixReg ){
+     assert( nPrefixReg==nExpr+bSeq );
+     regBase = regData - nExpr - bSeq;
+@@ -107042,14 +121266,17 @@
+     regBase = pParse->nMem + 1;
+     pParse->nMem += nBase;
+   }
+-  sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, SQLITE_ECEL_DUP);
++  assert( pSelect->iOffset==0 || pSelect->iLimit!=0 );
++  iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
++  pSort->labelDone = sqlite3VdbeMakeLabel(v);
++  sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
++                          SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0));
+   if( bSeq ){
+     sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
+   }
+-  if( nPrefixReg==0 ){
++  if( nPrefixReg==0 && nData>0 ){
+     sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);
+   }
+-
+   sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
+   if( nOBSat>0 ){
+     int regPrevKey;   /* The first nOBSat columns of the previous row */
+@@ -107084,6 +121311,10 @@
+     pSort->regReturn = ++pParse->nMem;
+     sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
+     sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
++    if( iLimit ){
++      sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone);
++      VdbeCoverage(v);
++    }
+     sqlite3VdbeJumpHere(v, addrFirst);
+     sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat);
+     sqlite3VdbeJumpHere(v, addrJmp);
+@@ -107093,18 +121324,34 @@
+   }else{
+     op = OP_IdxInsert;
+   }
+-  sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord);
+-  if( pSelect->iLimit ){
++  sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord,
++                       regBase+nOBSat, nBase-nOBSat);
++  if( iLimit ){
+     int addr;
+-    int iLimit;
+-    if( pSelect->iOffset ){
+-      iLimit = pSelect->iOffset+1;
+-    }else{
+-      iLimit = pSelect->iLimit;
+-    }
+-    addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, -1); VdbeCoverage(v);
++    int r1 = 0;
++    /* Fill the sorter until it contains LIMIT+OFFSET entries.  (The iLimit
++    ** register is initialized with value of LIMIT+OFFSET.)  After the sorter
++    ** fills up, delete the least entry in the sorter after each insert.
++    ** Thus we never hold more than the LIMIT+OFFSET rows in memory at once */
++    addr = sqlite3VdbeAddOp1(v, OP_IfNotZero, iLimit); VdbeCoverage(v);
+     sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
++    if( pSort->bOrderedInnerLoop ){
++      r1 = ++pParse->nMem;
++      sqlite3VdbeAddOp3(v, OP_Column, pSort->iECursor, nExpr, r1);
++      VdbeComment((v, "seq"));
++    }
+     sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor);
++    if( pSort->bOrderedInnerLoop ){
++      /* If the inner loop is driven by an index such that values from
++      ** the same iteration of the inner loop are in sorted order, then
++      ** immediately jump to the next iteration of an inner loop if the
++      ** entry from the current iteration does not fit into the top
++      ** LIMIT+OFFSET entries of the sorter. */
++      int iBrk = sqlite3VdbeCurrentAddr(v) + 2;
++      sqlite3VdbeAddOp3(v, OP_Eq, regBase+nExpr, iBrk, r1);
++      sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
++      VdbeCoverage(v);
++    }
+     sqlite3VdbeJumpHere(v, addr);
+   }
+ }
+@@ -107118,11 +121365,8 @@
+   int iContinue     /* Jump here to skip the current record */
+ ){
+   if( iOffset>0 ){
+-    int addr;
+-    addr = sqlite3VdbeAddOp3(v, OP_IfNeg, iOffset, 0, -1); VdbeCoverage(v);
+-    sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
+-    VdbeComment((v, "skip OFFSET records"));
+-    sqlite3VdbeJumpHere(v, addr);
++    sqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v);
++    VdbeComment((v, "OFFSET"));
+   }
+ }
+ 
+@@ -107149,34 +121393,11 @@
+   r1 = sqlite3GetTempReg(pParse);
+   sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v);
+   sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
+-  sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1);
++  sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, iMem, N);
++  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+   sqlite3ReleaseTempReg(pParse, r1);
+ }
  
+-#ifndef SQLITE_OMIT_SUBQUERY
 -/*
--** The following routines are convenience wrappers around methods
--** of the sqlite3_file object.  This is mostly just syntactic sugar. All
--** of this would be completely automatic if SQLite were coded using
--** C++ instead of plain old C.
+-** Generate an error message when a SELECT is used within a subexpression
+-** (example:  "a IN (SELECT * FROM table)") but it has more than 1 result
+-** column.  We do this in a subroutine because the error used to occur
+-** in multiple places.  (The error only occurs in one place now, but we
+-** retain the subroutine to minimize code disruption.)
 -*/
--SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file *pId){
--  int rc = SQLITE_OK;
--  if( pId->pMethods ){
--    rc = pId->pMethods->xClose(pId);
--    pId->pMethods = 0;
+-static int checkForMultiColumnSelectError(
+-  Parse *pParse,       /* Parse context. */
+-  SelectDest *pDest,   /* Destination of SELECT results */
+-  int nExpr            /* Number of result columns returned by SELECT */
+-){
+-  int eDest = pDest->eDest;
+-  if( nExpr>1 && (eDest==SRT_Mem || eDest==SRT_Set) ){
+-    sqlite3ErrorMsg(pParse, "only a single result allowed for "
+-       "a SELECT that is part of an expression");
+-    return 1;
+-  }else{
+-    return 0;
 -  }
--  return rc;
--}
--SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
--  DO_OS_MALLOC_TEST(id);
--  return id->pMethods->xRead(id, pBuf, amt, offset);
--}
--SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
--  DO_OS_MALLOC_TEST(id);
--  return id->pMethods->xWrite(id, pBuf, amt, offset);
--}
--SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){
--  return id->pMethods->xTruncate(id, size);
--}
--SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){
--  DO_OS_MALLOC_TEST(id);
--  return id->pMethods->xSync(id, flags);
--}
--SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
--  DO_OS_MALLOC_TEST(id);
--  return id->pMethods->xFileSize(id, pSize);
--}
--SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){
--  DO_OS_MALLOC_TEST(id);
--  return id->pMethods->xLock(id, lockType);
--}
--SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){
--  return id->pMethods->xUnlock(id, lockType);
--}
--SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
--  DO_OS_MALLOC_TEST(id);
--  return id->pMethods->xCheckReservedLock(id, pResOut);
 -}
- 
+-#endif
+-
  /*
--** Use sqlite3OsFileControl() when we are doing something that might fail
--** and we need to know about the failures.  Use sqlite3OsFileControlHint()
--** when simply tossing information over the wall to the VFS and we do not
--** really care if the VFS receives and understands the information since it
--** is only a hint and can be safely ignored.  The sqlite3OsFileControlHint()
--** routine has no return value since the return value would be meaningless.
-+** An array of names of all compile-time options.  This array should 
-+** be sorted A-Z.
-+**
-+** This array looks large, but in a typical installation actually uses
-+** only a handful of compile-time options, so most times this array is usually
-+** rather short and uses little memory space.
+ ** This routine generates the code for the inside of the inner loop
+ ** of a SELECT.
+@@ -107184,7 +121405,7 @@
+ ** If srcTab is negative, then the pEList expressions
+ ** are evaluated in order to get the data for this row.  If srcTab is
+ ** zero or more, then data is pulled from srcTab and pEList is used only 
+-** to get number columns and the datatype for each column.
++** to get the number of columns and the collation sequence for each column.
  */
--SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
--#ifdef SQLITE_TEST
--  if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
--    /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
--    ** is using a regular VFS, it is called after the corresponding 
--    ** transaction has been committed. Injecting a fault at this point 
--    ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
--    ** but the transaction is committed anyway.
--    **
--    ** The core must call OsFileControl() though, not OsFileControlHint(),
--    ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
--    ** means the commit really has failed and an error should be returned
--    ** to the user.  */
--    DO_OS_MALLOC_TEST(id);
--  }
--#endif
--  return id->pMethods->xFileControl(id, op, pArg);
--}
--SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
--  (void)id->pMethods->xFileControl(id, op, pArg);
--}
-+static const char * const azCompileOpt[] = {
+ static void selectInnerLoop(
+   Parse *pParse,          /* The parser context */
+@@ -107199,13 +121420,20 @@
+ ){
+   Vdbe *v = pParse->pVdbe;
+   int i;
+-  int hasDistinct;        /* True if the DISTINCT keyword is present */
+-  int regResult;              /* Start of memory holding result set */
++  int hasDistinct;            /* True if the DISTINCT keyword is present */
+   int eDest = pDest->eDest;   /* How to dispose of results */
+   int iParm = pDest->iSDParm; /* First argument to disposal method */
+   int nResultCol;             /* Number of result columns */
+   int nPrefixReg = 0;         /* Number of extra registers before regResult */
+ 
++  /* Usually, regResult is the first cell in an array of memory cells
++  ** containing the current result row. In this case regOrig is set to the
++  ** same value. However, if the results are being sent to the sorter, the
++  ** values for any expressions that are also part of the sort-key are omitted
++  ** from this array. In this case regOrig is set to zero.  */
++  int regResult;              /* Start of memory holding current results */
++  int regOrig;                /* Start of memory holding full result (or 0) */
++
+   assert( v );
+   assert( pEList!=0 );
+   hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
+@@ -107236,7 +121464,7 @@
+     pParse->nMem += nResultCol;
+   }
+   pDest->nSdst = nResultCol;
+-  regResult = pDest->iSdst;
++  regOrig = regResult = pDest->iSdst;
+   if( srcTab>=0 ){
+     for(i=0; i<nResultCol; i++){
+       sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
+@@ -107246,8 +121474,31 @@
+     /* If the destination is an EXISTS(...) expression, the actual
+     ** values returned by the SELECT are not required.
+     */
+-    sqlite3ExprCodeExprList(pParse, pEList, regResult,
+-                  (eDest==SRT_Output||eDest==SRT_Coroutine)?SQLITE_ECEL_DUP:0);
++    u8 ecelFlags;
++    if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){
++      ecelFlags = SQLITE_ECEL_DUP;
++    }else{
++      ecelFlags = 0;
++    }
++    if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){
++      /* For each expression in pEList that is a copy of an expression in
++      ** the ORDER BY clause (pSort->pOrderBy), set the associated 
++      ** iOrderByCol value to one more than the index of the ORDER BY 
++      ** expression within the sort-key that pushOntoSorter() will generate.
++      ** This allows the pEList field to be omitted from the sorted record,
++      ** saving space and CPU cycles.  */
++      ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF);
++      for(i=pSort->nOBSat; i<pSort->pOrderBy->nExpr; i++){
++        int j;
++        if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){
++          pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
++        }
++      }
++      regOrig = 0;
++      assert( eDest==SRT_Set || eDest==SRT_Mem 
++           || eDest==SRT_Coroutine || eDest==SRT_Output );
++    }
++    nResultCol = sqlite3ExprCodeExprList(pParse,pEList,regResult,0,ecelFlags);
+   }
  
--SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){
--  int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
--  return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
--}
--SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
--  return id->pMethods->xDeviceCharacteristics(id);
--}
--SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
--  return id->pMethods->xShmLock(id, offset, n, flags);
--}
--SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){
--  id->pMethods->xShmBarrier(id);
--}
--SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
--  return id->pMethods->xShmUnmap(id, deleteFlag);
--}
--SQLITE_PRIVATE int sqlite3OsShmMap(
--  sqlite3_file *id,               /* Database file handle */
--  int iPage,
--  int pgsz,
--  int bExtend,                    /* True to extend file if necessary */
--  void volatile **pp              /* OUT: Pointer to mapping */
--){
--  DO_OS_MALLOC_TEST(id);
--  return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
--}
-+/* These macros are provided to "stringify" the value of the define
-+** for those options in which the value is meaningful. */
-+#define CTIMEOPT_VAL_(opt) #opt
-+#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
+   /* If the DISTINCT keyword was present on the SELECT statement
+@@ -107302,7 +121553,8 @@
  
--#if SQLITE_MAX_MMAP_SIZE>0
--/* The real implementation of xFetch and xUnfetch */
--SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
--  DO_OS_MALLOC_TEST(id);
--  return id->pMethods->xFetch(id, iOff, iAmt, pp);
-+#if SQLITE_32BIT_ROWID
-+  "32BIT_ROWID",
-+#endif
-+#if SQLITE_4_BYTE_ALIGNED_MALLOC
-+  "4_BYTE_ALIGNED_MALLOC",
-+#endif
-+#if SQLITE_CASE_SENSITIVE_LIKE
-+  "CASE_SENSITIVE_LIKE",
-+#endif
-+#if SQLITE_CHECK_PAGES
-+  "CHECK_PAGES",
-+#endif
-+#if SQLITE_COVERAGE_TEST
-+  "COVERAGE_TEST",
-+#endif
-+#if SQLITE_DEBUG
-+  "DEBUG",
-+#endif
-+#if SQLITE_DEFAULT_LOCKING_MODE
-+  "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
-+#endif
-+#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
-+  "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
-+#endif
-+#if SQLITE_DISABLE_DIRSYNC
-+  "DISABLE_DIRSYNC",
-+#endif
-+#if SQLITE_DISABLE_LFS
-+  "DISABLE_LFS",
-+#endif
-+#if SQLITE_ENABLE_API_ARMOR
-+  "ENABLE_API_ARMOR",
-+#endif
-+#if SQLITE_ENABLE_ATOMIC_WRITE
-+  "ENABLE_ATOMIC_WRITE",
-+#endif
-+#if SQLITE_ENABLE_CEROD
-+  "ENABLE_CEROD",
-+#endif
-+#if SQLITE_ENABLE_COLUMN_METADATA
-+  "ENABLE_COLUMN_METADATA",
-+#endif
-+#if SQLITE_ENABLE_DBSTAT_VTAB
-+  "ENABLE_DBSTAT_VTAB",
-+#endif
-+#if SQLITE_ENABLE_EXPENSIVE_ASSERT
-+  "ENABLE_EXPENSIVE_ASSERT",
-+#endif
-+#if SQLITE_ENABLE_FTS1
-+  "ENABLE_FTS1",
-+#endif
-+#if SQLITE_ENABLE_FTS2
-+  "ENABLE_FTS2",
-+#endif
-+#if SQLITE_ENABLE_FTS3
-+  "ENABLE_FTS3",
-+#endif
-+#if SQLITE_ENABLE_FTS3_PARENTHESIS
-+  "ENABLE_FTS3_PARENTHESIS",
-+#endif
-+#if SQLITE_ENABLE_FTS4
-+  "ENABLE_FTS4",
-+#endif
-+#if SQLITE_ENABLE_ICU
-+  "ENABLE_ICU",
-+#endif
-+#if SQLITE_ENABLE_IOTRACE
-+  "ENABLE_IOTRACE",
-+#endif
-+#if SQLITE_ENABLE_LOAD_EXTENSION
-+  "ENABLE_LOAD_EXTENSION",
-+#endif
-+#if SQLITE_ENABLE_LOCKING_STYLE
-+  "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
-+#endif
-+#if SQLITE_ENABLE_MEMORY_MANAGEMENT
-+  "ENABLE_MEMORY_MANAGEMENT",
-+#endif
-+#if SQLITE_ENABLE_MEMSYS3
-+  "ENABLE_MEMSYS3",
-+#endif
-+#if SQLITE_ENABLE_MEMSYS5
-+  "ENABLE_MEMSYS5",
-+#endif
-+#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
-+  "ENABLE_OVERSIZE_CELL_CHECK",
-+#endif
-+#if SQLITE_ENABLE_RTREE
-+  "ENABLE_RTREE",
-+#endif
-+#if defined(SQLITE_ENABLE_STAT4)
-+  "ENABLE_STAT4",
-+#elif defined(SQLITE_ENABLE_STAT3)
-+  "ENABLE_STAT3",
-+#endif
-+#if SQLITE_ENABLE_UNLOCK_NOTIFY
-+  "ENABLE_UNLOCK_NOTIFY",
-+#endif
-+#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
-+  "ENABLE_UPDATE_DELETE_LIMIT",
-+#endif
-+#if SQLITE_HAS_CODEC
-+  "HAS_CODEC",
-+#endif
-+#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
-+  "HAVE_ISNAN",
-+#endif
-+#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
-+  "HOMEGROWN_RECURSIVE_MUTEX",
-+#endif
-+#if SQLITE_IGNORE_AFP_LOCK_ERRORS
-+  "IGNORE_AFP_LOCK_ERRORS",
-+#endif
-+#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS
-+  "IGNORE_FLOCK_LOCK_ERRORS",
-+#endif
-+#ifdef SQLITE_INT64_TYPE
-+  "INT64_TYPE",
-+#endif
-+#if SQLITE_LOCK_TRACE
-+  "LOCK_TRACE",
-+#endif
-+#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc)
-+  "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE),
-+#endif
-+#ifdef SQLITE_MAX_SCHEMA_RETRY
-+  "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
-+#endif
-+#if SQLITE_MEMDEBUG
-+  "MEMDEBUG",
-+#endif
-+#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
-+  "MIXED_ENDIAN_64BIT_FLOAT",
-+#endif
-+#if SQLITE_NO_SYNC
-+  "NO_SYNC",
-+#endif
-+#if SQLITE_OMIT_ALTERTABLE
-+  "OMIT_ALTERTABLE",
-+#endif
-+#if SQLITE_OMIT_ANALYZE
-+  "OMIT_ANALYZE",
-+#endif
-+#if SQLITE_OMIT_ATTACH
-+  "OMIT_ATTACH",
-+#endif
-+#if SQLITE_OMIT_AUTHORIZATION
-+  "OMIT_AUTHORIZATION",
-+#endif
-+#if SQLITE_OMIT_AUTOINCREMENT
-+  "OMIT_AUTOINCREMENT",
-+#endif
-+#if SQLITE_OMIT_AUTOINIT
-+  "OMIT_AUTOINIT",
-+#endif
-+#if SQLITE_OMIT_AUTOMATIC_INDEX
-+  "OMIT_AUTOMATIC_INDEX",
-+#endif
-+#if SQLITE_OMIT_AUTORESET
-+  "OMIT_AUTORESET",
-+#endif
-+#if SQLITE_OMIT_AUTOVACUUM
-+  "OMIT_AUTOVACUUM",
-+#endif
-+#if SQLITE_OMIT_BETWEEN_OPTIMIZATION
-+  "OMIT_BETWEEN_OPTIMIZATION",
-+#endif
-+#if SQLITE_OMIT_BLOB_LITERAL
-+  "OMIT_BLOB_LITERAL",
-+#endif
-+#if SQLITE_OMIT_BTREECOUNT
-+  "OMIT_BTREECOUNT",
-+#endif
-+#if SQLITE_OMIT_BUILTIN_TEST
-+  "OMIT_BUILTIN_TEST",
-+#endif
-+#if SQLITE_OMIT_CAST
-+  "OMIT_CAST",
-+#endif
-+#if SQLITE_OMIT_CHECK
-+  "OMIT_CHECK",
-+#endif
-+#if SQLITE_OMIT_COMPLETE
-+  "OMIT_COMPLETE",
-+#endif
-+#if SQLITE_OMIT_COMPOUND_SELECT
-+  "OMIT_COMPOUND_SELECT",
-+#endif
-+#if SQLITE_OMIT_CTE
-+  "OMIT_CTE",
-+#endif
-+#if SQLITE_OMIT_DATETIME_FUNCS
-+  "OMIT_DATETIME_FUNCS",
-+#endif
-+#if SQLITE_OMIT_DECLTYPE
-+  "OMIT_DECLTYPE",
-+#endif
-+#if SQLITE_OMIT_DEPRECATED
-+  "OMIT_DEPRECATED",
-+#endif
-+#if SQLITE_OMIT_DISKIO
-+  "OMIT_DISKIO",
-+#endif
-+#if SQLITE_OMIT_EXPLAIN
-+  "OMIT_EXPLAIN",
+       default: {
+         assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED );
+-        codeDistinct(pParse, pDistinct->tabTnct, iContinue, nResultCol, regResult);
++        codeDistinct(pParse, pDistinct->tabTnct, iContinue, nResultCol,
++                     regResult);
+         break;
+       }
+     }
+@@ -107320,7 +121572,7 @@
+       int r1;
+       r1 = sqlite3GetTempReg(pParse);
+       sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
+-      sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
++      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
+       sqlite3ReleaseTempReg(pParse, r1);
+       break;
+     }
+@@ -107344,6 +121596,8 @@
+       int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1);
+       testcase( eDest==SRT_Table );
+       testcase( eDest==SRT_EphemTab );
++      testcase( eDest==SRT_Fifo );
++      testcase( eDest==SRT_DistFifo );
+       sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
+ #ifndef SQLITE_OMIT_CTE
+       if( eDest==SRT_DistFifo ){
+@@ -107353,13 +121607,14 @@
+         ** current row to the index and proceed with writing it to the
+         ** output table as well.  */
+         int addr = sqlite3VdbeCurrentAddr(v) + 4;
+-        sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); VdbeCoverage(v);
+-        sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1);
++        sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0);
++        VdbeCoverage(v);
++        sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1,regResult,nResultCol);
+         assert( pSort==0 );
+       }
+ #endif
+       if( pSort ){
+-        pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, 1, nPrefixReg);
++        pushOntoSorter(pParse, pSort, p, r1+nPrefixReg,regResult,1,nPrefixReg);
+       }else{
+         int r2 = sqlite3GetTempReg(pParse);
+         sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
+@@ -107377,20 +121632,20 @@
+     ** item into the set table with bogus data.
+     */
+     case SRT_Set: {
+-      assert( nResultCol==1 );
+-      pDest->affSdst =
+-                  sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
+       if( pSort ){
+         /* At first glance you would think we could optimize out the
+         ** ORDER BY in this case since the order of entries in the set
+         ** does not matter.  But there might be a LIMIT clause, in which
+         ** case the order does matter */
+-        pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg);
++        pushOntoSorter(
++            pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
+       }else{
+         int r1 = sqlite3GetTempReg(pParse);
+-        sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
+-        sqlite3ExprCacheAffinityChange(pParse, regResult, 1);
+-        sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
++        assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol );
++        sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, 
++            r1, pDest->zAffSdst, nResultCol);
++        sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
++        sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
+         sqlite3ReleaseTempReg(pParse, r1);
+       }
+       break;
+@@ -107405,14 +121660,16 @@
+     }
+ 
+     /* If this is a scalar select that is part of an expression, then
+-    ** store the results in the appropriate memory cell and break out
+-    ** of the scan loop.
++    ** store the results in the appropriate memory cell or array of 
++    ** memory cells and break out of the scan loop.
+     */
+     case SRT_Mem: {
+-      assert( nResultCol==1 );
+       if( pSort ){
+-        pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg);
++        assert( nResultCol<=pDest->nSdst );
++        pushOntoSorter(
++            pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
+       }else{
++        assert( nResultCol==pDest->nSdst );
+         assert( regResult==iParm );
+         /* The LIMIT clause will jump out of the loop for us */
+       }
+@@ -107425,7 +121682,8 @@
+       testcase( eDest==SRT_Coroutine );
+       testcase( eDest==SRT_Output );
+       if( pSort ){
+-        pushOntoSorter(pParse, pSort, p, regResult, nResultCol, nPrefixReg);
++        pushOntoSorter(pParse, pSort, p, regResult, regOrig, nResultCol,
++                       nPrefixReg);
+       }else if( eDest==SRT_Coroutine ){
+         sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
+       }else{
+@@ -107474,7 +121732,7 @@
+       }
+       sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey);
+       sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1);
+-      sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
++      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2);
+       if( addrTest ) sqlite3VdbeJumpHere(v, addrTest);
+       sqlite3ReleaseTempReg(pParse, r1);
+       sqlite3ReleaseTempRange(pParse, r2, nKey+2);
+@@ -107511,8 +121769,8 @@
+ ** X extra columns.
+ */
+ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
+-  KeyInfo *p = sqlite3DbMallocZero(0, 
+-                   sizeof(KeyInfo) + (N+X)*(sizeof(CollSeq*)+1));
++  int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*);
++  KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
+   if( p ){
+     p->aSortOrder = (u8*)&p->aColl[N+X];
+     p->nField = (u16)N;
+@@ -107520,8 +121778,9 @@
+     p->enc = ENC(db);
+     p->db = db;
+     p->nRef = 1;
++    memset(&p[1], 0, nExtra);
+   }else{
+-    db->mallocFailed = 1;
++    sqlite3OomFault(db);
+   }
+   return p;
+ }
+@@ -107533,7 +121792,7 @@
+   if( p ){
+     assert( p->nRef>0 );
+     p->nRef--;
+-    if( p->nRef==0 ) sqlite3DbFree(0, p);
++    if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p);
+   }
+ }
+ 
+@@ -107599,7 +121858,6 @@
+   return pInfo;
+ }
+ 
+-#ifndef SQLITE_OMIT_COMPOUND_SELECT
+ /*
+ ** Name of the connection operator, used for error messages.
+ */
+@@ -107613,7 +121871,6 @@
+   }
+   return z;
+ }
+-#endif /* SQLITE_OMIT_COMPOUND_SELECT */
+ 
+ #ifndef SQLITE_OMIT_EXPLAIN
+ /*
+@@ -107700,7 +121957,7 @@
+   SelectDest *pDest /* Write the sorted results here */
+ ){
+   Vdbe *v = pParse->pVdbe;                     /* The prepared statement */
+-  int addrBreak = sqlite3VdbeMakeLabel(v);     /* Jump here to exit loop */
++  int addrBreak = pSort->labelDone;            /* Jump here to exit loop */
+   int addrContinue = sqlite3VdbeMakeLabel(v);  /* Jump here for next cycle */
+   int addr;
+   int addrOnce = 0;
+@@ -107710,36 +121967,36 @@
+   int iParm = pDest->iSDParm;
+   int regRow;
+   int regRowid;
++  int iCol;
+   int nKey;
+   int iSortTab;                   /* Sorter cursor to read from */
+   int nSortData;                  /* Trailing values to read from sorter */
+   int i;
+   int bSeq;                       /* True if sorter record includes seq. no. */
+-#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+   struct ExprList_item *aOutEx = p->pEList->a;
+-#endif
+ 
++  assert( addrBreak<0 );
+   if( pSort->labelBkOut ){
+     sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
+-    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBreak);
++    sqlite3VdbeGoto(v, addrBreak);
+     sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
+   }
+   iTab = pSort->iECursor;
+-  if( eDest==SRT_Output || eDest==SRT_Coroutine ){
++  if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){
+     regRowid = 0;
+     regRow = pDest->iSdst;
+     nSortData = nColumn;
+   }else{
+     regRowid = sqlite3GetTempReg(pParse);
+-    regRow = sqlite3GetTempReg(pParse);
+-    nSortData = 1;
++    regRow = sqlite3GetTempRange(pParse, nColumn);
++    nSortData = nColumn;
+   }
+   nKey = pOrderBy->nExpr - pSort->nOBSat;
+   if( pSort->sortFlags & SORTFLAG_UseSorter ){
+     int regSortOut = ++pParse->nMem;
+     iSortTab = pParse->nTab++;
+     if( pSort->labelBkOut ){
+-      addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
++      addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+     }
+     sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
+     if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
+@@ -107754,15 +122011,19 @@
+     iSortTab = iTab;
+     bSeq = 1;
+   }
+-  for(i=0; i<nSortData; i++){
+-    sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
++  for(i=0, iCol=nKey+bSeq; i<nSortData; i++){
++    int iRead;
++    if( aOutEx[i].u.x.iOrderByCol ){
++      iRead = aOutEx[i].u.x.iOrderByCol-1;
++    }else{
++      iRead = iCol++;
++    }
++    sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i);
+     VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
+   }
+   switch( eDest ){
+     case SRT_Table:
+     case SRT_EphemTab: {
+-      testcase( eDest==SRT_Table );
+-      testcase( eDest==SRT_EphemTab );
+       sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
+       sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
+       sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+@@ -107770,16 +122031,14 @@
+     }
+ #ifndef SQLITE_OMIT_SUBQUERY
+     case SRT_Set: {
+-      assert( nColumn==1 );
+-      sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid,
+-                        &pDest->affSdst, 1);
+-      sqlite3ExprCacheAffinityChange(pParse, regRow, 1);
+-      sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);
++      assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) );
++      sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid,
++                        pDest->zAffSdst, nColumn);
++      sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn);
++      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn);
+       break;
+     }
+     case SRT_Mem: {
+-      assert( nColumn==1 );
+-      sqlite3ExprCodeMove(pParse, regRow, iParm, 1);
+       /* The LIMIT clause will terminate the loop for us */
+       break;
+     }
+@@ -107798,7 +122057,11 @@
+     }
+   }
+   if( regRowid ){
+-    sqlite3ReleaseTempReg(pParse, regRow);
++    if( eDest==SRT_Set ){
++      sqlite3ReleaseTempRange(pParse, regRow, nColumn);
++    }else{
++      sqlite3ReleaseTempReg(pParse, regRow);
++    }
+     sqlite3ReleaseTempReg(pParse, regRowid);
+   }
+   /* The bottom of the loop
+@@ -107839,30 +122102,30 @@
+ */
+ #ifdef SQLITE_ENABLE_COLUMN_METADATA
+ # define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,C,D,E,F)
++#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */
++# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,F)
 +#endif
-+#if SQLITE_OMIT_FLAG_PRAGMAS
-+  "OMIT_FLAG_PRAGMAS",
+ static const char *columnTypeImpl(
+   NameContext *pNC, 
+   Expr *pExpr,
++#ifdef SQLITE_ENABLE_COLUMN_METADATA
+   const char **pzOrigDb,
+   const char **pzOrigTab,
+   const char **pzOrigCol,
 +#endif
-+#if SQLITE_OMIT_FLOATING_POINT
-+  "OMIT_FLOATING_POINT",
+   u8 *pEstWidth
+ ){
+-  char const *zOrigDb = 0;
+-  char const *zOrigTab = 0;
+-  char const *zOrigCol = 0;
+-#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */
+-# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,F)
+-static const char *columnTypeImpl(
+-  NameContext *pNC, 
+-  Expr *pExpr,
+-  u8 *pEstWidth
+-){
+-#endif /* !defined(SQLITE_ENABLE_COLUMN_METADATA) */
+   char const *zType = 0;
+   int j;
+   u8 estWidth = 1;
++#ifdef SQLITE_ENABLE_COLUMN_METADATA
++  char const *zOrigDb = 0;
++  char const *zOrigTab = 0;
++  char const *zOrigCol = 0;
 +#endif
-+#if SQLITE_OMIT_FOREIGN_KEY
-+  "OMIT_FOREIGN_KEY",
+ 
+-  if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0;
++  assert( pExpr!=0 );
++  assert( pNC->pSrcList!=0 );
+   switch( pExpr->op ){
+     case TK_AGG_COLUMN:
+     case TK_COLUMN: {
+@@ -107935,20 +122198,20 @@
+           zType = "INTEGER";
+           zOrigCol = "rowid";
+         }else{
+-          zType = pTab->aCol[iCol].zType;
+           zOrigCol = pTab->aCol[iCol].zName;
++          zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
+           estWidth = pTab->aCol[iCol].szEst;
+         }
+         zOrigTab = pTab->zName;
+         if( pNC->pParse ){
+           int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
+-          zOrigDb = pNC->pParse->db->aDb[iDb].zName;
++          zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName;
+         }
+ #else
+         if( iCol<0 ){
+           zType = "INTEGER";
+         }else{
+-          zType = pTab->aCol[iCol].zType;
++          zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
+           estWidth = pTab->aCol[iCol].szEst;
+         }
+ #endif
+@@ -108001,6 +122264,7 @@
+   NameContext sNC;
+   sNC.pSrcList = pTabList;
+   sNC.pParse = pParse;
++  sNC.pNext = 0;
+   for(i=0; i<pEList->nExpr; i++){
+     Expr *p = pEList->a[i].pExpr;
+     const char *zType;
+@@ -108025,20 +122289,49 @@
+ #endif /* !defined(SQLITE_OMIT_DECLTYPE) */
+ }
+ 
++
+ /*
+-** Generate code that will tell the VDBE the names of columns
+-** in the result set.  This information is used to provide the
+-** azCol[] values in the callback.
++** Compute the column names for a SELECT statement.
++**
++** The only guarantee that SQLite makes about column names is that if the
++** column has an AS clause assigning it a name, that will be the name used.
++** That is the only documented guarantee.  However, countless applications
++** developed over the years have made baseless assumptions about column names
++** and will break if those assumptions changes.  Hence, use extreme caution
++** when modifying this routine to avoid breaking legacy.
++**
++** See Also: sqlite3ColumnsFromExprList()
++**
++** The PRAGMA short_column_names and PRAGMA full_column_names settings are
++** deprecated.  The default setting is short=ON, full=OFF.  99.9% of all
++** applications should operate this way.  Nevertheless, we need to support the
++** other modes for legacy:
++**
++**    short=OFF, full=OFF:      Column name is the text of the expression has it
++**                              originally appears in the SELECT statement.  In
++**                              other words, the zSpan of the result expression.
++**
++**    short=ON, full=OFF:       (This is the default setting).  If the result
++**                              refers directly to a table column, then the result
++**                              column name is just the table column name: COLUMN. 
++**                              Otherwise use zSpan.
++**
++**    full=ON, short=ANY:       If the result refers directly to a table column,
++**                              then the result column name with the table name
++**                              prefix, ex: TABLE.COLUMN.  Otherwise use zSpan.
+ */
+ static void generateColumnNames(
+   Parse *pParse,      /* Parser context */
+-  SrcList *pTabList,  /* List of tables */
+-  ExprList *pEList    /* Expressions defining the result set */
++  Select *pSelect     /* Generate column names for this SELECT statement */
+ ){
+   Vdbe *v = pParse->pVdbe;
+-  int i, j;
++  int i;
++  Table *pTab;
++  SrcList *pTabList;
++  ExprList *pEList;
+   sqlite3 *db = pParse->db;
+-  int fullNames, shortNames;
++  int fullName;    /* TABLE.COLUMN if no AS clause and is a direct table ref */
++  int srcName;     /* COLUMN or TABLE.COLUMN if no AS clause and is direct */
+ 
+ #ifndef SQLITE_OMIT_EXPLAIN
+   /* If this is an EXPLAIN, skip this step */
+@@ -108047,27 +122340,30 @@
+   }
+ #endif
+ 
+-  if( pParse->colNamesSet || NEVER(v==0) || db->mallocFailed ) return;
++  if( pParse->colNamesSet || db->mallocFailed ) return;
++  /* Column names are determined by the left-most term of a compound select */
++  while( pSelect->pPrior ) pSelect = pSelect->pPrior;
++  pTabList = pSelect->pSrc;
++  pEList = pSelect->pEList;
++  assert( v!=0 );
++  assert( pTabList!=0 );
+   pParse->colNamesSet = 1;
+-  fullNames = (db->flags & SQLITE_FullColNames)!=0;
+-  shortNames = (db->flags & SQLITE_ShortColNames)!=0;
++  fullName = (db->flags & SQLITE_FullColNames)!=0;
++  srcName = (db->flags & SQLITE_ShortColNames)!=0 || fullName;
+   sqlite3VdbeSetNumCols(v, pEList->nExpr);
+   for(i=0; i<pEList->nExpr; i++){
+-    Expr *p;
+-    p = pEList->a[i].pExpr;
+-    if( NEVER(p==0) ) continue;
++    Expr *p = pEList->a[i].pExpr;
++
++    assert( p!=0 );
+     if( pEList->a[i].zName ){
++      /* An AS clause always takes first priority */
+       char *zName = pEList->a[i].zName;
+       sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
+-    }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && pTabList ){
+-      Table *pTab;
++    }else if( srcName && p->op==TK_COLUMN ){
+       char *zCol;
+       int iCol = p->iColumn;
+-      for(j=0; ALWAYS(j<pTabList->nSrc); j++){
+-        if( pTabList->a[j].iCursor==p->iTable ) break;
+-      }
+-      assert( j<pTabList->nSrc );
+-      pTab = pTabList->a[j].pTab;
++      pTab = p->pTab;
++      assert( pTab!=0 );
+       if( iCol<0 ) iCol = pTab->iPKey;
+       assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+       if( iCol<0 ){
+@@ -108075,10 +122371,7 @@
+       }else{
+         zCol = pTab->aCol[iCol].zName;
+       }
+-      if( !shortNames && !fullNames ){
+-        sqlite3VdbeSetColName(v, i, COLNAME_NAME, 
+-            sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
+-      }else if( fullNames ){
++      if( fullName ){
+         char *zName = 0;
+         zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol);
+         sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC);
+@@ -108106,8 +122399,17 @@
+ **
+ ** Return SQLITE_OK on success.  If a memory allocation error occurs,
+ ** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM.
++**
++** The only guarantee that SQLite makes about column names is that if the
++** column has an AS clause assigning it a name, that will be the name used.
++** That is the only documented guarantee.  However, countless applications
++** developed over the years have made baseless assumptions about column names
++** and will break if those assumptions changes.  Hence, use extreme caution
++** when modifying this routine to avoid breaking legacy.
++**
++** See Also: generateColumnNames()
+ */
+-static int selectColumnsFromExprList(
++SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
+   Parse *pParse,          /* Parsing context */
+   ExprList *pEList,       /* Expr list from which to derive column names */
+   i16 *pnCol,             /* Write the number of columns here */
+@@ -108115,13 +122417,14 @@
+ ){
+   sqlite3 *db = pParse->db;   /* Database connection */
+   int i, j;                   /* Loop counters */
+-  int cnt;                    /* Index added to make the name unique */
++  u32 cnt;                    /* Index added to make the name unique */
+   Column *aCol, *pCol;        /* For looping over result columns */
+   int nCol;                   /* Number of columns in the result set */
+-  Expr *p;                    /* Expression for a single result column */
+   char *zName;                /* Column name */
+   int nName;                  /* Size of name in zName[] */
++  Hash ht;                    /* Hash table of column names */
+ 
++  sqlite3HashInit(&ht);
+   if( pEList ){
+     nCol = pEList->nExpr;
+     aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
+@@ -108130,63 +122433,61 @@
+     nCol = 0;
+     aCol = 0;
+   }
++  assert( nCol==(i16)nCol );
+   *pnCol = nCol;
+   *paCol = aCol;
+ 
+-  for(i=0, pCol=aCol; i<nCol; i++, pCol++){
++  for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
+     /* Get an appropriate name for the column
+     */
+-    p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
+     if( (zName = pEList->a[i].zName)!=0 ){
+       /* If the column contains an "AS <name>" phrase, use <name> as the name */
+-      zName = sqlite3DbStrDup(db, zName);
+     }else{
+-      Expr *pColExpr = p;  /* The expression that is the result column name */
+-      Table *pTab;         /* Table associated with this expression */
++      Expr *pColExpr = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
+       while( pColExpr->op==TK_DOT ){
+         pColExpr = pColExpr->pRight;
+         assert( pColExpr!=0 );
+       }
+-      if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
++      if( pColExpr->op==TK_COLUMN && pColExpr->pTab!=0 ){
+         /* For columns use the column name name */
+         int iCol = pColExpr->iColumn;
+-        pTab = pColExpr->pTab;
++        Table *pTab = pColExpr->pTab;
+         if( iCol<0 ) iCol = pTab->iPKey;
+-        zName = sqlite3MPrintf(db, "%s",
+-                 iCol>=0 ? pTab->aCol[iCol].zName : "rowid");
++        zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
+       }else if( pColExpr->op==TK_ID ){
+         assert( !ExprHasProperty(pColExpr, EP_IntValue) );
+-        zName = sqlite3MPrintf(db, "%s", pColExpr->u.zToken);
++        zName = pColExpr->u.zToken;
+       }else{
+         /* Use the original text of the column expression as its name */
+-        zName = sqlite3MPrintf(db, "%s", pEList->a[i].zSpan);
++        zName = pEList->a[i].zSpan;
+       }
+     }
+-    if( db->mallocFailed ){
+-      sqlite3DbFree(db, zName);
+-      break;
++    if( zName ){
++      zName = sqlite3DbStrDup(db, zName);
++    }else{
++      zName = sqlite3MPrintf(db,"column%d",i+1);
+     }
+ 
+     /* Make sure the column name is unique.  If the name is not unique,
+     ** append an integer to the name so that it becomes unique.
+     */
+-    nName = sqlite3Strlen30(zName);
+-    for(j=cnt=0; j<i; j++){
+-      if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
+-        char *zNewName;
+-        int k;
+-        for(k=nName-1; k>1 && sqlite3Isdigit(zName[k]); k--){}
+-        if( k>=0 && zName[k]==':' ) nName = k;
+-        zName[nName] = 0;
+-        zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
+-        sqlite3DbFree(db, zName);
+-        zName = zNewName;
+-        j = -1;
+-        if( zName==0 ) break;
++    cnt = 0;
++    while( zName && sqlite3HashFind(&ht, zName)!=0 ){
++      nName = sqlite3Strlen30(zName);
++      if( nName>0 ){
++        for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){}
++        if( zName[j]==':' ) nName = j;
+       }
++      zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt);
++      if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
+     }
+     pCol->zName = zName;
++    sqlite3ColumnPropertiesFromName(0, pCol);
++    if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){
++      sqlite3OomFault(db);
++    }
+   }
++  sqlite3HashClear(&ht);
+   if( db->mallocFailed ){
+     for(j=0; j<i; j++){
+       sqlite3DbFree(db, aCol[j].zName);
+@@ -108194,7 +122495,7 @@
+     sqlite3DbFree(db, aCol);
+     *paCol = 0;
+     *pnCol = 0;
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   return SQLITE_OK;
+ }
+@@ -108210,7 +122511,7 @@
+ ** This routine requires that all identifiers in the SELECT
+ ** statement be resolved.
+ */
+-static void selectAddColumnTypeAndCollation(
++SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
+   Parse *pParse,        /* Parsing contexts */
+   Table *pTab,          /* Add column type information to this table */
+   Select *pSelect       /* SELECT used to determine types and collations */
+@@ -108232,13 +122533,21 @@
+   sNC.pSrcList = pSelect->pSrc;
+   a = pSelect->pEList->a;
+   for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
++    const char *zType;
++    int n, m;
+     p = a[i].pExpr;
+-    if( pCol->zType==0 ){
+-      pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
+-    }
++    zType = columnType(&sNC, p, 0, 0, 0, &pCol->szEst);
+     szAll += pCol->szEst;
+     pCol->affinity = sqlite3ExprAffinity(p);
+-    if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
++    if( zType && (m = sqlite3Strlen30(zType))>0 ){
++      n = sqlite3Strlen30(pCol->zName);
++      pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2);
++      if( pCol->zName ){
++        memcpy(&pCol->zName[n+1], zType, m+1);
++        pCol->colFlags |= COLFLAG_HASTYPE;
++      }
++    }
++    if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB;
+     pColl = sqlite3ExprCollSeq(pParse, p);
+     if( pColl && pCol->zColl==0 ){
+       pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
+@@ -108269,12 +122578,12 @@
+   }
+   /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
+   ** is disabled */
+-  assert( db->lookaside.bEnabled==0 );
+-  pTab->nRef = 1;
++  assert( db->lookaside.bDisable );
++  pTab->nTabRef = 1;
+   pTab->zName = 0;
+   pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
+-  selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
+-  selectAddColumnTypeAndCollation(pParse, pTab, pSelect);
++  sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
++  sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect);
+   pTab->iPKey = -1;
+   if( db->mallocFailed ){
+     sqlite3DeleteTable(db, pTab);
+@@ -108287,20 +122596,20 @@
+ ** Get a VDBE for the given parser context.  Create a new one if necessary.
+ ** If an error occurs, return NULL and leave a message in pParse.
+ */
+-SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
+-  Vdbe *v = pParse->pVdbe;
+-  if( v==0 ){
+-    v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
+-    if( v ) sqlite3VdbeAddOp0(v, OP_Init);
+-    if( pParse->pToplevel==0
+-     && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
+-    ){
+-      pParse->okConstFactor = 1;
+-    }
+-
++static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){
++  Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
++  if( v ) sqlite3VdbeAddOp2(v, OP_Init, 0, 1);
++  if( pParse->pToplevel==0
++   && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
++  ){
++    pParse->okConstFactor = 1;
+   }
+   return v;
+ }
++SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
++  Vdbe *v = pParse->pVdbe;
++  return v ? v : allocVdbe(pParse);
++}
+ 
+ 
+ /*
+@@ -108330,7 +122639,7 @@
+   Vdbe *v = 0;
+   int iLimit = 0;
+   int iOffset;
+-  int addr1, n;
++  int n;
+   if( p->iLimit ) return;
+ 
+   /* 
+@@ -108349,9 +122658,10 @@
+       sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
+       VdbeComment((v, "LIMIT counter"));
+       if( n==0 ){
+-        sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
+-      }else if( n>=0 && p->nSelectRow>(u64)n ){
+-        p->nSelectRow = n;
++        sqlite3VdbeGoto(v, iBreak);
++      }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){
++        p->nSelectRow = sqlite3LogEst((u64)n);
++        p->selFlags |= SF_FixedLimit;
+       }
+     }else{
+       sqlite3ExprCode(pParse, p->pLimit, iLimit);
+@@ -108365,14 +122675,8 @@
+       sqlite3ExprCode(pParse, p->pOffset, iOffset);
+       sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
+       VdbeComment((v, "OFFSET counter"));
+-      addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); VdbeCoverage(v);
+-      sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
+-      sqlite3VdbeJumpHere(v, addr1);
+-      sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
++      sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset);
+       VdbeComment((v, "LIMIT+OFFSET"));
+-      addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); VdbeCoverage(v);
+-      sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1);
+-      sqlite3VdbeJumpHere(v, addr1);
+     }
+   }
+ }
+@@ -108394,7 +122698,10 @@
+     pRet = 0;
+   }
+   assert( iCol>=0 );
+-  if( pRet==0 && iCol<p->pEList->nExpr ){
++  /* iCol must be less than p->pEList->nExpr.  Otherwise an error would
++  ** have been thrown during name resolution and we would not have gotten
++  ** this far */
++  if( pRet==0 && ALWAYS(iCol<p->pEList->nExpr) ){
+     pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
+   }
+   return pRet;
+@@ -108449,7 +122756,7 @@
+ **
+ **
+ ** There is exactly one reference to the recursive-table in the FROM clause
+-** of recursive-query, marked with the SrcList->a[].isRecursive flag.
++** of recursive-query, marked with the SrcList->a[].fg.isRecursive flag.
+ **
+ ** The setup-query runs once to generate an initial set of rows that go
+ ** into a Queue table.  Rows are extracted from the Queue table one by
+@@ -108503,6 +122810,7 @@
+ 
+   /* Process the LIMIT and OFFSET clauses, if they exist */
+   addrBreak = sqlite3VdbeMakeLabel(v);
++  p->nSelectRow = 320;  /* 4 billion rows */
+   computeLimitRegisters(pParse, p, addrBreak);
+   pLimit = p->pLimit;
+   pOffset = p->pOffset;
+@@ -108514,7 +122822,7 @@
+ 
+   /* Locate the cursor number of the Current table */
+   for(i=0; ALWAYS(i<pSrc->nSrc); i++){
+-    if( pSrc->a[i].isRecursive ){
++    if( pSrc->a[i].fg.isRecursive ){
+       iCurrent = pSrc->a[i].iCursor;
+       break;
+     }
+@@ -108584,13 +122892,17 @@
+   /* Execute the recursive SELECT taking the single row in Current as
+   ** the value for the recursive-table. Store the results in the Queue.
+   */
+-  p->pPrior = 0;
+-  sqlite3Select(pParse, p, &destQueue);
+-  assert( p->pPrior==0 );
+-  p->pPrior = pSetup;
++  if( p->selFlags & SF_Aggregate ){
++    sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
++  }else{
++    p->pPrior = 0;
++    sqlite3Select(pParse, p, &destQueue);
++    assert( p->pPrior==0 );
++    p->pPrior = pSetup;
++  }
+ 
+   /* Keep running the loop until the Queue is empty */
+-  sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
++  sqlite3VdbeGoto(v, addrTop);
+   sqlite3VdbeResolveLabel(v, addrBreak);
+ 
+ end_of_recursive_query:
+@@ -108610,19 +122922,6 @@
+ );
+ 
+ /*
+-** Error message for when two or more terms of a compound select have different
+-** size result sets.
+-*/
+-static void selectWrongNumTermsError(Parse *pParse, Select *p){
+-  if( p->selFlags & SF_Values ){
+-    sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
+-  }else{
+-    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
+-      " do not have the same number of result columns", selectOpName(p->op));
+-  }
+-}
+-
+-/*
+ ** Handle the special case of a compound-select that originates from a
+ ** VALUES clause.  By handling this as a special case, we avoid deep
+ ** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT
+@@ -108639,7 +122938,6 @@
+   SelectDest *pDest     /* What to do with query results */
+ ){
+   Select *pPrior;
+-  int nExpr = p->pEList->nExpr;
+   int nRow = 1;
+   int rc = 0;
+   assert( p->selFlags & SF_MultiValue );
+@@ -108648,10 +122946,7 @@
+     assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
+     assert( p->pLimit==0 );
+     assert( p->pOffset==0 );
+-    if( p->pEList->nExpr!=nExpr ){
+-      selectWrongNumTermsError(pParse, p);
+-      return 1;
+-    }
++    assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
+     if( p->pPrior==0 ) break;
+     assert( p->pPrior->pNext==p );
+     p = p->pPrior;
+@@ -108745,7 +123040,6 @@
+   if( dest.eDest==SRT_EphemTab ){
+     assert( p->pEList );
+     sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr);
+-    sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
+     dest.eDest = SRT_Table;
+   }
+ 
+@@ -108760,11 +123054,7 @@
+   ** in their result sets.
+   */
+   assert( p->pEList && pPrior->pEList );
+-  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
+-    selectWrongNumTermsError(pParse, p);
+-    rc = 1;
+-    goto multi_select_end;
+-  }
++  assert( p->pEList->nExpr==pPrior->pEList->nExpr );
+ 
+ #ifndef SQLITE_OMIT_CTE
+   if( p->selFlags & SF_Recursive ){
+@@ -108802,18 +123092,22 @@
+       if( p->iLimit ){
+         addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
+         VdbeComment((v, "Jump ahead if LIMIT reached"));
++        if( p->iOffset ){
++          sqlite3VdbeAddOp3(v, OP_OffsetLimit,
++                            p->iLimit, p->iOffset+1, p->iOffset);
++        }
+       }
+       explainSetInteger(iSub2, pParse->iNextSelectId);
+       rc = sqlite3Select(pParse, p, &dest);
+       testcase( rc!=SQLITE_OK );
+       pDelete = p->pPrior;
+       p->pPrior = pPrior;
+-      p->nSelectRow += pPrior->nSelectRow;
++      p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+       if( pPrior->pLimit
+        && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
+-       && nLimit>0 && p->nSelectRow > (u64)nLimit 
++       && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) 
+       ){
+-        p->nSelectRow = nLimit;
++        p->nSelectRow = sqlite3LogEst((u64)nLimit);
+       }
+       if( addr ){
+         sqlite3VdbeJumpHere(v, addr);
+@@ -108885,7 +123179,9 @@
+       pDelete = p->pPrior;
+       p->pPrior = pPrior;
+       p->pOrderBy = 0;
+-      if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow;
++      if( p->op==TK_UNION ){
++        p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
++      }
+       sqlite3ExprDelete(db, p->pLimit);
+       p->pLimit = pLimit;
+       p->pOffset = pOffset;
+@@ -108899,11 +123195,6 @@
+       if( dest.eDest!=priorOp ){
+         int iCont, iBreak, iStart;
+         assert( p->pEList );
+-        if( dest.eDest==SRT_Output ){
+-          Select *pFirst = p;
+-          while( pFirst->pPrior ) pFirst = pFirst->pPrior;
+-          generateColumnNames(pParse, 0, pFirst->pEList);
+-        }
+         iBreak = sqlite3VdbeMakeLabel(v);
+         iCont = sqlite3VdbeMakeLabel(v);
+         computeLimitRegisters(pParse, p, iBreak);
+@@ -108974,17 +123265,12 @@
+       ** tables.
+       */
+       assert( p->pEList );
+-      if( dest.eDest==SRT_Output ){
+-        Select *pFirst = p;
+-        while( pFirst->pPrior ) pFirst = pFirst->pPrior;
+-        generateColumnNames(pParse, 0, pFirst->pEList);
+-      }
+       iBreak = sqlite3VdbeMakeLabel(v);
+       iCont = sqlite3VdbeMakeLabel(v);
+       computeLimitRegisters(pParse, p, iBreak);
+       sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
+       r1 = sqlite3GetTempReg(pParse);
+-      iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1);
++      iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
+       sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v);
+       sqlite3ReleaseTempReg(pParse, r1);
+       selectInnerLoop(pParse, p, p->pEList, tab1,
+@@ -109020,7 +123306,7 @@
+     nCol = p->pEList->nExpr;
+     pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
+     if( !pKeyInfo ){
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+       goto multi_select_end;
+     }
+     for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
+@@ -109057,6 +123343,19 @@
+ #endif /* SQLITE_OMIT_COMPOUND_SELECT */
+ 
+ /*
++** Error message for when two or more terms of a compound select have different
++** size result sets.
++*/
++SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){
++  if( p->selFlags & SF_Values ){
++    sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
++  }else{
++    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
++      " do not have the same number of result columns", selectOpName(p->op));
++  }
++}
++
++/*
+ ** Code an output subroutine for a coroutine implementation of a
+ ** SELECT statment.
+ **
+@@ -109096,12 +123395,12 @@
+   /* Suppress duplicates for UNION, EXCEPT, and INTERSECT 
+   */
+   if( regPrev ){
+-    int j1, j2;
+-    j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
+-    j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
++    int addr1, addr2;
++    addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
++    addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
+                               (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
+-    sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); VdbeCoverage(v);
+-    sqlite3VdbeJumpHere(v, j1);
++    sqlite3VdbeAddOp3(v, OP_Jump, addr2+2, iContinue, addr2+2); VdbeCoverage(v);
++    sqlite3VdbeJumpHere(v, addr1);
+     sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
+     sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
+   }
+@@ -109111,15 +123410,14 @@
+   */
+   codeOffset(v, p->iOffset, iContinue);
+ 
++  assert( pDest->eDest!=SRT_Exists );
++  assert( pDest->eDest!=SRT_Table );
+   switch( pDest->eDest ){
+     /* Store the result as data using a unique key.
+     */
+-    case SRT_Table:
+     case SRT_EphemTab: {
+       int r1 = sqlite3GetTempReg(pParse);
+       int r2 = sqlite3GetTempReg(pParse);
+-      testcase( pDest->eDest==SRT_Table );
+-      testcase( pDest->eDest==SRT_EphemTab );
+       sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1);
+       sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2);
+       sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2);
+@@ -109130,33 +123428,21 @@
+     }
+ 
+ #ifndef SQLITE_OMIT_SUBQUERY
+-    /* If we are creating a set for an "expr IN (SELECT ...)" construct,
+-    ** then there should be a single item on the stack.  Write this
+-    ** item into the set table with bogus data.
++    /* If we are creating a set for an "expr IN (SELECT ...)".
+     */
+     case SRT_Set: {
+       int r1;
+-      assert( pIn->nSdst==1 || pParse->nErr>0 );
+-      pDest->affSdst = 
+-         sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
++      testcase( pIn->nSdst>1 );
+       r1 = sqlite3GetTempReg(pParse);
+-      sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1);
+-      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1);
+-      sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
++      sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, 
++          r1, pDest->zAffSdst, pIn->nSdst);
++      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
++      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1,
++                           pIn->iSdst, pIn->nSdst);
+       sqlite3ReleaseTempReg(pParse, r1);
+       break;
+     }
+ 
+-#if 0  /* Never occurs on an ORDER BY query */
+-    /* If any row exist in the result set, record that fact and abort.
+-    */
+-    case SRT_Exists: {
+-      sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm);
+-      /* The LIMIT clause will terminate the loop for us */
+-      break;
+-    }
+-#endif
+-
+     /* If this is a scalar select that is part of an expression, then
+     ** store the results in the appropriate memory cell and break out
+     ** of the scan loop.
+@@ -109329,7 +123615,7 @@
+   int savedOffset;      /* Saved value of p->iOffset */
+   int labelCmpr;        /* Label for the start of the merge algorithm */
+   int labelEnd;         /* Label for the end of the overall SELECT stmt */
+-  int j1;               /* Jump instructions that get retargetted */
++  int addr1;            /* Jump instructions that get retargetted */
+   int op;               /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
+   KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */
+   KeyInfo *pKeyMerge;   /* Comparison information for merging rows */
+@@ -109373,10 +123659,10 @@
+       }
+       if( j==nOrderBy ){
+         Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
+-        if( pNew==0 ) return SQLITE_NOMEM;
++        if( pNew==0 ) return SQLITE_NOMEM_BKPT;
+         pNew->flags |= EP_IntValue;
+         pNew->u.iValue = i;
+-        pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
++        p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
+         if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i;
+       }
+     }
+@@ -109389,14 +123675,13 @@
+   ** to the right and the left are evaluated, they use the correct
+   ** collation.
+   */
+-  aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
++  aPermute = sqlite3DbMallocRawNN(db, sizeof(int)*(nOrderBy + 1));
+   if( aPermute ){
+     struct ExprList_item *pItem;
+-    for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
++    aPermute[0] = nOrderBy;
++    for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){
+       assert( pItem->u.x.iOrderByCol>0 );
+-      /* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true
+-      ** but only for well-formed SELECT statements. */
+-      testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr );
++      assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
+       aPermute[i] = pItem->u.x.iOrderByCol - 1;
+     }
+     pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
+@@ -109467,19 +123752,19 @@
+   ** left of the compound operator - the "A" select.
+   */
+   addrSelectA = sqlite3VdbeCurrentAddr(v) + 1;
+-  j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
++  addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
+   VdbeComment((v, "left SELECT"));
+   pPrior->iLimit = regLimitA;
+   explainSetInteger(iSub1, pParse->iNextSelectId);
+   sqlite3Select(pParse, pPrior, &destA);
+-  sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrA);
+-  sqlite3VdbeJumpHere(v, j1);
++  sqlite3VdbeEndCoroutine(v, regAddrA);
++  sqlite3VdbeJumpHere(v, addr1);
+ 
+   /* Generate a coroutine to evaluate the SELECT statement on 
+   ** the right - the "B" select
+   */
+   addrSelectB = sqlite3VdbeCurrentAddr(v) + 1;
+-  j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB);
++  addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB);
+   VdbeComment((v, "right SELECT"));
+   savedLimit = p->iLimit;
+   savedOffset = p->iOffset;
+@@ -109489,7 +123774,7 @@
+   sqlite3Select(pParse, p, &destB);
+   p->iLimit = savedLimit;
+   p->iOffset = savedOffset;
+-  sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrB);
++  sqlite3VdbeEndCoroutine(v, regAddrB);
+ 
+   /* Generate a subroutine that outputs the current row of the A
+   ** select as the next output row of the compound select.
+@@ -109520,8 +123805,8 @@
+     addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
+     addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
+                                      VdbeCoverage(v);
+-    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);
+-    p->nSelectRow += pPrior->nSelectRow;
++    sqlite3VdbeGoto(v, addrEofA);
++    p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+   }
+ 
+   /* Generate a subroutine to run when the results from select B
+@@ -109534,7 +123819,7 @@
+     VdbeNoopComment((v, "eof-B subroutine"));
+     addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
+     sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v);
+-    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB);
++    sqlite3VdbeGoto(v, addrEofB);
+   }
+ 
+   /* Generate code to handle the case of A<B
+@@ -109542,7 +123827,7 @@
+   VdbeNoopComment((v, "A-lt-B subroutine"));
+   addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
+   sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
+-  sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
++  sqlite3VdbeGoto(v, labelCmpr);
+ 
+   /* Generate code to handle the case of A==B
+   */
+@@ -109555,7 +123840,7 @@
+     VdbeNoopComment((v, "A-eq-B subroutine"));
+     addrAeqB =
+     sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
+-    sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
++    sqlite3VdbeGoto(v, labelCmpr);
+   }
+ 
+   /* Generate code to handle the case of A>B
+@@ -109566,11 +123851,11 @@
+     sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
+   }
+   sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
+-  sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
++  sqlite3VdbeGoto(v, labelCmpr);
+ 
+   /* This code runs once to initialize everything.
+   */
+-  sqlite3VdbeJumpHere(v, j1);
++  sqlite3VdbeJumpHere(v, addr1);
+   sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v);
+   sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
+ 
+@@ -109587,14 +123872,6 @@
+   */
+   sqlite3VdbeResolveLabel(v, labelEnd);
+ 
+-  /* Set the number of output columns
+-  */
+-  if( pDest->eDest==SRT_Output ){
+-    Select *pFirst = pPrior;
+-    while( pFirst->pPrior ) pFirst = pFirst->pPrior;
+-    generateColumnNames(pParse, 0, pFirst->pEList);
+-  }
+-
+   /* Reassembly the compound query so that it will be freed correctly
+   ** by the calling function */
+   if( p->pPrior ){
+@@ -109611,9 +123888,24 @@
+ #endif
+ 
+ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
++
++/* An instance of the SubstContext object describes an substitution edit
++** to be performed on a parse tree.
++**
++** All references to columns in table iTable are to be replaced by corresponding
++** expressions in pEList.
++*/
++typedef struct SubstContext {
++  Parse *pParse;            /* The parsing context */
++  int iTable;               /* Replace references to this table */
++  int iNewTable;            /* New table number */
++  int isLeftJoin;           /* Add TK_IF_NULL_ROW opcodes on each replacement */
++  ExprList *pEList;         /* Replacement expressions */
++} SubstContext;
++
+ /* Forward Declarations */
+-static void substExprList(sqlite3*, ExprList*, int, ExprList*);
+-static void substSelect(sqlite3*, Select *, int, ExprList *);
++static void substExprList(SubstContext*, ExprList*);
++static void substSelect(SubstContext*, Select*, int);
+ 
+ /*
+ ** Scan through the expression pExpr.  Replace every reference to
+@@ -109624,74 +123916,98 @@
+ ** This routine is part of the flattening procedure.  A subquery
+ ** whose result set is defined by pEList appears as entry in the
+ ** FROM clause of a SELECT such that the VDBE cursor assigned to that
+-** FORM clause entry is iTable.  This routine make the necessary 
++** FORM clause entry is iTable.  This routine makes the necessary 
+ ** changes to pExpr so that it refers directly to the source table
+ ** of the subquery rather the result set of the subquery.
+ */
+ static Expr *substExpr(
+-  sqlite3 *db,        /* Report malloc errors to this connection */
+-  Expr *pExpr,        /* Expr in which substitution occurs */
+-  int iTable,         /* Table to be substituted */
+-  ExprList *pEList    /* Substitute expressions */
++  SubstContext *pSubst,  /* Description of the substitution */
++  Expr *pExpr            /* Expr in which substitution occurs */
+ ){
+   if( pExpr==0 ) return 0;
+-  if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
++  if( ExprHasProperty(pExpr, EP_FromJoin) && pExpr->iRightJoinTable==pSubst->iTable ){
++    pExpr->iRightJoinTable = pSubst->iNewTable;
++  }
++  if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){
+     if( pExpr->iColumn<0 ){
+       pExpr->op = TK_NULL;
+     }else{
+       Expr *pNew;
+-      assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
++      Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr;
++      Expr ifNullRow;
++      assert( pSubst->pEList!=0 && pExpr->iColumn<pSubst->pEList->nExpr );
+       assert( pExpr->pLeft==0 && pExpr->pRight==0 );
+-      pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
+-      sqlite3ExprDelete(db, pExpr);
+-      pExpr = pNew;
++      if( sqlite3ExprIsVector(pCopy) ){
++        sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
++      }else{
++        sqlite3 *db = pSubst->pParse->db;
++        if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
++          memset(&ifNullRow, 0, sizeof(ifNullRow));
++          ifNullRow.op = TK_IF_NULL_ROW;
++          ifNullRow.pLeft = pCopy;
++          ifNullRow.iTable = pSubst->iNewTable;
++          pCopy = &ifNullRow;
++        }
++        pNew = sqlite3ExprDup(db, pCopy, 0);
++        if( pNew && pSubst->isLeftJoin ){
++          ExprSetProperty(pNew, EP_CanBeNull);
++        }
++        if( pNew && ExprHasProperty(pExpr,EP_FromJoin) ){
++          pNew->iRightJoinTable = pExpr->iRightJoinTable;
++          ExprSetProperty(pNew, EP_FromJoin);
++        }
++        sqlite3ExprDelete(db, pExpr);
++        pExpr = pNew;
++      }
+     }
+   }else{
+-    pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
+-    pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
++    if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
++      pExpr->iTable = pSubst->iNewTable;
++    }
++    pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
++    pExpr->pRight = substExpr(pSubst, pExpr->pRight);
+     if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+-      substSelect(db, pExpr->x.pSelect, iTable, pEList);
++      substSelect(pSubst, pExpr->x.pSelect, 1);
+     }else{
+-      substExprList(db, pExpr->x.pList, iTable, pEList);
++      substExprList(pSubst, pExpr->x.pList);
+     }
+   }
+   return pExpr;
+ }
+ static void substExprList(
+-  sqlite3 *db,         /* Report malloc errors here */
+-  ExprList *pList,     /* List to scan and in which to make substitutes */
+-  int iTable,          /* Table to be substituted */
+-  ExprList *pEList     /* Substitute values */
++  SubstContext *pSubst, /* Description of the substitution */
++  ExprList *pList       /* List to scan and in which to make substitutes */
+ ){
+   int i;
+   if( pList==0 ) return;
+   for(i=0; i<pList->nExpr; i++){
+-    pList->a[i].pExpr = substExpr(db, pList->a[i].pExpr, iTable, pEList);
++    pList->a[i].pExpr = substExpr(pSubst, pList->a[i].pExpr);
+   }
+ }
+ static void substSelect(
+-  sqlite3 *db,         /* Report malloc errors here */
+-  Select *p,           /* SELECT statement in which to make substitutions */
+-  int iTable,          /* Table to be replaced */
+-  ExprList *pEList     /* Substitute values */
++  SubstContext *pSubst, /* Description of the substitution */
++  Select *p,            /* SELECT statement in which to make substitutions */
++  int doPrior           /* Do substitutes on p->pPrior too */
+ ){
+   SrcList *pSrc;
+   struct SrcList_item *pItem;
+   int i;
+   if( !p ) return;
+-  substExprList(db, p->pEList, iTable, pEList);
+-  substExprList(db, p->pGroupBy, iTable, pEList);
+-  substExprList(db, p->pOrderBy, iTable, pEList);
+-  p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
+-  p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
+-  substSelect(db, p->pPrior, iTable, pEList);
+-  pSrc = p->pSrc;
+-  assert( pSrc );  /* Even for (SELECT 1) we have: pSrc!=0 but pSrc->nSrc==0 */
+-  if( ALWAYS(pSrc) ){
++  do{
++    substExprList(pSubst, p->pEList);
++    substExprList(pSubst, p->pGroupBy);
++    substExprList(pSubst, p->pOrderBy);
++    p->pHaving = substExpr(pSubst, p->pHaving);
++    p->pWhere = substExpr(pSubst, p->pWhere);
++    pSrc = p->pSrc;
++    assert( pSrc!=0 );
+     for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
+-      substSelect(db, pItem->pSelect, iTable, pEList);
++      substSelect(pSubst, pItem->pSelect, 1);
++      if( pItem->fg.isTabFunc ){
++        substExprList(pSubst, pItem->u1.pFuncArg);
++      }
+     }
+-  }
++  }while( doPrior && (p = p->pPrior)!=0 );
+ }
+ #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
+ 
+@@ -109731,8 +124047,10 @@
+ **        FROM-clause subquery that is a candidate for flattening.  (2b is
+ **        due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
+ **
+-**   (3)  The subquery is not the right operand of a left outer join
+-**        (Originally ticket #306.  Strengthened by ticket #3300)
++**   (3)  The subquery is not the right operand of a LEFT JOIN
++**        or (a) the subquery is not itself a join and (b) the FROM clause
++**        of the subquery does not contain a virtual table and (c) the 
++**        outer query is not an aggregate.
+ **
+ **   (4)  The subquery is not DISTINCT.
+ **
+@@ -109744,7 +124062,7 @@
+ **        DISTINCT.
+ **
+ **   (7)  The subquery has a FROM clause.  TODO:  For subqueries without
+-**        A FROM clause, consider adding a FROM close with the special
++**        A FROM clause, consider adding a FROM clause with the special
+ **        table sqlite_once that consists of a single row containing a
+ **        single NULL.
+ **
+@@ -109755,8 +124073,8 @@
+ **
+ **  (**)  Restriction (10) was removed from the code on 2005-02-05 but we
+ **        accidently carried the comment forward until 2014-09-15.  Original
+-**        text: "The subquery does not use aggregates or the outer query does not
+-**        use LIMIT."
++**        text: "The subquery does not use aggregates or the outer query 
++**        does not use LIMIT."
+ **
+ **  (11)  The subquery and the outer query do not both have ORDER BY clauses.
+ **
+@@ -109843,13 +124161,14 @@
+   int subqueryIsAgg    /* True if the subquery uses aggregate functions */
+ ){
+   const char *zSavedAuthContext = pParse->zAuthContext;
+-  Select *pParent;
++  Select *pParent;    /* Current UNION ALL term of the other query */
+   Select *pSub;       /* The inner query or "subquery" */
+   Select *pSub1;      /* Pointer to the rightmost select in sub-query */
+   SrcList *pSrc;      /* The FROM clause of the outer query */
+   SrcList *pSubSrc;   /* The FROM clause of the subquery */
+-  ExprList *pList;    /* The result set of the outer query */
+   int iParent;        /* VDBE cursor number of the pSub result set temp table */
++  int iNewParent = -1;/* Replacement table for iParent */
++  int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */    
+   int i;              /* Loop counter */
+   Expr *pWhere;                    /* The WHERE clause */
+   struct SrcList_item *pSubitem;   /* The subquery */
+@@ -109876,7 +124195,7 @@
+       return 0;                                          /* Restriction (2b)  */
+     }
+   }
+-    
++
+   pSubSrc = pSub->pSrc;
+   assert( pSubSrc );
+   /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
+@@ -109914,10 +124233,9 @@
+     return 0; /* Restriction (23) */
+   }
+ 
+-  /* OBSOLETE COMMENT 1:
+-  ** Restriction 3:  If the subquery is a join, make sure the subquery is 
+-  ** not used as the right operand of an outer join.  Examples of why this
+-  ** is not allowed:
++  /*
++  ** If the subquery is the right operand of a LEFT JOIN, then the
++  ** subquery may not be a join itself.  Example of why this is not allowed:
+   **
+   **         t1 LEFT OUTER JOIN (t2 JOIN t3)
+   **
+@@ -109927,28 +124245,27 @@
+   **
+   ** which is not at all the same thing.
+   **
+-  ** OBSOLETE COMMENT 2:
+-  ** Restriction 12:  If the subquery is the right operand of a left outer
+-  ** join, make sure the subquery has no WHERE clause.
+-  ** An examples of why this is not allowed:
+-  **
+-  **         t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
+-  **
+-  ** If we flatten the above, we would get
+-  **
+-  **         (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
+-  **
+-  ** But the t2.x>0 test will always fail on a NULL row of t2, which
+-  ** effectively converts the OUTER JOIN into an INNER JOIN.
+-  **
+-  ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE:
+-  ** Ticket #3300 shows that flattening the right term of a LEFT JOIN
+-  ** is fraught with danger.  Best to avoid the whole thing.  If the
+-  ** subquery is the right term of a LEFT JOIN, then do not flatten.
+-  */
+-  if( (pSubitem->jointype & JT_OUTER)!=0 ){
+-    return 0;
++  ** If the subquery is the right operand of a LEFT JOIN, then the outer
++  ** query cannot be an aggregate.  This is an artifact of the way aggregates
++  ** are processed - there is no mechanism to determine if the LEFT JOIN
++  ** table should be all-NULL.
++  **
++  ** See also tickets #306, #350, and #3300.
++  */
++  if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
++    isLeftJoin = 1;
++    if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){
++      return 0; /* Restriction (3) */
++    }
++  }
++#ifdef SQLITE_EXTRA_IFNULLROW
++  else if( iFrom>0 && !isAgg ){
++    /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for
++    ** every reference to any result column from subquery in a join, even though
++    ** they are not necessary.  This will stress-test the OP_IfNullRow opcode. */
++    isLeftJoin = -1;
+   }
 +#endif
-+#if SQLITE_OMIT_GET_TABLE
-+  "OMIT_GET_TABLE",
+ 
+   /* Restriction 17: If the sub-query is a compound SELECT, then it must
+   ** use only the UNION ALL operator. And none of the simple select queries
+@@ -109966,10 +124283,10 @@
+       testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
+       testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
+       assert( pSub->pSrc!=0 );
++      assert( pSub->pEList->nExpr==pSub1->pEList->nExpr );
+       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;
+       }
+@@ -110085,12 +124402,12 @@
+   */
+   if( ALWAYS(pSubitem->pTab!=0) ){
+     Table *pTabToDel = pSubitem->pTab;
+-    if( pTabToDel->nRef==1 ){
++    if( pTabToDel->nTabRef==1 ){
+       Parse *pToplevel = sqlite3ParseToplevel(pParse);
+       pTabToDel->pNextZombie = pToplevel->pZombieTab;
+       pToplevel->pZombieTab = pTabToDel;
+     }else{
+-      pTabToDel->nRef--;
++      pTabToDel->nTabRef--;
+     }
+     pSubitem->pTab = 0;
+   }
+@@ -110117,7 +124434,7 @@
+ 
+     if( pSrc ){
+       assert( pParent==p );  /* First time through the loop */
+-      jointype = pSubitem->jointype;
++      jointype = pSubitem->fg.jointype;
+     }else{
+       assert( pParent!=p );  /* 2nd and subsequent times through the loop */
+       pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
+@@ -110138,9 +124455,9 @@
+     **
+     ** The outer query has 3 slots in its FROM clause.  One slot of the
+     ** outer query (the middle slot) is used by the subquery.  The next
+-    ** block of code will expand the out query to 4 slots.  The middle
+-    ** slot is expanded to two slots in order to make space for the
+-    ** two elements in the FROM clause of the subquery.
++    ** block of code will expand the outer query FROM clause to 4 slots.
++    ** The middle slot is expanded to two slots in order to make space
++    ** for the two elements in the FROM clause of the subquery.
+     */
+     if( nSubSrc>1 ){
+       pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
+@@ -110154,10 +124471,12 @@
+     */
+     for(i=0; i<nSubSrc; i++){
+       sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
++      assert( pSrc->a[i+iFrom].fg.isTabFunc==0 );
+       pSrc->a[i+iFrom] = pSubSrc->a[i];
++      iNewParent = pSubSrc->a[i].iCursor;
+       memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
+     }
+-    pSrc->a[iFrom].jointype = jointype;
++    pSrc->a[iFrom].fg.jointype = jointype;
+   
+     /* Now begin substituting subquery result set expressions for 
+     ** references to the iParent in the outer query.
+@@ -110171,19 +124490,6 @@
+     ** We look at every expression in the outer query and every place we see
+     ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
+     */
+-    pList = pParent->pEList;
+-    for(i=0; i<pList->nExpr; i++){
+-      if( pList->a[i].zName==0 ){
+-        char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
+-        sqlite3Dequote(zName);
+-        pList->a[i].zName = zName;
+-      }
+-    }
+-    substExprList(db, pParent->pEList, iParent, pSub->pEList);
+-    if( isAgg ){
+-      substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
+-      pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
+-    }
+     if( pSub->pOrderBy ){
+       /* At this point, any non-zero iOrderByCol values indicate that the
+       ** ORDER BY column expression is identical to the iOrderByCol'th
+@@ -110203,26 +124509,31 @@
+       assert( pSub->pPrior==0 );
+       pParent->pOrderBy = pOrderBy;
+       pSub->pOrderBy = 0;
+-    }else if( pParent->pOrderBy ){
+-      substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
+     }
+-    if( pSub->pWhere ){
+-      pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
+-    }else{
+-      pWhere = 0;
++    pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
++    if( isLeftJoin>0 ){
++      setJoinExpr(pWhere, iNewParent);
+     }
+     if( subqueryIsAgg ){
+       assert( pParent->pHaving==0 );
+       pParent->pHaving = pParent->pWhere;
+       pParent->pWhere = pWhere;
+-      pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
+-      pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving, 
+-                                  sqlite3ExprDup(db, pSub->pHaving, 0));
++      pParent->pHaving = sqlite3ExprAnd(db, 
++          sqlite3ExprDup(db, pSub->pHaving, 0), pParent->pHaving
++      );
+       assert( pParent->pGroupBy==0 );
+       pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
+     }else{
+-      pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList);
+-      pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
++      pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
++    }
++    if( db->mallocFailed==0 ){
++      SubstContext x;
++      x.pParse = pParse;
++      x.iTable = iParent;
++      x.iNewTable = iNewParent;
++      x.isLeftJoin = isLeftJoin;
++      x.pEList = pSub->pEList;
++      substSelect(&x, pParent, 0);
+     }
+   
+     /* The flattened query is distinct if either the inner or the
+@@ -110249,7 +124560,7 @@
+ 
+ #if SELECTTRACE_ENABLED
+   if( sqlite3SelectTrace & 0x100 ){
+-    sqlite3DebugPrintf("After flattening:\n");
++    SELECTTRACE(0x100,pParse,p,("After flattening:\n"));
+     sqlite3TreeViewSelect(0, p, 0);
+   }
+ #endif
+@@ -110258,6 +124569,89 @@
+ }
+ #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
+ 
++
++
++#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
++/*
++** Make copies of relevant WHERE clause terms of the outer query into
++** the WHERE clause of subquery.  Example:
++**
++**    SELECT * FROM (SELECT a AS x, c-d AS y FROM t1) WHERE x=5 AND y=10;
++**
++** Transformed into:
++**
++**    SELECT * FROM (SELECT a AS x, c-d AS y FROM t1 WHERE a=5 AND c-d=10)
++**     WHERE x=5 AND y=10;
++**
++** The hope is that the terms added to the inner query will make it more
++** efficient.
++**
++** Do not attempt this optimization if:
++**
++**   (1) The inner query is an aggregate.  (In that case, we'd really want
++**       to copy the outer WHERE-clause terms onto the HAVING clause of the
++**       inner query.  But they probably won't help there so do not bother.)
++**
++**   (2) The inner query is the recursive part of a common table expression.
++**
++**   (3) The inner query has a LIMIT clause (since the changes to the WHERE
++**       close would change the meaning of the LIMIT).
++**
++**   (4) The inner query is the right operand of a LEFT JOIN.  (The caller
++**       enforces this restriction since this routine does not have enough
++**       information to know.)
++**
++**   (5) The WHERE clause expression originates in the ON or USING clause
++**       of a LEFT JOIN.
++**
++** Return 0 if no changes are made and non-zero if one or more WHERE clause
++** terms are duplicated into the subquery.
++*/
++static int pushDownWhereTerms(
++  Parse *pParse,        /* Parse context (for malloc() and error reporting) */
++  Select *pSubq,        /* The subquery whose WHERE clause is to be augmented */
++  Expr *pWhere,         /* The WHERE clause of the outer query */
++  int iCursor           /* Cursor number of the subquery */
++){
++  Expr *pNew;
++  int nChng = 0;
++  Select *pX;           /* For looping over compound SELECTs in pSubq */
++  if( pWhere==0 ) return 0;
++  for(pX=pSubq; pX; pX=pX->pPrior){
++    if( (pX->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
++      testcase( pX->selFlags & SF_Aggregate );
++      testcase( pX->selFlags & SF_Recursive );
++      testcase( pX!=pSubq );
++      return 0; /* restrictions (1) and (2) */
++    }
++  }
++  if( pSubq->pLimit!=0 ){
++    return 0; /* restriction (3) */
++  }
++  while( pWhere->op==TK_AND ){
++    nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, iCursor);
++    pWhere = pWhere->pLeft;
++  }
++  if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */
++  if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
++    nChng++;
++    while( pSubq ){
++      SubstContext x;
++      pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
++      x.pParse = pParse;
++      x.iTable = iCursor;
++      x.iNewTable = iCursor;
++      x.isLeftJoin = 0;
++      x.pEList = pSubq->pEList;
++      pNew = substExpr(&x, pNew);
++      pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
++      pSubq = pSubq->pPrior;
++    }
++  }
++  return nChng;
++}
++#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
++
+ /*
+ ** Based on the contents of the AggInfo structure indicated by the first
+ ** argument, this function checks if the following are true:
+@@ -110341,20 +124735,20 @@
+ ** pFrom->pIndex and return SQLITE_OK.
+ */
+ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){
+-  if( pFrom->pTab && pFrom->zIndex ){
++  if( pFrom->pTab && pFrom->fg.isIndexedBy ){
+     Table *pTab = pFrom->pTab;
+-    char *zIndex = pFrom->zIndex;
++    char *zIndexedBy = pFrom->u1.zIndexedBy;
+     Index *pIdx;
+     for(pIdx=pTab->pIndex; 
+-        pIdx && sqlite3StrICmp(pIdx->zName, zIndex); 
++        pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); 
+         pIdx=pIdx->pNext
+     );
+     if( !pIdx ){
+-      sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0);
++      sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0);
+       pParse->checkSchema = 1;
+       return SQLITE_ERROR;
+     }
+-    pFrom->pIndex = pIdx;
++    pFrom->pIBIndex = pIdx;
+   }
+   return SQLITE_OK;
+ }
+@@ -110410,7 +124804,7 @@
+   if( pNewSrc==0 ) return WRC_Abort;
+   *pNew = *p;
+   p->pSrc = pNewSrc;
+-  p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ALL, 0));
++  p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
+   p->op = TK_SELECT;
+   p->pWhere = 0;
+   pNew->pGroupBy = 0;
+@@ -110429,6 +124823,19 @@
+   return WRC_Continue;
+ }
+ 
++/*
++** Check to see if the FROM clause term pFrom has table-valued function
++** arguments.  If it does, leave an error message in pParse and return
++** non-zero, since pFrom is not allowed to be a table-valued function.
++*/
++static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){
++  if( pFrom->fg.isTabFunc ){
++    sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName);
++    return 1;
++  }
++  return 0;
++}
++
+ #ifndef SQLITE_OMIT_CTE
+ /*
+ ** Argument pWith (which may be NULL) points to a linked list of nested 
+@@ -110441,7 +124848,7 @@
+ ** object that the returned CTE belongs to.
+ */
+ static struct Cte *searchWith(
+-  With *pWith,                    /* Current outermost WITH clause */
++  With *pWith,                    /* Current innermost WITH clause */
+   struct SrcList_item *pItem,     /* FROM clause element to resolve */
+   With **ppContext                /* OUT: WITH clause return value belongs to */
+ ){
+@@ -110472,11 +124879,12 @@
+ ** statement with which it is associated.
+ */
+ SQLITE_PRIVATE void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
+-  assert( bFree==0 || pParse->pWith==0 );
++  assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) );
+   if( pWith ){
++    assert( pParse->pWith!=pWith );
+     pWith->pOuter = pParse->pWith;
+     pParse->pWith = pWith;
+-    pParse->bFreeWith = bFree;
++    if( bFree ) pParse->pWithToFree = pWith;
+   }
+ }
+ 
+@@ -110515,25 +124923,26 @@
+     int bMayRecursive;            /* True if compound joined by UNION [ALL] */
+     With *pSavedWith;             /* Initial value of pParse->pWith */
+ 
+-    /* If pCte->zErr is non-NULL at this point, then this is an illegal
++    /* If pCte->zCteErr is non-NULL at this point, then this is an illegal
+     ** recursive reference to CTE pCte. Leave an error in pParse and return
+-    ** early. If pCte->zErr is NULL, then this is not a recursive reference.
++    ** early. If pCte->zCteErr is NULL, then this is not a recursive reference.
+     ** In this case, proceed.  */
+-    if( pCte->zErr ){
+-      sqlite3ErrorMsg(pParse, pCte->zErr, pCte->zName);
++    if( pCte->zCteErr ){
++      sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName);
+       return SQLITE_ERROR;
+     }
++    if( cannotBeFunction(pParse, pFrom) ) return SQLITE_ERROR;
+ 
+     assert( pFrom->pTab==0 );
+     pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
+     if( pTab==0 ) return WRC_Abort;
+-    pTab->nRef = 1;
++    pTab->nTabRef = 1;
+     pTab->zName = sqlite3DbStrDup(db, pCte->zName);
+     pTab->iPKey = -1;
+     pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
+-    pTab->tabFlags |= TF_Ephemeral;
++    pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
+     pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
+-    if( db->mallocFailed ) return SQLITE_NOMEM;
++    if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
+     assert( pFrom->pSelect );
+ 
+     /* Check if this is a recursive CTE. */
+@@ -110549,26 +124958,35 @@
+          && 0==sqlite3StrICmp(pItem->zName, pCte->zName)
+           ){
+           pItem->pTab = pTab;
+-          pItem->isRecursive = 1;
+-          pTab->nRef++;
++          pItem->fg.isRecursive = 1;
++          pTab->nTabRef++;
+           pSel->selFlags |= SF_Recursive;
+         }
+       }
+     }
+ 
+     /* Only one recursive reference is permitted. */ 
+-    if( pTab->nRef>2 ){
++    if( pTab->nTabRef>2 ){
+       sqlite3ErrorMsg(
+           pParse, "multiple references to recursive table: %s", pCte->zName
+       );
+       return SQLITE_ERROR;
+     }
+-    assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 ));
++    assert( pTab->nTabRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 ));
+ 
+-    pCte->zErr = "circular reference: %s";
++    pCte->zCteErr = "circular reference: %s";
+     pSavedWith = pParse->pWith;
+     pParse->pWith = pWith;
+-    sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel);
++    if( bMayRecursive ){
++      Select *pPrior = pSel->pPrior;
++      assert( pPrior->pWith==0 );
++      pPrior->pWith = pSel->pWith;
++      sqlite3WalkSelect(pWalker, pPrior);
++      pPrior->pWith = 0;
++    }else{
++      sqlite3WalkSelect(pWalker, pSel);
++    }
++    pParse->pWith = pWith;
+ 
+     for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
+     pEList = pLeft->pEList;
+@@ -110583,16 +125001,16 @@
+       pEList = pCte->pCols;
+     }
+ 
+-    selectColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol);
++    sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol);
+     if( bMayRecursive ){
+       if( pSel->selFlags & SF_Recursive ){
+-        pCte->zErr = "multiple recursive references: %s";
++        pCte->zCteErr = "multiple recursive references: %s";
+       }else{
+-        pCte->zErr = "recursive reference in a subquery: %s";
++        pCte->zCteErr = "recursive reference in a subquery: %s";
+       }
+       sqlite3WalkSelect(pWalker, pSel);
+     }
+-    pCte->zErr = 0;
++    pCte->zCteErr = 0;
+     pParse->pWith = pSavedWith;
+   }
+ 
+@@ -110611,10 +125029,12 @@
+ */
+ static void selectPopWith(Walker *pWalker, Select *p){
+   Parse *pParse = pWalker->pParse;
+-  With *pWith = findRightmost(p)->pWith;
+-  if( pWith!=0 ){
+-    assert( pParse->pWith==pWith );
+-    pParse->pWith = pWith->pOuter;
++  if( pParse->pWith && p->pPrior==0 ){
++    With *pWith = findRightmost(p)->pWith;
++    if( pWith!=0 ){
++      assert( pParse->pWith==pWith );
++      pParse->pWith = pWith->pOuter;
++    }
+   }
+ }
+ #else
+@@ -110664,8 +125084,8 @@
+   }
+   pTabList = p->pSrc;
+   pEList = p->pEList;
+-  if( pWalker->xSelectCallback2==selectPopWith ){
+-    sqlite3WithPush(pParse, findRightmost(p)->pWith, 0);
++  if( p->pWith ){
++    sqlite3WithPush(pParse, p->pWith, 0);
+   }
+ 
+   /* Make sure cursor numbers have been assigned to all entries in
+@@ -110679,17 +125099,9 @@
+   */
+   for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+     Table *pTab;
+-    assert( pFrom->isRecursive==0 || pFrom->pTab );
+-    if( pFrom->isRecursive ) continue;
+-    if( pFrom->pTab!=0 ){
+-      /* This statement has already been prepared.  There is no need
+-      ** to go further. */
+-      assert( i==0 );
+-#ifndef SQLITE_OMIT_CTE
+-      selectPopWith(pWalker, p);
+-#endif
+-      return WRC_Prune;
+-    }
++    assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 );
++    if( pFrom->fg.isRecursive ) continue;
++    assert( pFrom->pTab==0 );
+ #ifndef SQLITE_OMIT_CTE
+     if( withExpand(pWalker, pFrom) ) return WRC_Abort;
+     if( pFrom->pTab ) {} else
+@@ -110703,10 +125115,10 @@
+       if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
+       pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
+       if( pTab==0 ) return WRC_Abort;
+-      pTab->nRef = 1;
++      pTab->nTabRef = 1;
+       pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab);
+       while( pSel->pPrior ){ pSel = pSel->pPrior; }
+-      selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
++      sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
+       pTab->iPKey = -1;
+       pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
+       pTab->tabFlags |= TF_Ephemeral;
+@@ -110716,21 +125128,27 @@
+       assert( pFrom->pTab==0 );
+       pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
+       if( pTab==0 ) return WRC_Abort;
+-      if( pTab->nRef==0xffff ){
++      if( pTab->nTabRef>=0xffff ){
+         sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",
+            pTab->zName);
+         pFrom->pTab = 0;
+         return WRC_Abort;
+       }
+-      pTab->nRef++;
++      pTab->nTabRef++;
++      if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){
++        return WRC_Abort;
++      }
+ #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
+-      if( pTab->pSelect || IsVirtual(pTab) ){
+-        /* We reach here if the named table is a really a view */
++      if( IsVirtual(pTab) || pTab->pSelect ){
++        i16 nCol;
+         if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
+         assert( pFrom->pSelect==0 );
+         pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
+         sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
++        nCol = pTab->nCol;
++        pTab->nCol = -1;
+         sqlite3WalkSelect(pWalker, pFrom->pSelect);
++        pTab->nCol = nCol;
+       }
+ #endif
+     }
+@@ -110750,19 +125168,20 @@
+   /* For every "*" that occurs in the column list, insert the names of
+   ** all columns in all tables.  And for every TABLE.* insert the names
+   ** of all columns in TABLE.  The parser inserted a special expression
+-  ** with the TK_ALL operator for each "*" that it found in the column list.
+-  ** The following code just has to locate the TK_ALL expressions and expand
+-  ** each one to the list of all columns in all tables.
++  ** with the TK_ASTERISK operator for each "*" that it found in the column
++  ** list.  The following code just has to locate the TK_ASTERISK
++  ** expressions and expand each one to the list of all columns in
++  ** all tables.
+   **
+   ** The first loop just checks to see if there are any "*" operators
+   ** that need expanding.
+   */
+   for(k=0; k<pEList->nExpr; k++){
+     pE = pEList->a[k].pExpr;
+-    if( pE->op==TK_ALL ) break;
++    if( pE->op==TK_ASTERISK ) break;
+     assert( pE->op!=TK_DOT || pE->pRight!=0 );
+     assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
+-    if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break;
++    if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break;
+   }
+   if( k<pEList->nExpr ){
+     /*
+@@ -110776,18 +125195,13 @@
+     int longNames = (flags & SQLITE_FullColNames)!=0
+                       && (flags & SQLITE_ShortColNames)==0;
+ 
+-    /* When processing FROM-clause subqueries, it is always the case
+-    ** that full_column_names=OFF and short_column_names=ON.  The
+-    ** sqlite3ResultSetOfSelect() routine makes it so. */
+-    assert( (p->selFlags & SF_NestedFrom)==0
+-          || ((flags & SQLITE_FullColNames)==0 &&
+-              (flags & SQLITE_ShortColNames)!=0) );
+-
+     for(k=0; k<pEList->nExpr; k++){
+       pE = a[k].pExpr;
+       pRight = pE->pRight;
+       assert( pE->op!=TK_DOT || pRight!=0 );
+-      if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pRight->op!=TK_ALL) ){
++      if( pE->op!=TK_ASTERISK
++       && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK)
++      ){
+         /* This particular expression does not need to be expanded.
+         */
+         pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
+@@ -110824,7 +125238,7 @@
+               continue;
+             }
+             iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+-            zSchemaName = iDb>=0 ? db->aDb[iDb].zName : "*";
++            zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*";
+           }
+           for(j=0; j<pTab->nCol; j++){
+             char *zName = pTab->aCol[j].zName;
+@@ -110839,18 +125253,19 @@
+               continue;
+             }
+ 
+-            /* If a column is marked as 'hidden' (currently only possible
+-            ** for virtual tables), do not include it in the expanded
+-            ** result-set list.
++            /* If a column is marked as 'hidden', omit it from the expanded
++            ** result-set list unless the SELECT has the SF_IncludeHidden
++            ** bit set.
+             */
+-            if( IsHiddenColumn(&pTab->aCol[j]) ){
+-              assert(IsVirtual(pTab));
++            if( (p->selFlags & SF_IncludeHidden)==0
++             && IsHiddenColumn(&pTab->aCol[j]) 
++            ){
+               continue;
+             }
+             tableSeen = 1;
+ 
+             if( i>0 && zTName==0 ){
+-              if( (pFrom->jointype & JT_NATURAL)!=0
++              if( (pFrom->fg.jointype & JT_NATURAL)!=0
+                 && tableAndColumnIndex(pTabList, i, zName, 0, 0)
+               ){
+                 /* In a NATURAL join, omit the join columns from the 
+@@ -110869,10 +125284,10 @@
+             if( longNames || pTabList->nSrc>1 ){
+               Expr *pLeft;
+               pLeft = sqlite3Expr(db, TK_ID, zTabName);
+-              pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
++              pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
+               if( zSchemaName ){
+                 pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
+-                pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr, 0);
++                pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr);
+               }
+               if( longNames ){
+                 zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
+@@ -110882,8 +125297,7 @@
+               pExpr = pRight;
+             }
+             pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
+-            sColname.z = zColname;
+-            sColname.n = sqlite3Strlen30(zColname);
++            sqlite3TokenInit(&sColname, zColname);
+             sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
+             if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
+               struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
+@@ -110915,6 +125329,7 @@
+ #if SQLITE_MAX_COLUMN
+   if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
+     sqlite3ErrorMsg(pParse, "too many columns in result set");
++    return WRC_Abort;
+   }
+ #endif
+   return WRC_Continue;
+@@ -110929,11 +125344,30 @@
+ ** Walker.xSelectCallback is set to do something useful for every 
+ ** subquery in the parser tree.
+ */
+-static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
++SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
++  UNUSED_PARAMETER2(NotUsed, NotUsed2);
++  return WRC_Continue;
++}
++
++/*
++** No-op routine for the parse-tree walker for SELECT statements.
++** subquery in the parser tree.
++*/
++SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
+   UNUSED_PARAMETER2(NotUsed, NotUsed2);
+   return WRC_Continue;
+ }
+ 
++#if SQLITE_DEBUG
++/*
++** Always assert.  This xSelectCallback2 implementation proves that the
++** xSelectCallback2 is never invoked.
++*/
++SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2){
++  UNUSED_PARAMETER2(NotUsed, NotUsed2);
++  assert( 0 );
++}
 +#endif
-+#if SQLITE_OMIT_INCRBLOB
-+  "OMIT_INCRBLOB",
+ /*
+ ** This routine "expands" a SELECT statement and all of its subqueries.
+ ** For additional information on what it means to "expand" a SELECT
+@@ -110949,17 +125383,15 @@
+ */
+ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
+   Walker w;
+-  memset(&w, 0, sizeof(w));
+-  w.xExprCallback = exprWalkNoop;
++  w.xExprCallback = sqlite3ExprWalkNoop;
+   w.pParse = pParse;
+   if( pParse->hasCompound ){
+     w.xSelectCallback = convertCompoundSelectToSubquery;
++    w.xSelectCallback2 = 0;
+     sqlite3WalkSelect(&w, pSelect);
+   }
+   w.xSelectCallback = selectExpander;
+-  if( (pSelect->selFlags & SF_MultiValue)==0 ){
+-    w.xSelectCallback2 = selectPopWith;
+-  }
++  w.xSelectCallback2 = selectPopWith;
+   sqlite3WalkSelect(&w, pSelect);
+ }
+ 
+@@ -110985,19 +125417,19 @@
+   struct SrcList_item *pFrom;
+ 
+   assert( p->selFlags & SF_Resolved );
+-  if( (p->selFlags & SF_HasTypeInfo)==0 ){
+-    p->selFlags |= SF_HasTypeInfo;
+-    pParse = pWalker->pParse;
+-    pTabList = p->pSrc;
+-    for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+-      Table *pTab = pFrom->pTab;
+-      if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){
+-        /* A sub-query in the FROM clause of a SELECT */
+-        Select *pSel = pFrom->pSelect;
+-        if( pSel ){
+-          while( pSel->pPrior ) pSel = pSel->pPrior;
+-          selectAddColumnTypeAndCollation(pParse, pTab, pSel);
+-        }
++  assert( (p->selFlags & SF_HasTypeInfo)==0 );
++  p->selFlags |= SF_HasTypeInfo;
++  pParse = pWalker->pParse;
++  pTabList = p->pSrc;
++  for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
++    Table *pTab = pFrom->pTab;
++    assert( pTab!=0 );
++    if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
++      /* A sub-query in the FROM clause of a SELECT */
++      Select *pSel = pFrom->pSelect;
++      if( pSel ){
++        while( pSel->pPrior ) pSel = pSel->pPrior;
++        sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel);
+       }
+     }
+   }
+@@ -111015,9 +125447,9 @@
+ static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){
+ #ifndef SQLITE_OMIT_SUBQUERY
+   Walker w;
+-  memset(&w, 0, sizeof(w));
++  w.xSelectCallback = sqlite3SelectWalkNoop;
+   w.xSelectCallback2 = selectAddSubqueryTypeInfo;
+-  w.xExprCallback = exprWalkNoop;
++  w.xExprCallback = sqlite3ExprWalkNoop;
+   w.pParse = pParse;
+   sqlite3WalkSelect(&w, pSelect);
+ #endif
+@@ -111109,8 +125541,8 @@
+   for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
+     ExprList *pList = pF->pExpr->x.pList;
+     assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
+-    sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0,
+-                      (void*)pF->pFunc, P4_FUNCDEF);
++    sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0);
++    sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
+   }
+ }
+ 
+@@ -111136,7 +125568,7 @@
+     if( pList ){
+       nArg = pList->nExpr;
+       regAgg = sqlite3GetTempRange(pParse, nArg);
+-      sqlite3ExprCodeExprList(pParse, pList, regAgg, SQLITE_ECEL_DUP);
++      sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP);
+     }else{
+       nArg = 0;
+       regAgg = 0;
+@@ -111161,8 +125593,8 @@
+       if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
+       sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
+     }
+-    sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
+-                      (void*)pF->pFunc, P4_FUNCDEF);
++    sqlite3VdbeAddOp3(v, OP_AggStep0, 0, regAgg, pF->iMem);
++    sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
+     sqlite3VdbeChangeP5(v, (u8)nArg);
+     sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
+     sqlite3ReleaseTempRange(pParse, regAgg, nArg);
+@@ -111223,6 +125655,187 @@
+ #endif
+ 
+ /*
++** Context object for havingToWhereExprCb().
++*/
++struct HavingToWhereCtx {
++  Expr **ppWhere;
++  ExprList *pGroupBy;
++};
++
++/*
++** sqlite3WalkExpr() callback used by havingToWhere().
++**
++** If the node passed to the callback is a TK_AND node, return 
++** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes.
++**
++** Otherwise, return WRC_Prune. In this case, also check if the 
++** sub-expression matches the criteria for being moved to the WHERE
++** clause. If so, add it to the WHERE clause and replace the sub-expression
++** within the HAVING expression with a constant "1".
++*/
++static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
++  if( pExpr->op!=TK_AND ){
++    struct HavingToWhereCtx *p = pWalker->u.pHavingCtx;
++    if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, p->pGroupBy) ){
++      sqlite3 *db = pWalker->pParse->db;
++      Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
++      if( pNew ){
++        Expr *pWhere = *(p->ppWhere);
++        SWAP(Expr, *pNew, *pExpr);
++        pNew = sqlite3ExprAnd(db, pWhere, pNew);
++        *(p->ppWhere) = pNew;
++      }
++    }
++    return WRC_Prune;
++  }
++  return WRC_Continue;
++}
++
++/*
++** Transfer eligible terms from the HAVING clause of a query, which is
++** processed after grouping, to the WHERE clause, which is processed before
++** grouping. For example, the query:
++**
++**   SELECT * FROM <tables> WHERE a=? GROUP BY b HAVING b=? AND c=?
++**
++** can be rewritten as:
++**
++**   SELECT * FROM <tables> WHERE a=? AND b=? GROUP BY b HAVING c=?
++**
++** A term of the HAVING expression is eligible for transfer if it consists
++** entirely of constants and expressions that are also GROUP BY terms that
++** use the "BINARY" collation sequence.
++*/
++static void havingToWhere(
++  Parse *pParse,
++  ExprList *pGroupBy,
++  Expr *pHaving, 
++  Expr **ppWhere
++){
++  struct HavingToWhereCtx sCtx;
++  Walker sWalker;
++
++  sCtx.ppWhere = ppWhere;
++  sCtx.pGroupBy = pGroupBy;
++
++  memset(&sWalker, 0, sizeof(sWalker));
++  sWalker.pParse = pParse;
++  sWalker.xExprCallback = havingToWhereExprCb;
++  sWalker.u.pHavingCtx = &sCtx;
++  sqlite3WalkExpr(&sWalker, pHaving);
++}
++
++/*
++** Check to see if the pThis entry of pTabList is a self-join of a prior view.
++** If it is, then return the SrcList_item for the prior view.  If it is not,
++** then return 0.
++*/
++static struct SrcList_item *isSelfJoinView(
++  SrcList *pTabList,           /* Search for self-joins in this FROM clause */
++  struct SrcList_item *pThis   /* Search for prior reference to this subquery */
++){
++  struct SrcList_item *pItem;
++  for(pItem = pTabList->a; pItem<pThis; pItem++){
++    if( pItem->pSelect==0 ) continue;
++    if( pItem->fg.viaCoroutine ) continue;
++    if( pItem->zName==0 ) continue;
++    if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
++    if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
++    if( sqlite3ExprCompare(0, 
++          pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1) 
++    ){
++      /* The view was modified by some other optimization such as
++      ** pushDownWhereTerms() */
++      continue;
++    }
++    return pItem;
++  }
++  return 0;
++}
++
++#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
++/*
++** Attempt to transform a query of the form
++**
++**    SELECT count(*) FROM (SELECT x FROM t1 UNION ALL SELECT y FROM t2)
++**
++** Into this:
++**
++**    SELECT (SELECT count(*) FROM t1)+(SELECT count(*) FROM t2)
++**
++** The transformation only works if all of the following are true:
++**
++**   *  The subquery is a UNION ALL of two or more terms
++**   *  There is no WHERE or GROUP BY or HAVING clauses on the subqueries
++**   *  The outer query is a simple count(*)
++**
++** Return TRUE if the optimization is undertaken.
++*/
++static int countOfViewOptimization(Parse *pParse, Select *p){
++  Select *pSub, *pPrior;
++  Expr *pExpr;
++  Expr *pCount;
++  sqlite3 *db;
++  if( (p->selFlags & SF_Aggregate)==0 ) return 0;   /* This is an aggregate query */
++  if( p->pEList->nExpr!=1 ) return 0;               /* Single result column */
++  pExpr = p->pEList->a[0].pExpr;
++  if( pExpr->op!=TK_AGG_FUNCTION ) return 0;        /* Result is an aggregate */
++  if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0;  /* Must be count() */
++  if( pExpr->x.pList!=0 ) return 0;                 /* Must be count(*) */
++  if( p->pSrc->nSrc!=1 ) return 0;                  /* One table in the FROM clause */
++  pSub = p->pSrc->a[0].pSelect;
++  if( pSub==0 ) return 0;                           /* The FROM is a subquery */
++  if( pSub->pPrior==0 ) return 0;                   /* Must be a compound subquery */
++  do{
++    if( pSub->op!=TK_ALL && pSub->pPrior ) return 0;  /* Must be UNION ALL */
++    if( pSub->pWhere ) return 0;                      /* No WHERE clause */
++    if( pSub->selFlags & SF_Aggregate ) return 0;     /* Not an aggregate */
++    pSub = pSub->pPrior;                              /* Repeat over compound terms */
++  }while( pSub );
++
++  /* If we reach this point, that means it is OK to perform the transformation */
++
++  db = pParse->db;
++  pCount = pExpr;
++  pExpr = 0;
++  pSub = p->pSrc->a[0].pSelect;
++  p->pSrc->a[0].pSelect = 0;
++  sqlite3SrcListDelete(db, p->pSrc);
++  p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc));
++  while( pSub ){
++    Expr *pTerm;
++    pPrior = pSub->pPrior;
++    pSub->pPrior = 0;
++    pSub->pNext = 0;
++    pSub->selFlags |= SF_Aggregate;
++    pSub->selFlags &= ~SF_Compound;
++    pSub->nSelectRow = 0;
++    sqlite3ExprListDelete(db, pSub->pEList);
++    pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount;
++    pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm);
++    pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
++    sqlite3PExprAddSelect(pParse, pTerm, pSub);
++    if( pExpr==0 ){
++      pExpr = pTerm;
++    }else{
++      pExpr = sqlite3PExpr(pParse, TK_PLUS, pTerm, pExpr);
++    }
++    pSub = pPrior;
++  }
++  p->pEList->a[0].pExpr = pExpr;
++  p->selFlags &= ~SF_Aggregate;
++
++#if SELECTTRACE_ENABLED
++  if( sqlite3SelectTrace & 0x400 ){
++    SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n"));
++    sqlite3TreeViewSelect(0, p, 0);
++  }
 +#endif
-+#if SQLITE_OMIT_INTEGRITY_CHECK
-+  "OMIT_INTEGRITY_CHECK",
++  return 1;
++}
++#endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */
++
++/*
+ ** Generate code for the SELECT statement given in the p argument.  
+ **
+ ** The results are returned according to the SelectDest structure.
+@@ -111244,7 +125857,7 @@
+   WhereInfo *pWInfo;     /* Return from sqlite3WhereBegin() */
+   Vdbe *v;               /* The virtual machine under construction */
+   int isAgg;             /* True for select lists like "count(*)" */
+-  ExprList *pEList;      /* List of columns to extract. */
++  ExprList *pEList = 0;  /* List of columns to extract. */
+   SrcList *pTabList;     /* List of tables to select from */
+   Expr *pWhere;          /* The WHERE clause.  May be NULL */
+   ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
+@@ -111294,12 +125907,11 @@
+   memset(&sSort, 0, sizeof(sSort));
+   sSort.pOrderBy = p->pOrderBy;
+   pTabList = p->pSrc;
+-  pEList = p->pEList;
+   if( pParse->nErr || db->mallocFailed ){
+     goto select_end;
+   }
++  assert( p->pEList!=0 );
+   isAgg = (p->selFlags & SF_Aggregate)!=0;
+-  assert( pEList!=0 );
+ #if SELECTTRACE_ENABLED
+   if( sqlite3SelectTrace & 0x100 ){
+     SELECTTRACE(0x100,pParse,p, ("after name resolution:\n"));
+@@ -111307,30 +125919,96 @@
+   }
+ #endif
+ 
+-
+-  /* Begin generating code.
+-  */
++  /* Get a pointer the VDBE under construction, allocating a new VDBE if one
++  ** does not already exist */
+   v = sqlite3GetVdbe(pParse);
+   if( v==0 ) goto select_end;
+-
+-  /* If writing to memory or generating a set
+-  ** only a single column may be output.
+-  */
+-#ifndef SQLITE_OMIT_SUBQUERY
+-  if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
+-    goto select_end;
++  if( pDest->eDest==SRT_Output ){
++    generateColumnNames(pParse, p);
+   }
+-#endif
+ 
+-  /* Generate code for all sub-queries in the FROM clause
++  /* Try to flatten subqueries in the FROM clause up into the main query
+   */
+ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+   for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
+     struct SrcList_item *pItem = &pTabList->a[i];
+-    SelectDest dest;
+     Select *pSub = pItem->pSelect;
+     int isAggSub;
++    Table *pTab = pItem->pTab;
++    if( pSub==0 ) continue;
++
++    /* Catch mismatch in the declared columns of a view and the number of
++    ** columns in the SELECT on the RHS */
++    if( pTab->nCol!=pSub->pEList->nExpr ){
++      sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d",
++                      pTab->nCol, pTab->zName, pSub->pEList->nExpr);
++      goto select_end;
++    }
++
++    isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
++    if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
++      /* This subquery can be absorbed into its parent. */
++      if( isAggSub ){
++        isAgg = 1;
++        p->selFlags |= SF_Aggregate;
++      }
++      i = -1;
++    }
++    pTabList = p->pSrc;
++    if( db->mallocFailed ) goto select_end;
++    if( !IgnorableOrderby(pDest) ){
++      sSort.pOrderBy = p->pOrderBy;
++    }
++  }
 +#endif
-+#if SQLITE_OMIT_LIKE_OPTIMIZATION
-+  "OMIT_LIKE_OPTIMIZATION",
++
++#ifndef SQLITE_OMIT_COMPOUND_SELECT
++  /* Handle compound SELECT statements using the separate multiSelect()
++  ** procedure.
++  */
++  if( p->pPrior ){
++    rc = multiSelect(pParse, p, pDest);
++    explainSetInteger(pParse->iSelectId, iRestoreSelectId);
++#if SELECTTRACE_ENABLED
++    SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
++    pParse->nSelectIndent--;
 +#endif
-+#if SQLITE_OMIT_LOAD_EXTENSION
-+  "OMIT_LOAD_EXTENSION",
++    return rc;
++  }
 +#endif
-+#if SQLITE_OMIT_LOCALTIME
-+  "OMIT_LOCALTIME",
++
++  /* For each term in the FROM clause, do two things:
++  ** (1) Authorized unreferenced tables
++  ** (2) Generate code for all sub-queries
++  */
++  for(i=0; i<pTabList->nSrc; i++){
++    struct SrcList_item *pItem = &pTabList->a[i];
++    SelectDest dest;
++    Select *pSub;
+ 
++    /* Issue SQLITE_READ authorizations with a fake column name for any tables that
++    ** are referenced but from which no values are extracted. Examples of where these
++    ** kinds of null SQLITE_READ authorizations would occur:
++    **
++    **     SELECT count(*) FROM t1;   -- SQLITE_READ t1.""
++    **     SELECT t1.* FROM t1, t2;   -- SQLITE_READ t2.""
++    **
++    ** The fake column name is an empty string.  It is possible for a table to
++    ** have a column named by the empty string, in which case there is no way to
++    ** distinguish between an unreferenced table and an actual reference to the
++    ** "" column.  The original design was for the fake column name to be a NULL,
++    ** which would be unambiguous.  But legacy authorization callbacks might
++    ** assume the column name is non-NULL and segfault.  The use of an empty string
++    ** for the fake column name seems safer.
++    */
++    if( pItem->colUsed==0 ){
++      sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
++    }
++
++#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
++    /* Generate code for all sub-queries in the FROM clause
++    */
++    pSub = pItem->pSelect;
+     if( pSub==0 ) continue;
+ 
+     /* Sometimes the code for a subquery will be generated more than
+@@ -111340,7 +126018,11 @@
+     ** is sufficient, though the subroutine to manifest the view does need
+     ** to be invoked again. */
+     if( pItem->addrFillSub ){
+-      if( pItem->viaCoroutine==0 ){
++      if( pItem->fg.viaCoroutine==0 ){
++        /* The subroutine that manifests the view might be a one-time routine,
++        ** or it might need to be rerun on each iteration because it
++        ** encodes a correlated subquery. */
++        testcase( sqlite3VdbeGetOp(v, pItem->addrFillSub)->opcode==OP_Once );
+         sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
+       }
+       continue;
+@@ -111355,16 +126037,39 @@
+     */
+     pParse->nHeight += sqlite3SelectExprHeight(p);
+ 
+-    isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
+-    if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
+-      /* This subquery can be absorbed into its parent. */
+-      if( isAggSub ){
+-        isAgg = 1;
+-        p->selFlags |= SF_Aggregate;
++    /* Make copies of constant WHERE-clause terms in the outer query down
++    ** inside the subquery.  This can help the subquery to run more efficiently.
++    */
++    if( (pItem->fg.jointype & JT_OUTER)==0
++     && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor)
++    ){
++#if SELECTTRACE_ENABLED
++      if( sqlite3SelectTrace & 0x100 ){
++        SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n"));
++        sqlite3TreeViewSelect(0, p, 0);
+       }
+-      i = -1;
+-    }else if( pTabList->nSrc==1
+-           && OptimizationEnabled(db, SQLITE_SubqCoroutine)
 +#endif
-+#if SQLITE_OMIT_LOOKASIDE
-+  "OMIT_LOOKASIDE",
++    }
++
++    /* Generate code to implement the subquery
++    **
++    ** The subquery is implemented as a co-routine if all of these are true:
++    **   (1)  The subquery is guaranteed to be the outer loop (so that it
++    **        does not need to be computed more than once)
++    **   (2)  The ALL keyword after SELECT is omitted.  (Applications are
++    **        allowed to say "SELECT ALL" instead of just "SELECT" to disable
++    **        the use of co-routines.)
++    **   (3)  Co-routines are not disabled using sqlite3_test_control()
++    **        with SQLITE_TESTCTRL_OPTIMIZATIONS.
++    **
++    ** TODO: Are there other reasons beside (1) to use a co-routine
++    ** implementation?
++    */
++    if( i==0
++     && (pTabList->nSrc==1
++            || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)  /* (1) */
++     && (p->selFlags & SF_All)==0                                   /* (2) */
++     && OptimizationEnabled(db, SQLITE_SubqCoroutine)               /* (3) */
+     ){
+       /* Implement a co-routine that will return a single row of the result
+       ** set on each invocation.
+@@ -111377,10 +126082,10 @@
+       sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
+       explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
+       sqlite3Select(pParse, pSub, &dest);
+-      pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
+-      pItem->viaCoroutine = 1;
++      pItem->pTab->nRowLogEst = pSub->nSelectRow;
++      pItem->fg.viaCoroutine = 1;
+       pItem->regResult = dest.iSdst;
+-      sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn);
++      sqlite3VdbeEndCoroutine(v, pItem->regReturn);
+       sqlite3VdbeJumpHere(v, addrTop-1);
+       sqlite3ClearTempRegCache(pParse);
+     }else{
+@@ -111392,56 +126097,66 @@
+       int topAddr;
+       int onceAddr = 0;
+       int retAddr;
++      struct SrcList_item *pPrior;
++
+       assert( pItem->addrFillSub==0 );
+       pItem->regReturn = ++pParse->nMem;
+       topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
+       pItem->addrFillSub = topAddr+1;
+-      if( pItem->isCorrelated==0 ){
++      if( pItem->fg.isCorrelated==0 ){
+         /* If the subquery is not correlated and if we are not inside of
+         ** a trigger, then we only need to compute the value of the subquery
+         ** once. */
+-        onceAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
++        onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+         VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
+       }else{
+         VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
+       }
+-      sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
+-      explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
+-      sqlite3Select(pParse, pSub, &dest);
+-      pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
++      pPrior = isSelfJoinView(pTabList, pItem);
++      if( pPrior ){
++        sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
++        explainSetInteger(pItem->iSelectId, pPrior->iSelectId);
++        assert( pPrior->pSelect!=0 );
++        pSub->nSelectRow = pPrior->pSelect->nSelectRow;
++      }else{
++        sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
++        explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
++        sqlite3Select(pParse, pSub, &dest);
++      }
++      pItem->pTab->nRowLogEst = pSub->nSelectRow;
+       if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
+       retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
+       VdbeComment((v, "end %s", pItem->pTab->zName));
+       sqlite3VdbeChangeP1(v, topAddr, retAddr);
+       sqlite3ClearTempRegCache(pParse);
+     }
+-    if( /*pParse->nErr ||*/ db->mallocFailed ){
+-      goto select_end;
+-    }
++    if( db->mallocFailed ) goto select_end;
+     pParse->nHeight -= sqlite3SelectExprHeight(p);
+-    pTabList = p->pSrc;
+-    if( !IgnorableOrderby(pDest) ){
+-      sSort.pOrderBy = p->pOrderBy;
+-    }
 +#endif
-+#if SQLITE_OMIT_MEMORYDB
-+  "OMIT_MEMORYDB",
+   }
++
++  /* Various elements of the SELECT copied into local variables for
++  ** convenience */
+   pEList = p->pEList;
+-#endif
+   pWhere = p->pWhere;
+   pGroupBy = p->pGroupBy;
+   pHaving = p->pHaving;
+   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.
+-  */
+-  if( p->pPrior ){
+-    rc = multiSelect(pParse, p, pDest);
+-    explainSetInteger(pParse->iSelectId, iRestoreSelectId);
+ #if SELECTTRACE_ENABLED
+-    SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
+-    pParse->nSelectIndent--;
++  if( sqlite3SelectTrace & 0x400 ){
++    SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n"));
++    sqlite3TreeViewSelect(0, p, 0);
++  }
+ #endif
+-    return rc;
++
++#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
++  if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
++   && countOfViewOptimization(pParse, p)
++  ){
++    if( db->mallocFailed ) goto select_end;
++    pEList = p->pEList;
++    pTabList = p->pSrc;
+   }
+ #endif
+ 
+@@ -111461,23 +126176,30 @@
+   ** BY and DISTINCT, and an index or separate temp-table for the other.
+   */
+   if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct 
+-   && sqlite3ExprListCompare(sSort.pOrderBy, p->pEList, -1)==0
++   && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0
+   ){
+     p->selFlags &= ~SF_Distinct;
+-    p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
+-    pGroupBy = p->pGroupBy;
++    pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 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 SELECTTRACE_ENABLED
++    if( sqlite3SelectTrace & 0x400 ){
++      SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
++      sqlite3TreeViewSelect(0, p, 0);
++    }
 +#endif
-+#if SQLITE_OMIT_OR_OPTIMIZATION
-+  "OMIT_OR_OPTIMIZATION",
+   }
+ 
+-  /* If there is an ORDER BY clause, then this sorting
+-  ** index might end up being unused if the data can be 
+-  ** extracted in pre-sorted order.  If that is the case, then the
+-  ** OP_OpenEphemeral instruction will be changed to an OP_Noop once
+-  ** we figure out that the sorting index is not needed.  The addrSortIndex
+-  ** variable is used to facilitate that change.
++  /* If there is an ORDER BY clause, then create an ephemeral index to
++  ** do the sorting.  But this sorting ephemeral index might end up
++  ** being unused if the data can be extracted in pre-sorted order.
++  ** If that is the case, then the OP_OpenEphemeral instruction will be
++  ** changed to an OP_Noop once we figure out that the sorting index is
++  ** not needed.  The sSort.addrSortIndex variable is used to facilitate
++  ** that change.
+   */
+   if( sSort.pOrderBy ){
+     KeyInfo *pKeyInfo;
+@@ -111501,21 +126223,23 @@
+   /* Set the limiter.
+   */
+   iEnd = sqlite3VdbeMakeLabel(v);
+-  p->nSelectRow = LARGEST_INT64;
++  if( (p->selFlags & SF_FixedLimit)==0 ){
++    p->nSelectRow = 320;  /* 4 billion rows */
++  }
+   computeLimitRegisters(pParse, p, iEnd);
+   if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
+-    sqlite3VdbeGetOp(v, sSort.addrSortIndex)->opcode = OP_SorterOpen;
++    sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
+     sSort.sortFlags |= SORTFLAG_UseSorter;
+   }
+ 
+-  /* Open a virtual index to use for the distinct set.
++  /* Open an ephemeral index to use for the distinct set.
+   */
+   if( p->selFlags & SF_Distinct ){
+     sDistinct.tabTnct = pParse->nTab++;
+     sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
+-                                sDistinct.tabTnct, 0, 0,
+-                                (char*)keyInfoFromExprList(pParse, p->pEList,0,0),
+-                                P4_KEYINFO);
++                             sDistinct.tabTnct, 0, 0,
++                             (char*)keyInfoFromExprList(pParse, p->pEList,0,0),
++                             P4_KEYINFO);
+     sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
+     sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
+   }else{
+@@ -111525,10 +126249,12 @@
+   if( !isAgg && pGroupBy==0 ){
+     /* No aggregate functions and no GROUP BY clause */
+     u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
++    assert( WHERE_USE_LIMIT==SF_FixedLimit );
++    wctrlFlags |= p->selFlags & SF_FixedLimit;
+ 
+     /* Begin the database scan. */
+     pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
+-                               p->pEList, wctrlFlags, 0);
++                               p->pEList, wctrlFlags, p->nSelectRow);
+     if( pWInfo==0 ) goto select_end;
+     if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
+       p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
+@@ -111538,6 +126264,7 @@
+     }
+     if( sSort.pOrderBy ){
+       sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo);
++      sSort.bOrderedInnerLoop = sqlite3WhereOrderedInnerLoop(pWInfo);
+       if( sSort.nOBSat==sSort.pOrderBy->nExpr ){
+         sSort.pOrderBy = 0;
+       }
+@@ -111588,16 +126315,17 @@
+       for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
+         pItem->u.x.iAlias = 0;
+       }
+-      if( p->nSelectRow>100 ) p->nSelectRow = 100;
++      assert( 66==sqlite3LogEst(100) );
++      if( p->nSelectRow>66 ) p->nSelectRow = 66;
+     }else{
+-      p->nSelectRow = 1;
++      assert( 0==sqlite3LogEst(1) );
++      p->nSelectRow = 0;
+     }
+ 
+-
+     /* If there is both a GROUP BY and an ORDER BY clause and they are
+     ** identical, then it may be possible to disable the ORDER BY clause 
+     ** on the grounds that the GROUP BY will cause elements to come out 
+-    ** in the correct order. It also may not - the GROUP BY may use a
++    ** in the correct order. It also may not - the GROUP BY might use a
+     ** database index that causes rows to be grouped together as required
+     ** but not actually sorted. Either way, record the fact that the
+     ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp
+@@ -111623,6 +126351,11 @@
+     sqlite3ExprAnalyzeAggList(&sNC, pEList);
+     sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
+     if( pHaving ){
++      if( pGroupBy ){
++        assert( pWhere==p->pWhere );
++        havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere);
++        pWhere = p->pWhere;
++      }
+       sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
+     }
+     sAggInfo.nAccumulator = sAggInfo.nColumn;
+@@ -111640,7 +126373,7 @@
+     */
+     if( pGroupBy ){
+       KeyInfo *pKeyInfo;  /* Keying information for the group by clause */
+-      int j1;             /* A-vs-B comparision jump */
++      int addr1;          /* A-vs-B comparision jump */
+       int addrOutputRow;  /* Start of subroutine that outputs a result row */
+       int regOutputRow;   /* Return address register for output subroutine */
+       int addrSetAbort;   /* Set the abort flag and return */
+@@ -111721,19 +126454,14 @@
+         }
+         regBase = sqlite3GetTempRange(pParse, nCol);
+         sqlite3ExprCacheClear(pParse);
+-        sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0);
++        sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
+         j = nGroupBy;
+         for(i=0; i<sAggInfo.nColumn; i++){
+           struct AggInfo_col *pCol = &sAggInfo.aCol[i];
+           if( pCol->iSorterColumn>=j ){
+             int r1 = j + regBase;
+-            int r2;
+-
+-            r2 = sqlite3ExprCodeGetColumn(pParse, 
+-                               pCol->pTab, pCol->iColumn, pCol->iTable, r1, 0);
+-            if( r1!=r2 ){
+-              sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1);
+-            }
++            sqlite3ExprCodeGetColumnToReg(pParse, 
++                               pCol->pTab, pCol->iColumn, pCol->iTable, r1);
+             j++;
+           }
+         }
+@@ -111775,7 +126503,8 @@
+       addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
+       sqlite3ExprCacheClear(pParse);
+       if( groupBySort ){
+-        sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut,sortPTab);
++        sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx,
++                          sortOut, sortPTab);
+       }
+       for(j=0; j<pGroupBy->nExpr; j++){
+         if( groupBySort ){
+@@ -111787,8 +126516,8 @@
+       }
+       sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
+                           (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
+-      j1 = sqlite3VdbeCurrentAddr(v);
+-      sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1); VdbeCoverage(v);
++      addr1 = sqlite3VdbeCurrentAddr(v);
++      sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v);
+ 
+       /* Generate code that runs whenever the GROUP BY changes.
+       ** Changes in the GROUP BY are detected by the previous code
+@@ -111810,7 +126539,7 @@
+       /* Update the aggregate accumulators based on the content of
+       ** the current row
+       */
+-      sqlite3VdbeJumpHere(v, j1);
++      sqlite3VdbeJumpHere(v, addr1);
+       updateAccumulator(pParse, &sAggInfo);
+       sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
+       VdbeComment((v, "indicate data in accumulator"));
+@@ -111832,7 +126561,7 @@
+ 
+       /* Jump over the subroutines
+       */
+-      sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEnd);
++      sqlite3VdbeGoto(v, addrEnd);
+ 
+       /* Generate a subroutine that outputs a single row of the result
+       ** set.  This subroutine first looks at the iUseFlag.  If iUseFlag
+@@ -111847,7 +126576,8 @@
+       sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
+       sqlite3VdbeResolveLabel(v, addrOutputRow);
+       addrOutputRow = sqlite3VdbeCurrentAddr(v);
+-      sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeCoverage(v);
++      sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
++      VdbeCoverage(v);
+       VdbeComment((v, "Groupby result generator entry point"));
+       sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
+       finalizeAggFunctions(pParse, &sAggInfo);
+@@ -111966,7 +126696,8 @@
+         if( flag ){
+           pMinMax = sqlite3ExprListDup(db, pMinMax, 0);
+           pDel = pMinMax;
+-          if( pMinMax && !db->mallocFailed ){
++          assert( db->mallocFailed || pMinMax!=0 );
++          if( !db->mallocFailed ){
+             pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
+             pMinMax->a[0].pExpr->op = TK_COLUMN;
+           }
+@@ -111977,7 +126708,7 @@
+         ** of output.
+         */
+         resetAccumulator(pParse, &sAggInfo);
+-        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0);
++        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax, 0,flag,0);
+         if( pWInfo==0 ){
+           sqlite3ExprListDelete(db, pDel);
+           goto select_end;
+@@ -111985,7 +126716,7 @@
+         updateAccumulator(pParse, &sAggInfo);
+         assert( pMinMax==0 || pMinMax->nExpr==1 );
+         if( sqlite3WhereIsOrdered(pWInfo)>0 ){
+-          sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3WhereBreakLabel(pWInfo));
++          sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo));
+           VdbeComment((v, "%s() by index",
+                 (flag==WHERE_ORDERBY_MIN?"min":"max")));
+         }
+@@ -112011,7 +126742,8 @@
+   ** and send them to the callback one by one.
+   */
+   if( sSort.pOrderBy ){
+-    explainTempTable(pParse, sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY");
++    explainTempTable(pParse,
++                     sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY");
+     generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest);
+   }
+ 
+@@ -112029,12 +126761,6 @@
+ select_end:
+   explainSetInteger(pParse->iSelectId, iRestoreSelectId);
+ 
+-  /* Identify column names if results of the SELECT are to be output.
+-  */
+-  if( rc==SQLITE_OK && pDest->eDest==SRT_Output ){
+-    generateColumnNames(pParse, pTabList, pEList);
+-  }
+-
+   sqlite3DbFree(db, sAggInfo.aCol);
+   sqlite3DbFree(db, sAggInfo.aFunc);
+ #if SELECTTRACE_ENABLED
+@@ -112044,100 +126770,6 @@
+   return rc;
+ }
+ 
+-#ifdef SQLITE_DEBUG
+-/*
+-** Generate a human-readable description of a the Select object.
+-*/
+-SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
+-  int n = 0;
+-  pView = sqlite3TreeViewPush(pView, moreToFollow);
+-  sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p)",
+-    ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
+-    ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p
+-  );
+-  if( p->pSrc && p->pSrc->nSrc ) n++;
+-  if( p->pWhere ) n++;
+-  if( p->pGroupBy ) n++;
+-  if( p->pHaving ) n++;
+-  if( p->pOrderBy ) n++;
+-  if( p->pLimit ) n++;
+-  if( p->pOffset ) n++;
+-  if( p->pPrior ) n++;
+-  sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
+-  if( p->pSrc && p->pSrc->nSrc ){
+-    int i;
+-    pView = sqlite3TreeViewPush(pView, (n--)>0);
+-    sqlite3TreeViewLine(pView, "FROM");
+-    for(i=0; i<p->pSrc->nSrc; i++){
+-      struct SrcList_item *pItem = &p->pSrc->a[i];
+-      StrAccum x;
+-      char zLine[100];
+-      sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
+-      sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
+-      if( pItem->zDatabase ){
+-        sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
+-      }else if( pItem->zName ){
+-        sqlite3XPrintf(&x, 0, " %s", pItem->zName);
+-      }
+-      if( pItem->pTab ){
+-        sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName);
+-      }
+-      if( pItem->zAlias ){
+-        sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias);
+-      }
+-      if( pItem->jointype & JT_LEFT ){
+-        sqlite3XPrintf(&x, 0, " LEFT-JOIN");
+-      }
+-      sqlite3StrAccumFinish(&x);
+-      sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); 
+-      if( pItem->pSelect ){
+-        sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
+-      }
+-      sqlite3TreeViewPop(pView);
+-    }
+-    sqlite3TreeViewPop(pView);
+-  }
+-  if( p->pWhere ){
+-    sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
+-    sqlite3TreeViewExpr(pView, p->pWhere, 0);
+-    sqlite3TreeViewPop(pView);
+-  }
+-  if( p->pGroupBy ){
+-    sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
+-  }
+-  if( p->pHaving ){
+-    sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
+-    sqlite3TreeViewExpr(pView, p->pHaving, 0);
+-    sqlite3TreeViewPop(pView);
+-  }
+-  if( p->pOrderBy ){
+-    sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
+-  }
+-  if( p->pLimit ){
+-    sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
+-    sqlite3TreeViewExpr(pView, p->pLimit, 0);
+-    sqlite3TreeViewPop(pView);
+-  }
+-  if( p->pOffset ){
+-    sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
+-    sqlite3TreeViewExpr(pView, p->pOffset, 0);
+-    sqlite3TreeViewPop(pView);
+-  }
+-  if( p->pPrior ){
+-    const char *zOp = "UNION";
+-    switch( p->op ){
+-      case TK_ALL:         zOp = "UNION ALL";  break;
+-      case TK_INTERSECT:   zOp = "INTERSECT";  break;
+-      case TK_EXCEPT:      zOp = "EXCEPT";     break;
+-    }
+-    sqlite3TreeViewItem(pView, zOp, (n--)>0);
+-    sqlite3TreeViewSelect(pView, p->pPrior, 0);
+-    sqlite3TreeViewPop(pView);
+-  }
+-  sqlite3TreeViewPop(pView);
+-}
+-#endif /* SQLITE_DEBUG */
+-
+ /************** End of select.c **********************************************/
+ /************** Begin file table.c *******************************************/
+ /*
+@@ -112158,8 +126790,7 @@
+ ** These routines are in a separate files so that they will not be linked
+ ** if they are not used.
+ */
+-/* #include <stdlib.h> */
+-/* #include <string.h> */
++/* #include "sqliteInt.h" */
+ 
+ #ifndef SQLITE_OMIT_GET_TABLE
+ 
+@@ -112242,7 +126873,7 @@
+   return 0;
+ 
+ malloc_failed:
+-  p->rc = SQLITE_NOMEM;
++  p->rc = SQLITE_NOMEM_BKPT;
+   return 1;
+ }
+ 
+@@ -112256,7 +126887,7 @@
+ ** Instead, the entire table should be passed to sqlite3_free_table() when
+ ** the calling procedure is finished using it.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
++SQLITE_API int sqlite3_get_table(
+   sqlite3 *db,                /* The database on which the SQL executes */
+   const char *zSql,           /* The SQL to be executed */
+   char ***pazResult,          /* Write the result table here */
+@@ -112283,7 +126914,7 @@
+   res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
+   if( res.azResult==0 ){
+      db->errCode = SQLITE_NOMEM;
+-     return SQLITE_NOMEM;
++     return SQLITE_NOMEM_BKPT;
+   }
+   res.azResult[0] = 0;
+   rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
+@@ -112312,7 +126943,7 @@
+     if( azNew==0 ){
+       sqlite3_free_table(&res.azResult[1]);
+       db->errCode = SQLITE_NOMEM;
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     res.azResult = azNew;
+   }
+@@ -112325,7 +126956,7 @@
+ /*
+ ** This routine frees the space the sqlite3_get_table() malloced.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_free_table(
++SQLITE_API void sqlite3_free_table(
+   char **azResult            /* Result returned from sqlite3_get_table() */
+ ){
+   if( azResult ){
+@@ -112354,6 +126985,7 @@
+ *************************************************************************
+ ** This file contains the implementation for TRIGGERs
+ */
++/* #include "sqliteInt.h" */
+ 
+ #ifndef SQLITE_OMIT_TRIGGER
+ /*
+@@ -112439,7 +127071,6 @@
+   int iDb;                /* The database to store the trigger in */
+   Token *pName;           /* The unqualified db name */
+   DbFixer sFix;           /* State vector for the DB fixer */
+-  int iTabDb;             /* Index of the database holding pTab */
+ 
+   assert( pName1!=0 );   /* pName1->z might be NULL, but not pName1 itself */
+   assert( pName2!=0 );
+@@ -112552,13 +127183,13 @@
+         " trigger on table: %S", pTableName, 0);
+     goto trigger_cleanup;
+   }
+-  iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ 
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+   {
++    int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+     int code = SQLITE_CREATE_TRIGGER;
+-    const char *zDb = db->aDb[iTabDb].zName;
+-    const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
++    const char *zDb = db->aDb[iTabDb].zDbSName;
++    const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb;
+     if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
+     if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
+       goto trigger_cleanup;
+@@ -112630,8 +127261,7 @@
+     pStepList->pTrig = pTrig;
+     pStepList = pStepList->pNext;
+   }
+-  nameToken.z = pTrig->zName;
+-  nameToken.n = sqlite3Strlen30(nameToken.z);
++  sqlite3TokenInit(&nameToken, pTrig->zName);
+   sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken);
+   if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) 
+    || sqlite3FixExpr(&sFix, pTrig->pWhen) 
+@@ -112651,9 +127281,10 @@
+     if( v==0 ) goto triggerfinish_cleanup;
+     sqlite3BeginWriteOperation(pParse, 0, iDb);
+     z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
++    testcase( z==0 );
+     sqlite3NestedParse(pParse,
+        "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
+-       db->aDb[iDb].zName, SCHEMA_TABLE(iDb), zName,
++       db->aDb[iDb].zDbSName, MASTER_NAME, zName,
+        pTrig->table, z);
+     sqlite3DbFree(db, z);
+     sqlite3ChangeCookie(pParse, iDb);
+@@ -112667,7 +127298,7 @@
+     assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+     pTrig = sqlite3HashInsert(pHash, zName, pTrig);
+     if( pTrig ){
+-      db->mallocFailed = 1;
++      sqlite3OomFault(db);
+     }else if( pLink->pSchema==pLink->pTabSchema ){
+       Table *pTab;
+       pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table);
+@@ -112842,7 +127473,7 @@
+   assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
+   for(i=OMIT_TEMPDB; i<db->nDb; i++){
+     int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
+-    if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
++    if( zDb && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue;
+     assert( sqlite3SchemaMutexHeld(db, j, 0) );
+     pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
+     if( pTrigger ) break;
+@@ -112888,7 +127519,7 @@
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+   {
+     int code = SQLITE_DROP_TRIGGER;
+-    const char *zDb = db->aDb[iDb].zName;
++    const char *zDb = db->aDb[iDb].zDbSName;
+     const char *zTab = SCHEMA_TABLE(iDb);
+     if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
+     if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) ||
+@@ -112902,31 +127533,12 @@
+   */
+   assert( pTable!=0 );
+   if( (v = sqlite3GetVdbe(pParse))!=0 ){
+-    int base;
+-    static const int iLn = VDBE_OFFSET_LINENO(2);
+-    static const VdbeOpList dropTrigger[] = {
+-      { OP_Rewind,     0, ADDR(9),  0},
+-      { OP_String8,    0, 1,        0}, /* 1 */
+-      { OP_Column,     0, 1,        2},
+-      { OP_Ne,         2, ADDR(8),  1},
+-      { OP_String8,    0, 1,        0}, /* 4: "trigger" */
+-      { OP_Column,     0, 0,        2},
+-      { OP_Ne,         2, ADDR(8),  1},
+-      { OP_Delete,     0, 0,        0},
+-      { OP_Next,       0, ADDR(1),  0}, /* 8 */
+-    };
+-
+-    sqlite3BeginWriteOperation(pParse, 0, iDb);
+-    sqlite3OpenMasterTable(pParse, iDb);
+-    base = sqlite3VdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger, iLn);
+-    sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, P4_TRANSIENT);
+-    sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
++    sqlite3NestedParse(pParse,
++       "DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'",
++       db->aDb[iDb].zDbSName, MASTER_NAME, pTrigger->zName
++    );
+     sqlite3ChangeCookie(pParse, iDb);
+-    sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
+     sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
+-    if( pParse->nMem<3 ){
+-      pParse->nMem = 3;
+-    }
+   }
+ }
+ 
+@@ -113026,8 +127638,10 @@
+     pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
+     iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
+     if( iDb==0 || iDb>=2 ){
++      const char *zDb;
+       assert( iDb<db->nDb );
+-      pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
++      zDb = db->aDb[iDb].zDbSName;
++      pSrc->a[pSrc->nSrc-1].zDatabase =  sqlite3DbStrDup(db, zDb);
+     }
+   }
+   return pSrc;
+@@ -113241,7 +127855,6 @@
+     }
+     pProgram->nMem = pSubParse->nMem;
+     pProgram->nCsr = pSubParse->nTab;
+-    pProgram->nOnce = pSubParse->nOnce;
+     pProgram->token = (void *)pTrigger;
+     pPrg->aColmask[0] = pSubParse->oldmask;
+     pPrg->aColmask[1] = pSubParse->newmask;
+@@ -113314,8 +127927,8 @@
+   if( pPrg ){
+     int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers));
+ 
+-    sqlite3VdbeAddOp3(v, OP_Program, reg, ignoreJump, ++pParse->nMem);
+-    sqlite3VdbeChangeP4(v, -1, (const char *)pPrg->pProgram, P4_SUBPROGRAM);
++    sqlite3VdbeAddOp4(v, OP_Program, reg, ignoreJump, ++pParse->nMem,
++                      (const char *)pPrg->pProgram, P4_SUBPROGRAM);
+     VdbeComment(
+         (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf)));
+ 
+@@ -113477,6 +128090,7 @@
+ ** This file contains C code routines that are called by the parser
+ ** to handle UPDATE statements.
+ */
++/* #include "sqliteInt.h" */
+ 
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+ /* Forward declaration */
+@@ -113533,14 +128147,14 @@
+     sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, 
+                          pCol->affinity, &pValue);
+     if( pValue ){
+-      sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
++      sqlite3VdbeAppendP4(v, pValue, P4_MEM);
+     }
++  }
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+-    if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
+-      sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
+-    }
+-#endif
++  if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
++    sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
+   }
 +#endif
-+#if SQLITE_OMIT_PAGER_PRAGMAS
-+  "OMIT_PAGER_PRAGMAS",
+ }
+ 
+ /*
+@@ -113569,7 +128183,7 @@
+   int iDataCur;          /* Cursor for the canonical data btree */
+   int iIdxCur;           /* Cursor for the first index */
+   sqlite3 *db;           /* The database structure */
+-  int *aRegIdx = 0;      /* One register assigned to each index to be updated */
++  int *aRegIdx = 0;      /* First register in array assigned to each index */
+   int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
+                          ** an expression for the i-th column of the table.
+                          ** aXRef[i]==-1 if the i-th column is not changed. */
+@@ -113581,10 +128195,11 @@
+   AuthContext sContext;  /* The authorization context */
+   NameContext sNC;       /* The name-context to resolve expressions in */
+   int iDb;               /* Database containing the table being updated */
+-  int okOnePass;         /* True for one-pass algorithm without the FIFO */
++  int eOnePass;          /* ONEPASS_XXX value from where.c */
+   int hasFK;             /* True if foreign key processing is required */
+   int labelBreak;        /* Jump here to break out of UPDATE loop */
+   int labelContinue;     /* Jump here to continue next step of UPDATE loop */
++  int flags;             /* Flags for sqlite3WhereBegin() */
+ 
+ #ifndef SQLITE_OMIT_TRIGGER
+   int isView;            /* True when updating a view (INSTEAD OF trigger) */
+@@ -113595,12 +128210,16 @@
+   int iEph = 0;          /* Ephemeral table holding all primary key values */
+   int nKey = 0;          /* Number of elements in regKey for WITHOUT ROWID */
+   int aiCurOnePass[2];   /* The write cursors opened by WHERE_ONEPASS */
++  int addrOpen = 0;      /* Address of OP_OpenEphemeral */
++  int iPk = 0;           /* First of nPk cells holding PRIMARY KEY value */
++  i16 nPk = 0;           /* Number of components of the PRIMARY KEY */
++  int bReplace = 0;      /* True if REPLACE conflict resolution might happen */
+ 
+   /* Register Allocations */
+   int regRowCount = 0;   /* A count of rows changed */
+-  int regOldRowid;       /* The old rowid */
+-  int regNewRowid;       /* The new rowid */
+-  int regNew;            /* Content of the NEW.* table in triggers */
++  int regOldRowid = 0;   /* The old rowid */
++  int regNewRowid = 0;   /* The new rowid */
++  int regNew = 0;        /* Content of the NEW.* table in triggers */
+   int regOld = 0;        /* Content of OLD.* table in triggers */
+   int regRowSet = 0;     /* Rowset of rows to be updated */
+   int regKey = 0;        /* composite PRIMARY KEY value */
+@@ -113661,7 +128280,7 @@
+   /* Allocate space for aXRef[], aRegIdx[], and aToOpen[].  
+   ** Initialize aXRef[] and aToOpen[] to their default values.
+   */
+-  aXRef = sqlite3DbMallocRaw(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
++  aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
+   if( aXRef==0 ) goto update_cleanup;
+   aRegIdx = aXRef+pTab->nCol;
+   aToOpen = (u8*)(aRegIdx+nIdx);
+@@ -113713,7 +128332,7 @@
+       int rc;
+       rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
+                             j<0 ? "ROWID" : pTab->aCol[j].zName,
+-                            db->aDb[iDb].zName);
++                            db->aDb[iDb].zDbSName);
+       if( rc==SQLITE_DENY ){
+         goto update_cleanup;
+       }else if( rc==SQLITE_IGNORE ){
+@@ -113727,26 +128346,38 @@
+   assert( chngPk==0 || chngPk==1 );
+   chngKey = chngRowid + chngPk;
+ 
+-  /* The SET expressions are not actually used inside the WHERE loop.
+-  ** So reset the colUsed mask
++  /* The SET expressions are not actually used inside the WHERE loop.  
++  ** So reset the colUsed mask. Unless this is a virtual table. In that
++  ** case, set all bits of the colUsed mask (to ensure that the virtual
++  ** table implementation makes all columns available).
+   */
+-  pTabList->a[0].colUsed = 0;
++  pTabList->a[0].colUsed = IsVirtual(pTab) ? ALLBITS : 0;
+ 
+   hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
+ 
+   /* There is one entry in the aRegIdx[] array for each index on the table
+   ** being updated.  Fill in aRegIdx[] with a register number that will hold
+-  ** the key for accessing each index.  
++  ** the key for accessing each index.
++  **
++  ** FIXME:  Be smarter about omitting indexes that use expressions.
+   */
+   for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+     int reg;
+-    if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){
++    if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
+       reg = ++pParse->nMem;
++      pParse->nMem += pIdx->nColumn;
+     }else{
+       reg = 0;
+       for(i=0; i<pIdx->nKeyCol; i++){
+-        if( aXRef[pIdx->aiColumn[i]]>=0 ){
++        i16 iIdxCol = pIdx->aiColumn[i];
++        if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
+           reg = ++pParse->nMem;
++          pParse->nMem += pIdx->nColumn;
++          if( (onError==OE_Replace)
++           || (onError==OE_Default && pIdx->onError==OE_Replace) 
++          ){
++            bReplace = 1;
++          }
+           break;
+         }
+       }
+@@ -113754,6 +128385,11 @@
+     if( reg==0 ) aToOpen[j+1] = 0;
+     aRegIdx[j] = reg;
+   }
++  if( bReplace ){
++    /* If REPLACE conflict resolution might be invoked, open cursors on all 
++    ** indexes in case they are needed to delete records.  */
++    memset(aToOpen, 1, nIdx+1);
++  }
+ 
+   /* Begin generating code. */
+   v = sqlite3GetVdbe(pParse);
+@@ -113761,29 +128397,20 @@
+   if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
+   sqlite3BeginWriteOperation(pParse, 1, iDb);
+ 
+-#ifndef SQLITE_OMIT_VIRTUALTABLE
+-  /* Virtual tables must be handled separately */
+-  if( IsVirtual(pTab) ){
+-    updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
+-                       pWhere, onError);
+-    pWhere = 0;
+-    pTabList = 0;
+-    goto update_cleanup;
+-  }
+-#endif
+-
+   /* Allocate required registers. */
+-  regRowSet = ++pParse->nMem;
+-  regOldRowid = regNewRowid = ++pParse->nMem;
+-  if( chngPk || pTrigger || hasFK ){
+-    regOld = pParse->nMem + 1;
++  if( !IsVirtual(pTab) ){
++    regRowSet = ++pParse->nMem;
++    regOldRowid = regNewRowid = ++pParse->nMem;
++    if( chngPk || pTrigger || hasFK ){
++      regOld = pParse->nMem + 1;
++      pParse->nMem += pTab->nCol;
++    }
++    if( chngKey || pTrigger || hasFK ){
++      regNewRowid = ++pParse->nMem;
++    }
++    regNew = pParse->nMem + 1;
+     pParse->nMem += pTab->nCol;
+   }
+-  if( chngKey || pTrigger || hasFK ){
+-    regNewRowid = ++pParse->nMem;
+-  }
+-  regNew = pParse->nMem + 1;
+-  pParse->nMem += pTab->nCol;
+ 
+   /* Start the view context. */
+   if( isView ){
+@@ -113806,108 +128433,139 @@
+     goto update_cleanup;
+   }
+ 
+-  /* Begin the database scan
+-  */
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  /* Virtual tables must be handled separately */
++  if( IsVirtual(pTab) ){
++    updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
++                       pWhere, onError);
++    goto update_cleanup;
++  }
 +#endif
-+#if SQLITE_OMIT_PRAGMA
-+  "OMIT_PRAGMA",
++
++  /* Initialize the count of updated rows */
++  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
++    regRowCount = ++pParse->nMem;
++    sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
++  }
++
+   if( HasRowid(pTab) ){
+     sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
+-    pWInfo = sqlite3WhereBegin(
+-        pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, iIdxCur
+-    );
+-    if( pWInfo==0 ) goto update_cleanup;
+-    okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+-  
+-    /* Remember the rowid of every item to be updated.
+-    */
+-    sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
+-    if( !okOnePass ){
+-      sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
+-    }
+-  
+-    /* End the database scan loop.
+-    */
+-    sqlite3WhereEnd(pWInfo);
+   }else{
+-    int iPk;         /* First of nPk memory cells holding PRIMARY KEY value */
+-    i16 nPk;         /* Number of components of the PRIMARY KEY */
+-    int addrOpen;    /* Address of the OpenEphemeral instruction */
+-
+     assert( pPk!=0 );
+     nPk = pPk->nKeyCol;
+     iPk = pParse->nMem+1;
+     pParse->nMem += nPk;
+     regKey = ++pParse->nMem;
+     iEph = pParse->nTab++;
++
+     sqlite3VdbeAddOp2(v, OP_Null, 0, iPk);
+     addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
+     sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+-    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 
+-                               WHERE_ONEPASS_DESIRED, iIdxCur);
+-    if( pWInfo==0 ) goto update_cleanup;
+-    okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
++  }
++
++  /* Begin the database scan. 
++  **
++  ** Do not consider a single-pass strategy for a multi-row update if
++  ** there are any triggers or foreign keys to process, or rows may
++  ** be deleted as a result of REPLACE conflict handling. Any of these
++  ** things might disturb a cursor being used to scan through the table
++  ** or index, causing a single-pass approach to malfunction.  */
++  flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE;
++  if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
++    flags |= WHERE_ONEPASS_MULTIROW;
++  }
++  pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur);
++  if( pWInfo==0 ) goto update_cleanup;
++
++  /* A one-pass strategy that might update more than one row may not
++  ** be used if any column of the index used for the scan is being
++  ** updated. Otherwise, if there is an index on "b", statements like
++  ** the following could create an infinite loop:
++  **
++  **   UPDATE t1 SET b=b+1 WHERE b>?
++  **
++  ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI
++  ** strategy that uses an index for which one or more columns are being
++  ** updated.  */
++  eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
++  if( eOnePass==ONEPASS_MULTI ){
++    int iCur = aiCurOnePass[1];
++    if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){
++      eOnePass = ONEPASS_OFF;
++    }
++    assert( iCur!=iDataCur || !HasRowid(pTab) );
++  }
++  
++  if( HasRowid(pTab) ){
++    /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
++    ** mode, write the rowid into the FIFO. In either of the one-pass modes,
++    ** leave it in register regOldRowid.  */
++    sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
++    if( eOnePass==ONEPASS_OFF ){
++      sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
++    }
++  }else{
++    /* Read the PK of the current row into an array of registers. In
++    ** ONEPASS_OFF mode, serialize the array into a record and store it in
++    ** the ephemeral table. Or, in ONEPASS_SINGLE or MULTI mode, change
++    ** the OP_OpenEphemeral instruction to a Noop (the ephemeral table 
++    ** is not required) and leave the PK fields in the array of registers.  */
+     for(i=0; i<nPk; i++){
+-      sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pPk->aiColumn[i],
+-                                      iPk+i);
++      assert( pPk->aiColumn[i]>=0 );
++      sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,pPk->aiColumn[i],iPk+i);
+     }
+-    if( okOnePass ){
++    if( eOnePass ){
+       sqlite3VdbeChangeToNoop(v, addrOpen);
+       nKey = nPk;
+       regKey = iPk;
+     }else{
+       sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
+-                        sqlite3IndexAffinityStr(v, pPk), nPk);
+-      sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey);
++                        sqlite3IndexAffinityStr(db, pPk), nPk);
++      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEph, regKey, iPk, nPk);
+     }
+-    sqlite3WhereEnd(pWInfo);
+   }
+ 
+-  /* Initialize the count of updated rows
+-  */
+-  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
+-    regRowCount = ++pParse->nMem;
+-    sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
++  if( eOnePass!=ONEPASS_MULTI ){
++    sqlite3WhereEnd(pWInfo);
+   }
+ 
+   labelBreak = sqlite3VdbeMakeLabel(v);
+   if( !isView ){
+-    /* 
+-    ** Open every index that needs updating.  Note that if any
+-    ** index could potentially invoke a REPLACE conflict resolution 
+-    ** action, then we need to open all indices because we might need
+-    ** to be deleting some records.
+-    */
+-    if( onError==OE_Replace ){
+-      memset(aToOpen, 1, nIdx+1);
+-    }else{
+-      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+-        if( pIdx->onError==OE_Replace ){
+-          memset(aToOpen, 1, nIdx+1);
+-          break;
+-        }
+-      }
+-    }
+-    if( okOnePass ){
++    int addrOnce = 0;
++
++    /* Open every index that needs updating. */
++    if( eOnePass!=ONEPASS_OFF ){
+       if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
+       if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
+     }
+-    sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iBaseCur, aToOpen,
++
++    if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){
++      addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
++    }
++    sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen,
+                                0, 0);
++    if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
+   }
+ 
+   /* Top of the update loop */
+-  if( okOnePass ){
+-    if( aToOpen[iDataCur-iBaseCur] && !isView ){
++  if( eOnePass!=ONEPASS_OFF ){
++    if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
+       assert( pPk );
+       sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
+       VdbeCoverageNeverTaken(v);
+     }
+-    labelContinue = labelBreak;
++    if( eOnePass==ONEPASS_SINGLE ){
++      labelContinue = labelBreak;
++    }else{
++      labelContinue = sqlite3VdbeMakeLabel(v);
++    }
+     sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
+     VdbeCoverageIf(v, pPk==0);
+     VdbeCoverageIf(v, pPk!=0);
+   }else if( pPk ){
+     labelContinue = sqlite3VdbeMakeLabel(v);
+     sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
+-    addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey);
++    addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
+     sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
+     VdbeCoverage(v);
+   }else{
+@@ -113967,7 +128625,6 @@
+   newmask = sqlite3TriggerColmask(
+       pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
+   );
+-  /*sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);*/
+   for(i=0; i<pTab->nCol; i++){
+     if( i==pTab->iPKey ){
+       sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
+@@ -113983,7 +128640,7 @@
+         */
+         testcase( i==31 );
+         testcase( i==32 );
+-        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
++        sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i);
+       }else{
+         sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
+       }
+@@ -114025,13 +128682,13 @@
+   }
+ 
+   if( !isView ){
+-    int j1 = 0;           /* Address of jump instruction */
+-    int bReplace = 0;     /* True if REPLACE conflict resolution might happen */
++    int addr1 = 0;        /* Address of jump instruction */
+ 
+     /* Do constraint checks. */
+     assert( regOldRowid>0 );
+     sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+-        regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace);
++        regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace,
++        aXRef);
+ 
+     /* Do FK constraint checks. */
+     if( hasFK ){
+@@ -114041,20 +128698,43 @@
+     /* Delete the index entries associated with the current record.  */
+     if( bReplace || chngKey ){
+       if( pPk ){
+-        j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
++        addr1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
+       }else{
+-        j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
++        addr1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
+       }
+       VdbeCoverageNeverTaken(v);
+     }
+-    sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx);
+-  
+-    /* If changing the record number, delete the old record.  */
+-    if( hasFK || chngKey || pPk!=0 ){
++    sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1);
++
++    /* If changing the rowid value, or if there are foreign key constraints
++    ** to process, delete the old record. Otherwise, add a noop OP_Delete
++    ** to invoke the pre-update hook.
++    **
++    ** That (regNew==regnewRowid+1) is true is also important for the 
++    ** pre-update hook. If the caller invokes preupdate_new(), the returned
++    ** value is copied from memory cell (regNewRowid+1+iCol), where iCol
++    ** is the column index supplied by the user.
++    */
++    assert( regNew==regNewRowid+1 );
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++    sqlite3VdbeAddOp3(v, OP_Delete, iDataCur,
++        OPFLAG_ISUPDATE | ((hasFK>1 || chngKey) ? 0 : OPFLAG_ISNOOP),
++        regNewRowid
++    );
++    if( eOnePass==ONEPASS_MULTI ){
++      assert( hasFK==0 && chngKey==0 );
++      sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
++    }
++    if( !pParse->nested ){
++      sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
++    }
++#else
++    if( hasFK>1 || chngKey ){
+       sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
+     }
 +#endif
-+#if SQLITE_OMIT_PROGRESS_CALLBACK
-+  "OMIT_PROGRESS_CALLBACK",
+     if( bReplace || chngKey ){
+-      sqlite3VdbeJumpHere(v, j1);
++      sqlite3VdbeJumpHere(v, addr1);
+     }
+ 
+     if( hasFK ){
+@@ -114062,8 +128742,11 @@
+     }
+   
+     /* Insert the new index entries and the new record. */
+-    sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
+-                             regNewRowid, aRegIdx, 1, 0, 0);
++    sqlite3CompleteInsertion(
++        pParse, pTab, iDataCur, iIdxCur, regNewRowid, aRegIdx, 
++        OPFLAG_ISUPDATE | (eOnePass==ONEPASS_MULTI ? OPFLAG_SAVEPOSITION : 0), 
++        0, 0
++    );
+ 
+     /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
+     ** handle rows (possibly in other tables) that refer via a foreign key
+@@ -114085,25 +128768,19 @@
+   /* Repeat the above with the next record to be updated, until
+   ** all record selected by the WHERE clause have been updated.
+   */
+-  if( okOnePass ){
++  if( eOnePass==ONEPASS_SINGLE ){
+     /* Nothing to do at end-of-loop for a single-pass */
++  }else if( eOnePass==ONEPASS_MULTI ){
++    sqlite3VdbeResolveLabel(v, labelContinue);
++    sqlite3WhereEnd(pWInfo);
+   }else if( pPk ){
+     sqlite3VdbeResolveLabel(v, labelContinue);
+     sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v);
+   }else{
+-    sqlite3VdbeAddOp2(v, OP_Goto, 0, labelContinue);
++    sqlite3VdbeGoto(v, labelContinue);
+   }
+   sqlite3VdbeResolveLabel(v, labelBreak);
+ 
+-  /* Close all tables */
+-  for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+-    assert( aRegIdx );
+-    if( aToOpen[i+1] ){
+-      sqlite3VdbeAddOp2(v, OP_Close, iIdxCur+i, 0);
+-    }
+-  }
+-  if( iDataCur<iIdxCur ) sqlite3VdbeAddOp2(v, OP_Close, iDataCur, 0);
+-
+   /* Update the sqlite_sequence table by storing the content of the
+   ** maximum rowid counter values recorded while inserting into
+   ** autoincrement tables.
+@@ -114145,21 +128822,23 @@
+ /*
+ ** Generate code for an UPDATE of a virtual table.
+ **
+-** The strategy is that we create an ephemeral table that contains
++** There are two possible strategies - the default and the special 
++** "onepass" strategy. Onepass is only used if the virtual table 
++** implementation indicates that pWhere may match at most one row.
++**
++** The default strategy is to create an ephemeral table that contains
+ ** for each row to be changed:
+ **
+ **   (A)  The original rowid of that row.
+-**   (B)  The revised rowid for the row. (note1)
++**   (B)  The revised rowid for the row.
+ **   (C)  The content of every column in the row.
+ **
+-** Then we loop over this ephemeral table and for each row in
+-** the ephemeral table call VUpdate.
++** Then loop through the contents of this ephemeral table executing a
++** VUpdate for each row. When finished, drop the ephemeral table.
+ **
+-** When finished, drop the ephemeral table.
+-**
+-** (note1) Actually, if we know in advance that (A) is always the same
+-** as (B) we only store (A), then duplicate (A) when pulling
+-** it out of the ephemeral table before calling VUpdate.
++** The "onepass" strategy does not use an ephemeral table. Instead, it
++** stores the same values (A, B and C above) in a register array and
++** makes a single invocation of VUpdate.
+ */
+ static void updateVirtualTable(
+   Parse *pParse,       /* The parsing context */
+@@ -114172,68 +128851,96 @@
+   int onError          /* ON CONFLICT strategy */
+ ){
+   Vdbe *v = pParse->pVdbe;  /* Virtual machine under construction */
+-  ExprList *pEList = 0;     /* The result set of the SELECT statement */
+-  Select *pSelect = 0;      /* The SELECT statement */
+-  Expr *pExpr;              /* Temporary expression */
+   int ephemTab;             /* Table holding the result of the SELECT */
+   int i;                    /* Loop counter */
+-  int addr;                 /* Address of top of loop */
+-  int iReg;                 /* First register in set passed to OP_VUpdate */
+   sqlite3 *db = pParse->db; /* Database connection */
+   const char *pVTab = (const char*)sqlite3GetVTable(db, pTab);
+-  SelectDest dest;
++  WhereInfo *pWInfo;
++  int nArg = 2 + pTab->nCol;      /* Number of arguments to VUpdate */
++  int regArg;                     /* First register in VUpdate arg array */
++  int regRec;                     /* Register in which to assemble record */
++  int regRowid;                   /* Register for ephem table rowid */
++  int iCsr = pSrc->a[0].iCursor;  /* Cursor used for virtual table scan */
++  int aDummy[2];                  /* Unused arg for sqlite3WhereOkOnePass() */
++  int bOnePass;                   /* True to use onepass strategy */
++  int addr;                       /* Address of OP_OpenEphemeral */
++
++  /* Allocate nArg registers to martial the arguments to VUpdate. Then
++  ** create and open the ephemeral table in which the records created from
++  ** these arguments will be temporarily stored. */
++  assert( v );
++  ephemTab = pParse->nTab++;
++  addr= sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg);
++  regArg = pParse->nMem + 1;
++  pParse->nMem += nArg;
++  regRec = ++pParse->nMem;
++  regRowid = ++pParse->nMem;
++
++  /* Start scanning the virtual table */
++  pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0,0,WHERE_ONEPASS_DESIRED,0);
++  if( pWInfo==0 ) return;
+ 
+-  /* Construct the SELECT statement that will find the new values for
+-  ** all updated rows. 
+-  */
+-  pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, "_rowid_"));
++  /* Populate the argument registers. */
++  sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
+   if( pRowid ){
+-    pEList = sqlite3ExprListAppend(pParse, pEList,
+-                                   sqlite3ExprDup(db, pRowid, 0));
++    sqlite3ExprCode(pParse, pRowid, regArg+1);
++  }else{
++    sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1);
+   }
+-  assert( pTab->iPKey<0 );
+   for(i=0; i<pTab->nCol; i++){
+     if( aXRef[i]>=0 ){
+-      pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0);
++      sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
+     }else{
+-      pExpr = sqlite3Expr(db, TK_ID, pTab->aCol[i].zName);
++      sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
+     }
+-    pEList = sqlite3ExprListAppend(pParse, pEList, pExpr);
+   }
+-  pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0);
+-  
+-  /* Create the ephemeral table into which the update results will
+-  ** be stored.
+-  */
+-  assert( v );
+-  ephemTab = pParse->nTab++;
+-  sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
+-  sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
+ 
+-  /* fill the ephemeral table 
+-  */
+-  sqlite3SelectDestInit(&dest, SRT_Table, ephemTab);
+-  sqlite3Select(pParse, pSelect, &dest);
++  bOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
+ 
+-  /* Generate code to scan the ephemeral table and call VUpdate. */
+-  iReg = ++pParse->nMem;
+-  pParse->nMem += pTab->nCol+1;
+-  addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); VdbeCoverage(v);
+-  sqlite3VdbeAddOp3(v, OP_Column,  ephemTab, 0, iReg);
+-  sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1);
+-  for(i=0; i<pTab->nCol; i++){
+-    sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i+1+(pRowid!=0), iReg+2+i);
++  if( bOnePass ){
++    /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded
++    ** above. Also, if this is a top-level parse (not a trigger), clear the
++    ** multi-write flag so that the VM does not open a statement journal */
++    sqlite3VdbeChangeToNoop(v, addr);
++    if( sqlite3IsToplevel(pParse) ){
++      pParse->isMultiWrite = 0;
++    }
++  }else{
++    /* Create a record from the argument register contents and insert it into
++    ** the ephemeral table. */
++    sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec);
++    sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid);
++    sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid);
++  }
++
++
++  if( bOnePass==0 ){
++    /* End the virtual table scan */
++    sqlite3WhereEnd(pWInfo);
++
++    /* Begin scannning through the ephemeral table. */
++    addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v);
++
++    /* Extract arguments from the current row of the ephemeral table and 
++    ** invoke the VUpdate method.  */
++    for(i=0; i<nArg; i++){
++      sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i, regArg+i);
++    }
+   }
+   sqlite3VtabMakeWritable(pParse, pTab);
+-  sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB);
++  sqlite3VdbeAddOp4(v, OP_VUpdate, 0, nArg, regArg, pVTab, P4_VTAB);
+   sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
+   sqlite3MayAbort(pParse);
+-  sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
+-  sqlite3VdbeJumpHere(v, addr);
+-  sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
+ 
+-  /* Cleanup */
+-  sqlite3SelectDelete(db, pSelect);  
++  /* End of the ephemeral table scan. Or, if using the onepass strategy,
++  ** jump to here if the scan visited zero rows. */
++  if( bOnePass==0 ){
++    sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
++    sqlite3VdbeJumpHere(v, addr);
++    sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
++  }else{
++    sqlite3WhereEnd(pWInfo);
++  }
+ }
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+ 
+@@ -114255,59 +128962,56 @@
+ ** Most of the code in this file may be omitted by defining the
+ ** SQLITE_OMIT_VACUUM macro.
+ */
++/* #include "sqliteInt.h" */
++/* #include "vdbeInt.h" */
+ 
+ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
+-/*
+-** Finalize a prepared statement.  If there was an error, store the
+-** text of the error message in *pzErrMsg.  Return the result code.
+-*/
+-static int vacuumFinalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
+-  int rc;
+-  rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
+-  if( rc ){
+-    sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
+-  }
+-  return rc;
+-}
+ 
+ /*
+-** Execute zSql on database db. Return an error code.
++** Execute zSql on database db.
++**
++** If zSql returns rows, then each row will have exactly one
++** column.  (This will only happen if zSql begins with "SELECT".)
++** Take each row of result and call execSql() again recursively.
++**
++** The execSqlF() routine does the same thing, except it accepts
++** a format string as its third argument
+ */
+ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
+   sqlite3_stmt *pStmt;
+-  VVA_ONLY( int rc; )
+-  if( !zSql ){
+-    return SQLITE_NOMEM;
++  int rc;
++
++  /* printf("SQL: [%s]\n", zSql); fflush(stdout); */
++  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
++  if( rc!=SQLITE_OK ) return rc;
++  while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
++    const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
++    assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
++    if( zSubSql ){
++      assert( zSubSql[0]!='S' );
++      rc = execSql(db, pzErrMsg, zSubSql);
++      if( rc!=SQLITE_OK ) break;
++    }
+   }
+-  if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
++  assert( rc!=SQLITE_ROW );
++  if( rc==SQLITE_DONE ) rc = SQLITE_OK;
++  if( rc ){
+     sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
+-    return sqlite3_errcode(db);
+   }
+-  VVA_ONLY( rc = ) sqlite3_step(pStmt);
+-  assert( rc!=SQLITE_ROW || (db->flags&SQLITE_CountRows) );
+-  return vacuumFinalize(db, pStmt, pzErrMsg);
+-}
+-
+-/*
+-** Execute zSql on database db. The statement returns exactly
+-** one column. Execute this as SQL on the same database.
+-*/
+-static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
+-  sqlite3_stmt *pStmt;
+-  int rc;
+-
+-  rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
+-  if( rc!=SQLITE_OK ) return rc;
+-
+-  while( SQLITE_ROW==sqlite3_step(pStmt) ){
+-    rc = execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
+-    if( rc!=SQLITE_OK ){
+-      vacuumFinalize(db, pStmt, pzErrMsg);
+-      return rc;
+-    }
+-  }
+-
+-  return vacuumFinalize(db, pStmt, pzErrMsg);
++  (void)sqlite3_finalize(pStmt);
++  return rc;
++}
++static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
++  char *z;
++  va_list ap;
++  int rc;
++  va_start(ap, zSql);
++  z = sqlite3VMPrintf(db, zSql, ap);
++  va_end(ap);
++  if( z==0 ) return SQLITE_NOMEM;
++  rc = execSql(db, pzErrMsg, z);
++  sqlite3DbFree(db, z);
++  return rc;
+ }
+ 
+ /*
+@@ -114340,11 +129044,29 @@
+ ** transient would cause the database file to appear to be deleted
+ ** following reboot.
+ */
+-SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){
++SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){
+   Vdbe *v = sqlite3GetVdbe(pParse);
+-  if( v ){
+-    sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0);
+-    sqlite3VdbeUsesBtree(v, 0);
++  int iDb = 0;
++  if( v==0 ) return;
++  if( pNm ){
++#ifndef SQLITE_BUG_COMPATIBLE_20160819
++    /* Default behavior:  Report an error if the argument to VACUUM is
++    ** not recognized */
++    iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
++    if( iDb<0 ) return;
++#else
++    /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments
++    ** to VACUUM are silently ignored.  This is a back-out of a bug fix that
++    ** occurred on 2016-08-19 (https://www.sqlite.org/src/info/083f9e6270).
++    ** The buggy behavior is required for binary compatibility with some
++    ** legacy applications. */
++    iDb = sqlite3FindDb(pParse->db, pNm);
++    if( iDb<0 ) iDb = 0;
 +#endif
-+#if SQLITE_OMIT_QUICKBALANCE
-+  "OMIT_QUICKBALANCE",
++  }
++  if( iDb!=1 ){
++    sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
++    sqlite3VdbeUsesBtree(v, iDb);
+   }
+   return;
+ }
+@@ -114352,19 +129074,19 @@
+ /*
+ ** This routine implements the OP_Vacuum opcode of the VDBE.
+ */
+-SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
++SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
+   int rc = SQLITE_OK;     /* Return code from service routines */
+   Btree *pMain;           /* The database being vacuumed */
+   Btree *pTemp;           /* The temporary database we vacuum into */
+-  char *zSql = 0;         /* SQL statements */
+   int saved_flags;        /* Saved value of the db->flags */
+   int saved_nChange;      /* Saved value of db->nChange */
+   int saved_nTotalChange; /* Saved value of db->nTotalChange */
+-  void (*saved_xTrace)(void*,const char*);  /* Saved db->xTrace */
++  u8 saved_mTrace;        /* Saved trace settings */
+   Db *pDb = 0;            /* Database to detach at end of vacuum */
+   int isMemDb;            /* True if vacuuming a :memory: database */
+   int nRes;               /* Bytes of reserved space at the end of each page */
+   int nDb;                /* Number of attached databases */
++  const char *zDbMain;    /* Schema name of database to vacuum */
+ 
+   if( !db->autoCommit ){
+     sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
+@@ -114381,12 +129103,14 @@
+   saved_flags = db->flags;
+   saved_nChange = db->nChange;
+   saved_nTotalChange = db->nTotalChange;
+-  saved_xTrace = db->xTrace;
+-  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
+-  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
+-  db->xTrace = 0;
++  saved_mTrace = db->mTrace;
++  db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks
++                 | SQLITE_PreferBuiltin | SQLITE_Vacuum);
++  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
++  db->mTrace = 0;
+ 
+-  pMain = db->aDb[0].pBt;
++  zDbMain = db->aDb[iDb].zDbSName;
++  pMain = db->aDb[iDb].pBt;
+   isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
+ 
+   /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
+@@ -114404,18 +129128,12 @@
+   ** to write the journal header file.
+   */
+   nDb = db->nDb;
+-  if( sqlite3TempInMemory(db) ){
+-    zSql = "ATTACH ':memory:' AS vacuum_db;";
+-  }else{
+-    zSql = "ATTACH '' AS vacuum_db;";
+-  }
+-  rc = execSql(db, pzErrMsg, zSql);
+-  if( db->nDb>nDb ){
+-    pDb = &db->aDb[db->nDb-1];
+-    assert( strcmp(pDb->zName,"vacuum_db")==0 );
+-  }
++  rc = execSql(db, pzErrMsg, "ATTACH''AS vacuum_db");
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+-  pTemp = db->aDb[db->nDb-1].pBt;
++  assert( (db->nDb-1)==nDb );
++  pDb = &db->aDb[nDb];
++  assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
++  pTemp = pDb->pBt;
+ 
+   /* The call to execSql() to attach the temp database has left the file
+   ** locked (as there was more than one active statement when the transaction
+@@ -114431,19 +129149,20 @@
+     extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
+     int nKey;
+     char *zKey;
+-    sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
++    sqlite3CodecGetKey(db, iDb, (void**)&zKey, &nKey);
+     if( nKey ) db->nextPagesize = 0;
+   }
+ #endif
+ 
+-  rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF");
+-  if( rc!=SQLITE_OK ) goto end_of_vacuum;
++  sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
++  sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
++  sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL);
+ 
+   /* Begin a transaction and take an exclusive lock on the main database
+   ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
+   ** to ensure that we do not try to change the page-size on a WAL database.
+   */
+-  rc = execSql(db, pzErrMsg, "BEGIN;");
++  rc = execSql(db, pzErrMsg, "BEGIN");
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+   rc = sqlite3BtreeBeginTrans(pMain, 2);
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+@@ -114458,7 +129177,7 @@
+    || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
+    || NEVER(db->mallocFailed)
+   ){
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+     goto end_of_vacuum;
+   }
+ 
+@@ -114470,64 +129189,48 @@
+   /* Query the schema of the main database. Create a mirror schema
+   ** in the temporary database.
+   */
+-  rc = execExecSql(db, pzErrMsg,
+-      "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) "
+-      "  FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
+-      "   AND coalesce(rootpage,1)>0"
++  db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */
++  rc = execSqlF(db, pzErrMsg,
++      "SELECT sql FROM \"%w\".sqlite_master"
++      " WHERE type='table'AND name<>'sqlite_sequence'"
++      " AND coalesce(rootpage,1)>0",
++      zDbMain
+   );
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+-  rc = execExecSql(db, pzErrMsg,
+-      "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)"
+-      "  FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' ");
+-  if( rc!=SQLITE_OK ) goto end_of_vacuum;
+-  rc = execExecSql(db, pzErrMsg,
+-      "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) "
+-      "  FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
++  rc = execSqlF(db, pzErrMsg,
++      "SELECT sql FROM \"%w\".sqlite_master"
++      " WHERE type='index' AND length(sql)>10",
++      zDbMain
++  );
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
++  db->init.iDb = 0;
+ 
+   /* Loop through the tables in the main database. For each, do
+   ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
+   ** the contents to the temporary database.
+   */
+-  assert( (db->flags & SQLITE_Vacuum)==0 );
+-  db->flags |= SQLITE_Vacuum;
+-  rc = execExecSql(db, pzErrMsg,
+-      "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
+-      "|| ' SELECT * FROM main.' || quote(name) || ';'"
+-      "FROM main.sqlite_master "
+-      "WHERE type = 'table' AND name!='sqlite_sequence' "
+-      "  AND coalesce(rootpage,1)>0"
++  rc = execSqlF(db, pzErrMsg,
++      "SELECT'INSERT INTO vacuum_db.'||quote(name)"
++      "||' SELECT*FROM\"%w\".'||quote(name)"
++      "FROM vacuum_db.sqlite_master "
++      "WHERE type='table'AND coalesce(rootpage,1)>0",
++      zDbMain
+   );
+   assert( (db->flags & SQLITE_Vacuum)!=0 );
+   db->flags &= ~SQLITE_Vacuum;
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ 
+-  /* Copy over the sequence table
+-  */
+-  rc = execExecSql(db, pzErrMsg,
+-      "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
+-      "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
+-  );
+-  if( rc!=SQLITE_OK ) goto end_of_vacuum;
+-  rc = execExecSql(db, pzErrMsg,
+-      "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
+-      "|| ' SELECT * FROM main.' || quote(name) || ';' "
+-      "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';"
+-  );
+-  if( rc!=SQLITE_OK ) goto end_of_vacuum;
+-
+-
+   /* Copy the triggers, views, and virtual tables from the main database
+   ** over to the temporary database.  None of these objects has any
+   ** associated storage, so all we have to do is copy their entries
+   ** from the SQLITE_MASTER table.
+   */
+-  rc = execSql(db, pzErrMsg,
+-      "INSERT INTO vacuum_db.sqlite_master "
+-      "  SELECT type, name, tbl_name, rootpage, sql"
+-      "    FROM main.sqlite_master"
+-      "   WHERE type='view' OR type='trigger'"
+-      "      OR (type='table' AND rootpage=0)"
++  rc = execSqlF(db, pzErrMsg,
++      "INSERT INTO vacuum_db.sqlite_master"
++      " SELECT*FROM \"%w\".sqlite_master"
++      " WHERE type IN('view','trigger')"
++      " OR(type='table'AND rootpage=0)",
++      zDbMain
+   );
+   if( rc ) goto end_of_vacuum;
+ 
+@@ -114581,10 +129284,11 @@
+ 
+ end_of_vacuum:
+   /* Restore the original value of db->flags */
++  db->init.iDb = 0;
+   db->flags = saved_flags;
+   db->nChange = saved_nChange;
+   db->nTotalChange = saved_nTotalChange;
+-  db->xTrace = saved_xTrace;
++  db->mTrace = saved_mTrace;
+   sqlite3BtreeSetPageSize(pMain, -1, -1, 1);
+ 
+   /* Currently there is an SQL level transaction open on the vacuum
+@@ -114627,6 +129331,7 @@
+ ** This file contains code used to help implement virtual tables.
+ */
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** Before a virtual table xCreate() or xConnect() method is invoked, the
+@@ -114643,6 +129348,41 @@
+ };
+ 
+ /*
++** Construct and install a Module object for a virtual table.  When this
++** routine is called, it is guaranteed that all appropriate locks are held
++** and the module is not already part of the connection.
++*/
++SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
++  sqlite3 *db,                    /* Database in which module is registered */
++  const char *zName,              /* Name assigned to this module */
++  const sqlite3_module *pModule,  /* The definition of the module */
++  void *pAux,                     /* Context pointer for xCreate/xConnect */
++  void (*xDestroy)(void *)        /* Module destructor function */
++){
++  Module *pMod;
++  int nName = sqlite3Strlen30(zName);
++  pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1);
++  if( pMod ){
++    Module *pDel;
++    char *zCopy = (char *)(&pMod[1]);
++    memcpy(zCopy, zName, nName+1);
++    pMod->zName = zCopy;
++    pMod->pModule = pModule;
++    pMod->pAux = pAux;
++    pMod->xDestroy = xDestroy;
++    pMod->pEpoTab = 0;
++    pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
++    assert( pDel==0 || pDel==pMod );
++    if( pDel ){
++      sqlite3OomFault(db);
++      sqlite3DbFree(db, pDel);
++      pMod = 0;
++    }
++  }
++  return pMod;
++}
++
++/*
+ ** The actual function that does the work of creating a new module.
+ ** This function implements the sqlite3_create_module() and
+ ** sqlite3_create_module_v2() interfaces.
+@@ -114655,34 +129395,15 @@
+   void (*xDestroy)(void *)        /* Module destructor function */
+ ){
+   int rc = SQLITE_OK;
+-  int nName;
+ 
+   sqlite3_mutex_enter(db->mutex);
+-  nName = sqlite3Strlen30(zName);
+   if( sqlite3HashFind(&db->aModule, zName) ){
+     rc = SQLITE_MISUSE_BKPT;
+   }else{
+-    Module *pMod;
+-    pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
+-    if( pMod ){
+-      Module *pDel;
+-      char *zCopy = (char *)(&pMod[1]);
+-      memcpy(zCopy, zName, nName+1);
+-      pMod->zName = zCopy;
+-      pMod->pModule = pModule;
+-      pMod->pAux = pAux;
+-      pMod->xDestroy = xDestroy;
+-      pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
+-      assert( pDel==0 || pDel==pMod );
+-      if( pDel ){
+-        db->mallocFailed = 1;
+-        sqlite3DbFree(db, pDel);
+-      }
+-    }
++    (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy);
+   }
+   rc = sqlite3ApiExit(db, rc);
+   if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux);
+-
+   sqlite3_mutex_leave(db->mutex);
+   return rc;
+ }
+@@ -114691,7 +129412,7 @@
+ /*
+ ** External API function used to create a new virtual-table module.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
++SQLITE_API int sqlite3_create_module(
+   sqlite3 *db,                    /* Database in which module is registered */
+   const char *zName,              /* Name assigned to this module */
+   const sqlite3_module *pModule,  /* The definition of the module */
+@@ -114706,7 +129427,7 @@
+ /*
+ ** External API function used to create a new virtual-table module.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
++SQLITE_API int sqlite3_create_module_v2(
+   sqlite3 *db,                    /* Database in which module is registered */
+   const char *zName,              /* Name assigned to this module */
+   const sqlite3_module *pModule,  /* The definition of the module */
+@@ -114899,23 +129620,17 @@
+ ** deleted.
+ */
+ static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){
+-  int i = pTable->nModuleArg++;
+-  int nBytes = sizeof(char *)*(1+pTable->nModuleArg);
++  int nBytes = sizeof(char *)*(2+pTable->nModuleArg);
+   char **azModuleArg;
+   azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes);
+   if( azModuleArg==0 ){
+-    int j;
+-    for(j=0; j<i; j++){
+-      sqlite3DbFree(db, pTable->azModuleArg[j]);
+-    }
+     sqlite3DbFree(db, zArg);
+-    sqlite3DbFree(db, pTable->azModuleArg);
+-    pTable->nModuleArg = 0;
+   }else{
++    int i = pTable->nModuleArg++;
+     azModuleArg[i] = zArg;
+     azModuleArg[i+1] = 0;
++    pTable->azModuleArg = azModuleArg;
+   }
+-  pTable->azModuleArg = azModuleArg;
+ }
+ 
+ /*
+@@ -114943,8 +129658,7 @@
+   iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
+   assert( iDb>=0 );
+ 
+-  pTable->tabFlags |= TF_Virtual;
+-  pTable->nModuleArg = 0;
++  assert( pTable->nModuleArg==0 );
+   addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
+   addModuleArgument(db, pTable, 0);
+   addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
+@@ -114963,7 +129677,7 @@
+   */
+   if( pTable->azModuleArg ){
+     sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, 
+-            pTable->azModuleArg[0], pParse->db->aDb[iDb].zName);
++            pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
+   }
+ #endif
+ }
+@@ -115027,7 +129741,7 @@
+       "UPDATE %Q.%s "
+          "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
+        "WHERE rowid=#%d",
+-      db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
++      db->aDb[iDb].zDbSName, MASTER_NAME,
+       pTab->zName,
+       pTab->zName,
+       zStmt,
+@@ -115037,12 +129751,12 @@
+     v = sqlite3GetVdbe(pParse);
+     sqlite3ChangeCookie(pParse, iDb);
+ 
+-    sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
++    sqlite3VdbeAddOp0(v, OP_Expire);
+     zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName);
+     sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
+ 
+     iReg = ++pParse->nMem;
+-    sqlite3VdbeAddOp4(v, OP_String8, 0, iReg, 0, pTab->zName, 0);
++    sqlite3VdbeLoadString(v, iReg, pTab->zName);
+     sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
+   }
+ 
+@@ -115058,7 +129772,7 @@
+     assert( sqlite3SchemaMutexHeld(db, 0, pSchema) );
+     pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
+     if( pOld ){
+-      db->mallocFailed = 1;
++      sqlite3OomFault(db);
+       assert( pTab==pOld );  /* Malloc must have failed inside HashInsert() */
+       return;
+     }
+@@ -115125,19 +129839,19 @@
+ 
+   zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
+   if( !zModuleName ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+ 
+   pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
+   if( !pVTable ){
+     sqlite3DbFree(db, zModuleName);
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   pVTable->db = db;
+   pVTable->pMod = pMod;
+ 
+   iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+-  pTab->azModuleArg[1] = db->aDb[iDb].zName;
++  pTab->azModuleArg[1] = db->aDb[iDb].zDbSName;
+ 
+   /* Invoke the virtual table constructor */
+   assert( &db->pVtabCtx );
+@@ -115149,7 +129863,7 @@
+   db->pVtabCtx = &sCtx;
+   rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
+   db->pVtabCtx = sCtx.pPrior;
+-  if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
++  if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
+   assert( sCtx.pTab==pTab );
+ 
+   if( SQLITE_OK!=rc ){
+@@ -115183,22 +129897,16 @@
+       pTab->pVTable = pVTable;
+ 
+       for(iCol=0; iCol<pTab->nCol; iCol++){
+-        char *zType = pTab->aCol[iCol].zType;
++        char *zType = sqlite3ColumnType(&pTab->aCol[iCol], "");
+         int nType;
+         int i = 0;
+-        if( !zType ){
+-          pTab->tabFlags |= oooHidden;
+-          continue;
+-        }
+         nType = sqlite3Strlen30(zType);
+-        if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
+-          for(i=0; i<nType; i++){
+-            if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7))
+-             && (zType[i+7]=='\0' || zType[i+7]==' ')
+-            ){
+-              i++;
+-              break;
+-            }
++        for(i=0; i<nType; i++){
++          if( 0==sqlite3StrNICmp("hidden", &zType[i], 6)
++           && (i==0 || zType[i-1]==' ')
++           && (zType[i+6]=='\0' || zType[i+6]==' ')
++          ){
++            break;
+           }
+         }
+         if( i<nType ){
+@@ -115238,7 +129946,7 @@
+   int rc;
+ 
+   assert( pTab );
+-  if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
++  if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
+     return SQLITE_OK;
+   }
+ 
+@@ -115274,7 +129982,7 @@
+     int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
+     aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
+     if( !aVTrans ){
+-      return SQLITE_NOMEM;
++      return SQLITE_NOMEM_BKPT;
+     }
+     memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
+     db->aVTrans = aVTrans;
+@@ -115297,7 +130005,7 @@
+ ** This function is invoked by the vdbe to call the xCreate method
+ ** of the virtual table named zTab in database iDb. 
+ **
+-** If an error occurs, *pzErr is set to point an an English language
++** If an error occurs, *pzErr is set to point to an English language
+ ** description of the error and an SQLITE_XXX error code is returned.
+ ** In this case the caller must call sqlite3DbFree(db, ) on *pzErr.
+ */
+@@ -115307,8 +130015,8 @@
+   Module *pMod;
+   const char *zMod;
+ 
+-  pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
+-  assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
++  pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
++  assert( pTab && IsVirtual(pTab) && !pTab->pVTable );
+ 
+   /* Locate the required virtual table module */
+   zMod = pTab->azModuleArg[0];
+@@ -115318,7 +130026,7 @@
+   ** invoke it now. If the module has not been registered, return an 
+   ** error. Otherwise, do nothing.
+   */
+-  if( !pMod ){
++  if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){
+     *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod);
+     rc = SQLITE_ERROR;
+   }else{
+@@ -115342,7 +130050,7 @@
+ ** valid to call this function from within the xCreate() or xConnect() of a
+ ** virtual table module.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
++SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
+   VtabCtx *pCtx;
+   Parse *pParse;
+   int rc = SQLITE_OK;
+@@ -115362,11 +130070,11 @@
+     return SQLITE_MISUSE_BKPT;
+   }
+   pTab = pCtx->pTab;
+-  assert( (pTab->tabFlags & TF_Virtual)!=0 );
++  assert( IsVirtual(pTab) );
+ 
+   pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
+   if( pParse==0 ){
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+   }else{
+     pParse->declareVtab = 1;
+     pParse->db = db;
+@@ -115376,13 +130084,27 @@
+      && pParse->pNewTable
+      && !db->mallocFailed
+      && !pParse->pNewTable->pSelect
+-     && (pParse->pNewTable->tabFlags & TF_Virtual)==0
++     && !IsVirtual(pParse->pNewTable)
+     ){
+       if( !pTab->aCol ){
+-        pTab->aCol = pParse->pNewTable->aCol;
+-        pTab->nCol = pParse->pNewTable->nCol;
+-        pParse->pNewTable->nCol = 0;
+-        pParse->pNewTable->aCol = 0;
++        Table *pNew = pParse->pNewTable;
++        Index *pIdx;
++        pTab->aCol = pNew->aCol;
++        pTab->nCol = pNew->nCol;
++        pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
++        pNew->nCol = 0;
++        pNew->aCol = 0;
++        assert( pTab->pIndex==0 );
++        if( !HasRowid(pNew) && pCtx->pVTable->pMod->pModule->xUpdate!=0 ){
++          rc = SQLITE_ERROR;
++        }
++        pIdx = pNew->pIndex;
++        if( pIdx ){
++          assert( pIdx->pNext==0 );
++          pTab->pIndex = pIdx;
++          pNew->pIndex = 0;
++          pIdx->pTable = pTab;
++        }
+       }
+       pCtx->bDeclared = 1;
+     }else{
+@@ -115417,9 +130139,10 @@
+   int rc = SQLITE_OK;
+   Table *pTab;
+ 
+-  pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
+-  if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){
++  pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
++  if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){
+     VTable *p;
++    int (*xDestroy)(sqlite3_vtab *);
+     for(p=pTab->pVTable; p; p=p->pNext){
+       assert( p->pVtab );
+       if( p->pVtab->nRef>0 ){
+@@ -115427,7 +130150,9 @@
+       }
+     }
+     p = vtabDisconnectAll(db, pTab);
+-    rc = p->pMod->pModule->xDestroy(p->pVtab);
++    xDestroy = p->pMod->pModule->xDestroy;
++    assert( xDestroy!=0 );  /* Checked before the virtual table is created */
++    rc = xDestroy(p->pVtab);
+     /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
+     if( rc==SQLITE_OK ){
+       assert( pTab->pVTable==p && p->pNext==0 );
+@@ -115451,8 +130176,10 @@
+ static void callFinaliser(sqlite3 *db, int offset){
+   int i;
+   if( db->aVTrans ){
++    VTable **aVTrans = db->aVTrans;
++    db->aVTrans = 0;
+     for(i=0; i<db->nVTrans; i++){
+-      VTable *pVTab = db->aVTrans[i];
++      VTable *pVTab = aVTrans[i];
+       sqlite3_vtab *p = pVTab->pVtab;
+       if( p ){
+         int (*x)(sqlite3_vtab *);
+@@ -115462,9 +130189,8 @@
+       pVTab->iSavepoint = 0;
+       sqlite3VtabUnlock(pVTab);
+     }
+-    sqlite3DbFree(db, db->aVTrans);
++    sqlite3DbFree(db, aVTrans);
+     db->nVTrans = 0;
+-    db->aVTrans = 0;
+   }
+ }
+ 
+@@ -115552,7 +130278,12 @@
+     if( rc==SQLITE_OK ){
+       rc = pModule->xBegin(pVTab->pVtab);
+       if( rc==SQLITE_OK ){
++        int iSvpt = db->nStatement + db->nSavepoint;
+         addToVTrans(db, pVTab);
++        if( iSvpt && pModule->xSavepoint ){
++          pVTab->iSavepoint = iSvpt;
++          rc = pModule->xSavepoint(pVTab->pVtab, iSvpt-1);
++        }
+       }
+     }
+   }
+@@ -115629,7 +130360,7 @@
+   Table *pTab;
+   sqlite3_vtab *pVtab;
+   sqlite3_module *pMod;
+-  void (*xFunc)(sqlite3_context*,int,sqlite3_value**) = 0;
++  void (*xSFunc)(sqlite3_context*,int,sqlite3_value**) = 0;
+   void *pArg = 0;
+   FuncDef *pNew;
+   int rc = 0;
+@@ -115641,8 +130372,8 @@
+   if( NEVER(pExpr==0) ) return pDef;
+   if( pExpr->op!=TK_COLUMN ) return pDef;
+   pTab = pExpr->pTab;
+-  if( NEVER(pTab==0) ) return pDef;
+-  if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
++  if( pTab==0 ) return pDef;
++  if( !IsVirtual(pTab) ) return pDef;
+   pVtab = sqlite3GetVTable(db, pTab)->pVtab;
+   assert( pVtab!=0 );
+   assert( pVtab->pModule!=0 );
+@@ -115657,7 +130388,7 @@
+     for(z=(unsigned char*)zLowerName; *z; z++){
+       *z = sqlite3UpperToLower[*z];
+     }
+-    rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);
++    rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xSFunc, &pArg);
+     sqlite3DbFree(db, zLowerName);
+   }
+   if( rc==0 ){
+@@ -115672,9 +130403,9 @@
+     return pDef;
+   }
+   *pNew = *pDef;
+-  pNew->zName = (char *)&pNew[1];
+-  memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1);
+-  pNew->xFunc = xFunc;
++  pNew->zName = (const char*)&pNew[1];
++  memcpy((char*)&pNew[1], pDef->zName, sqlite3Strlen30(pDef->zName)+1);
++  pNew->xSFunc = xSFunc;
+   pNew->pUserData = pArg;
+   pNew->funcFlags |= SQLITE_FUNC_EPHEM;
+   return pNew;
+@@ -115701,7 +130432,70 @@
+     pToplevel->apVtabLock = apVtabLock;
+     pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
+   }else{
+-    pToplevel->db->mallocFailed = 1;
++    sqlite3OomFault(pToplevel->db);
++  }
++}
++
++/*
++** Check to see if virtual table module pMod can be have an eponymous
++** virtual table instance.  If it can, create one if one does not already
++** exist. Return non-zero if the eponymous virtual table instance exists
++** when this routine returns, and return zero if it does not exist.
++**
++** An eponymous virtual table instance is one that is named after its
++** module, and more importantly, does not require a CREATE VIRTUAL TABLE
++** statement in order to come into existance.  Eponymous virtual table
++** instances always exist.  They cannot be DROP-ed.
++**
++** Any virtual table module for which xConnect and xCreate are the same
++** method can have an eponymous virtual table instance.
++*/
++SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
++  const sqlite3_module *pModule = pMod->pModule;
++  Table *pTab;
++  char *zErr = 0;
++  int rc;
++  sqlite3 *db = pParse->db;
++  if( pMod->pEpoTab ) return 1;
++  if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0;
++  pTab = sqlite3DbMallocZero(db, sizeof(Table));
++  if( pTab==0 ) return 0;
++  pTab->zName = sqlite3DbStrDup(db, pMod->zName);
++  if( pTab->zName==0 ){
++    sqlite3DbFree(db, pTab);
++    return 0;
++  }
++  pMod->pEpoTab = pTab;
++  pTab->nTabRef = 1;
++  pTab->pSchema = db->aDb[0].pSchema;
++  assert( pTab->nModuleArg==0 );
++  pTab->iPKey = -1;
++  addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
++  addModuleArgument(db, pTab, 0);
++  addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
++  rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
++  if( rc ){
++    sqlite3ErrorMsg(pParse, "%s", zErr);
++    sqlite3DbFree(db, zErr);
++    sqlite3VtabEponymousTableClear(db, pMod);
++    return 0;
++  }
++  return 1;
++}
++
++/*
++** Erase the eponymous virtual table instance associated with
++** virtual table module pMod, if it exists.
++*/
++SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){
++  Table *pTab = pMod->pEpoTab;
++  if( pTab!=0 ){
++    /* Mark the table as Ephemeral prior to deleting it, so that the
++    ** sqlite3DeleteTable() routine will know that it is not stored in 
++    ** the schema. */
++    pTab->tabFlags |= TF_Ephemeral;
++    sqlite3DeleteTable(db, pTab);
++    pMod->pEpoTab = 0;
+   }
+ }
+ 
+@@ -115712,7 +130506,7 @@
+ ** The results of this routine are undefined unless it is called from
+ ** within an xUpdate method.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *db){
++SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
+   static const unsigned char aMap[] = { 
+     SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE 
+   };
+@@ -115730,7 +130524,7 @@
+ ** the SQLite core with additional information about the behavior
+ ** of the virtual table being implemented.
+ */
+-SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3 *db, int op, ...){
++SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
+   va_list ap;
+   int rc = SQLITE_OK;
+ 
+@@ -115745,7 +130539,7 @@
+       if( !p ){
+         rc = SQLITE_MISUSE_BKPT;
+       }else{
+-        assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 );
++        assert( p->pTab==0 || IsVirtual(p->pTab) );
+         p->pVTable->bConstraint = (u8)va_arg(ap, int);
+       }
+       break;
+@@ -115764,9 +130558,9 @@
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+ 
+ /************** End of vtab.c ************************************************/
+-/************** Begin file where.c *******************************************/
++/************** Begin file wherecode.c ***************************************/
+ /*
+-** 2001 September 15
++** 2015-06-06
+ **
+ ** The author disclaims copyright to this source code.  In place of
+ ** a legal notice, here is a blessing:
+@@ -115777,13 +130571,15 @@
+ **
+ *************************************************************************
+ ** This module contains C code that generates VDBE code used to process
+-** the WHERE clause of SQL statements.  This module is responsible for
+-** generating the code that loops through a table looking for applicable
+-** rows.  Indices are selected and used to speed the search when doing
+-** so is applicable.  Because this module is responsible for selecting
+-** indices, you might also think of this module as the "query optimizer".
++** the WHERE clause of SQL statements.
++**
++** This file was split off from where.c on 2015-06-06 in order to reduce the
++** size of where.c and make it easier to edit.  This file contains the routines
++** that actually generate the bulk of the WHERE loop code.  The original where.c
++** file retains the code that does query planning and analysis.
+ */
+-/************** Include whereInt.h in the middle of where.c ******************/
++/* #include "sqliteInt.h" */
++/************** Include whereInt.h in the middle of wherecode.c **************/
+ /************** Begin file whereInt.h ****************************************/
+ /*
+ ** 2013-11-12
+@@ -115806,7 +130602,7 @@
+ ** Trace output macros
+ */
+ #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
+-/***/ int sqlite3WhereTrace = 0;
++/***/ int sqlite3WhereTrace;
+ #endif
+ #if defined(SQLITE_DEBUG) \
+     && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
+@@ -115856,8 +130652,10 @@
+   int addrCont;         /* Jump here to continue with the next loop cycle */
+   int addrFirst;        /* First instruction of interior of the loop */
+   int addrBody;         /* Beginning of the body of this loop */
+-  int iLikeRepCntr;     /* LIKE range processing counter register */
++#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
++  u32 iLikeRepCntr;     /* LIKE range processing counter register (times 2) */
+   int addrLikeRep;      /* LIKE range processing address */
 +#endif
-+#if SQLITE_OMIT_REINDEX
-+  "OMIT_REINDEX",
+   u8 iFrom;             /* Which entry in the FROM clause */
+   u8 op, p3, p5;        /* Opcode, P3 & P5 of the opcode that ends the loop */
+   int p1, p2;           /* Operands of the opcode used to ends the loop */
+@@ -115907,6 +130705,9 @@
+   union {
+     struct {               /* Information for internal btree tables */
+       u16 nEq;               /* Number of equality constraints */
++      u16 nBtm;              /* Size of BTM vector */
++      u16 nTop;              /* Size of TOP vector */
++      u16 nIdxCol;           /* Index column used for ORDER BY */
+       Index *pIndex;         /* Index used, or NULL */
+     } btree;
+     struct {               /* Information for virtual tables */
+@@ -115948,10 +130749,6 @@
+   WhereOrCost a[N_OR_COST];   /* Set of best costs */
+ };
+ 
+-
+-/* Forward declaration of methods */
+-static int whereLoopResize(sqlite3*, WhereLoop*, int);
+-
+ /*
+ ** Each instance of this object holds a sequence of WhereLoop objects
+ ** that implement some or all of a query plan.
+@@ -116033,18 +130830,20 @@
+ */
+ struct WhereTerm {
+   Expr *pExpr;            /* Pointer to the subexpression that is this term */
++  WhereClause *pWC;       /* The clause this term is part of */
++  LogEst truthProb;       /* Probability of truth for this expression */
++  u16 wtFlags;            /* TERM_xxx bit flags.  See below */
++  u16 eOperator;          /* A WO_xx value describing <op> */
++  u8 nChild;              /* Number of children that must disable us */
++  u8 eMatchOp;            /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
+   int iParent;            /* Disable pWC->a[iParent] when this term disabled */
+   int leftCursor;         /* Cursor number of X in "X <op> <expr>" */
++  int iField;             /* Field in (?,?,?) IN (SELECT...) vector */
+   union {
+     int leftColumn;         /* Column number of X in "X <op> <expr>" */
+     WhereOrInfo *pOrInfo;   /* Extra information if (eOperator & WO_OR)!=0 */
+     WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
+   } u;
+-  LogEst truthProb;       /* Probability of truth for this expression */
+-  u16 eOperator;          /* A WO_xx value describing <op> */
+-  u16 wtFlags;            /* TERM_xxx bit flags.  See below */
+-  u8 nChild;              /* Number of children that must disable us */
+-  WhereClause *pWC;       /* The clause this term is part of */
+   Bitmask prereqRight;    /* Bitmask of tables used by pExpr->pRight */
+   Bitmask prereqAll;      /* Bitmask of tables referenced by pExpr */
+ };
+@@ -116067,6 +130866,8 @@
+ #define TERM_LIKEOPT    0x100  /* Virtual terms from the LIKE optimization */
+ #define TERM_LIKECOND   0x200  /* Conditionally this LIKE operator term */
+ #define TERM_LIKE       0x400  /* The original LIKE operator */
++#define TERM_IS         0x800  /* Term.pExpr is an IS operator */
++#define TERM_VARSELECT  0x1000 /* Term.pExpr contains a correlated sub-query */
+ 
+ /*
+ ** An instance of the WhereScan object is used as an iterator for locating
+@@ -116075,13 +130876,15 @@
+ struct WhereScan {
+   WhereClause *pOrigWC;      /* Original, innermost WhereClause */
+   WhereClause *pWC;          /* WhereClause currently being scanned */
+-  char *zCollName;           /* Required collating sequence, if not NULL */
++  const char *zCollName;     /* Required collating sequence, if not NULL */
++  Expr *pIdxExpr;            /* Search for this index expression */
+   char idxaff;               /* Must match this affinity, if zCollName!=NULL */
+   unsigned char nEquiv;      /* Number of entries in aEquiv[] */
+   unsigned char iEquiv;      /* Next unused slot in aEquiv[] */
+   u32 opMask;                /* Acceptable operators */
+   int k;                     /* Resume scanning at this->pWC->a[this->k] */
+-  int aEquiv[22];            /* Cursor,Column pairs for equivalence classes */
++  int aiCur[11];             /* Cursors in the equivalence class */
++  i16 aiColumn[11];          /* Corresponding column number in the eq-class */
+ };
+ 
+ /*
+@@ -116154,11 +130957,17 @@
+ ** no gaps.
+ */
+ struct WhereMaskSet {
++  int bVarSelect;               /* Used by sqlite3WhereExprUsage() */
+   int n;                        /* Number of assigned cursor values */
+   int ix[BMS];                  /* Cursor assigned to each bit */
+ };
+ 
+ /*
++** Initialize a WhereMaskSet object
++*/
++#define initMaskSet(P)  (P)->n=0
++
++/*
+ ** This object is a convenience wrapper holding all information needed
+ ** to construct WhereLoop objects for a particular query.
+ */
+@@ -116172,8 +130981,13 @@
+   UnpackedRecord *pRec;     /* Probe for stat4 (if required) */
+   int nRecValid;            /* Number of valid fields currently in pRec */
+ #endif
++  unsigned int bldFlags;    /* SQLITE_BLDF_* flags */
+ };
+ 
++/* Allowed values for WhereLoopBuider.bldFlags */
++#define SQLITE_BLDF_INDEXED  0x0001   /* An index is used */
++#define SQLITE_BLDF_UNIQUE   0x0002   /* All keys of a UNIQUE index used */
++
+ /*
+ ** The WHERE clause processing routine has two halves.  The
+ ** first part does the start of the WHERE loop and the second
+@@ -116188,48 +131002,120 @@
+   Parse *pParse;            /* Parsing and code generating context */
+   SrcList *pTabList;        /* List of tables in the join */
+   ExprList *pOrderBy;       /* The ORDER BY clause or NULL */
+-  ExprList *pResultSet;     /* Result set. DISTINCT operates on these */
+-  WhereLoop *pLoops;        /* List of all WhereLoop objects */
+-  Bitmask revMask;          /* Mask of ORDER BY terms that need reversing */
+-  LogEst nRowOut;           /* Estimated number of output rows */
++  ExprList *pResultSet;     /* Result set of the query */
++  Expr *pWhere;             /* The complete WHERE clause */
++  LogEst iLimit;            /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
++  int aiCurOnePass[2];      /* OP_OpenWrite cursors for the ONEPASS opt */
++  int iContinue;            /* Jump here to continue with next record */
++  int iBreak;               /* Jump here to break out of the loop */
++  int savedNQueryLoop;      /* pParse->nQueryLoop outside the WHERE loop */
+   u16 wctrlFlags;           /* Flags originally passed to sqlite3WhereBegin() */
++  u8 nLevel;                /* Number of nested loop */
+   i8 nOBSat;                /* Number of ORDER BY terms satisfied by indices */
+   u8 sorted;                /* True if really sorted (not just grouped) */
+-  u8 okOnePass;             /* Ok to use one-pass algorithm for UPDATE/DELETE */
++  u8 eOnePass;              /* ONEPASS_OFF, or _SINGLE, or _MULTI */
+   u8 untestedTerms;         /* Not all WHERE terms resolved by outer loop */
+-  u8 eDistinct;             /* One of the WHERE_DISTINCT_* values below */
+-  u8 nLevel;                /* Number of nested loop */
++  u8 eDistinct;             /* One of the WHERE_DISTINCT_* values */
++  u8 bOrderedInnerLoop;     /* True if only the inner-most loop is ordered */
+   int iTop;                 /* The very beginning of the WHERE loop */
+-  int iContinue;            /* Jump here to continue with next record */
+-  int iBreak;               /* Jump here to break out of the loop */
+-  int savedNQueryLoop;      /* pParse->nQueryLoop outside the WHERE loop */
+-  int aiCurOnePass[2];      /* OP_OpenWrite cursors for the ONEPASS opt */
+-  WhereMaskSet sMaskSet;    /* Map cursor numbers to bitmasks */
++  WhereLoop *pLoops;        /* List of all WhereLoop objects */
++  Bitmask revMask;          /* Mask of ORDER BY terms that need reversing */
++  LogEst nRowOut;           /* Estimated number of output rows */
+   WhereClause sWC;          /* Decomposition of the WHERE clause */
++  WhereMaskSet sMaskSet;    /* Map cursor numbers to bitmasks */
+   WhereLevel a[1];          /* Information about each nest loop in WHERE */
+ };
+ 
+ /*
++** Private interfaces - callable only by other where.c routines.
++**
++** where.c:
++*/
++SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int);
++#ifdef WHERETRACE_ENABLED
++SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC);
 +#endif
-+#if SQLITE_OMIT_SCHEMA_PRAGMAS
-+  "OMIT_SCHEMA_PRAGMAS",
++SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm(
++  WhereClause *pWC,     /* The WHERE clause to be searched */
++  int iCur,             /* Cursor number of LHS */
++  int iColumn,          /* Column number of LHS */
++  Bitmask notReady,     /* RHS must not overlap with this mask */
++  u32 op,               /* Mask of WO_xx values describing operator */
++  Index *pIdx           /* Must be compatible with this index, if not NULL */
++);
++
++/* wherecode.c: */
++#ifndef SQLITE_OMIT_EXPLAIN
++SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
++  Parse *pParse,                  /* Parse context */
++  SrcList *pTabList,              /* Table list this loop refers to */
++  WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
++  int iLevel,                     /* Value for "level" column of output */
++  int iFrom,                      /* Value for "from" column of output */
++  u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
++);
++#else
++# define sqlite3WhereExplainOneScan(u,v,w,x,y,z) 0
++#endif /* SQLITE_OMIT_EXPLAIN */
++#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
++SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
++  Vdbe *v,                        /* Vdbe to add scanstatus entry to */
++  SrcList *pSrclist,              /* FROM clause pLvl reads data from */
++  WhereLevel *pLvl,               /* Level to add scanstatus() entry for */
++  int addrExplain                 /* Address of OP_Explain (or 0) */
++);
++#else
++# define sqlite3WhereAddScanStatus(a, b, c, d) ((void)d)
 +#endif
-+#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
-+  "OMIT_SCHEMA_VERSION_PRAGMAS",
++SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
++  WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
++  int iLevel,          /* Which level of pWInfo->a[] should be coded */
++  Bitmask notReady     /* Which tables are currently available */
++);
++
++/* whereexpr.c: */
++SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
++SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
++SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8);
++SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
++SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
++SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
++SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
++
++
++
++
++
++/*
+ ** Bitmasks for the operators on WhereTerm objects.  These are all
+ ** operators that are of interest to the query planner.  An
+ ** OR-ed combination of these values can be used when searching for
+ ** particular WhereTerms within a WhereClause.
++**
++** Value constraints:
++**     WO_EQ    == SQLITE_INDEX_CONSTRAINT_EQ
++**     WO_LT    == SQLITE_INDEX_CONSTRAINT_LT
++**     WO_LE    == SQLITE_INDEX_CONSTRAINT_LE
++**     WO_GT    == SQLITE_INDEX_CONSTRAINT_GT
++**     WO_GE    == SQLITE_INDEX_CONSTRAINT_GE
++**     WO_MATCH == SQLITE_INDEX_CONSTRAINT_MATCH
+ */
+-#define WO_IN     0x001
+-#define WO_EQ     0x002
++#define WO_IN     0x0001
++#define WO_EQ     0x0002
+ #define WO_LT     (WO_EQ<<(TK_LT-TK_EQ))
+ #define WO_LE     (WO_EQ<<(TK_LE-TK_EQ))
+ #define WO_GT     (WO_EQ<<(TK_GT-TK_EQ))
+ #define WO_GE     (WO_EQ<<(TK_GE-TK_EQ))
+-#define WO_MATCH  0x040
+-#define WO_ISNULL 0x080
+-#define WO_OR     0x100       /* Two or more OR-connected terms */
+-#define WO_AND    0x200       /* Two or more AND-connected terms */
+-#define WO_EQUIV  0x400       /* Of the form A==B, both columns */
+-#define WO_NOOP   0x800       /* This term does not restrict search space */
++#define WO_MATCH  0x0040
++#define WO_IS     0x0080
++#define WO_ISNULL 0x0100
++#define WO_OR     0x0200       /* Two or more OR-connected terms */
++#define WO_AND    0x0400       /* Two or more AND-connected terms */
++#define WO_EQUIV  0x0800       /* Of the form A==B, both columns */
++#define WO_NOOP   0x1000       /* This term does not restrict search space */
+ 
+-#define WO_ALL    0xfff       /* Mask of all possible WO_* values */
+-#define WO_SINGLE 0x0ff       /* Mask of all non-compound WO_* values */
++#define WO_ALL    0x1fff       /* Mask of all possible WO_* values */
++#define WO_SINGLE 0x01ff       /* Mask of all non-compound WO_* values */
+ 
+ /*
+ ** These are definitions of bits in the WhereLoop.wsFlags field.
+@@ -116257,170 +131143,2179 @@
+ #define WHERE_PARTIALIDX   0x00020000  /* The automatic index is partial */
+ 
+ /************** End of whereInt.h ********************************************/
+-/************** Continuing where we left off in where.c **********************/
++/************** Continuing where we left off in wherecode.c ******************/
++
++#ifndef SQLITE_OMIT_EXPLAIN
+ 
+ /*
+-** Return the estimated number of output rows from a WHERE clause
++** Return the name of the i-th column of the pIdx index.
+ */
+-SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
+-  return sqlite3LogEstToInt(pWInfo->nRowOut);
++static const char *explainIndexColumnName(Index *pIdx, int i){
++  i = pIdx->aiColumn[i];
++  if( i==XN_EXPR ) return "<expr>";
++  if( i==XN_ROWID ) return "rowid";
++  return pIdx->pTable->aCol[i].zName;
+ }
+ 
+ /*
+-** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this
+-** WHERE clause returns outputs for DISTINCT processing.
++** This routine is a helper for explainIndexRange() below
++**
++** pStr holds the text of an expression that we are building up one term
++** at a time.  This routine adds a new term to the end of the expression.
++** Terms are separated by AND so add the "AND" text for second and subsequent
++** terms only.
+ */
+-SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo *pWInfo){
+-  return pWInfo->eDistinct;
++static void explainAppendTerm(
++  StrAccum *pStr,             /* The text expression being built */
++  Index *pIdx,                /* Index to read column names from */
++  int nTerm,                  /* Number of terms */
++  int iTerm,                  /* Zero-based index of first term. */
++  int bAnd,                   /* Non-zero to append " AND " */
++  const char *zOp             /* Name of the operator */
++){
++  int i;
++
++  assert( nTerm>=1 );
++  if( bAnd ) sqlite3StrAccumAppend(pStr, " AND ", 5);
++
++  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
++  for(i=0; i<nTerm; i++){
++    if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
++    sqlite3StrAccumAppendAll(pStr, explainIndexColumnName(pIdx, iTerm+i));
++  }
++  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
++
++  sqlite3StrAccumAppend(pStr, zOp, 1);
++
++  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
++  for(i=0; i<nTerm; i++){
++    if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
++    sqlite3StrAccumAppend(pStr, "?", 1);
++  }
++  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
+ }
+ 
+ /*
+-** Return TRUE if the WHERE clause returns rows in ORDER BY order.
+-** Return FALSE if the output needs to be sorted.
++** Argument pLevel describes a strategy for scanning table pTab. This 
++** function appends text to pStr that describes the subset of table
++** rows scanned by the strategy in the form of an SQL expression.
++**
++** For example, if the query:
++**
++**   SELECT * FROM t1 WHERE a=1 AND b>2;
++**
++** is run and there is an index on (a, b), then this function returns a
++** string similar to:
++**
++**   "a=? AND b>?"
+ */
+-SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){
+-  return pWInfo->nOBSat;
++static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
++  Index *pIndex = pLoop->u.btree.pIndex;
++  u16 nEq = pLoop->u.btree.nEq;
++  u16 nSkip = pLoop->nSkip;
++  int i, j;
++
++  if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
++  sqlite3StrAccumAppend(pStr, " (", 2);
++  for(i=0; i<nEq; i++){
++    const char *z = explainIndexColumnName(pIndex, i);
++    if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
++    sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
++  }
++
++  j = i;
++  if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
++    explainAppendTerm(pStr, pIndex, pLoop->u.btree.nBtm, j, i, ">");
++    i = 1;
++  }
++  if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
++    explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<");
++  }
++  sqlite3StrAccumAppend(pStr, ")", 1);
+ }
+ 
+ /*
+-** Return the VDBE address or label to jump to in order to continue
+-** immediately with the next row of a WHERE clause.
++** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
++** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was
++** defined at compile-time. If it is not a no-op, a single OP_Explain opcode 
++** is added to the output to describe the table scan strategy in pLevel.
++**
++** If an OP_Explain opcode is added to the VM, its address is returned.
++** Otherwise, if no OP_Explain is coded, zero is returned.
+ */
+-SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo *pWInfo){
+-  assert( pWInfo->iContinue!=0 );
+-  return pWInfo->iContinue;
++SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
++  Parse *pParse,                  /* Parse context */
++  SrcList *pTabList,              /* Table list this loop refers to */
++  WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
++  int iLevel,                     /* Value for "level" column of output */
++  int iFrom,                      /* Value for "from" column of output */
++  u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
++){
++  int ret = 0;
++#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
++  if( pParse->explain==2 )
 +#endif
-+#if SQLITE_OMIT_SHARED_CACHE
-+  "OMIT_SHARED_CACHE",
++  {
++    struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
++    Vdbe *v = pParse->pVdbe;      /* VM being constructed */
++    sqlite3 *db = pParse->db;     /* Database handle */
++    int iId = pParse->iSelectId;  /* Select id (left-most output column) */
++    int isSearch;                 /* True for a SEARCH. False for SCAN. */
++    WhereLoop *pLoop;             /* The controlling WhereLoop object */
++    u32 flags;                    /* Flags that describe this loop */
++    char *zMsg;                   /* Text to add to EQP output */
++    StrAccum str;                 /* EQP output string */
++    char zBuf[100];               /* Initial space for EQP output string */
++
++    pLoop = pLevel->pWLoop;
++    flags = pLoop->wsFlags;
++    if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_OR_SUBCLAUSE) ) return 0;
++
++    isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
++            || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
++            || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
++
++    sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
++    sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
++    if( pItem->pSelect ){
++      sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId);
++    }else{
++      sqlite3XPrintf(&str, " TABLE %s", pItem->zName);
++    }
++
++    if( pItem->zAlias ){
++      sqlite3XPrintf(&str, " AS %s", pItem->zAlias);
++    }
++    if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
++      const char *zFmt = 0;
++      Index *pIdx;
++
++      assert( pLoop->u.btree.pIndex!=0 );
++      pIdx = pLoop->u.btree.pIndex;
++      assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
++      if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
++        if( isSearch ){
++          zFmt = "PRIMARY KEY";
++        }
++      }else if( flags & WHERE_PARTIALIDX ){
++        zFmt = "AUTOMATIC PARTIAL COVERING INDEX";
++      }else if( flags & WHERE_AUTO_INDEX ){
++        zFmt = "AUTOMATIC COVERING INDEX";
++      }else if( flags & WHERE_IDX_ONLY ){
++        zFmt = "COVERING INDEX %s";
++      }else{
++        zFmt = "INDEX %s";
++      }
++      if( zFmt ){
++        sqlite3StrAccumAppend(&str, " USING ", 7);
++        sqlite3XPrintf(&str, zFmt, pIdx->zName);
++        explainIndexRange(&str, pLoop);
++      }
++    }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
++      const char *zRangeOp;
++      if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
++        zRangeOp = "=";
++      }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
++        zRangeOp = ">? AND rowid<";
++      }else if( flags&WHERE_BTM_LIMIT ){
++        zRangeOp = ">";
++      }else{
++        assert( flags&WHERE_TOP_LIMIT);
++        zRangeOp = "<";
++      }
++      sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
++    }
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++    else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
++      sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s",
++                  pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
++    }
 +#endif
-+#if SQLITE_OMIT_SUBQUERY
-+  "OMIT_SUBQUERY",
++#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
++    if( pLoop->nOut>=10 ){
++      sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
++    }else{
++      sqlite3StrAccumAppend(&str, " (~1 row)", 9);
++    }
 +#endif
-+#if SQLITE_OMIT_TCL_VARIABLE
-+  "OMIT_TCL_VARIABLE",
++    zMsg = sqlite3StrAccumFinish(&str);
++    ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC);
++  }
++  return ret;
+ }
++#endif /* SQLITE_OMIT_EXPLAIN */
+ 
++#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ /*
+-** Return the VDBE address or label to jump to in order to break
+-** out of a WHERE loop.
++** Configure the VM passed as the first argument with an
++** sqlite3_stmt_scanstatus() entry corresponding to the scan used to 
++** implement level pLvl. Argument pSrclist is a pointer to the FROM 
++** clause that the scan reads data from.
++**
++** If argument addrExplain is not 0, it must be the address of an 
++** OP_Explain instruction that describes the same loop.
+ */
+-SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){
+-  return pWInfo->iBreak;
++SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
++  Vdbe *v,                        /* Vdbe to add scanstatus entry to */
++  SrcList *pSrclist,              /* FROM clause pLvl reads data from */
++  WhereLevel *pLvl,               /* Level to add scanstatus() entry for */
++  int addrExplain                 /* Address of OP_Explain (or 0) */
++){
++  const char *zObj = 0;
++  WhereLoop *pLoop = pLvl->pWLoop;
++  if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0  &&  pLoop->u.btree.pIndex!=0 ){
++    zObj = pLoop->u.btree.pIndex->zName;
++  }else{
++    zObj = pSrclist->a[pLvl->iFrom].zName;
++  }
++  sqlite3VdbeScanStatus(
++      v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj
++  );
+ }
 +#endif
-+#if SQLITE_OMIT_TEMPDB
-+  "OMIT_TEMPDB",
++
+ 
+ /*
+-** Return TRUE if an UPDATE or DELETE statement can operate directly on
+-** the rowids returned by a WHERE clause.  Return FALSE if doing an
+-** UPDATE or DELETE might change subsequent WHERE clause results.
++** Disable a term in the WHERE clause.  Except, do not disable the term
++** if it controls a LEFT OUTER JOIN and it did not originate in the ON
++** or USING clause of that join.
+ **
+-** If the ONEPASS optimization is used (if this routine returns true)
+-** then also write the indices of open cursors used by ONEPASS
+-** into aiCur[0] and aiCur[1].  iaCur[0] gets the cursor of the data
+-** table and iaCur[1] gets the cursor used by an auxiliary index.
+-** Either value may be -1, indicating that cursor is not used.
+-** Any cursors returned will have been opened for writing.
++** Consider the term t2.z='ok' in the following queries:
+ **
+-** aiCur[0] and aiCur[1] both get -1 if the where-clause logic is
+-** unable to use the ONEPASS optimization.
++**   (1)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
++**   (2)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
++**   (3)  SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
++**
++** The t2.z='ok' is disabled in the in (2) because it originates
++** in the ON clause.  The term is disabled in (3) because it is not part
++** of a LEFT OUTER JOIN.  In (1), the term is not disabled.
++**
++** Disabling a term causes that term to not be tested in the inner loop
++** of the join.  Disabling is an optimization.  When terms are satisfied
++** by indices, we disable them to prevent redundant tests in the inner
++** loop.  We would get the correct results if nothing were ever disabled,
++** but joins might run a little slower.  The trick is to disable as much
++** as we can without disabling too much.  If we disabled in (1), we'd get
++** the wrong answer.  See ticket #813.
++**
++** If all the children of a term are disabled, then that term is also
++** automatically disabled.  In this way, terms get disabled if derived
++** virtual terms are tested first.  For example:
++**
++**      x GLOB 'abc*' AND x>='abc' AND x<'acd'
++**      \___________/     \______/     \_____/
++**         parent          child1       child2
++**
++** Only the parent term was in the original WHERE clause.  The child1
++** and child2 terms were added by the LIKE optimization.  If both of
++** the virtual child terms are valid, then testing of the parent can be 
++** skipped.
++**
++** Usually the parent term is marked as TERM_CODED.  But if the parent
++** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead.
++** The TERM_LIKECOND marking indicates that the term should be coded inside
++** a conditional such that is only evaluated on the second pass of a
++** LIKE-optimization loop, when scanning BLOBs instead of strings.
+ */
+-SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){
+-  memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2);
+-  return pWInfo->okOnePass;
++static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
++  int nLoop = 0;
++  while( ALWAYS(pTerm!=0)
++      && (pTerm->wtFlags & TERM_CODED)==0
++      && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
++      && (pLevel->notReady & pTerm->prereqAll)==0
++  ){
++    if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){
++      pTerm->wtFlags |= TERM_LIKECOND;
++    }else{
++      pTerm->wtFlags |= TERM_CODED;
++    }
++    if( pTerm->iParent<0 ) break;
++    pTerm = &pTerm->pWC->a[pTerm->iParent];
++    pTerm->nChild--;
++    if( pTerm->nChild!=0 ) break;
++    nLoop++;
++  }
+ }
+ 
+ /*
+-** Move the content of pSrc into pDest
++** Code an OP_Affinity opcode to apply the column affinity string zAff
++** to the n registers starting at base. 
++**
++** As an optimization, SQLITE_AFF_BLOB entries (which are no-ops) at the
++** beginning and end of zAff are ignored.  If all entries in zAff are
++** SQLITE_AFF_BLOB, then no code gets generated.
++**
++** This routine makes its own copy of zAff so that the caller is free
++** to modify zAff after this routine returns.
+ */
+-static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){
+-  pDest->n = pSrc->n;
+-  memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0]));
++static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
++  Vdbe *v = pParse->pVdbe;
++  if( zAff==0 ){
++    assert( pParse->db->mallocFailed );
++    return;
++  }
++  assert( v!=0 );
++
++  /* Adjust base and n to skip over SQLITE_AFF_BLOB entries at the beginning
++  ** and end of the affinity string.
++  */
++  while( n>0 && zAff[0]==SQLITE_AFF_BLOB ){
++    n--;
++    base++;
++    zAff++;
++  }
++  while( n>1 && zAff[n-1]==SQLITE_AFF_BLOB ){
++    n--;
++  }
++
++  /* Code the OP_Affinity opcode if there is anything left to do. */
++  if( n>0 ){
++    sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n);
++    sqlite3ExprCacheAffinityChange(pParse, base, n);
++  }
+ }
+ 
+ /*
+-** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet.
++** Expression pRight, which is the RHS of a comparison operation, is 
++** either a vector of n elements or, if n==1, a scalar expression.
++** Before the comparison operation, affinity zAff is to be applied
++** to the pRight values. This function modifies characters within the
++** affinity string to SQLITE_AFF_BLOB if either:
++**
++**   * the comparison will be performed with no affinity, or
++**   * the affinity change in zAff is guaranteed not to change the value.
++*/
++static void updateRangeAffinityStr(
++  Expr *pRight,                   /* RHS of comparison */
++  int n,                          /* Number of vector elements in comparison */
++  char *zAff                      /* Affinity string to modify */
++){
++  int i;
++  for(i=0; i<n; i++){
++    Expr *p = sqlite3VectorFieldSubexpr(pRight, i);
++    if( sqlite3CompareAffinity(p, zAff[i])==SQLITE_AFF_BLOB
++     || sqlite3ExprNeedsNoAffinityChange(p, zAff[i])
++    ){
++      zAff[i] = SQLITE_AFF_BLOB;
++    }
++  }
++}
++
++/*
++** Generate code for a single equality term of the WHERE clause.  An equality
++** term can be either X=expr or X IN (...).   pTerm is the term to be 
++** coded.
+ **
+-** The new entry might overwrite an existing entry, or it might be
+-** appended, or it might be discarded.  Do whatever is the right thing
+-** so that pSet keeps the N_OR_COST best entries seen so far.
++** The current value for the constraint is left in a register, the index
++** of which is returned.  An attempt is made store the result in iTarget but
++** this is only guaranteed for TK_ISNULL and TK_IN constraints.  If the
++** constraint is a TK_EQ or TK_IS, then the current value might be left in
++** some other register and it is the caller's responsibility to compensate.
++**
++** For a constraint of the form X=expr, the expression is evaluated in
++** straight-line code.  For constraints of the form X IN (...)
++** this routine sets up a loop that will iterate over all values of X.
+ */
+-static int whereOrInsert(
+-  WhereOrSet *pSet,      /* The WhereOrSet to be updated */
+-  Bitmask prereq,        /* Prerequisites of the new entry */
+-  LogEst rRun,           /* Run-cost of the new entry */
+-  LogEst nOut            /* Number of outputs for the new entry */
++static int codeEqualityTerm(
++  Parse *pParse,      /* The parsing context */
++  WhereTerm *pTerm,   /* The term of the WHERE clause to be coded */
++  WhereLevel *pLevel, /* The level of the FROM clause we are working on */
++  int iEq,            /* Index of the equality term within this level */
++  int bRev,           /* True for reverse-order IN operations */
++  int iTarget         /* Attempt to leave results in this register */
+ ){
+-  u16 i;
+-  WhereOrCost *p;
+-  for(i=pSet->n, p=pSet->a; i>0; i--, p++){
+-    if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){
+-      goto whereOrInsert_done;
++  Expr *pX = pTerm->pExpr;
++  Vdbe *v = pParse->pVdbe;
++  int iReg;                  /* Register holding results */
++
++  assert( pLevel->pWLoop->aLTerm[iEq]==pTerm );
++  assert( iTarget>0 );
++  if( pX->op==TK_EQ || pX->op==TK_IS ){
++    iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
++  }else if( pX->op==TK_ISNULL ){
++    iReg = iTarget;
++    sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
++#ifndef SQLITE_OMIT_SUBQUERY
++  }else{
++    int eType = IN_INDEX_NOOP;
++    int iTab;
++    struct InLoop *pIn;
++    WhereLoop *pLoop = pLevel->pWLoop;
++    int i;
++    int nEq = 0;
++    int *aiMap = 0;
++
++    if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
++      && pLoop->u.btree.pIndex!=0
++      && pLoop->u.btree.pIndex->aSortOrder[iEq]
++    ){
++      testcase( iEq==0 );
++      testcase( bRev );
++      bRev = !bRev;
+     }
+-    if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){
+-      return 0;
++    assert( pX->op==TK_IN );
++    iReg = iTarget;
++
++    for(i=0; i<iEq; i++){
++      if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){
++        disableTerm(pLevel, pTerm);
++        return iTarget;
++      }
++    }
++    for(i=iEq;i<pLoop->nLTerm; i++){
++      if( ALWAYS(pLoop->aLTerm[i]) && pLoop->aLTerm[i]->pExpr==pX ) nEq++;
++    }
++
++    if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){
++      eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0);
++    }else{
++      Select *pSelect = pX->x.pSelect;
++      sqlite3 *db = pParse->db;
++      u16 savedDbOptFlags = db->dbOptFlags;
++      ExprList *pOrigRhs = pSelect->pEList;
++      ExprList *pOrigLhs = pX->pLeft->x.pList;
++      ExprList *pRhs = 0;         /* New Select.pEList for RHS */
++      ExprList *pLhs = 0;         /* New pX->pLeft vector */
++
++      for(i=iEq;i<pLoop->nLTerm; i++){
++        if( pLoop->aLTerm[i]->pExpr==pX ){
++          int iField = pLoop->aLTerm[i]->iField - 1;
++          Expr *pNewRhs = sqlite3ExprDup(db, pOrigRhs->a[iField].pExpr, 0);
++          Expr *pNewLhs = sqlite3ExprDup(db, pOrigLhs->a[iField].pExpr, 0);
++
++          pRhs = sqlite3ExprListAppend(pParse, pRhs, pNewRhs);
++          pLhs = sqlite3ExprListAppend(pParse, pLhs, pNewLhs);
++        }
++      }
++      if( !db->mallocFailed ){
++        Expr *pLeft = pX->pLeft;
++
++        if( pSelect->pOrderBy ){
++          /* If the SELECT statement has an ORDER BY clause, zero the 
++          ** iOrderByCol variables. These are set to non-zero when an 
++          ** ORDER BY term exactly matches one of the terms of the 
++          ** result-set. Since the result-set of the SELECT statement may
++          ** have been modified or reordered, these variables are no longer 
++          ** set correctly.  Since setting them is just an optimization, 
++          ** it's easiest just to zero them here.  */
++          ExprList *pOrderBy = pSelect->pOrderBy;
++          for(i=0; i<pOrderBy->nExpr; i++){
++            pOrderBy->a[i].u.x.iOrderByCol = 0;
++          }
++        }
++
++        /* Take care here not to generate a TK_VECTOR containing only a
++        ** single value. Since the parser never creates such a vector, some
++        ** of the subroutines do not handle this case.  */
++        if( pLhs->nExpr==1 ){
++          pX->pLeft = pLhs->a[0].pExpr;
++        }else{
++          pLeft->x.pList = pLhs;
++          aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * nEq);
++          testcase( aiMap==0 );
++        }
++        pSelect->pEList = pRhs;
++        db->dbOptFlags |= SQLITE_QueryFlattener;
++        eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap);
++        db->dbOptFlags = savedDbOptFlags;
++        testcase( aiMap!=0 && aiMap[0]!=0 );
++        pSelect->pEList = pOrigRhs;
++        pLeft->x.pList = pOrigLhs;
++        pX->pLeft = pLeft;
++      }
++      sqlite3ExprListDelete(pParse->db, pLhs);
++      sqlite3ExprListDelete(pParse->db, pRhs);
++    }
++
++    if( eType==IN_INDEX_INDEX_DESC ){
++      testcase( bRev );
++      bRev = !bRev;
++    }
++    iTab = pX->iTable;
++    sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
++    VdbeCoverageIf(v, bRev);
++    VdbeCoverageIf(v, !bRev);
++    assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
++
++    pLoop->wsFlags |= WHERE_IN_ABLE;
++    if( pLevel->u.in.nIn==0 ){
++      pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
++    }
++
++    i = pLevel->u.in.nIn;
++    pLevel->u.in.nIn += nEq;
++    pLevel->u.in.aInLoop =
++       sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
++                              sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
++    pIn = pLevel->u.in.aInLoop;
++    if( pIn ){
++      int iMap = 0;               /* Index in aiMap[] */
++      pIn += i;
++      for(i=iEq;i<pLoop->nLTerm; i++){
++        if( pLoop->aLTerm[i]->pExpr==pX ){
++          int iOut = iReg + i - iEq;
++          if( eType==IN_INDEX_ROWID ){
++            testcase( nEq>1 );  /* Happens with a UNIQUE index on ROWID */
++            pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut);
++          }else{
++            int iCol = aiMap ? aiMap[iMap++] : 0;
++            pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut);
++          }
++          sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
++          if( i==iEq ){
++            pIn->iCur = iTab;
++            pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
++          }else{
++            pIn->eEndLoopOp = OP_Noop;
++          }
++          pIn++;
++        }
++      }
++    }else{
++      pLevel->u.in.nIn = 0;
+     }
++    sqlite3DbFree(pParse->db, aiMap);
 +#endif
-+#if SQLITE_OMIT_TRACE
-+  "OMIT_TRACE",
+   }
+-  if( pSet->n<N_OR_COST ){
+-    p = &pSet->a[pSet->n++];
+-    p->nOut = nOut;
+-  }else{
+-    p = pSet->a;
+-    for(i=1; i<pSet->n; i++){
+-      if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i;
++  disableTerm(pLevel, pTerm);
++  return iReg;
++}
++
++/*
++** Generate code that will evaluate all == and IN constraints for an
++** index scan.
++**
++** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c).
++** Suppose the WHERE clause is this:  a==5 AND b IN (1,2,3) AND c>5 AND c<10
++** The index has as many as three equality constraints, but in this
++** example, the third "c" value is an inequality.  So only two 
++** constraints are coded.  This routine will generate code to evaluate
++** a==5 and b IN (1,2,3).  The current values for a and b will be stored
++** in consecutive registers and the index of the first register is returned.
++**
++** In the example above nEq==2.  But this subroutine works for any value
++** of nEq including 0.  If nEq==0, this routine is nearly a no-op.
++** The only thing it does is allocate the pLevel->iMem memory cell and
++** compute the affinity string.
++**
++** The nExtraReg parameter is 0 or 1.  It is 0 if all WHERE clause constraints
++** are == or IN and are covered by the nEq.  nExtraReg is 1 if there is
++** an inequality constraint (such as the "c>=5 AND c<10" in the example) that
++** occurs after the nEq quality constraints.
++**
++** This routine allocates a range of nEq+nExtraReg memory cells and returns
++** the index of the first memory cell in that range. The code that
++** calls this routine will use that memory range to store keys for
++** start and termination conditions of the loop.
++** key value of the loop.  If one or more IN operators appear, then
++** this routine allocates an additional nEq memory cells for internal
++** use.
++**
++** Before returning, *pzAff is set to point to a buffer containing a
++** copy of the column affinity string of the index allocated using
++** sqlite3DbMalloc(). Except, entries in the copy of the string associated
++** with equality constraints that use BLOB or NONE affinity are set to
++** SQLITE_AFF_BLOB. This is to deal with SQL such as the following:
++**
++**   CREATE TABLE t1(a TEXT PRIMARY KEY, b);
++**   SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b;
++**
++** In the example above, the index on t1(a) has TEXT affinity. But since
++** the right hand side of the equality constraint (t2.b) has BLOB/NONE affinity,
++** no conversion should be attempted before using a t2.b value as part of
++** a key to search the index. Hence the first byte in the returned affinity
++** string in this example would be set to SQLITE_AFF_BLOB.
++*/
++static int codeAllEqualityTerms(
++  Parse *pParse,        /* Parsing context */
++  WhereLevel *pLevel,   /* Which nested loop of the FROM we are coding */
++  int bRev,             /* Reverse the order of IN operators */
++  int nExtraReg,        /* Number of extra registers to allocate */
++  char **pzAff          /* OUT: Set to point to affinity string */
++){
++  u16 nEq;                      /* The number of == or IN constraints to code */
++  u16 nSkip;                    /* Number of left-most columns to skip */
++  Vdbe *v = pParse->pVdbe;      /* The vm under construction */
++  Index *pIdx;                  /* The index being used for this loop */
++  WhereTerm *pTerm;             /* A single constraint term */
++  WhereLoop *pLoop;             /* The WhereLoop object */
++  int j;                        /* Loop counter */
++  int regBase;                  /* Base register */
++  int nReg;                     /* Number of registers to allocate */
++  char *zAff;                   /* Affinity string to return */
++
++  /* This module is only called on query plans that use an index. */
++  pLoop = pLevel->pWLoop;
++  assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
++  nEq = pLoop->u.btree.nEq;
++  nSkip = pLoop->nSkip;
++  pIdx = pLoop->u.btree.pIndex;
++  assert( pIdx!=0 );
++
++  /* Figure out how many memory cells we will need then allocate them.
++  */
++  regBase = pParse->nMem + 1;
++  nReg = pLoop->u.btree.nEq + nExtraReg;
++  pParse->nMem += nReg;
++
++  zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx));
++  assert( zAff!=0 || pParse->db->mallocFailed );
++
++  if( nSkip ){
++    int iIdxCur = pLevel->iIdxCur;
++    sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
++    VdbeCoverageIf(v, bRev==0);
++    VdbeCoverageIf(v, bRev!=0);
++    VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
++    j = sqlite3VdbeAddOp0(v, OP_Goto);
++    pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
++                            iIdxCur, 0, regBase, nSkip);
++    VdbeCoverageIf(v, bRev==0);
++    VdbeCoverageIf(v, bRev!=0);
++    sqlite3VdbeJumpHere(v, j);
++    for(j=0; j<nSkip; j++){
++      sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
++      testcase( pIdx->aiColumn[j]==XN_EXPR );
++      VdbeComment((v, "%s", explainIndexColumnName(pIdx, j)));
++    }
++  }    
++
++  /* Evaluate the equality constraints
++  */
++  assert( zAff==0 || (int)strlen(zAff)>=nEq );
++  for(j=nSkip; j<nEq; j++){
++    int r1;
++    pTerm = pLoop->aLTerm[j];
++    assert( pTerm!=0 );
++    /* The following testcase is true for indices with redundant columns. 
++    ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
++    testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
++    testcase( pTerm->wtFlags & TERM_VIRTUAL );
++    r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
++    if( r1!=regBase+j ){
++      if( nReg==1 ){
++        sqlite3ReleaseTempReg(pParse, regBase);
++        regBase = r1;
++      }else{
++        sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
++      }
++    }
++    if( pTerm->eOperator & WO_IN ){
++      if( pTerm->pExpr->flags & EP_xIsSelect ){
++        /* No affinity ever needs to be (or should be) applied to a value
++        ** from the RHS of an "? IN (SELECT ...)" expression. The 
++        ** sqlite3FindInIndex() routine has already ensured that the 
++        ** affinity of the comparison has been applied to the value.  */
++        if( zAff ) zAff[j] = SQLITE_AFF_BLOB;
++      }
++    }else if( (pTerm->eOperator & WO_ISNULL)==0 ){
++      Expr *pRight = pTerm->pExpr->pRight;
++      if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){
++        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
++        VdbeCoverage(v);
++      }
++      if( zAff ){
++        if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){
++          zAff[j] = SQLITE_AFF_BLOB;
++        }
++        if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){
++          zAff[j] = SQLITE_AFF_BLOB;
++        }
++      }
+     }
+-    if( p->rRun<=rRun ) return 0;
+   }
+-whereOrInsert_done:
+-  p->prereq = prereq;
+-  p->rRun = rRun;
+-  if( p->nOut>nOut ) p->nOut = nOut;
+-  return 1;
++  *pzAff = zAff;
++  return regBase;
+ }
+ 
++#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ /*
+-** Initialize a preallocated WhereClause structure.
++** If the most recently coded instruction is a constant range constraint
++** (a string literal) that originated from the LIKE optimization, then 
++** set P3 and P5 on the OP_String opcode so that the string will be cast
++** to a BLOB at appropriate times.
++**
++** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range
++** expression: "x>='ABC' AND x<'abd'".  But this requires that the range
++** scan loop run twice, once for strings and a second time for BLOBs.
++** The OP_String opcodes on the second pass convert the upper and lower
++** bound string constants to blobs.  This routine makes the necessary changes
++** to the OP_String opcodes for that to happen.
++**
++** Except, of course, if SQLITE_LIKE_DOESNT_MATCH_BLOBS is defined, then
++** only the one pass through the string space is required, so this routine
++** becomes a no-op.
+ */
+-static void whereClauseInit(
+-  WhereClause *pWC,        /* The WhereClause to be initialized */
+-  WhereInfo *pWInfo        /* The WHERE processing context */
++static void whereLikeOptimizationStringFixup(
++  Vdbe *v,                /* prepared statement under construction */
++  WhereLevel *pLevel,     /* The loop that contains the LIKE operator */
++  WhereTerm *pTerm        /* The upper or lower bound just coded */
+ ){
+-  pWC->pWInfo = pWInfo;
+-  pWC->pOuter = 0;
+-  pWC->nTerm = 0;
+-  pWC->nSlot = ArraySize(pWC->aStatic);
+-  pWC->a = pWC->aStatic;
++  if( pTerm->wtFlags & TERM_LIKEOPT ){
++    VdbeOp *pOp;
++    assert( pLevel->iLikeRepCntr>0 );
++    pOp = sqlite3VdbeGetOp(v, -1);
++    assert( pOp!=0 );
++    assert( pOp->opcode==OP_String8 
++            || pTerm->pWC->pWInfo->pParse->db->mallocFailed );
++    pOp->p3 = (int)(pLevel->iLikeRepCntr>>1);  /* Register holding counter */
++    pOp->p5 = (u8)(pLevel->iLikeRepCntr&1);    /* ASC or DESC */
++  }
+ }
++#else
++# define whereLikeOptimizationStringFixup(A,B,C)
 +#endif
-+#if SQLITE_OMIT_TRIGGER
-+  "OMIT_TRIGGER",
+ 
+-/* Forward reference */
+-static void whereClauseClear(WhereClause*);
++#ifdef SQLITE_ENABLE_CURSOR_HINTS
++/*
++** Information is passed from codeCursorHint() down to individual nodes of
++** the expression tree (by sqlite3WalkExpr()) using an instance of this
++** structure.
++*/
++struct CCurHint {
++  int iTabCur;    /* Cursor for the main table */
++  int iIdxCur;    /* Cursor for the index, if pIdx!=0.  Unused otherwise */
++  Index *pIdx;    /* The index used to access the table */
++};
+ 
+ /*
+-** Deallocate all memory associated with a WhereOrInfo object.
++** This function is called for every node of an expression that is a candidate
++** for a cursor hint on an index cursor.  For TK_COLUMN nodes that reference
++** the table CCurHint.iTabCur, verify that the same column can be
++** accessed through the index.  If it cannot, then set pWalker->eCode to 1.
++*/
++static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){
++  struct CCurHint *pHint = pWalker->u.pCCurHint;
++  assert( pHint->pIdx!=0 );
++  if( pExpr->op==TK_COLUMN
++   && pExpr->iTable==pHint->iTabCur
++   && sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn)<0
++  ){
++    pWalker->eCode = 1;
++  }
++  return WRC_Continue;
++}
++
++/*
++** Test whether or not expression pExpr, which was part of a WHERE clause,
++** should be included in the cursor-hint for a table that is on the rhs
++** of a LEFT JOIN. Set Walker.eCode to non-zero before returning if the 
++** expression is not suitable.
++**
++** An expression is unsuitable if it might evaluate to non NULL even if
++** a TK_COLUMN node that does affect the value of the expression is set
++** to NULL. For example:
++**
++**   col IS NULL
++**   col IS NOT NULL
++**   coalesce(col, 1)
++**   CASE WHEN col THEN 0 ELSE 1 END
++*/
++static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){
++  if( pExpr->op==TK_IS 
++   || pExpr->op==TK_ISNULL || pExpr->op==TK_ISNOT 
++   || pExpr->op==TK_NOTNULL || pExpr->op==TK_CASE 
++  ){
++    pWalker->eCode = 1;
++  }else if( pExpr->op==TK_FUNCTION ){
++    int d1;
++    char d2[3];
++    if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){
++      pWalker->eCode = 1;
++    }
++  }
++
++  return WRC_Continue;
++}
++
++
++/*
++** This function is called on every node of an expression tree used as an
++** argument to the OP_CursorHint instruction. If the node is a TK_COLUMN
++** that accesses any table other than the one identified by
++** CCurHint.iTabCur, then do the following:
++**
++**   1) allocate a register and code an OP_Column instruction to read 
++**      the specified column into the new register, and
++**
++**   2) transform the expression node to a TK_REGISTER node that reads 
++**      from the newly populated register.
++**
++** Also, if the node is a TK_COLUMN that does access the table idenified
++** by pCCurHint.iTabCur, and an index is being used (which we will
++** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into
++** an access of the index rather than the original table.
++*/
++static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){
++  int rc = WRC_Continue;
++  struct CCurHint *pHint = pWalker->u.pCCurHint;
++  if( pExpr->op==TK_COLUMN ){
++    if( pExpr->iTable!=pHint->iTabCur ){
++      Vdbe *v = pWalker->pParse->pVdbe;
++      int reg = ++pWalker->pParse->nMem;   /* Register for column value */
++      sqlite3ExprCodeGetColumnOfTable(
++          v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg
++      );
++      pExpr->op = TK_REGISTER;
++      pExpr->iTable = reg;
++    }else if( pHint->pIdx!=0 ){
++      pExpr->iTable = pHint->iIdxCur;
++      pExpr->iColumn = sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn);
++      assert( pExpr->iColumn>=0 );
++    }
++  }else if( pExpr->op==TK_AGG_FUNCTION ){
++    /* An aggregate function in the WHERE clause of a query means this must
++    ** be a correlated sub-query, and expression pExpr is an aggregate from
++    ** the parent context. Do not walk the function arguments in this case.
++    **
++    ** todo: It should be possible to replace this node with a TK_REGISTER
++    ** expression, as the result of the expression must be stored in a 
++    ** register at this point. The same holds for TK_AGG_COLUMN nodes. */
++    rc = WRC_Prune;
++  }
++  return rc;
++}
++
++/*
++** Insert an OP_CursorHint instruction if it is appropriate to do so.
+ */
+-static void whereOrInfoDelete(sqlite3 *db, WhereOrInfo *p){
+-  whereClauseClear(&p->wc);
+-  sqlite3DbFree(db, p);
++static void codeCursorHint(
++  struct SrcList_item *pTabItem,  /* FROM clause item */
++  WhereInfo *pWInfo,    /* The where clause */
++  WhereLevel *pLevel,   /* Which loop to provide hints for */
++  WhereTerm *pEndRange  /* Hint this end-of-scan boundary term if not NULL */
++){
++  Parse *pParse = pWInfo->pParse;
++  sqlite3 *db = pParse->db;
++  Vdbe *v = pParse->pVdbe;
++  Expr *pExpr = 0;
++  WhereLoop *pLoop = pLevel->pWLoop;
++  int iCur;
++  WhereClause *pWC;
++  WhereTerm *pTerm;
++  int i, j;
++  struct CCurHint sHint;
++  Walker sWalker;
++
++  if( OptimizationDisabled(db, SQLITE_CursorHints) ) return;
++  iCur = pLevel->iTabCur;
++  assert( iCur==pWInfo->pTabList->a[pLevel->iFrom].iCursor );
++  sHint.iTabCur = iCur;
++  sHint.iIdxCur = pLevel->iIdxCur;
++  sHint.pIdx = pLoop->u.btree.pIndex;
++  memset(&sWalker, 0, sizeof(sWalker));
++  sWalker.pParse = pParse;
++  sWalker.u.pCCurHint = &sHint;
++  pWC = &pWInfo->sWC;
++  for(i=0; i<pWC->nTerm; i++){
++    pTerm = &pWC->a[i];
++    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
++    if( pTerm->prereqAll & pLevel->notReady ) continue;
++
++    /* Any terms specified as part of the ON(...) clause for any LEFT 
++    ** JOIN for which the current table is not the rhs are omitted
++    ** from the cursor-hint. 
++    **
++    ** If this table is the rhs of a LEFT JOIN, "IS" or "IS NULL" terms 
++    ** that were specified as part of the WHERE clause must be excluded.
++    ** This is to address the following:
++    **
++    **   SELECT ... t1 LEFT JOIN t2 ON (t1.a=t2.b) WHERE t2.c IS NULL;
++    **
++    ** Say there is a single row in t2 that matches (t1.a=t2.b), but its
++    ** t2.c values is not NULL. If the (t2.c IS NULL) constraint is 
++    ** pushed down to the cursor, this row is filtered out, causing
++    ** SQLite to synthesize a row of NULL values. Which does match the
++    ** WHERE clause, and so the query returns a row. Which is incorrect.
++    **
++    ** For the same reason, WHERE terms such as:
++    **
++    **   WHERE 1 = (t2.c IS NULL)
++    **
++    ** are also excluded. See codeCursorHintIsOrFunction() for details.
++    */
++    if( pTabItem->fg.jointype & JT_LEFT ){
++      Expr *pExpr = pTerm->pExpr;
++      if( !ExprHasProperty(pExpr, EP_FromJoin) 
++       || pExpr->iRightJoinTable!=pTabItem->iCursor
++      ){
++        sWalker.eCode = 0;
++        sWalker.xExprCallback = codeCursorHintIsOrFunction;
++        sqlite3WalkExpr(&sWalker, pTerm->pExpr);
++        if( sWalker.eCode ) continue;
++      }
++    }else{
++      if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue;
++    }
++
++    /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize
++    ** the cursor.  These terms are not needed as hints for a pure range
++    ** scan (that has no == terms) so omit them. */
++    if( pLoop->u.btree.nEq==0 && pTerm!=pEndRange ){
++      for(j=0; j<pLoop->nLTerm && pLoop->aLTerm[j]!=pTerm; j++){}
++      if( j<pLoop->nLTerm ) continue;
++    }
++
++    /* No subqueries or non-deterministic functions allowed */
++    if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue;
++
++    /* For an index scan, make sure referenced columns are actually in
++    ** the index. */
++    if( sHint.pIdx!=0 ){
++      sWalker.eCode = 0;
++      sWalker.xExprCallback = codeCursorHintCheckExpr;
++      sqlite3WalkExpr(&sWalker, pTerm->pExpr);
++      if( sWalker.eCode ) continue;
++    }
++
++    /* If we survive all prior tests, that means this term is worth hinting */
++    pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
++  }
++  if( pExpr!=0 ){
++    sWalker.xExprCallback = codeCursorHintFixExpr;
++    sqlite3WalkExpr(&sWalker, pExpr);
++    sqlite3VdbeAddOp4(v, OP_CursorHint, 
++                      (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0,
++                      (const char*)pExpr, P4_EXPR);
++  }
+ }
++#else
++# define codeCursorHint(A,B,C,D)  /* No-op */
++#endif /* SQLITE_ENABLE_CURSOR_HINTS */
+ 
+ /*
+-** Deallocate all memory associated with a WhereAndInfo object.
++** Cursor iCur is open on an intkey b-tree (a table). Register iRowid contains
++** a rowid value just read from cursor iIdxCur, open on index pIdx. This
++** function generates code to do a deferred seek of cursor iCur to the 
++** rowid stored in register iRowid.
++**
++** Normally, this is just:
++**
++**   OP_DeferredSeek $iCur $iRowid
++**
++** However, if the scan currently being coded is a branch of an OR-loop and
++** the statement currently being coded is a SELECT, then P3 of OP_DeferredSeek
++** is set to iIdxCur and P4 is set to point to an array of integers
++** containing one entry for each column of the table cursor iCur is open 
++** on. For each table column, if the column is the i'th column of the 
++** index, then the corresponding array entry is set to (i+1). If the column
++** does not appear in the index at all, the array entry is set to 0.
+ */
+-static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){
+-  whereClauseClear(&p->wc);
+-  sqlite3DbFree(db, p);
++static void codeDeferredSeek(
++  WhereInfo *pWInfo,              /* Where clause context */
++  Index *pIdx,                    /* Index scan is using */
++  int iCur,                       /* Cursor for IPK b-tree */
++  int iIdxCur                     /* Index cursor */
++){
++  Parse *pParse = pWInfo->pParse; /* Parse context */
++  Vdbe *v = pParse->pVdbe;        /* Vdbe to generate code within */
++
++  assert( iIdxCur>0 );
++  assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 );
++  
++  sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur);
++  if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
++   && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask)
++  ){
++    int i;
++    Table *pTab = pIdx->pTable;
++    int *ai = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*(pTab->nCol+1));
++    if( ai ){
++      ai[0] = pTab->nCol;
++      for(i=0; i<pIdx->nColumn-1; i++){
++        assert( pIdx->aiColumn[i]<pTab->nCol );
++        if( pIdx->aiColumn[i]>=0 ) ai[pIdx->aiColumn[i]+1] = i+1;
++      }
++      sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY);
++    }
++  }
+ }
+ 
+ /*
+-** Deallocate a WhereClause structure.  The WhereClause structure
+-** itself is not freed.  This routine is the inverse of whereClauseInit().
++** If the expression passed as the second argument is a vector, generate
++** code to write the first nReg elements of the vector into an array
++** of registers starting with iReg.
++**
++** If the expression is not a vector, then nReg must be passed 1. In
++** this case, generate code to evaluate the expression and leave the
++** result in register iReg.
+ */
+-static void whereClauseClear(WhereClause *pWC){
+-  int i;
+-  WhereTerm *a;
+-  sqlite3 *db = pWC->pWInfo->pParse->db;
+-  for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
+-    if( a->wtFlags & TERM_DYNAMIC ){
+-      sqlite3ExprDelete(db, a->pExpr);
++static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
++  assert( nReg>0 );
++  if( sqlite3ExprIsVector(p) ){
++#ifndef SQLITE_OMIT_SUBQUERY
++    if( (p->flags & EP_xIsSelect) ){
++      Vdbe *v = pParse->pVdbe;
++      int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0);
++      sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
++    }else
 +#endif
-+#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION
-+  "OMIT_TRUNCATE_OPTIMIZATION",
++    {
++      int i;
++      ExprList *pList = p->x.pList;
++      assert( nReg<=pList->nExpr );
++      for(i=0; i<nReg; i++){
++        sqlite3ExprCode(pParse, pList->a[i].pExpr, iReg+i);
++      }
+     }
+-    if( a->wtFlags & TERM_ORINFO ){
+-      whereOrInfoDelete(db, a->u.pOrInfo);
+-    }else if( a->wtFlags & TERM_ANDINFO ){
+-      whereAndInfoDelete(db, a->u.pAndInfo);
++  }else{
++    assert( nReg==1 );
++    sqlite3ExprCode(pParse, p, iReg);
++  }
++}
++
++/* An instance of the IdxExprTrans object carries information about a
++** mapping from an expression on table columns into a column in an index
++** down through the Walker.
++*/
++typedef struct IdxExprTrans {
++  Expr *pIdxExpr;    /* The index expression */
++  int iTabCur;       /* The cursor of the corresponding table */
++  int iIdxCur;       /* The cursor for the index */
++  int iIdxCol;       /* The column for the index */
++} IdxExprTrans;
++
++/* The walker node callback used to transform matching expressions into
++** a reference to an index column for an index on an expression.
++**
++** If pExpr matches, then transform it into a reference to the index column
++** that contains the value of pExpr.
++*/
++static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
++  IdxExprTrans *pX = p->u.pIdxTrans;
++  if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
++    pExpr->op = TK_COLUMN;
++    pExpr->iTable = pX->iIdxCur;
++    pExpr->iColumn = pX->iIdxCol;
++    pExpr->pTab = 0;
++    return WRC_Prune;
++  }else{
++    return WRC_Continue;
++  }
++}
++
++/*
++** For an indexes on expression X, locate every instance of expression X in pExpr
++** and change that subexpression into a reference to the appropriate column of
++** the index.
++*/
++static void whereIndexExprTrans(
++  Index *pIdx,      /* The Index */
++  int iTabCur,      /* Cursor of the table that is being indexed */
++  int iIdxCur,      /* Cursor of the index itself */
++  WhereInfo *pWInfo /* Transform expressions in this WHERE clause */
++){
++  int iIdxCol;               /* Column number of the index */
++  ExprList *aColExpr;        /* Expressions that are indexed */
++  Walker w;
++  IdxExprTrans x;
++  aColExpr = pIdx->aColExpr;
++  if( aColExpr==0 ) return;  /* Not an index on expressions */
++  memset(&w, 0, sizeof(w));
++  w.xExprCallback = whereIndexExprTransNode;
++  w.u.pIdxTrans = &x;
++  x.iTabCur = iTabCur;
++  x.iIdxCur = iIdxCur;
++  for(iIdxCol=0; iIdxCol<aColExpr->nExpr; iIdxCol++){
++    if( pIdx->aiColumn[iIdxCol]!=XN_EXPR ) continue;
++    assert( aColExpr->a[iIdxCol].pExpr!=0 );
++    x.iIdxCol = iIdxCol;
++    x.pIdxExpr = aColExpr->a[iIdxCol].pExpr;
++    sqlite3WalkExpr(&w, pWInfo->pWhere);
++    sqlite3WalkExprList(&w, pWInfo->pOrderBy);
++    sqlite3WalkExprList(&w, pWInfo->pResultSet);
++  }
++}
++
++/*
++** Generate code for the start of the iLevel-th loop in the WHERE clause
++** implementation described by pWInfo.
++*/
++SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
++  WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
++  int iLevel,          /* Which level of pWInfo->a[] should be coded */
++  Bitmask notReady     /* Which tables are currently available */
++){
++  int j, k;            /* Loop counters */
++  int iCur;            /* The VDBE cursor for the table */
++  int addrNxt;         /* Where to jump to continue with the next IN case */
++  int omitTable;       /* True if we use the index only */
++  int bRev;            /* True if we need to scan in reverse order */
++  WhereLevel *pLevel;  /* The where level to be coded */
++  WhereLoop *pLoop;    /* The WhereLoop object being coded */
++  WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
++  WhereTerm *pTerm;               /* A WHERE clause term */
++  Parse *pParse;                  /* Parsing context */
++  sqlite3 *db;                    /* Database connection */
++  Vdbe *v;                        /* The prepared stmt under constructions */
++  struct SrcList_item *pTabItem;  /* FROM clause term being coded */
++  int addrBrk;                    /* Jump here to break out of the loop */
++  int addrHalt;                   /* addrBrk for the outermost loop */
++  int addrCont;                   /* Jump here to continue with next cycle */
++  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
++  int iReleaseReg = 0;      /* Temp register to free before returning */
++  Index *pIdx = 0;          /* Index used by loop (if any) */
++  int iLoop;                /* Iteration of constraint generator loop */
++
++  pParse = pWInfo->pParse;
++  v = pParse->pVdbe;
++  pWC = &pWInfo->sWC;
++  db = pParse->db;
++  pLevel = &pWInfo->a[iLevel];
++  pLoop = pLevel->pWLoop;
++  pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
++  iCur = pTabItem->iCursor;
++  pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
++  bRev = (pWInfo->revMask>>iLevel)&1;
++  omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 
++           && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
++  VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));
++
++  /* Create labels for the "break" and "continue" instructions
++  ** for the current loop.  Jump to addrBrk to break out of a loop.
++  ** Jump to cont to go immediately to the next iteration of the
++  ** loop.
++  **
++  ** When there is an IN operator, we also have a "addrNxt" label that
++  ** means to continue with the next IN value combination.  When
++  ** there are no IN operators in the constraints, the "addrNxt" label
++  ** is the same as "addrBrk".
++  */
++  addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
++  addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(v);
++
++  /* If this is the right table of a LEFT OUTER JOIN, allocate and
++  ** initialize a memory cell that records if this table matches any
++  ** row of the left table of the join.
++  */
++  if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
++    pLevel->iLeftJoin = ++pParse->nMem;
++    sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
++    VdbeComment((v, "init LEFT JOIN no-match flag"));
++  }
++
++  /* Compute a safe address to jump to if we discover that the table for
++  ** this loop is empty and can never contribute content. */
++  for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){}
++  addrHalt = pWInfo->a[j].addrBrk;
++
++  /* Special case of a FROM clause subquery implemented as a co-routine */
++  if( pTabItem->fg.viaCoroutine ){
++    int regYield = pTabItem->regReturn;
++    sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
++    pLevel->p2 =  sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
++    VdbeCoverage(v);
++    VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
++    pLevel->op = OP_Goto;
++  }else
++
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  if(  (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
++    /* Case 1:  The table is a virtual-table.  Use the VFilter and VNext
++    **          to access the data.
++    */
++    int iReg;   /* P3 Value for OP_VFilter */
++    int addrNotFound;
++    int nConstraint = pLoop->nLTerm;
++    int iIn;    /* Counter for IN constraints */
++
++    sqlite3ExprCachePush(pParse);
++    iReg = sqlite3GetTempRange(pParse, nConstraint+2);
++    addrNotFound = pLevel->addrBrk;
++    for(j=0; j<nConstraint; j++){
++      int iTarget = iReg+j+2;
++      pTerm = pLoop->aLTerm[j];
++      if( NEVER(pTerm==0) ) continue;
++      if( pTerm->eOperator & WO_IN ){
++        codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
++        addrNotFound = pLevel->addrNxt;
++      }else{
++        Expr *pRight = pTerm->pExpr->pRight;
++        codeExprOrVector(pParse, pRight, iTarget, 1);
++      }
++    }
++    sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
++    sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
++    sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
++                      pLoop->u.vtab.idxStr,
++                      pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC);
++    VdbeCoverage(v);
++    pLoop->u.vtab.needFree = 0;
++    pLevel->p1 = iCur;
++    pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
++    pLevel->p2 = sqlite3VdbeCurrentAddr(v);
++    iIn = pLevel->u.in.nIn;
++    for(j=nConstraint-1; j>=0; j--){
++      pTerm = pLoop->aLTerm[j];
++      if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
++        disableTerm(pLevel, pTerm);
++      }else if( (pTerm->eOperator & WO_IN)!=0 ){
++        Expr *pCompare;  /* The comparison operator */
++        Expr *pRight;    /* RHS of the comparison */
++        VdbeOp *pOp;     /* Opcode to access the value of the IN constraint */
++
++        /* Reload the constraint value into reg[iReg+j+2].  The same value
++        ** was loaded into the same register prior to the OP_VFilter, but
++        ** the xFilter implementation might have changed the datatype or
++        ** encoding of the value in the register, so it *must* be reloaded. */
++        assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed );
++        if( !db->mallocFailed ){
++          assert( iIn>0 );
++          pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[--iIn].addrInTop);
++          assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid );
++          assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 );
++          assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 );
++          testcase( pOp->opcode==OP_Rowid );
++          sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
++        }
++
++        /* Generate code that will continue to the next row if 
++        ** the IN constraint is not satisfied */
++        pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0);
++        assert( pCompare!=0 || db->mallocFailed );
++        if( pCompare ){
++          pCompare->pLeft = pTerm->pExpr->pLeft;
++          pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
++          if( pRight ){
++            pRight->iTable = iReg+j+2;
++            sqlite3ExprIfFalse(pParse, pCompare, pLevel->addrCont, 0);
++          }
++          pCompare->pLeft = 0;
++          sqlite3ExprDelete(db, pCompare);
++        }
++      }
++    }
++    /* These registers need to be preserved in case there is an IN operator
++    ** loop.  So we could deallocate the registers here (and potentially
++    ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0.  But it seems
++    ** simpler and safer to simply not reuse the registers.
++    **
++    **    sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
++    */
++    sqlite3ExprCachePop(pParse);
++  }else
++#endif /* SQLITE_OMIT_VIRTUALTABLE */
++
++  if( (pLoop->wsFlags & WHERE_IPK)!=0
++   && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0
++  ){
++    /* Case 2:  We can directly reference a single row using an
++    **          equality comparison against the ROWID field.  Or
++    **          we reference multiple rows using a "rowid IN (...)"
++    **          construct.
++    */
++    assert( pLoop->u.btree.nEq==1 );
++    pTerm = pLoop->aLTerm[0];
++    assert( pTerm!=0 );
++    assert( pTerm->pExpr!=0 );
++    assert( omitTable==0 );
++    testcase( pTerm->wtFlags & TERM_VIRTUAL );
++    iReleaseReg = ++pParse->nMem;
++    iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
++    if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
++    addrNxt = pLevel->addrNxt;
++    sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
++    VdbeCoverage(v);
++    sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
++    sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
++    VdbeComment((v, "pk"));
++    pLevel->op = OP_Noop;
++  }else if( (pLoop->wsFlags & WHERE_IPK)!=0
++         && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
++  ){
++    /* Case 3:  We have an inequality comparison against the ROWID field.
++    */
++    int testOp = OP_Noop;
++    int start;
++    int memEndValue = 0;
++    WhereTerm *pStart, *pEnd;
++
++    assert( omitTable==0 );
++    j = 0;
++    pStart = pEnd = 0;
++    if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
++    if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
++    assert( pStart!=0 || pEnd!=0 );
++    if( bRev ){
++      pTerm = pStart;
++      pStart = pEnd;
++      pEnd = pTerm;
++    }
++    codeCursorHint(pTabItem, pWInfo, pLevel, pEnd);
++    if( pStart ){
++      Expr *pX;             /* The expression that defines the start bound */
++      int r1, rTemp;        /* Registers for holding the start boundary */
++      int op;               /* Cursor seek operation */
++
++      /* The following constant maps TK_xx codes into corresponding 
++      ** seek opcodes.  It depends on a particular ordering of TK_xx
++      */
++      const u8 aMoveOp[] = {
++           /* TK_GT */  OP_SeekGT,
++           /* TK_LE */  OP_SeekLE,
++           /* TK_LT */  OP_SeekLT,
++           /* TK_GE */  OP_SeekGE
++      };
++      assert( TK_LE==TK_GT+1 );      /* Make sure the ordering.. */
++      assert( TK_LT==TK_GT+2 );      /*  ... of the TK_xx values... */
++      assert( TK_GE==TK_GT+3 );      /*  ... is correcct. */
++
++      assert( (pStart->wtFlags & TERM_VNULL)==0 );
++      testcase( pStart->wtFlags & TERM_VIRTUAL );
++      pX = pStart->pExpr;
++      assert( pX!=0 );
++      testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
++      if( sqlite3ExprIsVector(pX->pRight) ){
++        r1 = rTemp = sqlite3GetTempReg(pParse);
++        codeExprOrVector(pParse, pX->pRight, r1, 1);
++        op = aMoveOp[(pX->op - TK_GT) | 0x0001];
++      }else{
++        r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
++        disableTerm(pLevel, pStart);
++        op = aMoveOp[(pX->op - TK_GT)];
++      }
++      sqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1);
++      VdbeComment((v, "pk"));
++      VdbeCoverageIf(v, pX->op==TK_GT);
++      VdbeCoverageIf(v, pX->op==TK_LE);
++      VdbeCoverageIf(v, pX->op==TK_LT);
++      VdbeCoverageIf(v, pX->op==TK_GE);
++      sqlite3ExprCacheAffinityChange(pParse, r1, 1);
++      sqlite3ReleaseTempReg(pParse, rTemp);
++    }else{
++      sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt);
++      VdbeCoverageIf(v, bRev==0);
++      VdbeCoverageIf(v, bRev!=0);
++    }
++    if( pEnd ){
++      Expr *pX;
++      pX = pEnd->pExpr;
++      assert( pX!=0 );
++      assert( (pEnd->wtFlags & TERM_VNULL)==0 );
++      testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
++      testcase( pEnd->wtFlags & TERM_VIRTUAL );
++      memEndValue = ++pParse->nMem;
++      codeExprOrVector(pParse, pX->pRight, memEndValue, 1);
++      if( 0==sqlite3ExprIsVector(pX->pRight) 
++       && (pX->op==TK_LT || pX->op==TK_GT) 
++      ){
++        testOp = bRev ? OP_Le : OP_Ge;
++      }else{
++        testOp = bRev ? OP_Lt : OP_Gt;
++      }
++      if( 0==sqlite3ExprIsVector(pX->pRight) ){
++        disableTerm(pLevel, pEnd);
++      }
++    }
++    start = sqlite3VdbeCurrentAddr(v);
++    pLevel->op = bRev ? OP_Prev : OP_Next;
++    pLevel->p1 = iCur;
++    pLevel->p2 = start;
++    assert( pLevel->p5==0 );
++    if( testOp!=OP_Noop ){
++      iRowidReg = ++pParse->nMem;
++      sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
++      sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
++      sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
++      VdbeCoverageIf(v, testOp==OP_Le);
++      VdbeCoverageIf(v, testOp==OP_Lt);
++      VdbeCoverageIf(v, testOp==OP_Ge);
++      VdbeCoverageIf(v, testOp==OP_Gt);
++      sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
++    }
++  }else if( pLoop->wsFlags & WHERE_INDEXED ){
++    /* Case 4: A scan using an index.
++    **
++    **         The WHERE clause may contain zero or more equality 
++    **         terms ("==" or "IN" operators) that refer to the N
++    **         left-most columns of the index. It may also contain
++    **         inequality constraints (>, <, >= or <=) on the indexed
++    **         column that immediately follows the N equalities. Only 
++    **         the right-most column can be an inequality - the rest must
++    **         use the "==" and "IN" operators. For example, if the 
++    **         index is on (x,y,z), then the following clauses are all 
++    **         optimized:
++    **
++    **            x=5
++    **            x=5 AND y=10
++    **            x=5 AND y<10
++    **            x=5 AND y>5 AND y<10
++    **            x=5 AND y=5 AND z<=10
++    **
++    **         The z<10 term of the following cannot be used, only
++    **         the x=5 term:
++    **
++    **            x=5 AND z<10
++    **
++    **         N may be zero if there are inequality constraints.
++    **         If there are no inequality constraints, then N is at
++    **         least one.
++    **
++    **         This case is also used when there are no WHERE clause
++    **         constraints but an index is selected anyway, in order
++    **         to force the output order to conform to an ORDER BY.
++    */  
++    static const u8 aStartOp[] = {
++      0,
++      0,
++      OP_Rewind,           /* 2: (!start_constraints && startEq &&  !bRev) */
++      OP_Last,             /* 3: (!start_constraints && startEq &&   bRev) */
++      OP_SeekGT,           /* 4: (start_constraints  && !startEq && !bRev) */
++      OP_SeekLT,           /* 5: (start_constraints  && !startEq &&  bRev) */
++      OP_SeekGE,           /* 6: (start_constraints  &&  startEq && !bRev) */
++      OP_SeekLE            /* 7: (start_constraints  &&  startEq &&  bRev) */
++    };
++    static const u8 aEndOp[] = {
++      OP_IdxGE,            /* 0: (end_constraints && !bRev && !endEq) */
++      OP_IdxGT,            /* 1: (end_constraints && !bRev &&  endEq) */
++      OP_IdxLE,            /* 2: (end_constraints &&  bRev && !endEq) */
++      OP_IdxLT,            /* 3: (end_constraints &&  bRev &&  endEq) */
++    };
++    u16 nEq = pLoop->u.btree.nEq;     /* Number of == or IN terms */
++    u16 nBtm = pLoop->u.btree.nBtm;   /* Length of BTM vector */
++    u16 nTop = pLoop->u.btree.nTop;   /* Length of TOP vector */
++    int regBase;                 /* Base register holding constraint values */
++    WhereTerm *pRangeStart = 0;  /* Inequality constraint at range start */
++    WhereTerm *pRangeEnd = 0;    /* Inequality constraint at range end */
++    int startEq;                 /* True if range start uses ==, >= or <= */
++    int endEq;                   /* True if range end uses ==, >= or <= */
++    int start_constraints;       /* Start of range is constrained */
++    int nConstraint;             /* Number of constraint terms */
++    int iIdxCur;                 /* The VDBE cursor for the index */
++    int nExtraReg = 0;           /* Number of extra registers needed */
++    int op;                      /* Instruction opcode */
++    char *zStartAff;             /* Affinity for start of range constraint */
++    char *zEndAff = 0;           /* Affinity for end of range constraint */
++    u8 bSeekPastNull = 0;        /* True to seek past initial nulls */
++    u8 bStopAtNull = 0;          /* Add condition to terminate at NULLs */
++
++    pIdx = pLoop->u.btree.pIndex;
++    iIdxCur = pLevel->iIdxCur;
++    assert( nEq>=pLoop->nSkip );
++
++    /* If this loop satisfies a sort order (pOrderBy) request that 
++    ** was passed to this function to implement a "SELECT min(x) ..." 
++    ** query, then the caller will only allow the loop to run for
++    ** a single iteration. This means that the first row returned
++    ** should not have a NULL value stored in 'x'. If column 'x' is
++    ** the first one after the nEq equality constraints in the index,
++    ** this requires some special handling.
++    */
++    assert( pWInfo->pOrderBy==0
++         || pWInfo->pOrderBy->nExpr==1
++         || (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 );
++    if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
++     && pWInfo->nOBSat>0
++     && (pIdx->nKeyCol>nEq)
++    ){
++      assert( pLoop->nSkip==0 );
++      bSeekPastNull = 1;
++      nExtraReg = 1;
++    }
++
++    /* Find any inequality constraint terms for the start and end 
++    ** of the range. 
++    */
++    j = nEq;
++    if( pLoop->wsFlags & WHERE_BTM_LIMIT ){
++      pRangeStart = pLoop->aLTerm[j++];
++      nExtraReg = MAX(nExtraReg, pLoop->u.btree.nBtm);
++      /* Like optimization range constraints always occur in pairs */
++      assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 || 
++              (pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 );
++    }
++    if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
++      pRangeEnd = pLoop->aLTerm[j++];
++      nExtraReg = MAX(nExtraReg, pLoop->u.btree.nTop);
++#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
++      if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){
++        assert( pRangeStart!=0 );                     /* LIKE opt constraints */
++        assert( pRangeStart->wtFlags & TERM_LIKEOPT );   /* occur in pairs */
++        pLevel->iLikeRepCntr = (u32)++pParse->nMem;
++        sqlite3VdbeAddOp2(v, OP_Integer, 1, (int)pLevel->iLikeRepCntr);
++        VdbeComment((v, "LIKE loop counter"));
++        pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v);
++        /* iLikeRepCntr actually stores 2x the counter register number.  The
++        ** bottom bit indicates whether the search order is ASC or DESC. */
++        testcase( bRev );
++        testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC );
++        assert( (bRev & ~1)==0 );
++        pLevel->iLikeRepCntr <<=1;
++        pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC);
++      }
 +#endif
-+#if SQLITE_OMIT_UTF16
-+  "OMIT_UTF16",
++      if( pRangeStart==0 ){
++        j = pIdx->aiColumn[nEq];
++        if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){
++          bSeekPastNull = 1;
++        }
++      }
++    }
++    assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
++
++    /* If we are doing a reverse order scan on an ascending index, or
++    ** a forward order scan on a descending index, interchange the 
++    ** start and end terms (pRangeStart and pRangeEnd).
++    */
++    if( (nEq<pIdx->nKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
++     || (bRev && pIdx->nKeyCol==nEq)
++    ){
++      SWAP(WhereTerm *, pRangeEnd, pRangeStart);
++      SWAP(u8, bSeekPastNull, bStopAtNull);
++      SWAP(u8, nBtm, nTop);
++    }
++
++    /* Generate code to evaluate all constraint terms using == or IN
++    ** and store the values of those terms in an array of registers
++    ** starting at regBase.
++    */
++    codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd);
++    regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
++    assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
++    if( zStartAff && nTop ){
++      zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]);
++    }
++    addrNxt = pLevel->addrNxt;
++
++    testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
++    testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
++    testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
++    testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 );
++    startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
++    endEq =   !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
++    start_constraints = pRangeStart || nEq>0;
++
++    /* Seek the index cursor to the start of the range. */
++    nConstraint = nEq;
++    if( pRangeStart ){
++      Expr *pRight = pRangeStart->pExpr->pRight;
++      codeExprOrVector(pParse, pRight, regBase+nEq, nBtm);
++      whereLikeOptimizationStringFixup(v, pLevel, pRangeStart);
++      if( (pRangeStart->wtFlags & TERM_VNULL)==0
++       && sqlite3ExprCanBeNull(pRight)
++      ){
++        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
++        VdbeCoverage(v);
++      }
++      if( zStartAff ){
++        updateRangeAffinityStr(pRight, nBtm, &zStartAff[nEq]);
++      }  
++      nConstraint += nBtm;
++      testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
++      if( sqlite3ExprIsVector(pRight)==0 ){
++        disableTerm(pLevel, pRangeStart);
++      }else{
++        startEq = 1;
++      }
++      bSeekPastNull = 0;
++    }else if( bSeekPastNull ){
++      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
++      nConstraint++;
++      startEq = 0;
++      start_constraints = 1;
++    }
++    codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
++    if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){
++      /* The skip-scan logic inside the call to codeAllEqualityConstraints()
++      ** above has already left the cursor sitting on the correct row,
++      ** so no further seeking is needed */
++    }else{
++      op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
++      assert( op!=0 );
++      sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
++      VdbeCoverage(v);
++      VdbeCoverageIf(v, op==OP_Rewind);  testcase( op==OP_Rewind );
++      VdbeCoverageIf(v, op==OP_Last);    testcase( op==OP_Last );
++      VdbeCoverageIf(v, op==OP_SeekGT);  testcase( op==OP_SeekGT );
++      VdbeCoverageIf(v, op==OP_SeekGE);  testcase( op==OP_SeekGE );
++      VdbeCoverageIf(v, op==OP_SeekLE);  testcase( op==OP_SeekLE );
++      VdbeCoverageIf(v, op==OP_SeekLT);  testcase( op==OP_SeekLT );
++    }
++
++    /* Load the value for the inequality constraint at the end of the
++    ** range (if any).
++    */
++    nConstraint = nEq;
++    if( pRangeEnd ){
++      Expr *pRight = pRangeEnd->pExpr->pRight;
++      sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
++      codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
++      whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
++      if( (pRangeEnd->wtFlags & TERM_VNULL)==0
++       && sqlite3ExprCanBeNull(pRight)
++      ){
++        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
++        VdbeCoverage(v);
++      }
++      if( zEndAff ){
++        updateRangeAffinityStr(pRight, nTop, zEndAff);
++        codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff);
++      }else{
++        assert( pParse->db->mallocFailed );
++      }
++      nConstraint += nTop;
++      testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
++
++      if( sqlite3ExprIsVector(pRight)==0 ){
++        disableTerm(pLevel, pRangeEnd);
++      }else{
++        endEq = 1;
++      }
++    }else if( bStopAtNull ){
++      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
++      endEq = 0;
++      nConstraint++;
++    }
++    sqlite3DbFree(db, zStartAff);
++    sqlite3DbFree(db, zEndAff);
++
++    /* Top of the loop body */
++    pLevel->p2 = sqlite3VdbeCurrentAddr(v);
++
++    /* Check if the index cursor is past the end of the range. */
++    if( nConstraint ){
++      op = aEndOp[bRev*2 + endEq];
++      sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
++      testcase( op==OP_IdxGT );  VdbeCoverageIf(v, op==OP_IdxGT );
++      testcase( op==OP_IdxGE );  VdbeCoverageIf(v, op==OP_IdxGE );
++      testcase( op==OP_IdxLT );  VdbeCoverageIf(v, op==OP_IdxLT );
++      testcase( op==OP_IdxLE );  VdbeCoverageIf(v, op==OP_IdxLE );
++    }
++
++    /* Seek the table cursor, if required */
++    if( omitTable ){
++      /* pIdx is a covering index.  No need to access the main table. */
++    }else if( HasRowid(pIdx->pTable) ){
++      if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE) || (
++          (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE) 
++       && (pWInfo->eOnePass==ONEPASS_SINGLE)
++      )){
++        iRowidReg = ++pParse->nMem;
++        sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
++        sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
++        sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg);
++        VdbeCoverage(v);
++      }else{
++        codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur);
++      }
++    }else if( iCur!=iIdxCur ){
++      Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
++      iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol);
++      for(j=0; j<pPk->nKeyCol; j++){
++        k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
++        sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
++      }
++      sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
++                           iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
++    }
++
++    /* If pIdx is an index on one or more expressions, then look through
++    ** all the expressions in pWInfo and try to transform matching expressions
++    ** into reference to index columns.
++    */
++    whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
++
++
++    /* Record the instruction used to terminate the loop. */
++    if( pLoop->wsFlags & WHERE_ONEROW ){
++      pLevel->op = OP_Noop;
++    }else if( bRev ){
++      pLevel->op = OP_Prev;
++    }else{
++      pLevel->op = OP_Next;
++    }
++    pLevel->p1 = iIdxCur;
++    pLevel->p3 = (pLoop->wsFlags&WHERE_UNQ_WANTED)!=0 ? 1:0;
++    if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){
++      pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
++    }else{
++      assert( pLevel->p5==0 );
++    }
++    if( omitTable ) pIdx = 0;
++  }else
++
++#ifndef SQLITE_OMIT_OR_OPTIMIZATION
++  if( pLoop->wsFlags & WHERE_MULTI_OR ){
++    /* Case 5:  Two or more separately indexed terms connected by OR
++    **
++    ** Example:
++    **
++    **   CREATE TABLE t1(a,b,c,d);
++    **   CREATE INDEX i1 ON t1(a);
++    **   CREATE INDEX i2 ON t1(b);
++    **   CREATE INDEX i3 ON t1(c);
++    **
++    **   SELECT * FROM t1 WHERE a=5 OR b=7 OR (c=11 AND d=13)
++    **
++    ** In the example, there are three indexed terms connected by OR.
++    ** The top of the loop looks like this:
++    **
++    **          Null       1                # Zero the rowset in reg 1
++    **
++    ** Then, for each indexed term, the following. The arguments to
++    ** RowSetTest are such that the rowid of the current row is inserted
++    ** into the RowSet. If it is already present, control skips the
++    ** Gosub opcode and jumps straight to the code generated by WhereEnd().
++    **
++    **        sqlite3WhereBegin(<term>)
++    **          RowSetTest                  # Insert rowid into rowset
++    **          Gosub      2 A
++    **        sqlite3WhereEnd()
++    **
++    ** Following the above, code to terminate the loop. Label A, the target
++    ** of the Gosub above, jumps to the instruction right after the Goto.
++    **
++    **          Null       1                # Zero the rowset in reg 1
++    **          Goto       B                # The loop is finished.
++    **
++    **       A: <loop body>                 # Return data, whatever.
++    **
++    **          Return     2                # Jump back to the Gosub
++    **
++    **       B: <after the loop>
++    **
++    ** Added 2014-05-26: If the table is a WITHOUT ROWID table, then
++    ** use an ephemeral index instead of a RowSet to record the primary
++    ** keys of the rows we have already seen.
++    **
++    */
++    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 */
++    int regRowid = 0;                         /* Register holding rowid */
++    int iLoopBody = sqlite3VdbeMakeLabel(v);  /* Start of loop body */
++    int iRetInit;                             /* Address of regReturn init */
++    int untestedTerms = 0;             /* Some terms not completely tested */
++    int ii;                            /* Loop counter */
++    u16 wctrlFlags;                    /* Flags for sub-WHERE clause */
++    Expr *pAndExpr = 0;                /* An ".. AND (...)" expression */
++    Table *pTab = pTabItem->pTab;
++
++    pTerm = pLoop->aLTerm[0];
++    assert( pTerm!=0 );
++    assert( pTerm->eOperator & WO_OR );
++    assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
++    pOrWc = &pTerm->u.pOrInfo->wc;
++    pLevel->op = OP_Return;
++    pLevel->p1 = regReturn;
++
++    /* 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().
++    */
++    if( pWInfo->nLevel>1 ){
++      int nNotReady;                 /* The number of notReady tables */
++      struct SrcList_item *origSrc;     /* Original list of tables */
++      nNotReady = pWInfo->nLevel - iLevel - 1;
++      pOrTab = sqlite3StackAllocRaw(db,
++                            sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
++      if( pOrTab==0 ) return notReady;
++      pOrTab->nAlloc = (u8)(nNotReady + 1);
++      pOrTab->nSrc = pOrTab->nAlloc;
++      memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
++      origSrc = pWInfo->pTabList->a;
++      for(k=1; k<=nNotReady; k++){
++        memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k]));
++      }
++    }else{
++      pOrTab = pWInfo->pTabList;
++    }
++
++    /* Initialize the rowset register to contain NULL. An SQL NULL is 
++    ** equivalent to an empty rowset.  Or, create an ephemeral index
++    ** capable of holding primary keys in the case of a WITHOUT ROWID.
++    **
++    ** Also initialize regReturn to contain the address of the instruction 
++    ** immediately following the OP_Return at the bottom of the loop. This
++    ** is required in a few obscure LEFT JOIN cases where control jumps
++    ** over the top of the loop into the body of it. In this case the 
++    ** correct response for the end-of-loop code (the OP_Return) is to 
++    ** fall through to the next instruction, just as an OP_Next does if
++    ** called on an uninitialized cursor.
++    */
++    if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
++      if( HasRowid(pTab) ){
++        regRowset = ++pParse->nMem;
++        sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
++      }else{
++        Index *pPk = sqlite3PrimaryKeyIndex(pTab);
++        regRowset = pParse->nTab++;
++        sqlite3VdbeAddOp2(v, OP_OpenEphemeral, regRowset, pPk->nKeyCol);
++        sqlite3VdbeSetP4KeyInfo(pParse, pPk);
++      }
++      regRowid = ++pParse->nMem;
++    }
++    iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
++
++    /* If the original WHERE clause is z of the form:  (x1 OR x2 OR ...) AND y
++    ** Then for every term xN, evaluate as the subexpression: xN AND z
++    ** That way, terms in y that are factored into the disjunction will
++    ** be picked up by the recursive calls to sqlite3WhereBegin() below.
++    **
++    ** Actually, each subexpression is converted to "xN AND w" where w is
++    ** the "interesting" terms of z - terms that did not originate in the
++    ** ON or USING clause of a LEFT JOIN, and terms that are usable as 
++    ** indices.
++    **
++    ** This optimization also only applies if the (x1 OR x2 OR ...) term
++    ** is not contained in the ON clause of a LEFT JOIN.
++    ** See ticket http://www.sqlite.org/src/info/f2369304e4
++    */
++    if( pWC->nTerm>1 ){
++      int iTerm;
++      for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
++        Expr *pExpr = pWC->a[iTerm].pExpr;
++        if( &pWC->a[iTerm] == pTerm ) continue;
++        if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
++        testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
++        testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
++        if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
++        if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
++        testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
++        pExpr = sqlite3ExprDup(db, pExpr, 0);
++        pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
++      }
++      if( pAndExpr ){
++        pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr);
++      }
++    }
++
++    /* Run a separate WHERE clause for each term of the OR clause.  After
++    ** eliminating duplicates from other WHERE clauses, the action for each
++    ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
++    */
++    wctrlFlags =  WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE);
++    for(ii=0; ii<pOrWc->nTerm; ii++){
++      WhereTerm *pOrTerm = &pOrWc->a[ii];
++      if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
++        WhereInfo *pSubWInfo;           /* Info for single OR-term scan */
++        Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
++        int jmp1 = 0;                   /* Address of jump operation */
++        if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
++          pAndExpr->pLeft = pOrExpr;
++          pOrExpr = pAndExpr;
++        }
++        /* Loop through table entries that match term pOrTerm. */
++        WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
++        pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
++                                      wctrlFlags, iCovCur);
++        assert( pSubWInfo || pParse->nErr || db->mallocFailed );
++        if( pSubWInfo ){
++          WhereLoop *pSubLoop;
++          int addrExplain = sqlite3WhereExplainOneScan(
++              pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
++          );
++          sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain);
++
++          /* This is the sub-WHERE clause body.  First skip over
++          ** duplicate rows from prior sub-WHERE clauses, and record the
++          ** rowid (or PRIMARY KEY) for the current row so that the same
++          ** row will be skipped in subsequent sub-WHERE clauses.
++          */
++          if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
++            int r;
++            int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
++            if( HasRowid(pTab) ){
++              r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0);
++              jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0,
++                                           r,iSet);
++              VdbeCoverage(v);
++            }else{
++              Index *pPk = sqlite3PrimaryKeyIndex(pTab);
++              int nPk = pPk->nKeyCol;
++              int iPk;
++
++              /* Read the PK into an array of temp registers. */
++              r = sqlite3GetTempRange(pParse, nPk);
++              for(iPk=0; iPk<nPk; iPk++){
++                int iCol = pPk->aiColumn[iPk];
++                sqlite3ExprCodeGetColumnToReg(pParse, pTab, iCol, iCur, r+iPk);
++              }
++
++              /* Check if the temp table already contains this key. If so,
++              ** the row has already been included in the result set and
++              ** can be ignored (by jumping past the Gosub below). Otherwise,
++              ** insert the key into the temp table and proceed with processing
++              ** the row.
++              **
++              ** Use some of the same optimizations as OP_RowSetTest: If iSet
++              ** is zero, assume that the key cannot already be present in
++              ** the temp table. And if iSet is -1, assume that there is no 
++              ** need to insert the key into the temp table, as it will never 
++              ** be tested for.  */ 
++              if( iSet ){
++                jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk);
++                VdbeCoverage(v);
++              }
++              if( iSet>=0 ){
++                sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid);
++                sqlite3VdbeAddOp4Int(v, OP_IdxInsert, regRowset, regRowid,
++                                     r, nPk);
++                if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
++              }
++
++              /* Release the array of temp registers */
++              sqlite3ReleaseTempRange(pParse, r, nPk);
++            }
++          }
++
++          /* Invoke the main loop body as a subroutine */
++          sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
++
++          /* Jump here (skipping the main loop body subroutine) if the
++          ** current sub-WHERE row is a duplicate from prior sub-WHEREs. */
++          if( jmp1 ) sqlite3VdbeJumpHere(v, jmp1);
++
++          /* The pSubWInfo->untestedTerms flag means that this OR term
++          ** contained one or more AND term from a notReady table.  The
++          ** terms from the notReady table could not be tested and will
++          ** need to be tested later.
++          */
++          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.
++          */
++          pSubLoop = pSubWInfo->a[0].pWLoop;
++          assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
++          if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
++           && (ii==0 || pSubLoop->u.btree.pIndex==pCov)
++           && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex))
++          ){
++            assert( pSubWInfo->a[0].iIdxCur==iCovCur );
++            pCov = pSubLoop->u.btree.pIndex;
++          }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(db, pAndExpr);
++    }
++    sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
++    sqlite3VdbeGoto(v, pLevel->addrBrk);
++    sqlite3VdbeResolveLabel(v, iLoopBody);
++
++    if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
++    if( !untestedTerms ) disableTerm(pLevel, pTerm);
++  }else
++#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
++
++  {
++    /* Case 6:  There is no usable index.  We must do a complete
++    **          scan of the entire table.
++    */
++    static const u8 aStep[] = { OP_Next, OP_Prev };
++    static const u8 aStart[] = { OP_Rewind, OP_Last };
++    assert( bRev==0 || bRev==1 );
++    if( pTabItem->fg.isRecursive ){
++      /* Tables marked isRecursive have only a single row that is stored in
++      ** a pseudo-cursor.  No need to Rewind or Next such cursors. */
++      pLevel->op = OP_Noop;
++    }else{
++      codeCursorHint(pTabItem, pWInfo, pLevel, 0);
++      pLevel->op = aStep[bRev];
++      pLevel->p1 = iCur;
++      pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt);
++      VdbeCoverageIf(v, bRev==0);
++      VdbeCoverageIf(v, bRev!=0);
++      pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
+     }
+   }
+-  if( pWC->a!=pWC->aStatic ){
+-    sqlite3DbFree(db, pWC->a);
++
++#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
++  pLevel->addrVisit = sqlite3VdbeCurrentAddr(v);
 +#endif
-+#if SQLITE_OMIT_VACUUM
-+  "OMIT_VACUUM",
++
++  /* Insert code to test every subexpression that can be completely
++  ** computed using the current set of tables.
++  **
++  ** This loop may run between one and three times, depending on the
++  ** constraints to be generated. The value of stack variable iLoop
++  ** determines the constraints coded by each iteration, as follows:
++  **
++  ** iLoop==1: Code only expressions that are entirely covered by pIdx.
++  ** iLoop==2: Code remaining expressions that do not contain correlated
++  **           sub-queries.  
++  ** iLoop==3: Code all remaining expressions.
++  **
++  ** An effort is made to skip unnecessary iterations of the loop.
++  */
++  iLoop = (pIdx ? 1 : 2);
++  do{
++    int iNext = 0;                /* Next value for iLoop */
++    for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
++      Expr *pE;
++      int skipLikeAddr = 0;
++      testcase( pTerm->wtFlags & TERM_VIRTUAL );
++      testcase( pTerm->wtFlags & TERM_CODED );
++      if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
++      if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
++        testcase( pWInfo->untestedTerms==0
++            && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 );
++        pWInfo->untestedTerms = 1;
++        continue;
++      }
++      pE = pTerm->pExpr;
++      assert( pE!=0 );
++      if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
++        continue;
++      }
++      
++      if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
++        iNext = 2;
++        continue;
++      }
++      if( iLoop<3 && (pTerm->wtFlags & TERM_VARSELECT) ){
++        if( iNext==0 ) iNext = 3;
++        continue;
++      }
++
++      if( pTerm->wtFlags & TERM_LIKECOND ){
++        /* If the TERM_LIKECOND flag is set, that means that the range search
++        ** is sufficient to guarantee that the LIKE operator is true, so we
++        ** can skip the call to the like(A,B) function.  But this only works
++        ** for strings.  So do not skip the call to the function on the pass
++        ** that compares BLOBs. */
++#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
++        continue;
++#else
++        u32 x = pLevel->iLikeRepCntr;
++        assert( x>0 );
++        skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If, (int)(x>>1));
++        VdbeCoverage(v);
 +#endif
-+#if SQLITE_OMIT_VIEW
-+  "OMIT_VIEW",
++      }
++#ifdef WHERETRACE_ENABLED /* 0xffff */
++      if( sqlite3WhereTrace ){
++        VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d",
++                         pWC->nTerm-j, pTerm, iLoop));
++      }
 +#endif
-+#if SQLITE_OMIT_VIRTUALTABLE
-+  "OMIT_VIRTUALTABLE",
++      sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
++      if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
++      pTerm->wtFlags |= TERM_CODED;
++    }
++    iLoop = iNext;
++  }while( iLoop>0 );
++
++  /* Insert code to test for implied constraints based on transitivity
++  ** of the "==" operator.
++  **
++  ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
++  ** and we are coding the t1 loop and the t2 loop has not yet coded,
++  ** then we cannot use the "t1.a=t2.b" constraint, but we can code
++  ** the implied "t1.a=123" constraint.
++  */
++  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
++    Expr *pE, sEAlt;
++    WhereTerm *pAlt;
++    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
++    if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
++    if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
++    if( pTerm->leftCursor!=iCur ) continue;
++    if( pLevel->iLeftJoin ) continue;
++    pE = pTerm->pExpr;
++    assert( !ExprHasProperty(pE, EP_FromJoin) );
++    assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
++    pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.leftColumn, notReady,
++                    WO_EQ|WO_IN|WO_IS, 0);
++    if( pAlt==0 ) continue;
++    if( pAlt->wtFlags & (TERM_CODED) ) continue;
++    testcase( pAlt->eOperator & WO_EQ );
++    testcase( pAlt->eOperator & WO_IS );
++    testcase( pAlt->eOperator & WO_IN );
++    VdbeModuleComment((v, "begin transitive constraint"));
++    sEAlt = *pAlt->pExpr;
++    sEAlt.pLeft = pE->pLeft;
++    sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL);
++  }
++
++  /* For a LEFT OUTER JOIN, generate code that will record the fact that
++  ** at least one row of the right table has matched the left table.  
++  */
++  if( pLevel->iLeftJoin ){
++    pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
++    sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
++    VdbeComment((v, "record LEFT JOIN hit"));
++    sqlite3ExprCacheClear(pParse);
++    for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
++      testcase( pTerm->wtFlags & TERM_VIRTUAL );
++      testcase( pTerm->wtFlags & TERM_CODED );
++      if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
++      if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
++        assert( pWInfo->untestedTerms );
++        continue;
++      }
++      assert( pTerm->pExpr );
++      sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
++      pTerm->wtFlags |= TERM_CODED;
++    }
+   }
++
++  return pLevel->notReady;
++}
++
++/************** End of wherecode.c *******************************************/
++/************** Begin file whereexpr.c ***************************************/
++/*
++** 2015-06-08
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This module contains C code that generates VDBE code used to process
++** the WHERE clause of SQL statements.
++**
++** This file was originally part of where.c but was split out to improve
++** readability and editabiliity.  This file contains utility routines for
++** analyzing Expr objects in the WHERE clause.
++*/
++/* #include "sqliteInt.h" */
++/* #include "whereInt.h" */
++
++/* Forward declarations */
++static void exprAnalyze(SrcList*, WhereClause*, int);
++
++/*
++** Deallocate all memory associated with a WhereOrInfo object.
++*/
++static void whereOrInfoDelete(sqlite3 *db, WhereOrInfo *p){
++  sqlite3WhereClauseClear(&p->wc);
++  sqlite3DbFree(db, p);
++}
++
++/*
++** Deallocate all memory associated with a WhereAndInfo object.
++*/
++static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){
++  sqlite3WhereClauseClear(&p->wc);
++  sqlite3DbFree(db, p);
+ }
+ 
+ /*
+@@ -116449,7 +133344,7 @@
+   if( pWC->nTerm>=pWC->nSlot ){
+     WhereTerm *pOld = pWC->a;
+     sqlite3 *db = pWC->pWInfo->pParse->db;
+-    pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
++    pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
+     if( pWC->a==0 ){
+       if( wtFlags & TERM_DYNAMIC ){
+         sqlite3ExprDelete(db, p);
+@@ -116462,7 +133357,6 @@
+       sqlite3DbFree(db, pOld);
+     }
+     pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
+-    memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm));
+   }
+   pTerm = &pWC->a[idx = pWC->nTerm++];
+   if( p && ExprHasProperty(p, EP_Unlikely) ){
+@@ -116474,136 +133368,22 @@
+   pTerm->wtFlags = wtFlags;
+   pTerm->pWC = pWC;
+   pTerm->iParent = -1;
++  memset(&pTerm->eOperator, 0,
++         sizeof(WhereTerm) - offsetof(WhereTerm,eOperator));
+   return idx;
+ }
+ 
+ /*
+-** This routine identifies subexpressions in the WHERE clause where
+-** each subexpression is separated by the AND operator or some other
+-** operator specified in the op parameter.  The WhereClause structure
+-** is filled with pointers to subexpressions.  For example:
+-**
+-**    WHERE  a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22)
+-**           \________/     \_______________/     \________________/
+-**            slot[0]            slot[1]               slot[2]
+-**
+-** The original WHERE clause in pExpr is unaltered.  All this routine
+-** does is make slot[] entries point to substructure within pExpr.
+-**
+-** In the previous sentence and in the diagram, "slot[]" refers to
+-** the WhereClause.a[] array.  The slot[] array grows as needed to contain
+-** all terms of the WHERE clause.
+-*/
+-static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
+-  Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
+-  pWC->op = op;
+-  if( pE2==0 ) return;
+-  if( pE2->op!=op ){
+-    whereClauseInsert(pWC, pExpr, 0);
+-  }else{
+-    whereSplit(pWC, pE2->pLeft, op);
+-    whereSplit(pWC, pE2->pRight, op);
+-  }
+-}
+-
+-/*
+-** Initialize a WhereMaskSet object
+-*/
+-#define initMaskSet(P)  (P)->n=0
+-
+-/*
+-** Return the bitmask for the given cursor number.  Return 0 if
+-** iCursor is not in the set.
+-*/
+-static Bitmask getMask(WhereMaskSet *pMaskSet, int iCursor){
+-  int i;
+-  assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 );
+-  for(i=0; i<pMaskSet->n; i++){
+-    if( pMaskSet->ix[i]==iCursor ){
+-      return MASKBIT(i);
+-    }
+-  }
+-  return 0;
+-}
+-
+-/*
+-** Create a new mask for cursor iCursor.
+-**
+-** There is one cursor per table in the FROM clause.  The number of
+-** tables in the FROM clause is limited by a test early in the
+-** sqlite3WhereBegin() routine.  So we know that the pMaskSet->ix[]
+-** array will never overflow.
+-*/
+-static void createMask(WhereMaskSet *pMaskSet, int iCursor){
+-  assert( pMaskSet->n < ArraySize(pMaskSet->ix) );
+-  pMaskSet->ix[pMaskSet->n++] = iCursor;
+-}
+-
+-/*
+-** These routines walk (recursively) an expression tree and generate
+-** a bitmask indicating which tables are used in that expression
+-** tree.
+-*/
+-static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);
+-static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);
+-static Bitmask exprTableUsage(WhereMaskSet *pMaskSet, Expr *p){
+-  Bitmask mask = 0;
+-  if( p==0 ) return 0;
+-  if( p->op==TK_COLUMN ){
+-    mask = getMask(pMaskSet, p->iTable);
+-    return mask;
+-  }
+-  mask = exprTableUsage(pMaskSet, p->pRight);
+-  mask |= exprTableUsage(pMaskSet, p->pLeft);
+-  if( ExprHasProperty(p, EP_xIsSelect) ){
+-    mask |= exprSelectTableUsage(pMaskSet, p->x.pSelect);
+-  }else{
+-    mask |= exprListTableUsage(pMaskSet, p->x.pList);
+-  }
+-  return mask;
+-}
+-static Bitmask exprListTableUsage(WhereMaskSet *pMaskSet, ExprList *pList){
+-  int i;
+-  Bitmask mask = 0;
+-  if( pList ){
+-    for(i=0; i<pList->nExpr; i++){
+-      mask |= exprTableUsage(pMaskSet, pList->a[i].pExpr);
+-    }
+-  }
+-  return mask;
+-}
+-static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){
+-  Bitmask mask = 0;
+-  while( pS ){
+-    SrcList *pSrc = pS->pSrc;
+-    mask |= exprListTableUsage(pMaskSet, pS->pEList);
+-    mask |= exprListTableUsage(pMaskSet, pS->pGroupBy);
+-    mask |= exprListTableUsage(pMaskSet, pS->pOrderBy);
+-    mask |= exprTableUsage(pMaskSet, pS->pWhere);
+-    mask |= exprTableUsage(pMaskSet, pS->pHaving);
+-    if( ALWAYS(pSrc!=0) ){
+-      int i;
+-      for(i=0; i<pSrc->nSrc; i++){
+-        mask |= exprSelectTableUsage(pMaskSet, pSrc->a[i].pSelect);
+-        mask |= exprTableUsage(pMaskSet, pSrc->a[i].pOn);
+-      }
+-    }
+-    pS = pS->pPrior;
+-  }
+-  return mask;
+-}
+-
+-/*
+ ** Return TRUE if the given operator is one of the operators that is
+ ** allowed for an indexable WHERE clause term.  The allowed operators are
+-** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
++** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL"
+ */
+ static int allowedOp(int op){
+   assert( TK_GT>TK_EQ && TK_GT<TK_GE );
+   assert( TK_LT>TK_EQ && TK_LT<TK_GE );
+   assert( TK_LE>TK_EQ && TK_LE<TK_GE );
+   assert( TK_GE==TK_EQ+4 );
+-  return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
++  return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS;
+ }
+ 
+ /*
+@@ -116656,6 +133436,8 @@
+     c = WO_IN;
+   }else if( op==TK_ISNULL ){
+     c = WO_ISNULL;
++  }else if( op==TK_IS ){
++    c = WO_IS;
+   }else{
+     assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
+     c = (u16)(WO_EQ<<(op-TK_EQ));
+@@ -116667,199 +133449,10 @@
+   assert( op!=TK_LE || c==WO_LE );
+   assert( op!=TK_GT || c==WO_GT );
+   assert( op!=TK_GE || c==WO_GE );
++  assert( op!=TK_IS || c==WO_IS );
+   return c;
+ }
+ 
+-/*
+-** Advance to the next WhereTerm that matches according to the criteria
+-** established when the pScan object was initialized by whereScanInit().
+-** Return NULL if there are no more matching WhereTerms.
+-*/
+-static WhereTerm *whereScanNext(WhereScan *pScan){
+-  int iCur;            /* The cursor on the LHS of the term */
+-  int iColumn;         /* The column on the LHS of the term.  -1 for IPK */
+-  Expr *pX;            /* An expression being tested */
+-  WhereClause *pWC;    /* Shorthand for pScan->pWC */
+-  WhereTerm *pTerm;    /* The term being tested */
+-  int k = pScan->k;    /* Where to start scanning */
+-
+-  while( pScan->iEquiv<=pScan->nEquiv ){
+-    iCur = pScan->aEquiv[pScan->iEquiv-2];
+-    iColumn = pScan->aEquiv[pScan->iEquiv-1];
+-    while( (pWC = pScan->pWC)!=0 ){
+-      for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
+-        if( pTerm->leftCursor==iCur
+-         && pTerm->u.leftColumn==iColumn
+-         && (pScan->iEquiv<=2 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+-        ){
+-          if( (pTerm->eOperator & WO_EQUIV)!=0
+-           && pScan->nEquiv<ArraySize(pScan->aEquiv)
+-          ){
+-            int j;
+-            pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight);
+-            assert( pX->op==TK_COLUMN );
+-            for(j=0; j<pScan->nEquiv; j+=2){
+-              if( pScan->aEquiv[j]==pX->iTable
+-               && pScan->aEquiv[j+1]==pX->iColumn ){
+-                  break;
+-              }
+-            }
+-            if( j==pScan->nEquiv ){
+-              pScan->aEquiv[j] = pX->iTable;
+-              pScan->aEquiv[j+1] = pX->iColumn;
+-              pScan->nEquiv += 2;
+-            }
+-          }
+-          if( (pTerm->eOperator & pScan->opMask)!=0 ){
+-            /* Verify the affinity and collating sequence match */
+-            if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){
+-              CollSeq *pColl;
+-              Parse *pParse = pWC->pWInfo->pParse;
+-              pX = pTerm->pExpr;
+-              if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){
+-                continue;
+-              }
+-              assert(pX->pLeft);
+-              pColl = sqlite3BinaryCompareCollSeq(pParse,
+-                                                  pX->pLeft, pX->pRight);
+-              if( pColl==0 ) pColl = pParse->db->pDfltColl;
+-              if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
+-                continue;
+-              }
+-            }
+-            if( (pTerm->eOperator & WO_EQ)!=0
+-             && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
+-             && pX->iTable==pScan->aEquiv[0]
+-             && pX->iColumn==pScan->aEquiv[1]
+-            ){
+-              continue;
+-            }
+-            pScan->k = k+1;
+-            return pTerm;
+-          }
+-        }
+-      }
+-      pScan->pWC = pScan->pWC->pOuter;
+-      k = 0;
+-    }
+-    pScan->pWC = pScan->pOrigWC;
+-    k = 0;
+-    pScan->iEquiv += 2;
+-  }
+-  return 0;
+-}
+-
+-/*
+-** Initialize a WHERE clause scanner object.  Return a pointer to the
+-** first match.  Return NULL if there are no matches.
+-**
+-** The scanner will be searching the WHERE clause pWC.  It will look
+-** for terms of the form "X <op> <expr>" where X is column iColumn of table
+-** iCur.  The <op> must be one of the operators described by opMask.
+-**
+-** If the search is for X and the WHERE clause contains terms of the
+-** form X=Y then this routine might also return terms of the form
+-** "Y <op> <expr>".  The number of levels of transitivity is limited,
+-** but is enough to handle most commonly occurring SQL statements.
+-**
+-** If X is not the INTEGER PRIMARY KEY then X must be compatible with
+-** index pIdx.
+-*/
+-static WhereTerm *whereScanInit(
+-  WhereScan *pScan,       /* The WhereScan object being initialized */
+-  WhereClause *pWC,       /* The WHERE clause to be scanned */
+-  int iCur,               /* Cursor to scan for */
+-  int iColumn,            /* Column to scan for */
+-  u32 opMask,             /* Operator(s) to scan for */
+-  Index *pIdx             /* Must be compatible with this index */
+-){
+-  int j;
+-
+-  /* memset(pScan, 0, sizeof(*pScan)); */
+-  pScan->pOrigWC = pWC;
+-  pScan->pWC = pWC;
+-  if( pIdx && iColumn>=0 ){
+-    pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
+-    for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
+-      if( NEVER(j>pIdx->nColumn) ) return 0;
+-    }
+-    pScan->zCollName = pIdx->azColl[j];
+-  }else{
+-    pScan->idxaff = 0;
+-    pScan->zCollName = 0;
+-  }
+-  pScan->opMask = opMask;
+-  pScan->k = 0;
+-  pScan->aEquiv[0] = iCur;
+-  pScan->aEquiv[1] = iColumn;
+-  pScan->nEquiv = 2;
+-  pScan->iEquiv = 2;
+-  return whereScanNext(pScan);
+-}
+-
+-/*
+-** Search for a term in the WHERE clause that is of the form "X <op> <expr>"
+-** where X is a reference to the iColumn of table iCur and <op> is one of
+-** the WO_xx operator codes specified by the op parameter.
+-** Return a pointer to the term.  Return 0 if not found.
+-**
+-** The term returned might by Y=<expr> if there is another constraint in
+-** the WHERE clause that specifies that X=Y.  Any such constraints will be
+-** identified by the WO_EQUIV bit in the pTerm->eOperator field.  The
+-** aEquiv[] array holds X and all its equivalents, with each SQL variable
+-** taking up two slots in aEquiv[].  The first slot is for the cursor number
+-** and the second is for the column number.  There are 22 slots in aEquiv[]
+-** so that means we can look for X plus up to 10 other equivalent values.
+-** Hence a search for X will return <expr> if X=A1 and A1=A2 and A2=A3
+-** and ... and A9=A10 and A10=<expr>.
+-**
+-** If there are multiple terms in the WHERE clause of the form "X <op> <expr>"
+-** then try for the one with no dependencies on <expr> - in other words where
+-** <expr> is a constant expression of some kind.  Only return entries of
+-** the form "X <op> Y" where Y is a column in another table if no terms of
+-** the form "X <op> <const-expr>" exist.   If no terms with a constant RHS
+-** exist, try to return a term that does not use WO_EQUIV.
+-*/
+-static WhereTerm *findTerm(
+-  WhereClause *pWC,     /* The WHERE clause to be searched */
+-  int iCur,             /* Cursor number of LHS */
+-  int iColumn,          /* Column number of LHS */
+-  Bitmask notReady,     /* RHS must not overlap with this mask */
+-  u32 op,               /* Mask of WO_xx values describing operator */
+-  Index *pIdx           /* Must be compatible with this index, if not NULL */
+-){
+-  WhereTerm *pResult = 0;
+-  WhereTerm *p;
+-  WhereScan scan;
+-
+-  p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx);
+-  while( p ){
+-    if( (p->prereqRight & notReady)==0 ){
+-      if( p->prereqRight==0 && (p->eOperator&WO_EQ)!=0 ){
+-        return p;
+-      }
+-      if( pResult==0 ) pResult = p;
+-    }
+-    p = whereScanNext(&scan);
+-  }
+-  return pResult;
+-}
+-
+-/* Forward reference */
+-static void exprAnalyze(SrcList*, WhereClause*, int);
+-
+-/*
+-** Call exprAnalyze on all terms in a WHERE clause.  
+-*/
+-static void exprAnalyzeAll(
+-  SrcList *pTabList,       /* the FROM clause */
+-  WhereClause *pWC         /* the WHERE clause to be analyzed */
+-){
+-  int i;
+-  for(i=pWC->nTerm-1; i>=0; i--){
+-    exprAnalyze(pTabList, pWC, i);
+-  }
+-}
+ 
+ #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION
+ /*
+@@ -116870,7 +133463,7 @@
+ ** In order for the operator to be optimizible, the RHS must be a string
+ ** literal that does not begin with a wildcard.  The LHS must be a column
+ ** that may only be NULL, a string, or a BLOB, never a number. (This means
+-** that virtual tables cannot participate in the LIKE optimization.)  If the
++** that virtual tables cannot participate in the LIKE optimization.)  The
+ ** collating sequence for the column on the LHS must be appropriate for
+ ** the operator.
+ */
+@@ -116890,6 +133483,7 @@
+   sqlite3 *db = pParse->db;  /* Database connection */
+   sqlite3_value *pVal = 0;
+   int op;                    /* Opcode of pRight */
++  int rc;                    /* Result code to return */
+ 
+   if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){
+     return 0;
+@@ -116899,22 +133493,13 @@
+ #endif
+   pList = pExpr->x.pList;
+   pLeft = pList->a[1].pExpr;
+-  if( pLeft->op!=TK_COLUMN 
+-   || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
+-   || IsVirtual(pLeft->pTab)  /* Value might be numeric */
+-  ){
+-    /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
+-    ** be the name of an indexed column with TEXT affinity. */
+-    return 0;
+-  }
+-  assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
+ 
+   pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
+   op = pRight->op;
+-  if( op==TK_VARIABLE ){
++  if( op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){
+     Vdbe *pReprepare = pParse->pReprepare;
+     int iCol = pRight->iColumn;
+-    pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_NONE);
++    pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB);
+     if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
+       z = (char *)sqlite3_value_text(pVal);
+     }
+@@ -116924,6 +133509,23 @@
+     z = pRight->u.zToken;
+   }
+   if( z ){
++
++    /* If the RHS begins with a digit or a minus sign, then the LHS must
++    ** be an ordinary column (not a virtual table column) with TEXT affinity.
++    ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
++    ** even though "lhs LIKE rhs" is true.  But if the RHS does not start
++    ** with a digit or '-', then "lhs LIKE rhs" will always be false if
++    ** the LHS is numeric and so the optimization still works.
++    */
++    if( sqlite3Isdigit(z[0]) || z[0]=='-' ){
++      if( pLeft->op!=TK_COLUMN 
++       || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
++       || IsVirtual(pLeft->pTab)  /* Value might be numeric */
++      ){
++        sqlite3ValueFree(pVal);
++        return 0;
++      }
++    }
+     cnt = 0;
+     while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
+       cnt++;
+@@ -116955,8 +133557,9 @@
+     }
+   }
+ 
++  rc = (z!=0);
+   sqlite3ValueFree(pVal);
+-  return (z!=0);
++  return rc;
+ }
+ #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
+ 
+@@ -116965,29 +133568,48 @@
+ /*
+ ** Check to see if the given expression is of the form
+ **
+-**         column MATCH expr
++**         column OP expr
++**
++** where OP is one of MATCH, GLOB, LIKE or REGEXP and "column" is a 
++** column of a virtual table.
+ **
+ ** If it is then return TRUE.  If not, return FALSE.
+ */
+ static int isMatchOfColumn(
+-  Expr *pExpr      /* Test this expression */
++  Expr *pExpr,                    /* Test this expression */
++  unsigned char *peOp2            /* OUT: 0 for MATCH, or else an op2 value */
+ ){
++  static const struct Op2 {
++    const char *zOp;
++    unsigned char eOp2;
++  } aOp[] = {
++    { "match",  SQLITE_INDEX_CONSTRAINT_MATCH },
++    { "glob",   SQLITE_INDEX_CONSTRAINT_GLOB },
++    { "like",   SQLITE_INDEX_CONSTRAINT_LIKE },
++    { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP }
++  };
+   ExprList *pList;
++  Expr *pCol;                     /* Column reference */
++  int i;
+ 
+   if( pExpr->op!=TK_FUNCTION ){
+     return 0;
+   }
+-  if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){
+-    return 0;
+-  }
+   pList = pExpr->x.pList;
+-  if( pList->nExpr!=2 ){
++  if( pList==0 || pList->nExpr!=2 ){
+     return 0;
+   }
+-  if( pList->a[1].pExpr->op != TK_COLUMN ){
++  pCol = pList->a[1].pExpr;
++  if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){
+     return 0;
+   }
+-  return 1;
++  for(i=0; i<ArraySize(aOp); i++){
++    if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
++      *peOp2 = aOp[i].eOp2;
++      return 1;
++    }
++  }
++  return 0;
+ }
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+ 
+@@ -117064,8 +133686,8 @@
+    && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return;
+   assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 );
+   assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 );
+-  if( sqlite3ExprCompare(pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return;
+-  if( sqlite3ExprCompare(pOne->pExpr->pRight, pTwo->pExpr->pRight, -1) )return;
++  if( sqlite3ExprCompare(0,pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return;
++  if( sqlite3ExprCompare(0,pOne->pExpr->pRight, pTwo->pExpr->pRight,-1) )return;
+   /* If we reach this point, it means the two subterms can be combined */
+   if( (eOp & (eOp-1))!=0 ){
+     if( eOp & (WO_LT|WO_LE) ){
+@@ -117125,7 +133747,7 @@
+ **
+ ** CASE 2:
+ **
+-** If there are exactly two disjuncts one side has x>A and the other side
++** If there are exactly two disjuncts and one side has x>A and the other side
+ ** has x=A (for the same x and A) then add a new virtual conjunct term to the
+ ** WHERE clause of the form "x>=A".  Example:
+ **
+@@ -117154,22 +133776,22 @@
+ ** is decided elsewhere.  This analysis only looks at whether subterms
+ ** appropriate for indexing exist.
+ **
+-** All examples A through E above satisfy case 2.  But if a term
++** All examples A through E above satisfy case 3.  But if a term
+ ** also satisfies case 1 (such as B) we know that the optimizer will
+-** always prefer case 1, so in that case we pretend that case 2 is not
++** always prefer case 1, so in that case we pretend that case 3 is not
+ ** satisfied.
+ **
+ ** It might be the case that multiple tables are indexable.  For example,
+ ** (E) above is indexable on tables P, Q, and R.
+ **
+-** Terms that satisfy case 2 are candidates for lookup by using
++** Terms that satisfy case 3 are candidates for lookup by using
+ ** separate indices to find rowids for each subterm and composing
+ ** the union of all rowids using a RowSet object.  This is similar
+ ** to "bitmap indices" in other database engines.
+ **
+ ** OTHERWISE:
+ **
+-** If neither case 1 nor case 2 apply, then leave the eOperator set to
++** If none of cases 1, 2, or 3 apply, then leave the eOperator set to
+ ** zero.  This term is not useful for search.
+ */
+ static void exprAnalyzeOrTerm(
+@@ -117200,14 +133822,15 @@
+   if( pOrInfo==0 ) return;
+   pTerm->wtFlags |= TERM_ORINFO;
+   pOrWc = &pOrInfo->wc;
+-  whereClauseInit(pOrWc, pWInfo);
+-  whereSplit(pOrWc, pExpr, TK_OR);
+-  exprAnalyzeAll(pSrc, pOrWc);
++  memset(pOrWc->aStatic, 0, sizeof(pOrWc->aStatic));
++  sqlite3WhereClauseInit(pOrWc, pWInfo);
++  sqlite3WhereSplit(pOrWc, pExpr, TK_OR);
++  sqlite3WhereExprAnalyze(pSrc, pOrWc);
+   if( db->mallocFailed ) return;
+   assert( pOrWc->nTerm>=2 );
+ 
+   /*
+-  ** Compute the set of tables that might satisfy cases 1 or 2.
++  ** Compute the set of tables that might satisfy cases 1 or 3.
+   */
+   indexable = ~(Bitmask)0;
+   chngToIN = ~(Bitmask)0;
+@@ -117216,7 +133839,7 @@
+       WhereAndInfo *pAndInfo;
+       assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 );
+       chngToIN = 0;
+-      pAndInfo = sqlite3DbMallocRaw(db, sizeof(*pAndInfo));
++      pAndInfo = sqlite3DbMallocRawNN(db, sizeof(*pAndInfo));
+       if( pAndInfo ){
+         WhereClause *pAndWC;
+         WhereTerm *pAndTerm;
+@@ -117226,16 +133849,18 @@
+         pOrTerm->wtFlags |= TERM_ANDINFO;
+         pOrTerm->eOperator = WO_AND;
+         pAndWC = &pAndInfo->wc;
+-        whereClauseInit(pAndWC, pWC->pWInfo);
+-        whereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
+-        exprAnalyzeAll(pSrc, pAndWC);
++        memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic));
++        sqlite3WhereClauseInit(pAndWC, pWC->pWInfo);
++        sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
++        sqlite3WhereExprAnalyze(pSrc, pAndWC);
+         pAndWC->pOuter = pWC;
+-        testcase( db->mallocFailed );
+         if( !db->mallocFailed ){
+           for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
+             assert( pAndTerm->pExpr );
+-            if( allowedOp(pAndTerm->pExpr->op) ){
+-              b |= getMask(&pWInfo->sMaskSet, pAndTerm->leftCursor);
++            if( allowedOp(pAndTerm->pExpr->op) 
++             || pAndTerm->eOperator==WO_MATCH 
++            ){
++              b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor);
+             }
+           }
+         }
+@@ -117246,10 +133871,10 @@
+       ** corresponding TERM_VIRTUAL term */
+     }else{
+       Bitmask b;
+-      b = getMask(&pWInfo->sMaskSet, pOrTerm->leftCursor);
++      b = sqlite3WhereGetMask(&pWInfo->sMaskSet, pOrTerm->leftCursor);
+       if( pOrTerm->wtFlags & TERM_VIRTUAL ){
+         WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent];
+-        b |= getMask(&pWInfo->sMaskSet, pOther->leftCursor);
++        b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pOther->leftCursor);
+       }
+       indexable &= b;
+       if( (pOrTerm->eOperator & WO_EQ)==0 ){
+@@ -117325,7 +133950,8 @@
+           assert( j==1 );
+           continue;
+         }
+-        if( (chngToIN & getMask(&pWInfo->sMaskSet, pOrTerm->leftCursor))==0 ){
++        if( (chngToIN & sqlite3WhereGetMask(&pWInfo->sMaskSet,
++                                            pOrTerm->leftCursor))==0 ){
+           /* This term must be of the form t1.a==t2.b where t2 is in the
+           ** chngToIN set but t1 is not.  This term will be either preceded
+           ** or follwed by an inverted copy (t2.b==t1.a).  Skip this term 
+@@ -117344,7 +133970,7 @@
+         ** on the second iteration */
+         assert( j==1 );
+         assert( IsPowerOfTwo(chngToIN) );
+-        assert( chngToIN==getMask(&pWInfo->sMaskSet, iCursor) );
++        assert( chngToIN==sqlite3WhereGetMask(&pWInfo->sMaskSet, iCursor) );
+         break;
+       }
+       testcase( j==1 );
+@@ -117396,7 +134022,7 @@
+       }
+       assert( pLeft!=0 );
+       pDup = sqlite3ExprDup(db, pLeft, 0);
+-      pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0);
++      pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0);
+       if( pNew ){
+         int idxNew;
+         transferJoinMarkings(pNew, pExpr);
+@@ -117417,6 +134043,134 @@
+ #endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */
+ 
+ /*
++** We already know that pExpr is a binary operator where both operands are
++** column references.  This routine checks to see if pExpr is an equivalence
++** relation:
++**   1.  The SQLITE_Transitive optimization must be enabled
++**   2.  Must be either an == or an IS operator
++**   3.  Not originating in the ON clause of an OUTER JOIN
++**   4.  The affinities of A and B must be compatible
++**   5a. Both operands use the same collating sequence OR
++**   5b. The overall collating sequence is BINARY
++** If this routine returns TRUE, that means that the RHS can be substituted
++** for the LHS anyplace else in the WHERE clause where the LHS column occurs.
++** This is an optimization.  No harm comes from returning 0.  But if 1 is
++** returned when it should not be, then incorrect answers might result.
++*/
++static int termIsEquivalence(Parse *pParse, Expr *pExpr){
++  char aff1, aff2;
++  CollSeq *pColl;
++  const char *zColl1, *zColl2;
++  if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
++  if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
++  if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;
++  aff1 = sqlite3ExprAffinity(pExpr->pLeft);
++  aff2 = sqlite3ExprAffinity(pExpr->pRight);
++  if( aff1!=aff2
++   && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2))
++  ){
++    return 0;
++  }
++  pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
++  if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1;
++  pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
++  zColl1 = pColl ? pColl->zName : 0;
++  pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
++  zColl2 = pColl ? pColl->zName : 0;
++  return sqlite3_stricmp(zColl1, zColl2)==0;
++}
++
++/*
++** Recursively walk the expressions of a SELECT statement and generate
++** a bitmask indicating which tables are used in that expression
++** tree.
++*/
++static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
++  Bitmask mask = 0;
++  while( pS ){
++    SrcList *pSrc = pS->pSrc;
++    mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pEList);
++    mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pGroupBy);
++    mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pOrderBy);
++    mask |= sqlite3WhereExprUsage(pMaskSet, pS->pWhere);
++    mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving);
++    if( ALWAYS(pSrc!=0) ){
++      int i;
++      for(i=0; i<pSrc->nSrc; i++){
++        mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect);
++        mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn);
++      }
++    }
++    pS = pS->pPrior;
++  }
++  return mask;
++}
++
++/*
++** Expression pExpr is one operand of a comparison operator that might
++** be useful for indexing.  This routine checks to see if pExpr appears
++** in any index.  Return TRUE (1) if pExpr is an indexed term and return
++** FALSE (0) if not.  If TRUE is returned, also set aiCurCol[0] to the cursor
++** number of the table that is indexed and aiCurCol[1] to the column number
++** of the column that is indexed, or XN_EXPR (-2) if an expression is being
++** indexed.
++**
++** If pExpr is a TK_COLUMN column reference, then this routine always returns
++** true even if that particular column is not indexed, because the column
++** might be added to an automatic index later.
++*/
++static SQLITE_NOINLINE int exprMightBeIndexed2(
++  SrcList *pFrom,        /* The FROM clause */
++  Bitmask mPrereq,       /* Bitmask of FROM clause terms referenced by pExpr */
++  int *aiCurCol,         /* Write the referenced table cursor and column here */
++  Expr *pExpr            /* An operand of a comparison operator */
++){
++  Index *pIdx;
++  int i;
++  int iCur;
++  for(i=0; mPrereq>1; i++, mPrereq>>=1){}
++  iCur = pFrom->a[i].iCursor;
++  for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
++    if( pIdx->aColExpr==0 ) continue;
++    for(i=0; i<pIdx->nKeyCol; i++){
++      if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
++      if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
++        aiCurCol[0] = iCur;
++        aiCurCol[1] = XN_EXPR;
++        return 1;
++      }
++    }
++  }
++  return 0;
++}
++static int exprMightBeIndexed(
++  SrcList *pFrom,        /* The FROM clause */
++  Bitmask mPrereq,       /* Bitmask of FROM clause terms referenced by pExpr */
++  int *aiCurCol,         /* Write the referenced table cursor & column here */
++  Expr *pExpr,           /* An operand of a comparison operator */
++  int op                 /* The specific comparison operator */
++){
++  /* If this expression is a vector to the left or right of a 
++  ** inequality constraint (>, <, >= or <=), perform the processing 
++  ** on the first element of the vector.  */
++  assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE );
++  assert( TK_IS<TK_GE && TK_ISNULL<TK_GE && TK_IN<TK_GE );
++  assert( op<=TK_GE );
++  if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
++    pExpr = pExpr->x.pList->a[0].pExpr;
++  }
++
++  if( pExpr->op==TK_COLUMN ){
++    aiCurCol[0] = pExpr->iTable;
++    aiCurCol[1] = pExpr->iColumn;
++    return 1;
++  }
++  if( mPrereq==0 ) return 0;                 /* No table references */
++  if( (mPrereq&(mPrereq-1))!=0 ) return 0;   /* Refs more than one table */
++  return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
++}
++
++/*
+ ** The input to this routine is an WhereTerm structure with only the
+ ** "pExpr" field filled in.  The job of this routine is to analyze the
+ ** subexpression and populate all the other fields of the WhereTerm
+@@ -117452,6 +134206,8 @@
+   int op;                          /* Top-level operator.  pExpr->op */
+   Parse *pParse = pWInfo->pParse;  /* Parsing context */
+   sqlite3 *db = pParse->db;        /* Database connection */
++  unsigned char eOp2;              /* op2 value for LIKE/REGEXP/GLOB */
++  int nLeft;                       /* Number of elements on left side vector */
+ 
+   if( db->mallocFailed ){
+     return;
+@@ -117460,44 +134216,63 @@
+   pMaskSet = &pWInfo->sMaskSet;
+   pExpr = pTerm->pExpr;
+   assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
+-  prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
++  prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft);
+   op = pExpr->op;
+   if( op==TK_IN ){
+     assert( pExpr->pRight==0 );
++    if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
+     if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+-      pTerm->prereqRight = exprSelectTableUsage(pMaskSet, pExpr->x.pSelect);
++      pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect);
+     }else{
+-      pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->x.pList);
++      pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList);
+     }
+   }else if( op==TK_ISNULL ){
+     pTerm->prereqRight = 0;
+   }else{
+-    pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
++    pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight);
+   }
+-  prereqAll = exprTableUsage(pMaskSet, pExpr);
++  pMaskSet->bVarSelect = 0;
++  prereqAll = sqlite3WhereExprUsage(pMaskSet, pExpr);
++  if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT;
+   if( ExprHasProperty(pExpr, EP_FromJoin) ){
+-    Bitmask x = getMask(pMaskSet, pExpr->iRightJoinTable);
++    Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
+     prereqAll |= x;
+     extraRight = x-1;  /* ON clause terms may not be used with an index
+                        ** on left table of a LEFT JOIN.  Ticket #3015 */
++    if( (prereqAll>>1)>=x ){
++      sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
++      return;
++    }
+   }
+   pTerm->prereqAll = prereqAll;
+   pTerm->leftCursor = -1;
+   pTerm->iParent = -1;
+   pTerm->eOperator = 0;
+   if( allowedOp(op) ){
++    int aiCurCol[2];
+     Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
+     Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
+     u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
+-    if( pLeft->op==TK_COLUMN ){
+-      pTerm->leftCursor = pLeft->iTable;
+-      pTerm->u.leftColumn = pLeft->iColumn;
++
++    if( pTerm->iField>0 ){
++      assert( op==TK_IN );
++      assert( pLeft->op==TK_VECTOR );
++      pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
++    }
++
++    if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
++      pTerm->leftCursor = aiCurCol[0];
++      pTerm->u.leftColumn = aiCurCol[1];
+       pTerm->eOperator = operatorMask(op) & opMask;
+     }
+-    if( pRight && pRight->op==TK_COLUMN ){
++    if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
++    if( pRight 
++     && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
++    ){
+       WhereTerm *pNew;
+       Expr *pDup;
+       u16 eExtraOp = 0;        /* Extra bits for pNew->eOperator */
++      assert( pTerm->iField==0 );
+       if( pTerm->leftCursor>=0 ){
+         int idxNew;
+         pDup = sqlite3ExprDup(db, pExpr, 0);
+@@ -117509,12 +134284,11 @@
+         if( idxNew==0 ) return;
+         pNew = &pWC->a[idxNew];
+         markTermAsChild(pWC, idxNew, idxTerm);
++        if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
+         pTerm = &pWC->a[idxTerm];
+         pTerm->wtFlags |= TERM_COPIED;
+-        if( pExpr->op==TK_EQ
+-         && !ExprHasProperty(pExpr, EP_FromJoin)
+-         && OptimizationEnabled(db, SQLITE_Transitive)
+-        ){
++
++        if( termIsEquivalence(pParse, pDup) ){
+           pTerm->eOperator |= WO_EQUIV;
+           eExtraOp = WO_EQUIV;
+         }
+@@ -117523,9 +134297,8 @@
+         pNew = pTerm;
+       }
+       exprCommute(pParse, pDup);
+-      pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
+-      pNew->leftCursor = pLeft->iTable;
+-      pNew->u.leftColumn = pLeft->iColumn;
++      pNew->leftCursor = aiCurCol[0];
++      pNew->u.leftColumn = aiCurCol[1];
+       testcase( (prereqLeft | extraRight) != prereqLeft );
+       pNew->prereqRight = prereqLeft | extraRight;
+       pNew->prereqAll = prereqAll;
+@@ -117560,7 +134333,7 @@
+       int idxNew;
+       pNewExpr = sqlite3PExpr(pParse, ops[i], 
+                              sqlite3ExprDup(db, pExpr->pLeft, 0),
+-                             sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
++                             sqlite3ExprDup(db, pList->a[i].pExpr, 0));
+       transferJoinMarkings(pNewExpr, pExpr);
+       idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
+       testcase( idxNew==0 );
+@@ -117645,7 +134418,7 @@
+     pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
+     pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
+            sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
+-           pStr1, 0);
++           pStr1);
+     transferJoinMarkings(pNewExpr1, pExpr);
+     idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags);
+     testcase( idxNew1==0 );
+@@ -117653,7 +134426,7 @@
+     pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
+     pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
+            sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName),
+-           pStr2, 0);
++           pStr2);
+     transferJoinMarkings(pNewExpr2, pExpr);
+     idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags);
+     testcase( idxNew2==0 );
+@@ -117673,7 +134446,7 @@
+   ** virtual tables.  The native query optimizer does not attempt
+   ** to do anything with MATCH functions.
+   */
+-  if( isMatchOfColumn(pExpr) ){
++  if( pWC->op==TK_AND && isMatchOfColumn(pExpr, &eOp2) ){
+     int idxNew;
+     Expr *pRight, *pLeft;
+     WhereTerm *pNewTerm;
+@@ -117681,12 +134454,15 @@
+ 
+     pRight = pExpr->x.pList->a[0].pExpr;
+     pLeft = pExpr->x.pList->a[1].pExpr;
+-    prereqExpr = exprTableUsage(pMaskSet, pRight);
+-    prereqColumn = exprTableUsage(pMaskSet, pLeft);
++    prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight);
++    prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft);
+     if( (prereqExpr & prereqColumn)==0 ){
+       Expr *pNewExpr;
+       pNewExpr = sqlite3PExpr(pParse, TK_MATCH, 
+-                              0, sqlite3ExprDup(db, pRight, 0), 0);
++                              0, sqlite3ExprDup(db, pRight, 0));
++      if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
++        ExprSetProperty(pNewExpr, EP_FromJoin);
++      }
+       idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
+       testcase( idxNew==0 );
+       pNewTerm = &pWC->a[idxNew];
+@@ -117694,6 +134470,7 @@
+       pNewTerm->leftCursor = pLeft->iTable;
+       pNewTerm->u.leftColumn = pLeft->iColumn;
+       pNewTerm->eOperator = WO_MATCH;
++      pNewTerm->eMatchOp = eOp2;
+       markTermAsChild(pWC, idxNew, idxTerm);
+       pTerm = &pWC->a[idxTerm];
+       pTerm->wtFlags |= TERM_COPIED;
+@@ -117702,16 +134479,66 @@
+   }
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+ 
++  /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create
++  ** new terms for each component comparison - "a = ?" and "b = ?".  The
++  ** new terms completely replace the original vector comparison, which is
++  ** no longer used.
++  **
++  ** This is only required if at least one side of the comparison operation
++  ** is not a sub-select.  */
++  if( pWC->op==TK_AND 
++  && (pExpr->op==TK_EQ || pExpr->op==TK_IS)
++  && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
++  && sqlite3ExprVectorSize(pExpr->pRight)==nLeft
++  && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 
++    || (pExpr->pRight->flags & EP_xIsSelect)==0)
++  ){
++    int i;
++    for(i=0; i<nLeft; i++){
++      int idxNew;
++      Expr *pNew;
++      Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i);
++      Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i);
++
++      pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
++      transferJoinMarkings(pNew, pExpr);
++      idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
++      exprAnalyze(pSrc, pWC, idxNew);
++    }
++    pTerm = &pWC->a[idxTerm];
++    pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL;  /* Disable the original */
++    pTerm->eOperator = 0;
++  }
++
++  /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
++  ** a virtual term for each vector component. The expression object
++  ** used by each such virtual term is pExpr (the full vector IN(...) 
++  ** expression). The WhereTerm.iField variable identifies the index within
++  ** the vector on the LHS that the virtual term represents.
++  **
++  ** This only works if the RHS is a simple SELECT, not a compound
++  */
++  if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0
++   && pExpr->pLeft->op==TK_VECTOR
++   && pExpr->x.pSelect->pPrior==0
++  ){
++    int i;
++    for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
++      int idxNew;
++      idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
++      pWC->a[idxNew].iField = i+1;
++      exprAnalyze(pSrc, pWC, idxNew);
++      markTermAsChild(pWC, idxNew, idxTerm);
++    }
++  }
++
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+   /* When sqlite_stat3 histogram data is available an operator of the
+   ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
+   ** as "x>NULL" if x is not an INTEGER PRIMARY KEY.  So construct a
+   ** virtual term of that form.
+   **
+-  ** Note that the virtual term must be tagged with TERM_VNULL.  This
+-  ** TERM_VNULL tag will suppress the not-null check at the beginning
+-  ** of the loop.  Without the TERM_VNULL flag, the not-null check at
+-  ** the start of the loop will prevent any results from being returned.
++  ** Note that the virtual term must be tagged with TERM_VNULL.
+   */
+   if( pExpr->op==TK_NOTNULL
+    && pExpr->pLeft->op==TK_COLUMN
+@@ -117725,7 +134552,7 @@
+ 
+     pNewExpr = sqlite3PExpr(pParse, TK_GT,
+                             sqlite3ExprDup(db, pLeft, 0),
+-                            sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0);
++                            sqlite3ExprAlloc(db, TK_NULL, 0, 0));
+ 
+     idxNew = whereClauseInsert(pWC, pNewExpr,
+                               TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL);
+@@ -117746,9 +134573,563 @@
+   /* Prevent ON clause terms of a LEFT JOIN from being used to drive
+   ** an index for tables to the left of the join.
+   */
++  testcase( pTerm!=&pWC->a[idxTerm] );
++  pTerm = &pWC->a[idxTerm];
+   pTerm->prereqRight |= extraRight;
+ }
+ 
++/***************************************************************************
++** Routines with file scope above.  Interface to the rest of the where.c
++** subsystem follows.
++***************************************************************************/
++
++/*
++** This routine identifies subexpressions in the WHERE clause where
++** each subexpression is separated by the AND operator or some other
++** operator specified in the op parameter.  The WhereClause structure
++** is filled with pointers to subexpressions.  For example:
++**
++**    WHERE  a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22)
++**           \________/     \_______________/     \________________/
++**            slot[0]            slot[1]               slot[2]
++**
++** The original WHERE clause in pExpr is unaltered.  All this routine
++** does is make slot[] entries point to substructure within pExpr.
++**
++** In the previous sentence and in the diagram, "slot[]" refers to
++** the WhereClause.a[] array.  The slot[] array grows as needed to contain
++** all terms of the WHERE clause.
++*/
++SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
++  Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
++  pWC->op = op;
++  if( pE2==0 ) return;
++  if( pE2->op!=op ){
++    whereClauseInsert(pWC, pExpr, 0);
++  }else{
++    sqlite3WhereSplit(pWC, pE2->pLeft, op);
++    sqlite3WhereSplit(pWC, pE2->pRight, op);
++  }
++}
++
++/*
++** Initialize a preallocated WhereClause structure.
++*/
++SQLITE_PRIVATE void sqlite3WhereClauseInit(
++  WhereClause *pWC,        /* The WhereClause to be initialized */
++  WhereInfo *pWInfo        /* The WHERE processing context */
++){
++  pWC->pWInfo = pWInfo;
++  pWC->pOuter = 0;
++  pWC->nTerm = 0;
++  pWC->nSlot = ArraySize(pWC->aStatic);
++  pWC->a = pWC->aStatic;
++}
++
++/*
++** Deallocate a WhereClause structure.  The WhereClause structure
++** itself is not freed.  This routine is the inverse of
++** sqlite3WhereClauseInit().
++*/
++SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){
++  int i;
++  WhereTerm *a;
++  sqlite3 *db = pWC->pWInfo->pParse->db;
++  for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
++    if( a->wtFlags & TERM_DYNAMIC ){
++      sqlite3ExprDelete(db, a->pExpr);
++    }
++    if( a->wtFlags & TERM_ORINFO ){
++      whereOrInfoDelete(db, a->u.pOrInfo);
++    }else if( a->wtFlags & TERM_ANDINFO ){
++      whereAndInfoDelete(db, a->u.pAndInfo);
++    }
++  }
++  if( pWC->a!=pWC->aStatic ){
++    sqlite3DbFree(db, pWC->a);
++  }
++}
++
++
++/*
++** These routines walk (recursively) an expression tree and generate
++** a bitmask indicating which tables are used in that expression
++** tree.
++*/
++SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
++  Bitmask mask;
++  if( p==0 ) return 0;
++  if( p->op==TK_COLUMN ){
++    return sqlite3WhereGetMask(pMaskSet, p->iTable);
++  }
++  mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
++  assert( !ExprHasProperty(p, EP_TokenOnly) );
++  if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
++  if( p->pRight ){
++    mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight);
++    assert( p->x.pList==0 );
++  }else if( ExprHasProperty(p, EP_xIsSelect) ){
++    if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1;
++    mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
++  }else if( p->x.pList ){
++    mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
++  }
++  return mask;
++}
++SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){
++  int i;
++  Bitmask mask = 0;
++  if( pList ){
++    for(i=0; i<pList->nExpr; i++){
++      mask |= sqlite3WhereExprUsage(pMaskSet, pList->a[i].pExpr);
++    }
++  }
++  return mask;
++}
++
++
++/*
++** Call exprAnalyze on all terms in a WHERE clause.  
++**
++** Note that exprAnalyze() might add new virtual terms onto the
++** end of the WHERE clause.  We do not want to analyze these new
++** virtual terms, so start analyzing at the end and work forward
++** so that the added virtual terms are never processed.
++*/
++SQLITE_PRIVATE void sqlite3WhereExprAnalyze(
++  SrcList *pTabList,       /* the FROM clause */
++  WhereClause *pWC         /* the WHERE clause to be analyzed */
++){
++  int i;
++  for(i=pWC->nTerm-1; i>=0; i--){
++    exprAnalyze(pTabList, pWC, i);
++  }
++}
++
++/*
++** For table-valued-functions, transform the function arguments into
++** new WHERE clause terms.  
++**
++** Each function argument translates into an equality constraint against
++** a HIDDEN column in the table.
++*/
++SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
++  Parse *pParse,                    /* Parsing context */
++  struct SrcList_item *pItem,       /* The FROM clause term to process */
++  WhereClause *pWC                  /* Xfer function arguments to here */
++){
++  Table *pTab;
++  int j, k;
++  ExprList *pArgs;
++  Expr *pColRef;
++  Expr *pTerm;
++  if( pItem->fg.isTabFunc==0 ) return;
++  pTab = pItem->pTab;
++  assert( pTab!=0 );
++  pArgs = pItem->u1.pFuncArg;
++  if( pArgs==0 ) return;
++  for(j=k=0; j<pArgs->nExpr; j++){
++    while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
++    if( k>=pTab->nCol ){
++      sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
++                      pTab->zName, j);
++      return;
++    }
++    pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
++    if( pColRef==0 ) return;
++    pColRef->iTable = pItem->iCursor;
++    pColRef->iColumn = k++;
++    pColRef->pTab = pTab;
++    pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
++                         sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
++    whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
++  }
++}
++
++/************** End of whereexpr.c *******************************************/
++/************** Begin file where.c *******************************************/
++/*
++** 2001 September 15
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This module contains C code that generates VDBE code used to process
++** the WHERE clause of SQL statements.  This module is responsible for
++** generating the code that loops through a table looking for applicable
++** rows.  Indices are selected and used to speed the search when doing
++** so is applicable.  Because this module is responsible for selecting
++** indices, you might also think of this module as the "query optimizer".
++*/
++/* #include "sqliteInt.h" */
++/* #include "whereInt.h" */
++
++/* Forward declaration of methods */
++static int whereLoopResize(sqlite3*, WhereLoop*, int);
++
++/* Test variable that can be set to enable WHERE tracing */
++#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
++/***/ int sqlite3WhereTrace = 0;
 +#endif
-+#if SQLITE_OMIT_WAL
-+  "OMIT_WAL",
++
++
++/*
++** Return the estimated number of output rows from a WHERE clause
++*/
++SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
++  return pWInfo->nRowOut;
++}
++
++/*
++** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this
++** WHERE clause returns outputs for DISTINCT processing.
++*/
++SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo *pWInfo){
++  return pWInfo->eDistinct;
++}
++
++/*
++** Return TRUE if the WHERE clause returns rows in ORDER BY order.
++** Return FALSE if the output needs to be sorted.
++*/
++SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){
++  return pWInfo->nOBSat;
++}
++
++/*
++** Return TRUE if the innermost loop of the WHERE clause implementation
++** returns rows in ORDER BY order for complete run of the inner loop.
++**
++** Across multiple iterations of outer loops, the output rows need not be
++** sorted.  As long as rows are sorted for just the innermost loop, this
++** routine can return TRUE.
++*/
++SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo *pWInfo){
++  return pWInfo->bOrderedInnerLoop;
++}
++
++/*
++** Return the VDBE address or label to jump to in order to continue
++** immediately with the next row of a WHERE clause.
++*/
++SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo *pWInfo){
++  assert( pWInfo->iContinue!=0 );
++  return pWInfo->iContinue;
++}
++
++/*
++** Return the VDBE address or label to jump to in order to break
++** out of a WHERE loop.
++*/
++SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){
++  return pWInfo->iBreak;
++}
++
++/*
++** Return ONEPASS_OFF (0) if an UPDATE or DELETE statement is unable to
++** operate directly on the rowis returned by a WHERE clause.  Return
++** ONEPASS_SINGLE (1) if the statement can operation directly because only
++** a single row is to be changed.  Return ONEPASS_MULTI (2) if the one-pass
++** optimization can be used on multiple 
++**
++** If the ONEPASS optimization is used (if this routine returns true)
++** then also write the indices of open cursors used by ONEPASS
++** into aiCur[0] and aiCur[1].  iaCur[0] gets the cursor of the data
++** table and iaCur[1] gets the cursor used by an auxiliary index.
++** Either value may be -1, indicating that cursor is not used.
++** Any cursors returned will have been opened for writing.
++**
++** aiCur[0] and aiCur[1] both get -1 if the where-clause logic is
++** unable to use the ONEPASS optimization.
++*/
++SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){
++  memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2);
++#ifdef WHERETRACE_ENABLED
++  if( sqlite3WhereTrace && pWInfo->eOnePass!=ONEPASS_OFF ){
++    sqlite3DebugPrintf("%s cursors: %d %d\n",
++         pWInfo->eOnePass==ONEPASS_SINGLE ? "ONEPASS_SINGLE" : "ONEPASS_MULTI",
++         aiCur[0], aiCur[1]);
++  }
 +#endif
-+#if SQLITE_OMIT_WSD
-+  "OMIT_WSD",
++  return pWInfo->eOnePass;
++}
++
++/*
++** Move the content of pSrc into pDest
++*/
++static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){
++  pDest->n = pSrc->n;
++  memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0]));
++}
++
++/*
++** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet.
++**
++** The new entry might overwrite an existing entry, or it might be
++** appended, or it might be discarded.  Do whatever is the right thing
++** so that pSet keeps the N_OR_COST best entries seen so far.
++*/
++static int whereOrInsert(
++  WhereOrSet *pSet,      /* The WhereOrSet to be updated */
++  Bitmask prereq,        /* Prerequisites of the new entry */
++  LogEst rRun,           /* Run-cost of the new entry */
++  LogEst nOut            /* Number of outputs for the new entry */
++){
++  u16 i;
++  WhereOrCost *p;
++  for(i=pSet->n, p=pSet->a; i>0; i--, p++){
++    if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){
++      goto whereOrInsert_done;
++    }
++    if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){
++      return 0;
++    }
++  }
++  if( pSet->n<N_OR_COST ){
++    p = &pSet->a[pSet->n++];
++    p->nOut = nOut;
++  }else{
++    p = pSet->a;
++    for(i=1; i<pSet->n; i++){
++      if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i;
++    }
++    if( p->rRun<=rRun ) return 0;
++  }
++whereOrInsert_done:
++  p->prereq = prereq;
++  p->rRun = rRun;
++  if( p->nOut>nOut ) p->nOut = nOut;
++  return 1;
++}
++
++/*
++** Return the bitmask for the given cursor number.  Return 0 if
++** iCursor is not in the set.
++*/
++SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){
++  int i;
++  assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 );
++  for(i=0; i<pMaskSet->n; i++){
++    if( pMaskSet->ix[i]==iCursor ){
++      return MASKBIT(i);
++    }
++  }
++  return 0;
++}
++
++/*
++** Create a new mask for cursor iCursor.
++**
++** There is one cursor per table in the FROM clause.  The number of
++** tables in the FROM clause is limited by a test early in the
++** sqlite3WhereBegin() routine.  So we know that the pMaskSet->ix[]
++** array will never overflow.
++*/
++static void createMask(WhereMaskSet *pMaskSet, int iCursor){
++  assert( pMaskSet->n < ArraySize(pMaskSet->ix) );
++  pMaskSet->ix[pMaskSet->n++] = iCursor;
++}
++
++/*
++** Advance to the next WhereTerm that matches according to the criteria
++** established when the pScan object was initialized by whereScanInit().
++** Return NULL if there are no more matching WhereTerms.
++*/
++static WhereTerm *whereScanNext(WhereScan *pScan){
++  int iCur;            /* The cursor on the LHS of the term */
++  i16 iColumn;         /* The column on the LHS of the term.  -1 for IPK */
++  Expr *pX;            /* An expression being tested */
++  WhereClause *pWC;    /* Shorthand for pScan->pWC */
++  WhereTerm *pTerm;    /* The term being tested */
++  int k = pScan->k;    /* Where to start scanning */
++
++  assert( pScan->iEquiv<=pScan->nEquiv );
++  pWC = pScan->pWC;
++  while(1){
++    iColumn = pScan->aiColumn[pScan->iEquiv-1];
++    iCur = pScan->aiCur[pScan->iEquiv-1];
++    assert( pWC!=0 );
++    do{
++      for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
++        if( pTerm->leftCursor==iCur
++         && pTerm->u.leftColumn==iColumn
++         && (iColumn!=XN_EXPR
++             || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
++                                       pScan->pIdxExpr,iCur)==0)
++         && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
++        ){
++          if( (pTerm->eOperator & WO_EQUIV)!=0
++           && pScan->nEquiv<ArraySize(pScan->aiCur)
++           && (pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight))->op==TK_COLUMN
++          ){
++            int j;
++            for(j=0; j<pScan->nEquiv; j++){
++              if( pScan->aiCur[j]==pX->iTable
++               && pScan->aiColumn[j]==pX->iColumn ){
++                  break;
++              }
++            }
++            if( j==pScan->nEquiv ){
++              pScan->aiCur[j] = pX->iTable;
++              pScan->aiColumn[j] = pX->iColumn;
++              pScan->nEquiv++;
++            }
++          }
++          if( (pTerm->eOperator & pScan->opMask)!=0 ){
++            /* Verify the affinity and collating sequence match */
++            if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){
++              CollSeq *pColl;
++              Parse *pParse = pWC->pWInfo->pParse;
++              pX = pTerm->pExpr;
++              if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){
++                continue;
++              }
++              assert(pX->pLeft);
++              pColl = sqlite3BinaryCompareCollSeq(pParse,
++                                                  pX->pLeft, pX->pRight);
++              if( pColl==0 ) pColl = pParse->db->pDfltColl;
++              if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
++                continue;
++              }
++            }
++            if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0
++             && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
++             && pX->iTable==pScan->aiCur[0]
++             && pX->iColumn==pScan->aiColumn[0]
++            ){
++              testcase( pTerm->eOperator & WO_IS );
++              continue;
++            }
++            pScan->pWC = pWC;
++            pScan->k = k+1;
++            return pTerm;
++          }
++        }
++      }
++      pWC = pWC->pOuter;
++      k = 0;
++    }while( pWC!=0 );
++    if( pScan->iEquiv>=pScan->nEquiv ) break;
++    pWC = pScan->pOrigWC;
++    k = 0;
++    pScan->iEquiv++;
++  }
++  return 0;
++}
++
++/*
++** Initialize a WHERE clause scanner object.  Return a pointer to the
++** first match.  Return NULL if there are no matches.
++**
++** The scanner will be searching the WHERE clause pWC.  It will look
++** for terms of the form "X <op> <expr>" where X is column iColumn of table
++** iCur.   Or if pIdx!=0 then X is column iColumn of index pIdx.  pIdx
++** must be one of the indexes of table iCur.
++**
++** The <op> must be one of the operators described by opMask.
++**
++** If the search is for X and the WHERE clause contains terms of the
++** form X=Y then this routine might also return terms of the form
++** "Y <op> <expr>".  The number of levels of transitivity is limited,
++** but is enough to handle most commonly occurring SQL statements.
++**
++** If X is not the INTEGER PRIMARY KEY then X must be compatible with
++** index pIdx.
++*/
++static WhereTerm *whereScanInit(
++  WhereScan *pScan,       /* The WhereScan object being initialized */
++  WhereClause *pWC,       /* The WHERE clause to be scanned */
++  int iCur,               /* Cursor to scan for */
++  int iColumn,            /* Column to scan for */
++  u32 opMask,             /* Operator(s) to scan for */
++  Index *pIdx             /* Must be compatible with this index */
++){
++  pScan->pOrigWC = pWC;
++  pScan->pWC = pWC;
++  pScan->pIdxExpr = 0;
++  pScan->idxaff = 0;
++  pScan->zCollName = 0;
++  if( pIdx ){
++    int j = iColumn;
++    iColumn = pIdx->aiColumn[j];
++    if( iColumn==XN_EXPR ){
++      pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
++      pScan->zCollName = pIdx->azColl[j];
++    }else if( iColumn==pIdx->pTable->iPKey ){
++      iColumn = XN_ROWID;
++    }else if( iColumn>=0 ){
++      pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
++      pScan->zCollName = pIdx->azColl[j];
++    }
++  }else if( iColumn==XN_EXPR ){
++    return 0;
++  }
++  pScan->opMask = opMask;
++  pScan->k = 0;
++  pScan->aiCur[0] = iCur;
++  pScan->aiColumn[0] = iColumn;
++  pScan->nEquiv = 1;
++  pScan->iEquiv = 1;
++  return whereScanNext(pScan);
++}
++
++/*
++** Search for a term in the WHERE clause that is of the form "X <op> <expr>"
++** where X is a reference to the iColumn of table iCur or of index pIdx
++** if pIdx!=0 and <op> is one of the WO_xx operator codes specified by
++** the op parameter.  Return a pointer to the term.  Return 0 if not found.
++**
++** If pIdx!=0 then it must be one of the indexes of table iCur.  
++** Search for terms matching the iColumn-th column of pIdx
++** rather than the iColumn-th column of table iCur.
++**
++** The term returned might by Y=<expr> if there is another constraint in
++** the WHERE clause that specifies that X=Y.  Any such constraints will be
++** identified by the WO_EQUIV bit in the pTerm->eOperator field.  The
++** aiCur[]/iaColumn[] arrays hold X and all its equivalents. There are 11
++** slots in aiCur[]/aiColumn[] so that means we can look for X plus up to 10
++** other equivalent values.  Hence a search for X will return <expr> if X=A1
++** and A1=A2 and A2=A3 and ... and A9=A10 and A10=<expr>.
++**
++** If there are multiple terms in the WHERE clause of the form "X <op> <expr>"
++** then try for the one with no dependencies on <expr> - in other words where
++** <expr> is a constant expression of some kind.  Only return entries of
++** the form "X <op> Y" where Y is a column in another table if no terms of
++** the form "X <op> <const-expr>" exist.   If no terms with a constant RHS
++** exist, try to return a term that does not use WO_EQUIV.
++*/
++SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm(
++  WhereClause *pWC,     /* The WHERE clause to be searched */
++  int iCur,             /* Cursor number of LHS */
++  int iColumn,          /* Column number of LHS */
++  Bitmask notReady,     /* RHS must not overlap with this mask */
++  u32 op,               /* Mask of WO_xx values describing operator */
++  Index *pIdx           /* Must be compatible with this index, if not NULL */
++){
++  WhereTerm *pResult = 0;
++  WhereTerm *p;
++  WhereScan scan;
++
++  p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx);
++  op &= WO_EQ|WO_IS;
++  while( p ){
++    if( (p->prereqRight & notReady)==0 ){
++      if( p->prereqRight==0 && (p->eOperator&op)!=0 ){
++        testcase( p->eOperator & WO_IS );
++        return p;
++      }
++      if( pResult==0 ) pResult = p;
++    }
++    p = whereScanNext(&scan);
++  }
++  return pResult;
++}
++
+ /*
+ ** This function searches pList for an entry that matches the iCol-th column
+ ** of index pIdx.
+@@ -117783,11 +135164,30 @@
+ }
+ 
+ /*
++** Return TRUE if the iCol-th column of index pIdx is NOT NULL
++*/
++static int indexColumnNotNull(Index *pIdx, int iCol){
++  int j;
++  assert( pIdx!=0 );
++  assert( iCol>=0 && iCol<pIdx->nColumn );
++  j = pIdx->aiColumn[iCol];
++  if( j>=0 ){
++    return pIdx->pTable->aCol[j].notNull;
++  }else if( j==(-1) ){
++    return 1;
++  }else{
++    assert( j==(-2) );
++    return 0;  /* Assume an indexed expression can always yield a NULL */
++
++  }
++}
++
++/*
+ ** Return true if the DISTINCT expression-list passed as the third argument
+ ** is redundant.
+ **
+-** A DISTINCT list is redundant if the database contains some subset of
+-** columns that are unique and non-null.
++** A DISTINCT list is redundant if any subset of the columns in the
++** DISTINCT list are collectively unique and individually non-null.
+ */
+ static int isDistinctRedundant(
+   Parse *pParse,            /* Parsing context */
+@@ -117832,12 +135232,9 @@
+   for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+     if( !IsUniqueIndex(pIdx) ) continue;
+     for(i=0; i<pIdx->nKeyCol; i++){
+-      i16 iCol = pIdx->aiColumn[i];
+-      if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){
+-        int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i);
+-        if( iIdxCol<0 || pTab->aCol[iCol].notNull==0 ){
+-          break;
+-        }
++      if( 0==sqlite3WhereFindTerm(pWC, iBase, i, ~(Bitmask)0, WO_EQ, pIdx) ){
++        if( findIndexCol(pParse, pDistinct, iBase, pIdx, i)<0 ) break;
++        if( indexColumnNotNull(pIdx, i)==0 ) break;
+       }
+     }
+     if( i==pIdx->nKeyCol ){
+@@ -117858,6 +135255,51 @@
+ }
+ 
+ /*
++** Convert OP_Column opcodes to OP_Copy in previously generated code.
++**
++** This routine runs over generated VDBE code and translates OP_Column
++** opcodes into OP_Copy when the table is being accessed via co-routine 
++** instead of via table lookup.
++**
++** If the bIncrRowid parameter is 0, then any OP_Rowid instructions on
++** cursor iTabCur are transformed into OP_Null. Or, if bIncrRowid is non-zero,
++** then each OP_Rowid is transformed into an instruction to increment the
++** value stored in its output register.
++*/
++static void translateColumnToCopy(
++  Parse *pParse,      /* Parsing context */
++  int iStart,         /* Translate from this opcode to the end */
++  int iTabCur,        /* OP_Column/OP_Rowid references to this table */
++  int iRegister,      /* The first column is in this register */
++  int bIncrRowid      /* If non-zero, transform OP_rowid to OP_AddImm(1) */
++){
++  Vdbe *v = pParse->pVdbe;
++  VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
++  int iEnd = sqlite3VdbeCurrentAddr(v);
++  if( pParse->db->mallocFailed ) return;
++  for(; iStart<iEnd; iStart++, pOp++){
++    if( pOp->p1!=iTabCur ) continue;
++    if( pOp->opcode==OP_Column ){
++      pOp->opcode = OP_Copy;
++      pOp->p1 = pOp->p2 + iRegister;
++      pOp->p2 = pOp->p3;
++      pOp->p3 = 0;
++    }else if( pOp->opcode==OP_Rowid ){
++      if( bIncrRowid ){
++        /* Increment the value stored in the P2 operand of the OP_Rowid. */
++        pOp->opcode = OP_AddImm;
++        pOp->p1 = pOp->p2;
++        pOp->p2 = 1;
++      }else{
++        pOp->opcode = OP_Null;
++        pOp->p1 = 0;
++        pOp->p3 = 0;
++      }
++    }
++  }
++}
++
++/*
+ ** Two routines for printing the content of an sqlite3_index_info
+ ** structure.  Used for testing and debugging only.  If neither
+ ** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
+@@ -117915,11 +135357,21 @@
+ ){
+   char aff;
+   if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
+-  if( (pTerm->eOperator & WO_EQ)==0 ) return 0;
++  if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
++  if( (pSrc->fg.jointype & JT_LEFT) 
++   && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
++   && (pTerm->eOperator & WO_IS)
++  ){
++    /* Cannot use an IS term from the WHERE clause as an index driver for
++    ** the RHS of a LEFT JOIN. Such a term can only be used if it is from
++    ** the ON clause.  */
++    return 0;
++  }
+   if( (pTerm->prereqRight & notReady)!=0 ) return 0;
+   if( pTerm->u.leftColumn<0 ) return 0;
+   aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
+   if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
++  testcase( pTerm->pExpr->op==TK_IS );
+   return 1;
+ }
+ #endif
+@@ -117958,12 +135410,15 @@
+   u8 sentWarning = 0;         /* True if a warnning has been issued */
+   Expr *pPartial = 0;         /* Partial Index Expression */
+   int iContinue = 0;          /* Jump here to skip excluded rows */
++  struct SrcList_item *pTabItem;  /* FROM clause term being indexed */
++  int addrCounter = 0;        /* Address where integer counter is initialized */
++  int regBase;                /* Array of registers where record is assembled */
+ 
+   /* Generate code to skip over the creation and initialization of the
+   ** transient index on 2nd and subsequent iterations of the loop. */
+   v = pParse->pVdbe;
+   assert( v!=0 );
+-  addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v);
++  addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ 
+   /* Count the number of columns that will be added to the index
+   ** and used to match WHERE clause constraints */
+@@ -118047,7 +135502,7 @@
+         idxCols |= cMask;
+         pIdx->aiColumn[n] = pTerm->u.leftColumn;
+         pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
+-        pIdx->azColl[n] = pColl ? pColl->zName : "BINARY";
++        pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY;
+         n++;
+       }
+     }
+@@ -118059,20 +135514,20 @@
+   for(i=0; i<mxBitCol; i++){
+     if( extraCols & MASKBIT(i) ){
+       pIdx->aiColumn[n] = i;
+-      pIdx->azColl[n] = "BINARY";
++      pIdx->azColl[n] = sqlite3StrBINARY;
+       n++;
+     }
+   }
+   if( pSrc->colUsed & MASKBIT(BMS-1) ){
+     for(i=BMS-1; i<pTable->nCol; i++){
+       pIdx->aiColumn[n] = i;
+-      pIdx->azColl[n] = "BINARY";
++      pIdx->azColl[n] = sqlite3StrBINARY;
+       n++;
+     }
+   }
+   assert( n==nKeyCol );
+-  pIdx->aiColumn[n] = -1;
+-  pIdx->azColl[n] = "BINARY";
++  pIdx->aiColumn[n] = XN_ROWID;
++  pIdx->azColl[n] = sqlite3StrBINARY;
+ 
+   /* Create the automatic index */
+   assert( pLevel->iIdxCur>=0 );
+@@ -118083,18 +135538,39 @@
+ 
+   /* Fill the automatic index with content */
+   sqlite3ExprCachePush(pParse);
+-  addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
++  pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
++  if( pTabItem->fg.viaCoroutine ){
++    int regYield = pTabItem->regReturn;
++    addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
++    sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
++    addrTop =  sqlite3VdbeAddOp1(v, OP_Yield, regYield);
++    VdbeCoverage(v);
++    VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
++  }else{
++    addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
++  }
+   if( pPartial ){
+     iContinue = sqlite3VdbeMakeLabel(v);
+     sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
+     pLoop->wsFlags |= WHERE_PARTIALIDX;
+   }
+   regRecord = sqlite3GetTempReg(pParse);
+-  sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
++  regBase = sqlite3GenerateIndexKey(
++      pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0
++  );
+   sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
+   sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+   if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
+-  sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
++  if( pTabItem->fg.viaCoroutine ){
++    sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
++    testcase( pParse->db->mallocFailed );
++    translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
++                          pTabItem->regResult, 1);
++    sqlite3VdbeGoto(v, addrTop);
++    pTabItem->fg.viaCoroutine = 0;
++  }else{
++    sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
++  }
+   sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
+   sqlite3VdbeJumpHere(v, addrTop);
+   sqlite3ReleaseTempReg(pParse, regRecord);
+@@ -118117,8 +135593,10 @@
+ static sqlite3_index_info *allocateIndexInfo(
+   Parse *pParse,
+   WhereClause *pWC,
++  Bitmask mUnusable,              /* Ignore terms with these prereqs */
+   struct SrcList_item *pSrc,
+-  ExprList *pOrderBy
++  ExprList *pOrderBy,
++  u16 *pmNoOmit                   /* Mask of terms not to omit */
+ ){
+   int i, j;
+   int nTerm;
+@@ -118128,17 +135606,21 @@
+   WhereTerm *pTerm;
+   int nOrderBy;
+   sqlite3_index_info *pIdxInfo;
++  u16 mNoOmit = 0;
+ 
+   /* Count the number of possible WHERE clause constraints referring
+   ** to this virtual table */
+   for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
+     if( pTerm->leftCursor != pSrc->iCursor ) continue;
++    if( pTerm->prereqRight & mUnusable ) continue;
+     assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
+     testcase( pTerm->eOperator & WO_IN );
+     testcase( pTerm->eOperator & WO_ISNULL );
++    testcase( pTerm->eOperator & WO_IS );
+     testcase( pTerm->eOperator & WO_ALL );
+-    if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue;
++    if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
+     if( pTerm->wtFlags & TERM_VNULL ) continue;
++    assert( pTerm->u.leftColumn>=(-1) );
+     nTerm++;
+   }
+ 
+@@ -118186,16 +135668,22 @@
+   for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
+     u8 op;
+     if( pTerm->leftCursor != pSrc->iCursor ) continue;
++    if( pTerm->prereqRight & mUnusable ) continue;
+     assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
+     testcase( pTerm->eOperator & WO_IN );
++    testcase( pTerm->eOperator & WO_IS );
+     testcase( pTerm->eOperator & WO_ISNULL );
+     testcase( pTerm->eOperator & WO_ALL );
+-    if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue;
++    if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
+     if( pTerm->wtFlags & TERM_VNULL ) continue;
++    assert( pTerm->u.leftColumn>=(-1) );
+     pIdxCons[j].iColumn = pTerm->u.leftColumn;
+     pIdxCons[j].iTermOffset = i;
+     op = (u8)pTerm->eOperator & WO_ALL;
+     if( op==WO_IN ) op = WO_EQ;
++    if( op==WO_MATCH ){
++      op = pTerm->eMatchOp;
++    }
+     pIdxCons[j].op = op;
+     /* The direct assignment in the previous line is possible only because
+     ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical.  The
+@@ -118207,6 +135695,15 @@
+     assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
+     assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
+     assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
++
++    if( op & (WO_LT|WO_LE|WO_GT|WO_GE)
++     && sqlite3ExprIsVector(pTerm->pExpr->pRight) 
++    ){
++      if( i<16 ) mNoOmit |= (1 << i);
++      if( op==WO_LT ) pIdxCons[j].op = WO_LE;
++      if( op==WO_GT ) pIdxCons[j].op = WO_GE;
++    }
++
+     j++;
+   }
+   for(i=0; i<nOrderBy; i++){
+@@ -118215,6 +135712,7 @@
+     pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder;
+   }
+ 
++  *pmNoOmit = mNoOmit;
+   return pIdxInfo;
+ }
+ 
+@@ -118234,7 +135732,6 @@
+ */
+ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
+   sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
+-  int i;
+   int rc;
+ 
+   TRACE_IDX_INPUTS(p);
+@@ -118243,7 +135740,7 @@
+ 
+   if( rc!=SQLITE_OK ){
+     if( rc==SQLITE_NOMEM ){
+-      pParse->db->mallocFailed = 1;
++      sqlite3OomFault(pParse->db);
+     }else if( !pVtab->zErrMsg ){
+       sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
+     }else{
+@@ -118253,12 +135750,16 @@
+   sqlite3_free(pVtab->zErrMsg);
+   pVtab->zErrMsg = 0;
+ 
++#if 0
++  /* This error is now caught by the caller.
++  ** Search for "xBestIndex malfunction" below */
+   for(i=0; i<p->nConstraint; i++){
+     if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){
+       sqlite3ErrorMsg(pParse, 
+           "table %s: xBestIndex returned an invalid plan", pTab->zName);
+     }
+   }
 +#endif
-+#if SQLITE_OMIT_XFER_OPT
-+  "OMIT_XFER_OPT",
+ 
+   return pParse->nErr;
+ }
+@@ -118450,7 +135951,7 @@
+       iGap = iGap/3;
+     }
+     aStat[0] = iLower + iGap;
+-    aStat[1] = pIdx->aAvgEq[iCol];
++    aStat[1] = pIdx->aAvgEq[nField-1];
+   }
+ 
+   /* Restore the pRec->nField value before returning.  */
+@@ -118482,6 +135983,21 @@
+   return nRet;
+ }
+ 
++
++#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
++/*
++** Return the affinity for a single column of an index.
++*/
++SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){
++  assert( iCol>=0 && iCol<pIdx->nColumn );
++  if( !pIdx->zColAff ){
++    if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB;
++  }
++  return pIdx->zColAff[iCol];
++}
 +#endif
-+#if SQLITE_PERFORMANCE_TRACE
-+  "PERFORMANCE_TRACE",
++
++
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ /* 
+ ** This function is called to estimate the number of rows visited by a
+@@ -118531,8 +136047,7 @@
+   int nLower = -1;
+   int nUpper = p->nSample+1;
+   int rc = SQLITE_OK;
+-  int iCol = p->aiColumn[nEq];
+-  u8 aff = iCol>=0 ? p->pTable->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
++  u8 aff = sqlite3IndexColumnAffinity(db, p, nEq);
+   CollSeq *pColl;
+   
+   sqlite3_value *p1 = 0;          /* Value extracted from pLower */
+@@ -118650,7 +136165,8 @@
+     if( nEq==pBuilder->nRecValid ){
+       UnpackedRecord *pRec = pBuilder->pRec;
+       tRowcnt a[2];
+-      u8 aff;
++      int nBtm = pLoop->u.btree.nBtm;
++      int nTop = pLoop->u.btree.nTop;
+ 
+       /* Variable iLower will be set to the estimate of the number of rows in 
+       ** the index that are less than the lower bound of the range query. The
+@@ -118680,11 +136196,6 @@
+         testcase( pRec->nField!=pBuilder->nRecValid );
+         pRec->nField = pBuilder->nRecValid;
+       }
+-      if( nEq==p->nKeyCol ){
+-        aff = SQLITE_AFF_INTEGER;
+-      }else{
+-        aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
+-      }
+       /* Determine iLower and iUpper using ($P) only. */
+       if( nEq==0 ){
+         iLower = 0;
+@@ -118703,17 +136214,20 @@
+       if( p->aSortOrder[nEq] ){
+         /* The roles of pLower and pUpper are swapped for a DESC index */
+         SWAP(WhereTerm*, pLower, pUpper);
++        SWAP(int, nBtm, nTop);
+       }
+ 
+       /* If possible, improve on the iLower estimate using ($P:$L). */
+       if( pLower ){
+-        int bOk;                    /* True if value is extracted from pExpr */
++        int n;                    /* Values extracted from pExpr */
+         Expr *pExpr = pLower->pExpr->pRight;
+-        rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
+-        if( rc==SQLITE_OK && bOk ){
++        rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nBtm, nEq, &n);
++        if( rc==SQLITE_OK && n ){
+           tRowcnt iNew;
++          u16 mask = WO_GT|WO_LE;
++          if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT);
+           iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a);
+-          iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
++          iNew = a[0] + ((pLower->eOperator & mask) ? a[1] : 0);
+           if( iNew>iLower ) iLower = iNew;
+           nOut--;
+           pLower = 0;
+@@ -118722,13 +136236,15 @@
+ 
+       /* If possible, improve on the iUpper estimate using ($P:$U). */
+       if( pUpper ){
+-        int bOk;                    /* True if value is extracted from pExpr */
++        int n;                    /* Values extracted from pExpr */
+         Expr *pExpr = pUpper->pExpr->pRight;
+-        rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
+-        if( rc==SQLITE_OK && bOk ){
++        rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nTop, nEq, &n);
++        if( rc==SQLITE_OK && n ){
+           tRowcnt iNew;
++          u16 mask = WO_GT|WO_LE;
++          if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT);
+           iUprIdx = whereKeyStats(pParse, p, pRec, 1, a);
+-          iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
++          iNew = a[0] + ((pUpper->eOperator & mask) ? a[1] : 0);
+           if( iNew<iUpper ) iUpper = iNew;
+           nOut--;
+           pUpper = 0;
+@@ -118818,7 +136334,6 @@
+   Index *p = pBuilder->pNew->u.btree.pIndex;
+   int nEq = pBuilder->pNew->u.btree.nEq;
+   UnpackedRecord *pRec = pBuilder->pRec;
+-  u8 aff;                   /* Column affinity */
+   int rc;                   /* Subfunction return code */
+   tRowcnt a[2];             /* Statistics */
+   int bOk;
+@@ -118842,15 +136357,15 @@
+     return SQLITE_OK;
+   }
+ 
+-  aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity;
+-  rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk);
++  rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, 1, nEq-1, &bOk);
+   pBuilder->pRec = pRec;
+   if( rc!=SQLITE_OK ) return rc;
+   if( bOk==0 ) return SQLITE_NOTFOUND;
+   pBuilder->nRecValid = nEq;
+ 
+   whereKeyStats(pParse, p, pRec, 0, a);
+-  WHERETRACE(0x10,("equality scan regions: %d\n", (int)a[1]));
++  WHERETRACE(0x10,("equality scan regions %s(%d): %d\n",
++                   p->zName, nEq-1, (int)a[1]));
+   *pnRow = a[1];
+   
+   return rc;
+@@ -118906,1484 +136421,6 @@
+ }
+ #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
+ 
+-/*
+-** Disable a term in the WHERE clause.  Except, do not disable the term
+-** if it controls a LEFT OUTER JOIN and it did not originate in the ON
+-** or USING clause of that join.
+-**
+-** Consider the term t2.z='ok' in the following queries:
+-**
+-**   (1)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
+-**   (2)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
+-**   (3)  SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
+-**
+-** The t2.z='ok' is disabled in the in (2) because it originates
+-** in the ON clause.  The term is disabled in (3) because it is not part
+-** of a LEFT OUTER JOIN.  In (1), the term is not disabled.
+-**
+-** Disabling a term causes that term to not be tested in the inner loop
+-** of the join.  Disabling is an optimization.  When terms are satisfied
+-** by indices, we disable them to prevent redundant tests in the inner
+-** loop.  We would get the correct results if nothing were ever disabled,
+-** but joins might run a little slower.  The trick is to disable as much
+-** as we can without disabling too much.  If we disabled in (1), we'd get
+-** the wrong answer.  See ticket #813.
+-**
+-** If all the children of a term are disabled, then that term is also
+-** automatically disabled.  In this way, terms get disabled if derived
+-** virtual terms are tested first.  For example:
+-**
+-**      x GLOB 'abc*' AND x>='abc' AND x<'acd'
+-**      \___________/     \______/     \_____/
+-**         parent          child1       child2
+-**
+-** Only the parent term was in the original WHERE clause.  The child1
+-** and child2 terms were added by the LIKE optimization.  If both of
+-** the virtual child terms are valid, then testing of the parent can be 
+-** skipped.
+-**
+-** Usually the parent term is marked as TERM_CODED.  But if the parent
+-** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead.
+-** The TERM_LIKECOND marking indicates that the term should be coded inside
+-** a conditional such that is only evaluated on the second pass of a
+-** LIKE-optimization loop, when scanning BLOBs instead of strings.
+-*/
+-static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
+-  int nLoop = 0;
+-  while( pTerm
+-      && (pTerm->wtFlags & TERM_CODED)==0
+-      && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+-      && (pLevel->notReady & pTerm->prereqAll)==0
+-  ){
+-    if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){
+-      pTerm->wtFlags |= TERM_LIKECOND;
+-    }else{
+-      pTerm->wtFlags |= TERM_CODED;
+-    }
+-    if( pTerm->iParent<0 ) break;
+-    pTerm = &pTerm->pWC->a[pTerm->iParent];
+-    pTerm->nChild--;
+-    if( pTerm->nChild!=0 ) break;
+-    nLoop++;
+-  }
+-}
+-
+-/*
+-** Code an OP_Affinity opcode to apply the column affinity string zAff
+-** to the n registers starting at base. 
+-**
+-** As an optimization, SQLITE_AFF_NONE entries (which are no-ops) at the
+-** beginning and end of zAff are ignored.  If all entries in zAff are
+-** SQLITE_AFF_NONE, then no code gets generated.
+-**
+-** This routine makes its own copy of zAff so that the caller is free
+-** to modify zAff after this routine returns.
+-*/
+-static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
+-  Vdbe *v = pParse->pVdbe;
+-  if( zAff==0 ){
+-    assert( pParse->db->mallocFailed );
+-    return;
+-  }
+-  assert( v!=0 );
+-
+-  /* Adjust base and n to skip over SQLITE_AFF_NONE entries at the beginning
+-  ** and end of the affinity string.
+-  */
+-  while( n>0 && zAff[0]==SQLITE_AFF_NONE ){
+-    n--;
+-    base++;
+-    zAff++;
+-  }
+-  while( n>1 && zAff[n-1]==SQLITE_AFF_NONE ){
+-    n--;
+-  }
+-
+-  /* Code the OP_Affinity opcode if there is anything left to do. */
+-  if( n>0 ){
+-    sqlite3VdbeAddOp2(v, OP_Affinity, base, n);
+-    sqlite3VdbeChangeP4(v, -1, zAff, n);
+-    sqlite3ExprCacheAffinityChange(pParse, base, n);
+-  }
+-}
+-
+-
+-/*
+-** Generate code for a single equality term of the WHERE clause.  An equality
+-** term can be either X=expr or X IN (...).   pTerm is the term to be 
+-** coded.
+-**
+-** The current value for the constraint is left in register iReg.
+-**
+-** For a constraint of the form X=expr, the expression is evaluated and its
+-** result is left on the stack.  For constraints of the form X IN (...)
+-** this routine sets up a loop that will iterate over all values of X.
+-*/
+-static int codeEqualityTerm(
+-  Parse *pParse,      /* The parsing context */
+-  WhereTerm *pTerm,   /* The term of the WHERE clause to be coded */
+-  WhereLevel *pLevel, /* The level of the FROM clause we are working on */
+-  int iEq,            /* Index of the equality term within this level */
+-  int bRev,           /* True for reverse-order IN operations */
+-  int iTarget         /* Attempt to leave results in this register */
+-){
+-  Expr *pX = pTerm->pExpr;
+-  Vdbe *v = pParse->pVdbe;
+-  int iReg;                  /* Register holding results */
+-
+-  assert( iTarget>0 );
+-  if( pX->op==TK_EQ ){
+-    iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
+-  }else if( pX->op==TK_ISNULL ){
+-    iReg = iTarget;
+-    sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
+-#ifndef SQLITE_OMIT_SUBQUERY
+-  }else{
+-    int eType;
+-    int iTab;
+-    struct InLoop *pIn;
+-    WhereLoop *pLoop = pLevel->pWLoop;
+-
+-    if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
+-      && pLoop->u.btree.pIndex!=0
+-      && pLoop->u.btree.pIndex->aSortOrder[iEq]
+-    ){
+-      testcase( iEq==0 );
+-      testcase( bRev );
+-      bRev = !bRev;
+-    }
+-    assert( pX->op==TK_IN );
+-    iReg = iTarget;
+-    eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0);
+-    if( eType==IN_INDEX_INDEX_DESC ){
+-      testcase( bRev );
+-      bRev = !bRev;
+-    }
+-    iTab = pX->iTable;
+-    sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
+-    VdbeCoverageIf(v, bRev);
+-    VdbeCoverageIf(v, !bRev);
+-    assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
+-    pLoop->wsFlags |= WHERE_IN_ABLE;
+-    if( pLevel->u.in.nIn==0 ){
+-      pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
+-    }
+-    pLevel->u.in.nIn++;
+-    pLevel->u.in.aInLoop =
+-       sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
+-                              sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
+-    pIn = pLevel->u.in.aInLoop;
+-    if( pIn ){
+-      pIn += pLevel->u.in.nIn - 1;
+-      pIn->iCur = iTab;
+-      if( eType==IN_INDEX_ROWID ){
+-        pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
+-      }else{
+-        pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
+-      }
+-      pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
+-      sqlite3VdbeAddOp1(v, OP_IsNull, iReg); VdbeCoverage(v);
+-    }else{
+-      pLevel->u.in.nIn = 0;
+-    }
+-#endif
+-  }
+-  disableTerm(pLevel, pTerm);
+-  return iReg;
+-}
+-
+-/*
+-** Generate code that will evaluate all == and IN constraints for an
+-** index scan.
+-**
+-** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c).
+-** Suppose the WHERE clause is this:  a==5 AND b IN (1,2,3) AND c>5 AND c<10
+-** The index has as many as three equality constraints, but in this
+-** example, the third "c" value is an inequality.  So only two 
+-** constraints are coded.  This routine will generate code to evaluate
+-** a==5 and b IN (1,2,3).  The current values for a and b will be stored
+-** in consecutive registers and the index of the first register is returned.
+-**
+-** In the example above nEq==2.  But this subroutine works for any value
+-** of nEq including 0.  If nEq==0, this routine is nearly a no-op.
+-** The only thing it does is allocate the pLevel->iMem memory cell and
+-** compute the affinity string.
+-**
+-** The nExtraReg parameter is 0 or 1.  It is 0 if all WHERE clause constraints
+-** are == or IN and are covered by the nEq.  nExtraReg is 1 if there is
+-** an inequality constraint (such as the "c>=5 AND c<10" in the example) that
+-** occurs after the nEq quality constraints.
+-**
+-** This routine allocates a range of nEq+nExtraReg memory cells and returns
+-** the index of the first memory cell in that range. The code that
+-** calls this routine will use that memory range to store keys for
+-** start and termination conditions of the loop.
+-** key value of the loop.  If one or more IN operators appear, then
+-** this routine allocates an additional nEq memory cells for internal
+-** use.
+-**
+-** Before returning, *pzAff is set to point to a buffer containing a
+-** copy of the column affinity string of the index allocated using
+-** sqlite3DbMalloc(). Except, entries in the copy of the string associated
+-** with equality constraints that use NONE affinity are set to
+-** SQLITE_AFF_NONE. This is to deal with SQL such as the following:
+-**
+-**   CREATE TABLE t1(a TEXT PRIMARY KEY, b);
+-**   SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b;
+-**
+-** In the example above, the index on t1(a) has TEXT affinity. But since
+-** the right hand side of the equality constraint (t2.b) has NONE affinity,
+-** no conversion should be attempted before using a t2.b value as part of
+-** a key to search the index. Hence the first byte in the returned affinity
+-** string in this example would be set to SQLITE_AFF_NONE.
+-*/
+-static int codeAllEqualityTerms(
+-  Parse *pParse,        /* Parsing context */
+-  WhereLevel *pLevel,   /* Which nested loop of the FROM we are coding */
+-  int bRev,             /* Reverse the order of IN operators */
+-  int nExtraReg,        /* Number of extra registers to allocate */
+-  char **pzAff          /* OUT: Set to point to affinity string */
+-){
+-  u16 nEq;                      /* The number of == or IN constraints to code */
+-  u16 nSkip;                    /* Number of left-most columns to skip */
+-  Vdbe *v = pParse->pVdbe;      /* The vm under construction */
+-  Index *pIdx;                  /* The index being used for this loop */
+-  WhereTerm *pTerm;             /* A single constraint term */
+-  WhereLoop *pLoop;             /* The WhereLoop object */
+-  int j;                        /* Loop counter */
+-  int regBase;                  /* Base register */
+-  int nReg;                     /* Number of registers to allocate */
+-  char *zAff;                   /* Affinity string to return */
+-
+-  /* This module is only called on query plans that use an index. */
+-  pLoop = pLevel->pWLoop;
+-  assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
+-  nEq = pLoop->u.btree.nEq;
+-  nSkip = pLoop->nSkip;
+-  pIdx = pLoop->u.btree.pIndex;
+-  assert( pIdx!=0 );
+-
+-  /* Figure out how many memory cells we will need then allocate them.
+-  */
+-  regBase = pParse->nMem + 1;
+-  nReg = pLoop->u.btree.nEq + nExtraReg;
+-  pParse->nMem += nReg;
+-
+-  zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx));
+-  if( !zAff ){
+-    pParse->db->mallocFailed = 1;
+-  }
+-
+-  if( nSkip ){
+-    int iIdxCur = pLevel->iIdxCur;
+-    sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
+-    VdbeCoverageIf(v, bRev==0);
+-    VdbeCoverageIf(v, bRev!=0);
+-    VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
+-    j = sqlite3VdbeAddOp0(v, OP_Goto);
+-    pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
+-                            iIdxCur, 0, regBase, nSkip);
+-    VdbeCoverageIf(v, bRev==0);
+-    VdbeCoverageIf(v, bRev!=0);
+-    sqlite3VdbeJumpHere(v, j);
+-    for(j=0; j<nSkip; j++){
+-      sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
+-      assert( pIdx->aiColumn[j]>=0 );
+-      VdbeComment((v, "%s", pIdx->pTable->aCol[pIdx->aiColumn[j]].zName));
+-    }
+-  }    
+-
+-  /* Evaluate the equality constraints
+-  */
+-  assert( zAff==0 || (int)strlen(zAff)>=nEq );
+-  for(j=nSkip; j<nEq; j++){
+-    int r1;
+-    pTerm = pLoop->aLTerm[j];
+-    assert( pTerm!=0 );
+-    /* The following testcase is true for indices with redundant columns. 
+-    ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
+-    testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
+-    testcase( pTerm->wtFlags & TERM_VIRTUAL );
+-    r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
+-    if( r1!=regBase+j ){
+-      if( nReg==1 ){
+-        sqlite3ReleaseTempReg(pParse, regBase);
+-        regBase = r1;
+-      }else{
+-        sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
+-      }
+-    }
+-    testcase( pTerm->eOperator & WO_ISNULL );
+-    testcase( pTerm->eOperator & WO_IN );
+-    if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
+-      Expr *pRight = pTerm->pExpr->pRight;
+-      if( sqlite3ExprCanBeNull(pRight) ){
+-        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
+-        VdbeCoverage(v);
+-      }
+-      if( zAff ){
+-        if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){
+-          zAff[j] = SQLITE_AFF_NONE;
+-        }
+-        if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){
+-          zAff[j] = SQLITE_AFF_NONE;
+-        }
+-      }
+-    }
+-  }
+-  *pzAff = zAff;
+-  return regBase;
+-}
+-
+-#ifndef SQLITE_OMIT_EXPLAIN
+-/*
+-** This routine is a helper for explainIndexRange() below
+-**
+-** pStr holds the text of an expression that we are building up one term
+-** at a time.  This routine adds a new term to the end of the expression.
+-** Terms are separated by AND so add the "AND" text for second and subsequent
+-** terms only.
+-*/
+-static void explainAppendTerm(
+-  StrAccum *pStr,             /* The text expression being built */
+-  int iTerm,                  /* Index of this term.  First is zero */
+-  const char *zColumn,        /* Name of the column */
+-  const char *zOp             /* Name of the operator */
+-){
+-  if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5);
+-  sqlite3StrAccumAppendAll(pStr, zColumn);
+-  sqlite3StrAccumAppend(pStr, zOp, 1);
+-  sqlite3StrAccumAppend(pStr, "?", 1);
+-}
+-
+-/*
+-** Argument pLevel describes a strategy for scanning table pTab. This 
+-** function appends text to pStr that describes the subset of table
+-** rows scanned by the strategy in the form of an SQL expression.
+-**
+-** For example, if the query:
+-**
+-**   SELECT * FROM t1 WHERE a=1 AND b>2;
+-**
+-** is run and there is an index on (a, b), then this function returns a
+-** string similar to:
+-**
+-**   "a=? AND b>?"
+-*/
+-static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
+-  Index *pIndex = pLoop->u.btree.pIndex;
+-  u16 nEq = pLoop->u.btree.nEq;
+-  u16 nSkip = pLoop->nSkip;
+-  int i, j;
+-  Column *aCol = pTab->aCol;
+-  i16 *aiColumn = pIndex->aiColumn;
+-
+-  if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
+-  sqlite3StrAccumAppend(pStr, " (", 2);
+-  for(i=0; i<nEq; i++){
+-    char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
+-    if( i>=nSkip ){
+-      explainAppendTerm(pStr, i, z, "=");
+-    }else{
+-      if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
+-      sqlite3XPrintf(pStr, 0, "ANY(%s)", z);
+-    }
+-  }
+-
+-  j = i;
+-  if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
+-    char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
+-    explainAppendTerm(pStr, i++, z, ">");
+-  }
+-  if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
+-    char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
+-    explainAppendTerm(pStr, i, z, "<");
+-  }
+-  sqlite3StrAccumAppend(pStr, ")", 1);
+-}
+-
+-/*
+-** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
+-** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was
+-** defined at compile-time. If it is not a no-op, a single OP_Explain opcode 
+-** is added to the output to describe the table scan strategy in pLevel.
+-**
+-** If an OP_Explain opcode is added to the VM, its address is returned.
+-** Otherwise, if no OP_Explain is coded, zero is returned.
+-*/
+-static int explainOneScan(
+-  Parse *pParse,                  /* Parse context */
+-  SrcList *pTabList,              /* Table list this loop refers to */
+-  WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
+-  int iLevel,                     /* Value for "level" column of output */
+-  int iFrom,                      /* Value for "from" column of output */
+-  u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
+-){
+-  int ret = 0;
+-#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
+-  if( pParse->explain==2 )
+-#endif
+-  {
+-    struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
+-    Vdbe *v = pParse->pVdbe;      /* VM being constructed */
+-    sqlite3 *db = pParse->db;     /* Database handle */
+-    int iId = pParse->iSelectId;  /* Select id (left-most output column) */
+-    int isSearch;                 /* True for a SEARCH. False for SCAN. */
+-    WhereLoop *pLoop;             /* The controlling WhereLoop object */
+-    u32 flags;                    /* Flags that describe this loop */
+-    char *zMsg;                   /* Text to add to EQP output */
+-    StrAccum str;                 /* EQP output string */
+-    char zBuf[100];               /* Initial space for EQP output string */
+-
+-    pLoop = pLevel->pWLoop;
+-    flags = pLoop->wsFlags;
+-    if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return 0;
+-
+-    isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
+-            || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
+-            || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
+-
+-    sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
+-    sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
+-    if( pItem->pSelect ){
+-      sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
+-    }else{
+-      sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
+-    }
+-
+-    if( pItem->zAlias ){
+-      sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias);
+-    }
+-    if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
+-      const char *zFmt = 0;
+-      Index *pIdx;
+-
+-      assert( pLoop->u.btree.pIndex!=0 );
+-      pIdx = pLoop->u.btree.pIndex;
+-      assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
+-      if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
+-        if( isSearch ){
+-          zFmt = "PRIMARY KEY";
+-        }
+-      }else if( flags & WHERE_PARTIALIDX ){
+-        zFmt = "AUTOMATIC PARTIAL COVERING INDEX";
+-      }else if( flags & WHERE_AUTO_INDEX ){
+-        zFmt = "AUTOMATIC COVERING INDEX";
+-      }else if( flags & WHERE_IDX_ONLY ){
+-        zFmt = "COVERING INDEX %s";
+-      }else{
+-        zFmt = "INDEX %s";
+-      }
+-      if( zFmt ){
+-        sqlite3StrAccumAppend(&str, " USING ", 7);
+-        sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
+-        explainIndexRange(&str, pLoop, pItem->pTab);
+-      }
+-    }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
+-      const char *zRange;
+-      if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
+-        zRange = "(rowid=?)";
+-      }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
+-        zRange = "(rowid>? AND rowid<?)";
+-      }else if( flags&WHERE_BTM_LIMIT ){
+-        zRange = "(rowid>?)";
+-      }else{
+-        assert( flags&WHERE_TOP_LIMIT);
+-        zRange = "(rowid<?)";
+-      }
+-      sqlite3StrAccumAppendAll(&str, " USING INTEGER PRIMARY KEY ");
+-      sqlite3StrAccumAppendAll(&str, zRange);
+-    }
+-#ifndef SQLITE_OMIT_VIRTUALTABLE
+-    else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
+-      sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
+-                  pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
+-    }
+-#endif
+-#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
+-    if( pLoop->nOut>=10 ){
+-      sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
+-    }else{
+-      sqlite3StrAccumAppend(&str, " (~1 row)", 9);
+-    }
+-#endif
+-    zMsg = sqlite3StrAccumFinish(&str);
+-    ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC);
+-  }
+-  return ret;
+-}
+-#else
+-# define explainOneScan(u,v,w,x,y,z) 0
+-#endif /* SQLITE_OMIT_EXPLAIN */
+-
+-#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+-/*
+-** Configure the VM passed as the first argument with an
+-** sqlite3_stmt_scanstatus() entry corresponding to the scan used to 
+-** implement level pLvl. Argument pSrclist is a pointer to the FROM 
+-** clause that the scan reads data from.
+-**
+-** If argument addrExplain is not 0, it must be the address of an 
+-** OP_Explain instruction that describes the same loop.
+-*/
+-static void addScanStatus(
+-  Vdbe *v,                        /* Vdbe to add scanstatus entry to */
+-  SrcList *pSrclist,              /* FROM clause pLvl reads data from */
+-  WhereLevel *pLvl,               /* Level to add scanstatus() entry for */
+-  int addrExplain                 /* Address of OP_Explain (or 0) */
+-){
+-  const char *zObj = 0;
+-  WhereLoop *pLoop = pLvl->pWLoop;
+-  if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0  &&  pLoop->u.btree.pIndex!=0 ){
+-    zObj = pLoop->u.btree.pIndex->zName;
+-  }else{
+-    zObj = pSrclist->a[pLvl->iFrom].zName;
+-  }
+-  sqlite3VdbeScanStatus(
+-      v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj
+-  );
+-}
+-#else
+-# define addScanStatus(a, b, c, d) ((void)d)
+-#endif
+-
+-/*
+-** If the most recently coded instruction is a constant range contraint
+-** that originated from the LIKE optimization, then change the P3 to be
+-** pLoop->iLikeRepCntr and set P5.
+-**
+-** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range
+-** expression: "x>='ABC' AND x<'abd'".  But this requires that the range
+-** scan loop run twice, once for strings and a second time for BLOBs.
+-** The OP_String opcodes on the second pass convert the upper and lower
+-** bound string contants to blobs.  This routine makes the necessary changes
+-** to the OP_String opcodes for that to happen.
+-*/
+-static void whereLikeOptimizationStringFixup(
+-  Vdbe *v,                /* prepared statement under construction */
+-  WhereLevel *pLevel,     /* The loop that contains the LIKE operator */
+-  WhereTerm *pTerm        /* The upper or lower bound just coded */
+-){
+-  if( pTerm->wtFlags & TERM_LIKEOPT ){
+-    VdbeOp *pOp;
+-    assert( pLevel->iLikeRepCntr>0 );
+-    pOp = sqlite3VdbeGetOp(v, -1);
+-    assert( pOp!=0 );
+-    assert( pOp->opcode==OP_String8 
+-            || pTerm->pWC->pWInfo->pParse->db->mallocFailed );
+-    pOp->p3 = pLevel->iLikeRepCntr;
+-    pOp->p5 = 1;
+-  }
+-}
+-
+-/*
+-** Generate code for the start of the iLevel-th loop in the WHERE clause
+-** implementation described by pWInfo.
+-*/
+-static Bitmask codeOneLoopStart(
+-  WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
+-  int iLevel,          /* Which level of pWInfo->a[] should be coded */
+-  Bitmask notReady     /* Which tables are currently available */
+-){
+-  int j, k;            /* Loop counters */
+-  int iCur;            /* The VDBE cursor for the table */
+-  int addrNxt;         /* Where to jump to continue with the next IN case */
+-  int omitTable;       /* True if we use the index only */
+-  int bRev;            /* True if we need to scan in reverse order */
+-  WhereLevel *pLevel;  /* The where level to be coded */
+-  WhereLoop *pLoop;    /* The WhereLoop object being coded */
+-  WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
+-  WhereTerm *pTerm;               /* A WHERE clause term */
+-  Parse *pParse;                  /* Parsing context */
+-  sqlite3 *db;                    /* Database connection */
+-  Vdbe *v;                        /* The prepared stmt under constructions */
+-  struct SrcList_item *pTabItem;  /* FROM clause term being coded */
+-  int addrBrk;                    /* Jump here to break out of the loop */
+-  int addrCont;                   /* Jump here to continue with next cycle */
+-  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
+-  int iReleaseReg = 0;      /* Temp register to free before returning */
+-
+-  pParse = pWInfo->pParse;
+-  v = pParse->pVdbe;
+-  pWC = &pWInfo->sWC;
+-  db = pParse->db;
+-  pLevel = &pWInfo->a[iLevel];
+-  pLoop = pLevel->pWLoop;
+-  pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
+-  iCur = pTabItem->iCursor;
+-  pLevel->notReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);
+-  bRev = (pWInfo->revMask>>iLevel)&1;
+-  omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 
+-           && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0;
+-  VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));
+-
+-  /* Create labels for the "break" and "continue" instructions
+-  ** for the current loop.  Jump to addrBrk to break out of a loop.
+-  ** Jump to cont to go immediately to the next iteration of the
+-  ** loop.
+-  **
+-  ** When there is an IN operator, we also have a "addrNxt" label that
+-  ** means to continue with the next IN value combination.  When
+-  ** there are no IN operators in the constraints, the "addrNxt" label
+-  ** is the same as "addrBrk".
+-  */
+-  addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
+-  addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(v);
+-
+-  /* If this is the right table of a LEFT OUTER JOIN, allocate and
+-  ** initialize a memory cell that records if this table matches any
+-  ** row of the left table of the join.
+-  */
+-  if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
+-    pLevel->iLeftJoin = ++pParse->nMem;
+-    sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
+-    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;
+-    sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
+-    pLevel->p2 =  sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
+-    VdbeCoverage(v);
+-    VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
+-    pLevel->op = OP_Goto;
+-  }else
+-
+-#ifndef SQLITE_OMIT_VIRTUALTABLE
+-  if(  (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
+-    /* Case 1:  The table is a virtual-table.  Use the VFilter and VNext
+-    **          to access the data.
+-    */
+-    int iReg;   /* P3 Value for OP_VFilter */
+-    int addrNotFound;
+-    int nConstraint = pLoop->nLTerm;
+-
+-    sqlite3ExprCachePush(pParse);
+-    iReg = sqlite3GetTempRange(pParse, nConstraint+2);
+-    addrNotFound = pLevel->addrBrk;
+-    for(j=0; j<nConstraint; j++){
+-      int iTarget = iReg+j+2;
+-      pTerm = pLoop->aLTerm[j];
+-      if( pTerm==0 ) continue;
+-      if( pTerm->eOperator & WO_IN ){
+-        codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
+-        addrNotFound = pLevel->addrNxt;
+-      }else{
+-        sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
+-      }
+-    }
+-    sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
+-    sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
+-    sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
+-                      pLoop->u.vtab.idxStr,
+-                      pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);
+-    VdbeCoverage(v);
+-    pLoop->u.vtab.needFree = 0;
+-    for(j=0; j<nConstraint && j<16; j++){
+-      if( (pLoop->u.vtab.omitMask>>j)&1 ){
+-        disableTerm(pLevel, pLoop->aLTerm[j]);
+-      }
+-    }
+-    pLevel->op = OP_VNext;
+-    pLevel->p1 = iCur;
+-    pLevel->p2 = sqlite3VdbeCurrentAddr(v);
+-    sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
+-    sqlite3ExprCachePop(pParse);
+-  }else
+-#endif /* SQLITE_OMIT_VIRTUALTABLE */
+-
+-  if( (pLoop->wsFlags & WHERE_IPK)!=0
+-   && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0
+-  ){
+-    /* Case 2:  We can directly reference a single row using an
+-    **          equality comparison against the ROWID field.  Or
+-    **          we reference multiple rows using a "rowid IN (...)"
+-    **          construct.
+-    */
+-    assert( pLoop->u.btree.nEq==1 );
+-    pTerm = pLoop->aLTerm[0];
+-    assert( pTerm!=0 );
+-    assert( pTerm->pExpr!=0 );
+-    assert( omitTable==0 );
+-    testcase( pTerm->wtFlags & TERM_VIRTUAL );
+-    iReleaseReg = ++pParse->nMem;
+-    iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
+-    if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
+-    addrNxt = pLevel->addrNxt;
+-    sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); VdbeCoverage(v);
+-    sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
+-    VdbeCoverage(v);
+-    sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
+-    sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
+-    VdbeComment((v, "pk"));
+-    pLevel->op = OP_Noop;
+-  }else if( (pLoop->wsFlags & WHERE_IPK)!=0
+-         && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
+-  ){
+-    /* Case 3:  We have an inequality comparison against the ROWID field.
+-    */
+-    int testOp = OP_Noop;
+-    int start;
+-    int memEndValue = 0;
+-    WhereTerm *pStart, *pEnd;
+-
+-    assert( omitTable==0 );
+-    j = 0;
+-    pStart = pEnd = 0;
+-    if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
+-    if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
+-    assert( pStart!=0 || pEnd!=0 );
+-    if( bRev ){
+-      pTerm = pStart;
+-      pStart = pEnd;
+-      pEnd = pTerm;
+-    }
+-    if( pStart ){
+-      Expr *pX;             /* The expression that defines the start bound */
+-      int r1, rTemp;        /* Registers for holding the start boundary */
+-
+-      /* The following constant maps TK_xx codes into corresponding 
+-      ** seek opcodes.  It depends on a particular ordering of TK_xx
+-      */
+-      const u8 aMoveOp[] = {
+-           /* TK_GT */  OP_SeekGT,
+-           /* TK_LE */  OP_SeekLE,
+-           /* TK_LT */  OP_SeekLT,
+-           /* TK_GE */  OP_SeekGE
+-      };
+-      assert( TK_LE==TK_GT+1 );      /* Make sure the ordering.. */
+-      assert( TK_LT==TK_GT+2 );      /*  ... of the TK_xx values... */
+-      assert( TK_GE==TK_GT+3 );      /*  ... is correcct. */
+-
+-      assert( (pStart->wtFlags & TERM_VNULL)==0 );
+-      testcase( pStart->wtFlags & TERM_VIRTUAL );
+-      pX = pStart->pExpr;
+-      assert( pX!=0 );
+-      testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
+-      r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
+-      sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
+-      VdbeComment((v, "pk"));
+-      VdbeCoverageIf(v, pX->op==TK_GT);
+-      VdbeCoverageIf(v, pX->op==TK_LE);
+-      VdbeCoverageIf(v, pX->op==TK_LT);
+-      VdbeCoverageIf(v, pX->op==TK_GE);
+-      sqlite3ExprCacheAffinityChange(pParse, r1, 1);
+-      sqlite3ReleaseTempReg(pParse, rTemp);
+-      disableTerm(pLevel, pStart);
+-    }else{
+-      sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
+-      VdbeCoverageIf(v, bRev==0);
+-      VdbeCoverageIf(v, bRev!=0);
+-    }
+-    if( pEnd ){
+-      Expr *pX;
+-      pX = pEnd->pExpr;
+-      assert( pX!=0 );
+-      assert( (pEnd->wtFlags & TERM_VNULL)==0 );
+-      testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
+-      testcase( pEnd->wtFlags & TERM_VIRTUAL );
+-      memEndValue = ++pParse->nMem;
+-      sqlite3ExprCode(pParse, pX->pRight, memEndValue);
+-      if( pX->op==TK_LT || pX->op==TK_GT ){
+-        testOp = bRev ? OP_Le : OP_Ge;
+-      }else{
+-        testOp = bRev ? OP_Lt : OP_Gt;
+-      }
+-      disableTerm(pLevel, pEnd);
+-    }
+-    start = sqlite3VdbeCurrentAddr(v);
+-    pLevel->op = bRev ? OP_Prev : OP_Next;
+-    pLevel->p1 = iCur;
+-    pLevel->p2 = start;
+-    assert( pLevel->p5==0 );
+-    if( testOp!=OP_Noop ){
+-      iRowidReg = ++pParse->nMem;
+-      sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
+-      sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
+-      sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
+-      VdbeCoverageIf(v, testOp==OP_Le);
+-      VdbeCoverageIf(v, testOp==OP_Lt);
+-      VdbeCoverageIf(v, testOp==OP_Ge);
+-      VdbeCoverageIf(v, testOp==OP_Gt);
+-      sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
+-    }
+-  }else if( pLoop->wsFlags & WHERE_INDEXED ){
+-    /* Case 4: A scan using an index.
+-    **
+-    **         The WHERE clause may contain zero or more equality 
+-    **         terms ("==" or "IN" operators) that refer to the N
+-    **         left-most columns of the index. It may also contain
+-    **         inequality constraints (>, <, >= or <=) on the indexed
+-    **         column that immediately follows the N equalities. Only 
+-    **         the right-most column can be an inequality - the rest must
+-    **         use the "==" and "IN" operators. For example, if the 
+-    **         index is on (x,y,z), then the following clauses are all 
+-    **         optimized:
+-    **
+-    **            x=5
+-    **            x=5 AND y=10
+-    **            x=5 AND y<10
+-    **            x=5 AND y>5 AND y<10
+-    **            x=5 AND y=5 AND z<=10
+-    **
+-    **         The z<10 term of the following cannot be used, only
+-    **         the x=5 term:
+-    **
+-    **            x=5 AND z<10
+-    **
+-    **         N may be zero if there are inequality constraints.
+-    **         If there are no inequality constraints, then N is at
+-    **         least one.
+-    **
+-    **         This case is also used when there are no WHERE clause
+-    **         constraints but an index is selected anyway, in order
+-    **         to force the output order to conform to an ORDER BY.
+-    */  
+-    static const u8 aStartOp[] = {
+-      0,
+-      0,
+-      OP_Rewind,           /* 2: (!start_constraints && startEq &&  !bRev) */
+-      OP_Last,             /* 3: (!start_constraints && startEq &&   bRev) */
+-      OP_SeekGT,           /* 4: (start_constraints  && !startEq && !bRev) */
+-      OP_SeekLT,           /* 5: (start_constraints  && !startEq &&  bRev) */
+-      OP_SeekGE,           /* 6: (start_constraints  &&  startEq && !bRev) */
+-      OP_SeekLE            /* 7: (start_constraints  &&  startEq &&  bRev) */
+-    };
+-    static const u8 aEndOp[] = {
+-      OP_IdxGE,            /* 0: (end_constraints && !bRev && !endEq) */
+-      OP_IdxGT,            /* 1: (end_constraints && !bRev &&  endEq) */
+-      OP_IdxLE,            /* 2: (end_constraints &&  bRev && !endEq) */
+-      OP_IdxLT,            /* 3: (end_constraints &&  bRev &&  endEq) */
+-    };
+-    u16 nEq = pLoop->u.btree.nEq;     /* Number of == or IN terms */
+-    int regBase;                 /* Base register holding constraint values */
+-    WhereTerm *pRangeStart = 0;  /* Inequality constraint at range start */
+-    WhereTerm *pRangeEnd = 0;    /* Inequality constraint at range end */
+-    int startEq;                 /* True if range start uses ==, >= or <= */
+-    int endEq;                   /* True if range end uses ==, >= or <= */
+-    int start_constraints;       /* Start of range is constrained */
+-    int nConstraint;             /* Number of constraint terms */
+-    Index *pIdx;                 /* The index we will be using */
+-    int iIdxCur;                 /* The VDBE cursor for the index */
+-    int nExtraReg = 0;           /* Number of extra registers needed */
+-    int op;                      /* Instruction opcode */
+-    char *zStartAff;             /* Affinity for start of range constraint */
+-    char cEndAff = 0;            /* Affinity for end of range constraint */
+-    u8 bSeekPastNull = 0;        /* True to seek past initial nulls */
+-    u8 bStopAtNull = 0;          /* Add condition to terminate at NULLs */
+-
+-    pIdx = pLoop->u.btree.pIndex;
+-    iIdxCur = pLevel->iIdxCur;
+-    assert( nEq>=pLoop->nSkip );
+-
+-    /* If this loop satisfies a sort order (pOrderBy) request that 
+-    ** was passed to this function to implement a "SELECT min(x) ..." 
+-    ** query, then the caller will only allow the loop to run for
+-    ** a single iteration. This means that the first row returned
+-    ** should not have a NULL value stored in 'x'. If column 'x' is
+-    ** the first one after the nEq equality constraints in the index,
+-    ** this requires some special handling.
+-    */
+-    assert( pWInfo->pOrderBy==0
+-         || pWInfo->pOrderBy->nExpr==1
+-         || (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 );
+-    if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
+-     && pWInfo->nOBSat>0
+-     && (pIdx->nKeyCol>nEq)
+-    ){
+-      assert( pLoop->nSkip==0 );
+-      bSeekPastNull = 1;
+-      nExtraReg = 1;
+-    }
+-
+-    /* Find any inequality constraint terms for the start and end 
+-    ** of the range. 
+-    */
+-    j = nEq;
+-    if( pLoop->wsFlags & WHERE_BTM_LIMIT ){
+-      pRangeStart = pLoop->aLTerm[j++];
+-      nExtraReg = 1;
+-      /* Like optimization range constraints always occur in pairs */
+-      assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 || 
+-              (pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 );
+-    }
+-    if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
+-      pRangeEnd = pLoop->aLTerm[j++];
+-      nExtraReg = 1;
+-      if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){
+-        assert( pRangeStart!=0 );                     /* LIKE opt constraints */
+-        assert( pRangeStart->wtFlags & TERM_LIKEOPT );   /* occur in pairs */
+-        pLevel->iLikeRepCntr = ++pParse->nMem;
+-        testcase( bRev );
+-        testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC );
+-        sqlite3VdbeAddOp2(v, OP_Integer,
+-                          bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC),
+-                          pLevel->iLikeRepCntr);
+-        VdbeComment((v, "LIKE loop counter"));
+-        pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v);
+-      }
+-      if( pRangeStart==0
+-       && (j = pIdx->aiColumn[nEq])>=0 
+-       && pIdx->pTable->aCol[j].notNull==0
+-      ){
+-        bSeekPastNull = 1;
+-      }
+-    }
+-    assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
+-
+-    /* Generate code to evaluate all constraint terms using == or IN
+-    ** and store the values of those terms in an array of registers
+-    ** starting at regBase.
+-    */
+-    regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
+-    assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
+-    if( zStartAff ) cEndAff = zStartAff[nEq];
+-    addrNxt = pLevel->addrNxt;
+-
+-    /* If we are doing a reverse order scan on an ascending index, or
+-    ** a forward order scan on a descending index, interchange the 
+-    ** start and end terms (pRangeStart and pRangeEnd).
+-    */
+-    if( (nEq<pIdx->nKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
+-     || (bRev && pIdx->nKeyCol==nEq)
+-    ){
+-      SWAP(WhereTerm *, pRangeEnd, pRangeStart);
+-      SWAP(u8, bSeekPastNull, bStopAtNull);
+-    }
+-
+-    testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
+-    testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
+-    testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
+-    testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 );
+-    startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
+-    endEq =   !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
+-    start_constraints = pRangeStart || nEq>0;
+-
+-    /* Seek the index cursor to the start of the range. */
+-    nConstraint = nEq;
+-    if( pRangeStart ){
+-      Expr *pRight = pRangeStart->pExpr->pRight;
+-      sqlite3ExprCode(pParse, pRight, regBase+nEq);
+-      whereLikeOptimizationStringFixup(v, pLevel, pRangeStart);
+-      if( (pRangeStart->wtFlags & TERM_VNULL)==0
+-       && sqlite3ExprCanBeNull(pRight)
+-      ){
+-        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
+-        VdbeCoverage(v);
+-      }
+-      if( zStartAff ){
+-        if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_NONE){
+-          /* Since the comparison is to be performed with no conversions
+-          ** applied to the operands, set the affinity to apply to pRight to 
+-          ** SQLITE_AFF_NONE.  */
+-          zStartAff[nEq] = SQLITE_AFF_NONE;
+-        }
+-        if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
+-          zStartAff[nEq] = SQLITE_AFF_NONE;
+-        }
+-      }  
+-      nConstraint++;
+-      testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
+-    }else if( bSeekPastNull ){
+-      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
+-      nConstraint++;
+-      startEq = 0;
+-      start_constraints = 1;
+-    }
+-    codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
+-    op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
+-    assert( op!=0 );
+-    sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
+-    VdbeCoverage(v);
+-    VdbeCoverageIf(v, op==OP_Rewind);  testcase( op==OP_Rewind );
+-    VdbeCoverageIf(v, op==OP_Last);    testcase( op==OP_Last );
+-    VdbeCoverageIf(v, op==OP_SeekGT);  testcase( op==OP_SeekGT );
+-    VdbeCoverageIf(v, op==OP_SeekGE);  testcase( op==OP_SeekGE );
+-    VdbeCoverageIf(v, op==OP_SeekLE);  testcase( op==OP_SeekLE );
+-    VdbeCoverageIf(v, op==OP_SeekLT);  testcase( op==OP_SeekLT );
+-
+-    /* Load the value for the inequality constraint at the end of the
+-    ** range (if any).
+-    */
+-    nConstraint = nEq;
+-    if( pRangeEnd ){
+-      Expr *pRight = pRangeEnd->pExpr->pRight;
+-      sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
+-      sqlite3ExprCode(pParse, pRight, regBase+nEq);
+-      whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
+-      if( (pRangeEnd->wtFlags & TERM_VNULL)==0
+-       && sqlite3ExprCanBeNull(pRight)
+-      ){
+-        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
+-        VdbeCoverage(v);
+-      }
+-      if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_NONE
+-       && !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff)
+-      ){
+-        codeApplyAffinity(pParse, regBase+nEq, 1, &cEndAff);
+-      }
+-      nConstraint++;
+-      testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
+-    }else if( bStopAtNull ){
+-      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
+-      endEq = 0;
+-      nConstraint++;
+-    }
+-    sqlite3DbFree(db, zStartAff);
+-
+-    /* Top of the loop body */
+-    pLevel->p2 = sqlite3VdbeCurrentAddr(v);
+-
+-    /* Check if the index cursor is past the end of the range. */
+-    if( nConstraint ){
+-      op = aEndOp[bRev*2 + endEq];
+-      sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
+-      testcase( op==OP_IdxGT );  VdbeCoverageIf(v, op==OP_IdxGT );
+-      testcase( op==OP_IdxGE );  VdbeCoverageIf(v, op==OP_IdxGE );
+-      testcase( op==OP_IdxLT );  VdbeCoverageIf(v, op==OP_IdxLT );
+-      testcase( op==OP_IdxLE );  VdbeCoverageIf(v, op==OP_IdxLE );
+-    }
+-
+-    /* Seek the table cursor, if required */
+-    disableTerm(pLevel, pRangeStart);
+-    disableTerm(pLevel, pRangeEnd);
+-    if( omitTable ){
+-      /* pIdx is a covering index.  No need to access the main table. */
+-    }else if( HasRowid(pIdx->pTable) ){
+-      iRowidReg = ++pParse->nMem;
+-      sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
+-      sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
+-      sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg);  /* Deferred seek */
+-    }else if( iCur!=iIdxCur ){
+-      Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
+-      iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol);
+-      for(j=0; j<pPk->nKeyCol; j++){
+-        k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
+-        sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
+-      }
+-      sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
+-                           iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
+-    }
+-
+-    /* Record the instruction used to terminate the loop. Disable 
+-    ** WHERE clause terms made redundant by the index range scan.
+-    */
+-    if( pLoop->wsFlags & WHERE_ONEROW ){
+-      pLevel->op = OP_Noop;
+-    }else if( bRev ){
+-      pLevel->op = OP_Prev;
+-    }else{
+-      pLevel->op = OP_Next;
+-    }
+-    pLevel->p1 = iIdxCur;
+-    pLevel->p3 = (pLoop->wsFlags&WHERE_UNQ_WANTED)!=0 ? 1:0;
+-    if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){
+-      pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
+-    }else{
+-      assert( pLevel->p5==0 );
+-    }
+-  }else
+-
+-#ifndef SQLITE_OMIT_OR_OPTIMIZATION
+-  if( pLoop->wsFlags & WHERE_MULTI_OR ){
+-    /* Case 5:  Two or more separately indexed terms connected by OR
+-    **
+-    ** Example:
+-    **
+-    **   CREATE TABLE t1(a,b,c,d);
+-    **   CREATE INDEX i1 ON t1(a);
+-    **   CREATE INDEX i2 ON t1(b);
+-    **   CREATE INDEX i3 ON t1(c);
+-    **
+-    **   SELECT * FROM t1 WHERE a=5 OR b=7 OR (c=11 AND d=13)
+-    **
+-    ** In the example, there are three indexed terms connected by OR.
+-    ** The top of the loop looks like this:
+-    **
+-    **          Null       1                # Zero the rowset in reg 1
+-    **
+-    ** Then, for each indexed term, the following. The arguments to
+-    ** RowSetTest are such that the rowid of the current row is inserted
+-    ** into the RowSet. If it is already present, control skips the
+-    ** Gosub opcode and jumps straight to the code generated by WhereEnd().
+-    **
+-    **        sqlite3WhereBegin(<term>)
+-    **          RowSetTest                  # Insert rowid into rowset
+-    **          Gosub      2 A
+-    **        sqlite3WhereEnd()
+-    **
+-    ** Following the above, code to terminate the loop. Label A, the target
+-    ** of the Gosub above, jumps to the instruction right after the Goto.
+-    **
+-    **          Null       1                # Zero the rowset in reg 1
+-    **          Goto       B                # The loop is finished.
+-    **
+-    **       A: <loop body>                 # Return data, whatever.
+-    **
+-    **          Return     2                # Jump back to the Gosub
+-    **
+-    **       B: <after the loop>
+-    **
+-    ** Added 2014-05-26: If the table is a WITHOUT ROWID table, then
+-    ** use an ephemeral index instead of a RowSet to record the primary
+-    ** keys of the rows we have already seen.
+-    **
+-    */
+-    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 */
+-    int regRowid = 0;                         /* Register holding rowid */
+-    int iLoopBody = sqlite3VdbeMakeLabel(v);  /* Start of loop body */
+-    int iRetInit;                             /* Address of regReturn init */
+-    int untestedTerms = 0;             /* Some terms not completely tested */
+-    int ii;                            /* Loop counter */
+-    u16 wctrlFlags;                    /* Flags for sub-WHERE clause */
+-    Expr *pAndExpr = 0;                /* An ".. AND (...)" expression */
+-    Table *pTab = pTabItem->pTab;
+-   
+-    pTerm = pLoop->aLTerm[0];
+-    assert( pTerm!=0 );
+-    assert( pTerm->eOperator & WO_OR );
+-    assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
+-    pOrWc = &pTerm->u.pOrInfo->wc;
+-    pLevel->op = OP_Return;
+-    pLevel->p1 = regReturn;
+-
+-    /* 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().
+-    */
+-    if( pWInfo->nLevel>1 ){
+-      int nNotReady;                 /* The number of notReady tables */
+-      struct SrcList_item *origSrc;     /* Original list of tables */
+-      nNotReady = pWInfo->nLevel - iLevel - 1;
+-      pOrTab = sqlite3StackAllocRaw(db,
+-                            sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
+-      if( pOrTab==0 ) return notReady;
+-      pOrTab->nAlloc = (u8)(nNotReady + 1);
+-      pOrTab->nSrc = pOrTab->nAlloc;
+-      memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
+-      origSrc = pWInfo->pTabList->a;
+-      for(k=1; k<=nNotReady; k++){
+-        memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k]));
+-      }
+-    }else{
+-      pOrTab = pWInfo->pTabList;
+-    }
+-
+-    /* Initialize the rowset register to contain NULL. An SQL NULL is 
+-    ** equivalent to an empty rowset.  Or, create an ephemeral index
+-    ** capable of holding primary keys in the case of a WITHOUT ROWID.
+-    **
+-    ** Also initialize regReturn to contain the address of the instruction 
+-    ** immediately following the OP_Return at the bottom of the loop. This
+-    ** is required in a few obscure LEFT JOIN cases where control jumps
+-    ** over the top of the loop into the body of it. In this case the 
+-    ** correct response for the end-of-loop code (the OP_Return) is to 
+-    ** fall through to the next instruction, just as an OP_Next does if
+-    ** called on an uninitialized cursor.
+-    */
+-    if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
+-      if( HasRowid(pTab) ){
+-        regRowset = ++pParse->nMem;
+-        sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
+-      }else{
+-        Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+-        regRowset = pParse->nTab++;
+-        sqlite3VdbeAddOp2(v, OP_OpenEphemeral, regRowset, pPk->nKeyCol);
+-        sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+-      }
+-      regRowid = ++pParse->nMem;
+-    }
+-    iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
+-
+-    /* If the original WHERE clause is z of the form:  (x1 OR x2 OR ...) AND y
+-    ** Then for every term xN, evaluate as the subexpression: xN AND z
+-    ** That way, terms in y that are factored into the disjunction will
+-    ** be picked up by the recursive calls to sqlite3WhereBegin() below.
+-    **
+-    ** Actually, each subexpression is converted to "xN AND w" where w is
+-    ** the "interesting" terms of z - terms that did not originate in the
+-    ** ON or USING clause of a LEFT JOIN, and terms that are usable as 
+-    ** indices.
+-    **
+-    ** This optimization also only applies if the (x1 OR x2 OR ...) term
+-    ** is not contained in the ON clause of a LEFT JOIN.
+-    ** See ticket http://www.sqlite.org/src/info/f2369304e4
+-    */
+-    if( pWC->nTerm>1 ){
+-      int iTerm;
+-      for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
+-        Expr *pExpr = pWC->a[iTerm].pExpr;
+-        if( &pWC->a[iTerm] == pTerm ) continue;
+-        if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
+-        if( (pWC->a[iTerm].wtFlags & TERM_VIRTUAL)!=0 ) continue;
+-        if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
+-        testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
+-        pExpr = sqlite3ExprDup(db, pExpr, 0);
+-        pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
+-      }
+-      if( pAndExpr ){
+-        pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
+-      }
+-    }
+-
+-    /* Run a separate WHERE clause for each term of the OR clause.  After
+-    ** eliminating duplicates from other WHERE clauses, the action for each
+-    ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
+-    */
+-    wctrlFlags =  WHERE_OMIT_OPEN_CLOSE
+-                | WHERE_FORCE_TABLE
+-                | WHERE_ONETABLE_ONLY
+-                | WHERE_NO_AUTOINDEX;
+-    for(ii=0; ii<pOrWc->nTerm; ii++){
+-      WhereTerm *pOrTerm = &pOrWc->a[ii];
+-      if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
+-        WhereInfo *pSubWInfo;           /* Info for single OR-term scan */
+-        Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
+-        int j1 = 0;                     /* Address of jump operation */
+-        if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
+-          pAndExpr->pLeft = pOrExpr;
+-          pOrExpr = pAndExpr;
+-        }
+-        /* Loop through table entries that match term pOrTerm. */
+-        WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
+-        pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
+-                                      wctrlFlags, iCovCur);
+-        assert( pSubWInfo || pParse->nErr || db->mallocFailed );
+-        if( pSubWInfo ){
+-          WhereLoop *pSubLoop;
+-          int addrExplain = explainOneScan(
+-              pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
+-          );
+-          addScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain);
+-
+-          /* This is the sub-WHERE clause body.  First skip over
+-          ** duplicate rows from prior sub-WHERE clauses, and record the
+-          ** rowid (or PRIMARY KEY) for the current row so that the same
+-          ** row will be skipped in subsequent sub-WHERE clauses.
+-          */
+-          if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
+-            int r;
+-            int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
+-            if( HasRowid(pTab) ){
+-              r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0);
+-              j1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, r,iSet);
+-              VdbeCoverage(v);
+-            }else{
+-              Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+-              int nPk = pPk->nKeyCol;
+-              int iPk;
+-
+-              /* Read the PK into an array of temp registers. */
+-              r = sqlite3GetTempRange(pParse, nPk);
+-              for(iPk=0; iPk<nPk; iPk++){
+-                int iCol = pPk->aiColumn[iPk];
+-                sqlite3ExprCodeGetColumn(pParse, pTab, iCol, iCur, r+iPk, 0);
+-              }
+-
+-              /* Check if the temp table already contains this key. If so,
+-              ** the row has already been included in the result set and
+-              ** can be ignored (by jumping past the Gosub below). Otherwise,
+-              ** insert the key into the temp table and proceed with processing
+-              ** the row.
+-              **
+-              ** Use some of the same optimizations as OP_RowSetTest: If iSet
+-              ** is zero, assume that the key cannot already be present in
+-              ** the temp table. And if iSet is -1, assume that there is no 
+-              ** need to insert the key into the temp table, as it will never 
+-              ** be tested for.  */ 
+-              if( iSet ){
+-                j1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk);
+-                VdbeCoverage(v);
+-              }
+-              if( iSet>=0 ){
+-                sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid);
+-                sqlite3VdbeAddOp3(v, OP_IdxInsert, regRowset, regRowid, 0);
+-                if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+-              }
+-
+-              /* Release the array of temp registers */
+-              sqlite3ReleaseTempRange(pParse, r, nPk);
+-            }
+-          }
+-
+-          /* Invoke the main loop body as a subroutine */
+-          sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
+-
+-          /* Jump here (skipping the main loop body subroutine) if the
+-          ** current sub-WHERE row is a duplicate from prior sub-WHEREs. */
+-          if( j1 ) sqlite3VdbeJumpHere(v, j1);
+-
+-          /* The pSubWInfo->untestedTerms flag means that this OR term
+-          ** contained one or more AND term from a notReady table.  The
+-          ** terms from the notReady table could not be tested and will
+-          ** need to be tested later.
+-          */
+-          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.
+-          */
+-          pSubLoop = pSubWInfo->a[0].pWLoop;
+-          assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
+-          if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
+-           && (ii==0 || pSubLoop->u.btree.pIndex==pCov)
+-           && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex))
+-          ){
+-            assert( pSubWInfo->a[0].iIdxCur==iCovCur );
+-            pCov = pSubLoop->u.btree.pIndex;
+-            wctrlFlags |= WHERE_REOPEN_IDX;
+-          }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(db, pAndExpr);
+-    }
+-    sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
+-    sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
+-    sqlite3VdbeResolveLabel(v, iLoopBody);
+-
+-    if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
+-    if( !untestedTerms ) disableTerm(pLevel, pTerm);
+-  }else
+-#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
+-
+-  {
+-    /* Case 6:  There is no usable index.  We must do a complete
+-    **          scan of the entire table.
+-    */
+-    static const u8 aStep[] = { OP_Next, OP_Prev };
+-    static const u8 aStart[] = { OP_Rewind, OP_Last };
+-    assert( bRev==0 || bRev==1 );
+-    if( pTabItem->isRecursive ){
+-      /* Tables marked isRecursive have only a single row that is stored in
+-      ** a pseudo-cursor.  No need to Rewind or Next such cursors. */
+-      pLevel->op = OP_Noop;
+-    }else{
+-      pLevel->op = aStep[bRev];
+-      pLevel->p1 = iCur;
+-      pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
+-      VdbeCoverageIf(v, bRev==0);
+-      VdbeCoverageIf(v, bRev!=0);
+-      pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
+-    }
+-  }
+-
+-#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+-  pLevel->addrVisit = sqlite3VdbeCurrentAddr(v);
+-#endif
+-
+-  /* Insert code to test every subexpression that can be completely
+-  ** computed using the current set of tables.
+-  */
+-  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
+-    Expr *pE;
+-    int skipLikeAddr = 0;
+-    testcase( pTerm->wtFlags & TERM_VIRTUAL );
+-    testcase( pTerm->wtFlags & TERM_CODED );
+-    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+-    if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
+-      testcase( pWInfo->untestedTerms==0
+-               && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
+-      pWInfo->untestedTerms = 1;
+-      continue;
+-    }
+-    pE = pTerm->pExpr;
+-    assert( pE!=0 );
+-    if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
+-      continue;
+-    }
+-    if( pTerm->wtFlags & TERM_LIKECOND ){
+-      assert( pLevel->iLikeRepCntr>0 );
+-      skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr);
+-      VdbeCoverage(v);
+-    }
+-    sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
+-    if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
+-    pTerm->wtFlags |= TERM_CODED;
+-  }
+-
+-  /* Insert code to test for implied constraints based on transitivity
+-  ** of the "==" operator.
+-  **
+-  ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
+-  ** and we are coding the t1 loop and the t2 loop has not yet coded,
+-  ** then we cannot use the "t1.a=t2.b" constraint, but we can code
+-  ** the implied "t1.a=123" constraint.
+-  */
+-  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
+-    Expr *pE, *pEAlt;
+-    WhereTerm *pAlt;
+-    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+-    if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
+-    if( pTerm->leftCursor!=iCur ) continue;
+-    if( pLevel->iLeftJoin ) continue;
+-    pE = pTerm->pExpr;
+-    assert( !ExprHasProperty(pE, EP_FromJoin) );
+-    assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
+-    pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
+-    if( pAlt==0 ) continue;
+-    if( pAlt->wtFlags & (TERM_CODED) ) continue;
+-    testcase( pAlt->eOperator & WO_EQ );
+-    testcase( pAlt->eOperator & WO_IN );
+-    VdbeModuleComment((v, "begin transitive constraint"));
+-    pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
+-    if( pEAlt ){
+-      *pEAlt = *pAlt->pExpr;
+-      pEAlt->pLeft = pE->pLeft;
+-      sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL);
+-      sqlite3StackFree(db, pEAlt);
+-    }
+-  }
+-
+-  /* For a LEFT OUTER JOIN, generate code that will record the fact that
+-  ** at least one row of the right table has matched the left table.  
+-  */
+-  if( pLevel->iLeftJoin ){
+-    pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
+-    sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
+-    VdbeComment((v, "record LEFT JOIN hit"));
+-    sqlite3ExprCacheClear(pParse);
+-    for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
+-      testcase( pTerm->wtFlags & TERM_VIRTUAL );
+-      testcase( pTerm->wtFlags & TERM_CODED );
+-      if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+-      if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
+-        assert( pWInfo->untestedTerms );
+-        continue;
+-      }
+-      assert( pTerm->pExpr );
+-      sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
+-      pTerm->wtFlags |= TERM_CODED;
+-    }
+-  }
+-
+-  return pLevel->notReady;
+-}
+ 
+ #ifdef WHERETRACE_ENABLED
+ /*
+@@ -120394,13 +136431,29 @@
+     sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm);
+   }else{
+     char zType[4];
++    char zLeft[50];
+     memcpy(zType, "...", 4);
+     if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
+     if( pTerm->eOperator & WO_EQUIV  ) zType[1] = 'E';
+     if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
+-    sqlite3DebugPrintf("TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x\n",
+-                       iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
+-                       pTerm->eOperator);
++    if( pTerm->eOperator & WO_SINGLE ){
++      sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
++                       pTerm->leftCursor, pTerm->u.leftColumn);
++    }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){
++      sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%lld", 
++                       pTerm->u.pOrInfo->indexable);
++    }else{
++      sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor);
++    }
++    sqlite3DebugPrintf(
++       "TERM-%-3d %p %s %-12s prob=%-3d op=0x%03x wtFlags=0x%04x",
++       iTerm, pTerm, zType, zLeft, pTerm->truthProb,
++       pTerm->eOperator, pTerm->wtFlags);
++    if( pTerm->iField ){
++      sqlite3DebugPrintf(" iField=%d\n", pTerm->iField);
++    }else{
++      sqlite3DebugPrintf("\n");
++    }
+     sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
+   }
+ }
+@@ -120408,15 +136461,28 @@
+ 
+ #ifdef WHERETRACE_ENABLED
+ /*
++** Show the complete content of a WhereClause
++*/
++SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){
++  int i;
++  for(i=0; i<pWC->nTerm; i++){
++    whereTermPrint(&pWC->a[i], i);
++  }
++}
 +#endif
-+#if SQLITE_PROXY_DEBUG
-+  "PROXY_DEBUG",
++
++#ifdef WHERETRACE_ENABLED
++/*
+ ** Print a WhereLoop object for debugging purposes
+ */
+ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
+   WhereInfo *pWInfo = pWC->pWInfo;
+-  int nb = 1+(pWInfo->pTabList->nSrc+7)/8;
++  int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
+   struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab;
+   Table *pTab = pItem->pTab;
++  Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
+   sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
+-                     p->iTab, nb, p->maskSelf, nb, p->prereq);
++                     p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
+   sqlite3DebugPrintf(" %12s",
+                      pItem->zAlias ? pItem->zAlias : pTab->zName);
+   if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
+@@ -120479,7 +136545,7 @@
+       p->u.vtab.idxStr = 0;
+     }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
+       sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
+-      sqlite3DbFree(db, p->u.btree.pIndex);
++      sqlite3DbFreeNN(db, p->u.btree.pIndex);
+       p->u.btree.pIndex = 0;
+     }
+   }
+@@ -120489,7 +136555,7 @@
+ ** Deallocate internal memory used by a WhereLoop object
+ */
+ static void whereLoopClear(sqlite3 *db, WhereLoop *p){
+-  if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
++  if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm);
+   whereLoopClearUnion(db, p);
+   whereLoopInit(p);
+ }
+@@ -120501,10 +136567,10 @@
+   WhereTerm **paNew;
+   if( p->nLSlot>=n ) return SQLITE_OK;
+   n = (n+7)&~7;
+-  paNew = sqlite3DbMallocRaw(db, sizeof(p->aLTerm[0])*n);
+-  if( paNew==0 ) return SQLITE_NOMEM;
++  paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n);
++  if( paNew==0 ) return SQLITE_NOMEM_BKPT;
+   memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot);
+-  if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
++  if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm);
+   p->aLTerm = paNew;
+   p->nLSlot = n;
+   return SQLITE_OK;
+@@ -120517,7 +136583,7 @@
+   whereLoopClearUnion(db, pTo);
+   if( whereLoopResize(db, pTo, pFrom->nLTerm) ){
+     memset(&pTo->u, 0, sizeof(pTo->u));
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ);
+   memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0]));
+@@ -120534,7 +136600,7 @@
+ */
+ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
+   whereLoopClear(db, p);
+-  sqlite3DbFree(db, p);
++  sqlite3DbFreeNN(db, p);
+ }
+ 
+ /*
+@@ -120549,13 +136615,13 @@
+         sqlite3DbFree(db, pLevel->u.in.aInLoop);
+       }
+     }
+-    whereClauseClear(&pWInfo->sWC);
++    sqlite3WhereClauseClear(&pWInfo->sWC);
+     while( pWInfo->pLoops ){
+       WhereLoop *p = pWInfo->pLoops;
+       pWInfo->pLoops = p->pNextLoop;
+       whereLoopDelete(db, p);
+     }
+-    sqlite3DbFree(db, pWInfo);
++    sqlite3DbFreeNN(db, pWInfo);
+   }
+ }
+ 
+@@ -120638,16 +136704,17 @@
+ 
+ /*
+ ** Search the list of WhereLoops in *ppPrev looking for one that can be
+-** supplanted by pTemplate.
++** replaced by pTemplate.
+ **
+-** Return NULL if the WhereLoop list contains an entry that can supplant
+-** pTemplate, in other words if pTemplate does not belong on the list.
++** Return NULL if pTemplate does not belong on the WhereLoop list.
++** In other words if pTemplate ought to be dropped from further consideration.
+ **
+-** If pX is a WhereLoop that pTemplate can supplant, then return the
++** If pX is a WhereLoop that pTemplate can replace, then return the
+ ** link that points to pX.
+ **
+-** If pTemplate cannot supplant any existing element of the list but needs
+-** to be added to the list, then return a pointer to the tail of the list.
++** If pTemplate cannot replace any existing element of the list but needs
++** to be added to the list as a new entry, then return a pointer to the
++** tail of the list.
+ */
+ static WhereLoop **whereLoopFindLesser(
+   WhereLoop **ppPrev,
+@@ -120741,23 +136808,26 @@
+   WhereLoop **ppPrev, *p;
+   WhereInfo *pWInfo = pBuilder->pWInfo;
+   sqlite3 *db = pWInfo->pParse->db;
++  int rc;
+ 
+   /* If pBuilder->pOrSet is defined, then only keep track of the costs
+   ** and prereqs.
+   */
+   if( pBuilder->pOrSet!=0 ){
++    if( pTemplate->nLTerm ){
+ #if WHERETRACE_ENABLED
+-    u16 n = pBuilder->pOrSet->n;
+-    int x =
++      u16 n = pBuilder->pOrSet->n;
++      int x =
+ #endif
+-    whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
++      whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
+                                     pTemplate->nOut);
+ #if WHERETRACE_ENABLED /* 0x8 */
+-    if( sqlite3WhereTrace & 0x8 ){
+-      sqlite3DebugPrintf(x?"   or-%d:  ":"   or-X:  ", n);
+-      whereLoopPrint(pTemplate, pBuilder->pWC);
+-    }
++      if( sqlite3WhereTrace & 0x8 ){
++        sqlite3DebugPrintf(x?"   or-%d:  ":"   or-X:  ", n);
++        whereLoopPrint(pTemplate, pBuilder->pWC);
++      }
+ #endif
++    }
+     return SQLITE_OK;
+   }
+ 
+@@ -120789,15 +136859,17 @@
+     if( p!=0 ){
+       sqlite3DebugPrintf("replace: ");
+       whereLoopPrint(p, pBuilder->pWC);
++      sqlite3DebugPrintf("   with: ");
++    }else{
++      sqlite3DebugPrintf("    add: ");
+     }
+-    sqlite3DebugPrintf("    add: ");
+     whereLoopPrint(pTemplate, pBuilder->pWC);
+   }
+ #endif
+   if( p==0 ){
+     /* Allocate a new WhereLoop to add to the end of the list */
+-    *ppPrev = p = sqlite3DbMallocRaw(db, sizeof(WhereLoop));
+-    if( p==0 ) return SQLITE_NOMEM;
++    *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop));
++    if( p==0 ) return SQLITE_NOMEM_BKPT;
+     whereLoopInit(p);
+     p->pNextLoop = 0;
+   }else{
+@@ -120821,14 +136893,14 @@
+       whereLoopDelete(db, pToDel);
+     }
+   }
+-  whereLoopXfer(db, p, pTemplate);
++  rc = whereLoopXfer(db, p, pTemplate);
+   if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
+     Index *pIndex = p->u.btree.pIndex;
+     if( pIndex && pIndex->tnum==0 ){
+       p->u.btree.pIndex = 0;
+     }
+   }
+-  return SQLITE_OK;
++  return rc;
+ }
+ 
+ /*
+@@ -120890,8 +136962,9 @@
+         /* In the absence of explicit truth probabilities, use heuristics to
+         ** guess a reasonable truth probability. */
+         pLoop->nOut--;
+-        if( pTerm->eOperator&WO_EQ ){
++        if( pTerm->eOperator&(WO_EQ|WO_IS) ){
+           Expr *pRight = pTerm->pExpr->pRight;
++          testcase( pTerm->pExpr->op==TK_IS );
+           if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
+             k = 10;
+           }else{
+@@ -120905,6 +136978,72 @@
+   if( pLoop->nOut > nRow-iReduce )  pLoop->nOut = nRow - iReduce;
+ }
+ 
++/* 
++** Term pTerm is a vector range comparison operation. The first comparison
++** in the vector can be optimized using column nEq of the index. This
++** function returns the total number of vector elements that can be used
++** as part of the range comparison.
++**
++** For example, if the query is:
++**
++**   WHERE a = ? AND (b, c, d) > (?, ?, ?)
++**
++** and the index:
++**
++**   CREATE INDEX ... ON (a, b, c, d, e)
++**
++** then this function would be invoked with nEq=1. The value returned in
++** this case is 3.
++*/
++static int whereRangeVectorLen(
++  Parse *pParse,       /* Parsing context */
++  int iCur,            /* Cursor open on pIdx */
++  Index *pIdx,         /* The index to be used for a inequality constraint */
++  int nEq,             /* Number of prior equality constraints on same index */
++  WhereTerm *pTerm     /* The vector inequality constraint */
++){
++  int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft);
++  int i;
++
++  nCmp = MIN(nCmp, (pIdx->nColumn - nEq));
++  for(i=1; i<nCmp; i++){
++    /* Test if comparison i of pTerm is compatible with column (i+nEq) 
++    ** of the index. If not, exit the loop.  */
++    char aff;                     /* Comparison affinity */
++    char idxaff = 0;              /* Indexed columns affinity */
++    CollSeq *pColl;               /* Comparison collation sequence */
++    Expr *pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr;
++    Expr *pRhs = pTerm->pExpr->pRight;
++    if( pRhs->flags & EP_xIsSelect ){
++      pRhs = pRhs->x.pSelect->pEList->a[i].pExpr;
++    }else{
++      pRhs = pRhs->x.pList->a[i].pExpr;
++    }
++
++    /* Check that the LHS of the comparison is a column reference to
++    ** the right column of the right source table. And that the sort
++    ** order of the index column is the same as the sort order of the
++    ** leftmost index column.  */
++    if( pLhs->op!=TK_COLUMN 
++     || pLhs->iTable!=iCur 
++     || pLhs->iColumn!=pIdx->aiColumn[i+nEq] 
++     || pIdx->aSortOrder[i+nEq]!=pIdx->aSortOrder[nEq]
++    ){
++      break;
++    }
++
++    testcase( pLhs->iColumn==XN_ROWID );
++    aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs));
++    idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn);
++    if( aff!=idxaff ) break;
++
++    pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
++    if( pColl==0 ) break;
++    if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break;
++  }
++  return i;
++}
++
+ /*
+ ** Adjust the cost C by the costMult facter T.  This only occurs if
+ ** compiled with -DSQLITE_ENABLE_COSTMULT
+@@ -120943,40 +137082,43 @@
+   Bitmask saved_prereq;           /* Original value of pNew->prereq */
+   u16 saved_nLTerm;               /* Original value of pNew->nLTerm */
+   u16 saved_nEq;                  /* Original value of pNew->u.btree.nEq */
++  u16 saved_nBtm;                 /* Original value of pNew->u.btree.nBtm */
++  u16 saved_nTop;                 /* Original value of pNew->u.btree.nTop */
+   u16 saved_nSkip;                /* Original value of pNew->nSkip */
+   u32 saved_wsFlags;              /* Original value of pNew->wsFlags */
+   LogEst saved_nOut;              /* Original value of pNew->nOut */
+-  int iCol;                       /* Index of the column in the table */
+   int rc = SQLITE_OK;             /* Return code */
+   LogEst rSize;                   /* Number of rows in the table */
+   LogEst rLogSize;                /* Logarithm of table size */
+   WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
+ 
+   pNew = pBuilder->pNew;
+-  if( db->mallocFailed ) return SQLITE_NOMEM;
++  if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
++  WHERETRACE(0x800, ("BEGIN addBtreeIdx(%s), nEq=%d\n",
++                     pProbe->zName, pNew->u.btree.nEq));
+ 
+   assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
+   assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
+   if( pNew->wsFlags & WHERE_BTM_LIMIT ){
+     opMask = WO_LT|WO_LE;
+-  }else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
+-    opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
+   }else{
+-    opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
++    assert( pNew->u.btree.nBtm==0 );
++    opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
+   }
+   if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
+ 
+   assert( pNew->u.btree.nEq<pProbe->nColumn );
+-  iCol = pProbe->aiColumn[pNew->u.btree.nEq];
+ 
+-  pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol,
+-                        opMask, pProbe);
+   saved_nEq = pNew->u.btree.nEq;
++  saved_nBtm = pNew->u.btree.nBtm;
++  saved_nTop = pNew->u.btree.nTop;
+   saved_nSkip = pNew->nSkip;
+   saved_nLTerm = pNew->nLTerm;
+   saved_wsFlags = pNew->wsFlags;
+   saved_prereq = pNew->prereq;
+   saved_nOut = pNew->nOut;
++  pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, saved_nEq,
++                        opMask, pProbe);
+   pNew->rSetup = 0;
+   rSize = pProbe->aiRowLogEst[0];
+   rLogSize = estLog(rSize);
+@@ -120989,7 +137131,7 @@
+     int nRecValid = pBuilder->nRecValid;
+ #endif
+     if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
+-     && (iCol<0 || pSrc->pTab->aCol[iCol].notNull)
++     && indexColumnNotNull(pProbe, saved_nEq)
+     ){
+       continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */
+     }
+@@ -120999,8 +137141,27 @@
+     ** to mix with a lower range bound from some other source */
+     if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
+ 
++    /* Do not allow IS constraints from the WHERE clause to be used by the
++    ** right table of a LEFT JOIN.  Only constraints in the ON clause are
++    ** allowed */
++    if( (pSrc->fg.jointype & JT_LEFT)!=0
++     && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
++     && (eOp & (WO_IS|WO_ISNULL))!=0
++    ){
++      testcase( eOp & WO_IS );
++      testcase( eOp & WO_ISNULL );
++      continue;
++    }
++
++    if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
++      pBuilder->bldFlags |= SQLITE_BLDF_UNIQUE;
++    }else{
++      pBuilder->bldFlags |= SQLITE_BLDF_INDEXED;
++    }
+     pNew->wsFlags = saved_wsFlags;
+     pNew->u.btree.nEq = saved_nEq;
++    pNew->u.btree.nBtm = saved_nBtm;
++    pNew->u.btree.nTop = saved_nTop;
+     pNew->nLTerm = saved_nLTerm;
+     if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
+     pNew->aLTerm[pNew->nLTerm++] = pTerm;
+@@ -121017,17 +137178,30 @@
+       pNew->wsFlags |= WHERE_COLUMN_IN;
+       if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+         /* "x IN (SELECT ...)":  TUNING: the SELECT returns 25 rows */
++        int i;
+         nIn = 46;  assert( 46==sqlite3LogEst(25) );
++
++        /* The expression may actually be of the form (x, y) IN (SELECT...).
++        ** In this case there is a separate term for each of (x) and (y).
++        ** However, the nIn multiplier should only be applied once, not once
++        ** for each such term. The following loop checks that pTerm is the
++        ** first such term in use, and sets nIn back to 0 if it is not. */
++        for(i=0; i<pNew->nLTerm-1; i++){
++          if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0;
++        }
+       }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
+         /* "x IN (value, value, ...)" */
+         nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
++        assert( nIn>0 );  /* RHS always has 2 or more terms...  The parser
++                          ** changes "x IN (?)" into "x=?". */
+       }
+-      assert( nIn>0 );  /* RHS always has 2 or more terms...  The parser
+-                        ** changes "x IN (?)" into "x=?". */
+-
+-    }else if( eOp & (WO_EQ) ){
++    }else if( eOp & (WO_EQ|WO_IS) ){
++      int iCol = pProbe->aiColumn[saved_nEq];
+       pNew->wsFlags |= WHERE_COLUMN_EQ;
+-      if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){
++      assert( saved_nEq==pNew->u.btree.nEq );
++      if( iCol==XN_ROWID 
++       || (iCol>0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
++      ){
+         if( iCol>=0 && pProbe->uniqNotNull==0 ){
+           pNew->wsFlags |= WHERE_UNQ_WANTED;
+         }else{
+@@ -121040,6 +137214,9 @@
+       testcase( eOp & WO_GT );
+       testcase( eOp & WO_GE );
+       pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
++      pNew->u.btree.nBtm = whereRangeVectorLen(
++          pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm
++      );
+       pBtm = pTerm;
+       pTop = 0;
+       if( pTerm->wtFlags & TERM_LIKEOPT ){
+@@ -121052,12 +137229,16 @@
+         if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
+         pNew->aLTerm[pNew->nLTerm++] = pTop;
+         pNew->wsFlags |= WHERE_TOP_LIMIT;
++        pNew->u.btree.nTop = 1;
+       }
+     }else{
+       assert( eOp & (WO_LT|WO_LE) );
+       testcase( eOp & WO_LT );
+       testcase( eOp & WO_LE );
+       pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
++      pNew->u.btree.nTop = whereRangeVectorLen(
++          pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm
++      );
+       pTop = pTerm;
+       pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
+                      pNew->aLTerm[pNew->nLTerm-2] : 0;
+@@ -121075,10 +137256,10 @@
+       whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew);
+     }else{
+       int nEq = ++pNew->u.btree.nEq;
+-      assert( eOp & (WO_ISNULL|WO_EQ|WO_IN) );
++      assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) );
+ 
+       assert( pNew->nOut==saved_nOut );
+-      if( pTerm->truthProb<=0 && iCol>=0 ){
++      if( pTerm->truthProb<=0 && pProbe->aiColumn[saved_nEq]>=0 ){
+         assert( (eOp & WO_IN) || nIn==0 );
+         testcase( eOp & WO_IN );
+         pNew->nOut += pTerm->truthProb;
+@@ -121092,8 +137273,9 @@
+          && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
+         ){
+           Expr *pExpr = pTerm->pExpr;
+-          if( (eOp & (WO_EQ|WO_ISNULL))!=0 ){
++          if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
+             testcase( eOp & WO_EQ );
++            testcase( eOp & WO_IS );
+             testcase( eOp & WO_ISNULL );
+             rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
+           }else{
+@@ -121156,6 +137338,8 @@
+   }
+   pNew->prereq = saved_prereq;
+   pNew->u.btree.nEq = saved_nEq;
++  pNew->u.btree.nBtm = saved_nBtm;
++  pNew->u.btree.nTop = saved_nTop;
+   pNew->nSkip = saved_nSkip;
+   pNew->wsFlags = saved_wsFlags;
+   pNew->nOut = saved_nOut;
+@@ -121195,6 +137379,8 @@
+     pNew->wsFlags = saved_wsFlags;
+   }
+ 
++  WHERETRACE(0x800, ("END addBtreeIdx(%s), nEq=%d, rc=%d\n",
++                      pProbe->zName, saved_nEq, rc));
+   return rc;
+ }
+ 
+@@ -121212,18 +137398,25 @@
+   int iCursor
+ ){
+   ExprList *pOB;
++  ExprList *aColExpr;
+   int ii, jj;
+ 
+   if( pIndex->bUnordered ) return 0;
+   if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0;
+   for(ii=0; ii<pOB->nExpr; ii++){
+     Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr);
+-    if( pExpr->op!=TK_COLUMN ) return 0;
+-    if( pExpr->iTable==iCursor ){
++    if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){
+       if( pExpr->iColumn<0 ) return 1;
+       for(jj=0; jj<pIndex->nKeyCol; jj++){
+         if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1;
+       }
++    }else if( (aColExpr = pIndex->aColExpr)!=0 ){
++      for(jj=0; jj<pIndex->nKeyCol; jj++){
++        if( pIndex->aiColumn[jj]!=XN_EXPR ) continue;
++        if( sqlite3ExprCompare(0, pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){
++          return 1;
++        }
++      }
+     }
+   }
+   return 0;
+@@ -121253,10 +137446,16 @@
+ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
+   int i;
+   WhereTerm *pTerm;
++  Parse *pParse = pWC->pWInfo->pParse;
++  while( pWhere->op==TK_AND ){
++    if( !whereUsablePartialIndex(iTab,pWC,pWhere->pLeft) ) return 0;
++    pWhere = pWhere->pRight;
++  }
++  if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
+   for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
+     Expr *pExpr = pTerm->pExpr;
+-    if( sqlite3ExprImpliesExpr(pExpr, pWhere, iTab) 
+-     && (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
++    if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
++     && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) 
+     ){
+       return 1;
+     }
+@@ -121266,7 +137465,7 @@
+ 
+ /*
+ ** Add all WhereLoop objects for a single table of the join where the table
+-** is idenfied by pBuilder->pNew->iTab.  That table is guaranteed to be
++** is identified by pBuilder->pNew->iTab.  That table is guaranteed to be
+ ** a b-tree table, not a virtual table.
+ **
+ ** The costs (WhereLoop.rRun) of the b-tree loops added by this function
+@@ -121302,7 +137501,7 @@
+ */
+ static int whereLoopAddBtree(
+   WhereLoopBuilder *pBuilder, /* WHERE clause information */
+-  Bitmask mExtra              /* Extra prerequesites for using this table */
++  Bitmask mPrereq             /* Extra prerequesites for using this table */
+ ){
+   WhereInfo *pWInfo;          /* WHERE analysis context */
+   Index *pProbe;              /* An index we are evaluating */
+@@ -121328,9 +137527,9 @@
+   pWC = pBuilder->pWC;
+   assert( !IsVirtual(pSrc->pTab) );
+ 
+-  if( pSrc->pIndex ){
++  if( pSrc->pIBIndex ){
+     /* An INDEXED BY clause specifies a particular index to use */
+-    pProbe = pSrc->pIndex;
++    pProbe = pSrc->pIBIndex;
+   }else if( !HasRowid(pTab) ){
+     pProbe = pTab->pIndex;
+   }else{
+@@ -121350,7 +137549,7 @@
+     aiRowEstPk[0] = pTab->nRowLogEst;
+     aiRowEstPk[1] = 0;
+     pFirst = pSrc->pTab->pIndex;
+-    if( pSrc->notIndexed==0 ){
++    if( pSrc->fg.notIndexed==0 ){
+       /* The real indices of the table are only considered if the
+       ** NOT INDEXED qualifier is omitted from the FROM clause */
+       sPk.pNext = pFirst;
+@@ -121362,15 +137561,14 @@
+ 
+ #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
+   /* Automatic indexes */
+-  if( !pBuilder->pOrSet
+-   && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0
++  if( !pBuilder->pOrSet      /* Not part of an OR optimization */
++   && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
+    && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
+-   && pSrc->pIndex==0
+-   && !pSrc->viaCoroutine
+-   && !pSrc->notIndexed
+-   && HasRowid(pTab)
+-   && !pSrc->isCorrelated
+-   && !pSrc->isRecursive
++   && pSrc->pIBIndex==0      /* Has no INDEXED BY clause */
++   && !pSrc->fg.notIndexed   /* Has no NOT INDEXED clause */
++   && HasRowid(pTab)         /* Not WITHOUT ROWID table. (FIXME: Why not?) */
++   && !pSrc->fg.isCorrelated /* Not a correlated subquery */
++   && !pSrc->fg.isRecursive  /* Not a recursive common table expression. */
+   ){
+     /* Generate auto-index WhereLoops */
+     WhereTerm *pTerm;
+@@ -121396,6 +137594,7 @@
+           pNew->rSetup += 24;
+         }
+         ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
++        if( pNew->rSetup<0 ) pNew->rSetup = 0;
+         /* TUNING: Each index lookup yields 20 rows in the table.  This
+         ** is more than the usual guess of 10 rows, since we have no way
+         ** of knowing how selective the index will ultimately be.  It would
+@@ -121403,7 +137602,7 @@
+         pNew->nOut = 43;  assert( 43==sqlite3LogEst(20) );
+         pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut);
+         pNew->wsFlags = WHERE_AUTO_INDEX;
+-        pNew->prereq = mExtra | pTerm->prereqRight;
++        pNew->prereq = mPrereq | pTerm->prereqRight;
+         rc = whereLoopInsert(pBuilder, pNew);
+       }
+     }
+@@ -121420,11 +137619,13 @@
+     }
+     rSize = pProbe->aiRowLogEst[0];
+     pNew->u.btree.nEq = 0;
++    pNew->u.btree.nBtm = 0;
++    pNew->u.btree.nTop = 0;
+     pNew->nSkip = 0;
+     pNew->nLTerm = 0;
+     pNew->iSortIdx = 0;
+     pNew->rSetup = 0;
+-    pNew->prereq = mExtra;
++    pNew->prereq = mPrereq;
+     pNew->nOut = rSize;
+     pNew->u.btree.pIndex = pProbe;
+     b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
+@@ -121456,6 +137657,7 @@
+       /* Full scan via index */
+       if( b
+        || !HasRowid(pTab)
++       || pProbe->pPartIdxWhere!=0
+        || ( m==0
+          && pProbe->bUnordered==0
+          && (pProbe->szIdxRow<pTab->szTabRow)
+@@ -121468,11 +137670,34 @@
+ 
+         /* The cost of visiting the index rows is N*K, where K is
+         ** between 1.1 and 3.0, depending on the relative sizes of the
+-        ** index and table rows. If this is a non-covering index scan,
+-        ** also add the cost of visiting table rows (N*3.0).  */
++        ** index and table rows. */
+         pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow;
+         if( m!=0 ){
+-          pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16);
++          /* If this is a non-covering index scan, add in the cost of
++          ** doing table lookups.  The cost will be 3x the number of
++          ** lookups.  Take into account WHERE clause terms that can be
++          ** satisfied using just the index, and that do not require a
++          ** table lookup. */
++          LogEst nLookup = rSize + 16;  /* Base cost:  N*3 */
++          int ii;
++          int iCur = pSrc->iCursor;
++          WhereClause *pWC2 = &pWInfo->sWC;
++          for(ii=0; ii<pWC2->nTerm; ii++){
++            WhereTerm *pTerm = &pWC2->a[ii];
++            if( !sqlite3ExprCoveredByIndex(pTerm->pExpr, iCur, pProbe) ){
++              break;
++            }
++            /* pTerm can be evaluated using just the index.  So reduce
++            ** the expected number of table lookups accordingly */
++            if( pTerm->truthProb<=0 ){
++              nLookup += pTerm->truthProb;
++            }else{
++              nLookup--;
++              if( pTerm->eOperator & (WO_EQ|WO_IS) ) nLookup -= 19;
++            }
++          }
++          
++          pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup);
+         }
+         ApplyCostMultiplier(pNew->rRun, pTab->costMult);
+         whereLoopOutputAdjust(pWC, pNew, rSize);
+@@ -121482,7 +137707,15 @@
+       }
+     }
+ 
++    pBuilder->bldFlags = 0;
+     rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
++    if( pBuilder->bldFlags==SQLITE_BLDF_INDEXED ){
++      /* If a non-unique index is used, or if a prefix of the key for
++      ** unique index is used (making the index functionally non-unique)
++      ** then the sqlite_stat1 data becomes important for scoring the
++      ** plan */
++      pTab->tabFlags |= TF_StatsUsed;
++    }
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+     sqlite3Stat4ProbeFree(pBuilder->pRec);
+     pBuilder->nRecValid = 0;
+@@ -121491,176 +137724,300 @@
+ 
+     /* If there was an INDEXED BY clause, then only that one index is
+     ** considered. */
+-    if( pSrc->pIndex ) break;
++    if( pSrc->pIBIndex ) break;
+   }
+   return rc;
+ }
+ 
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
++
++/*
++** Argument pIdxInfo is already populated with all constraints that may
++** be used by the virtual table identified by pBuilder->pNew->iTab. This
++** function marks a subset of those constraints usable, invokes the
++** xBestIndex method and adds the returned plan to pBuilder.
++**
++** A constraint is marked usable if:
++**
++**   * Argument mUsable indicates that its prerequisites are available, and
++**
++**   * It is not one of the operators specified in the mExclude mask passed
++**     as the fourth argument (which in practice is either WO_IN or 0).
++**
++** Argument mPrereq is a mask of tables that must be scanned before the
++** virtual table in question. These are added to the plans prerequisites
++** before it is added to pBuilder.
++**
++** Output parameter *pbIn is set to true if the plan added to pBuilder
++** uses one or more WO_IN terms, or false otherwise.
++*/
++static int whereLoopAddVirtualOne(
++  WhereLoopBuilder *pBuilder,
++  Bitmask mPrereq,                /* Mask of tables that must be used. */
++  Bitmask mUsable,                /* Mask of usable tables */
++  u16 mExclude,                   /* Exclude terms using these operators */
++  sqlite3_index_info *pIdxInfo,   /* Populated object for xBestIndex */
++  u16 mNoOmit,                    /* Do not omit these constraints */
++  int *pbIn                       /* OUT: True if plan uses an IN(...) op */
++){
++  WhereClause *pWC = pBuilder->pWC;
++  struct sqlite3_index_constraint *pIdxCons;
++  struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
++  int i;
++  int mxTerm;
++  int rc = SQLITE_OK;
++  WhereLoop *pNew = pBuilder->pNew;
++  Parse *pParse = pBuilder->pWInfo->pParse;
++  struct SrcList_item *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab];
++  int nConstraint = pIdxInfo->nConstraint;
++
++  assert( (mUsable & mPrereq)==mPrereq );
++  *pbIn = 0;
++  pNew->prereq = mPrereq;
++
++  /* Set the usable flag on the subset of constraints identified by 
++  ** arguments mUsable and mExclude. */
++  pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
++  for(i=0; i<nConstraint; i++, pIdxCons++){
++    WhereTerm *pTerm = &pWC->a[pIdxCons->iTermOffset];
++    pIdxCons->usable = 0;
++    if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight 
++     && (pTerm->eOperator & mExclude)==0
++    ){
++      pIdxCons->usable = 1;
++    }
++  }
++
++  /* Initialize the output fields of the sqlite3_index_info structure */
++  memset(pUsage, 0, sizeof(pUsage[0])*nConstraint);
++  assert( pIdxInfo->needToFreeIdxStr==0 );
++  pIdxInfo->idxStr = 0;
++  pIdxInfo->idxNum = 0;
++  pIdxInfo->orderByConsumed = 0;
++  pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
++  pIdxInfo->estimatedRows = 25;
++  pIdxInfo->idxFlags = 0;
++  pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
++
++  /* Invoke the virtual table xBestIndex() method */
++  rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
++  if( rc ) return rc;
++
++  mxTerm = -1;
++  assert( pNew->nLSlot>=nConstraint );
++  for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
++  pNew->u.vtab.omitMask = 0;
++  pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
++  for(i=0; i<nConstraint; i++, pIdxCons++){
++    int iTerm;
++    if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
++      WhereTerm *pTerm;
++      int j = pIdxCons->iTermOffset;
++      if( iTerm>=nConstraint
++       || j<0
++       || j>=pWC->nTerm
++       || pNew->aLTerm[iTerm]!=0
++       || pIdxCons->usable==0
++      ){
++        rc = SQLITE_ERROR;
++        sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
++        return rc;
++      }
++      testcase( iTerm==nConstraint-1 );
++      testcase( j==0 );
++      testcase( j==pWC->nTerm-1 );
++      pTerm = &pWC->a[j];
++      pNew->prereq |= pTerm->prereqRight;
++      assert( iTerm<pNew->nLSlot );
++      pNew->aLTerm[iTerm] = pTerm;
++      if( iTerm>mxTerm ) mxTerm = iTerm;
++      testcase( iTerm==15 );
++      testcase( iTerm==16 );
++      if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
++      if( (pTerm->eOperator & WO_IN)!=0 ){
++        /* A virtual table that is constrained by an IN clause may not
++        ** consume the ORDER BY clause because (1) the order of IN terms
++        ** is not necessarily related to the order of output terms and
++        ** (2) Multiple outputs from a single IN value will not merge
++        ** together.  */
++        pIdxInfo->orderByConsumed = 0;
++        pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
++        *pbIn = 1; assert( (mExclude & WO_IN)==0 );
++      }
++    }
++  }
++  pNew->u.vtab.omitMask &= ~mNoOmit;
++
++  pNew->nLTerm = mxTerm+1;
++  assert( pNew->nLTerm<=pNew->nLSlot );
++  pNew->u.vtab.idxNum = pIdxInfo->idxNum;
++  pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
++  pIdxInfo->needToFreeIdxStr = 0;
++  pNew->u.vtab.idxStr = pIdxInfo->idxStr;
++  pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
++      pIdxInfo->nOrderBy : 0);
++  pNew->rSetup = 0;
++  pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
++  pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
++
++  /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated
++  ** that the scan will visit at most one row. Clear it otherwise. */
++  if( pIdxInfo->idxFlags & SQLITE_INDEX_SCAN_UNIQUE ){
++    pNew->wsFlags |= WHERE_ONEROW;
++  }else{
++    pNew->wsFlags &= ~WHERE_ONEROW;
++  }
++  rc = whereLoopInsert(pBuilder, pNew);
++  if( pNew->u.vtab.needFree ){
++    sqlite3_free(pNew->u.vtab.idxStr);
++    pNew->u.vtab.needFree = 0;
++  }
++  WHERETRACE(0xffff, ("  bIn=%d prereqIn=%04llx prereqOut=%04llx\n",
++                      *pbIn, (sqlite3_uint64)mPrereq,
++                      (sqlite3_uint64)(pNew->prereq & ~mPrereq)));
++
++  return rc;
++}
++
++
+ /*
+ ** Add all WhereLoop objects for a table of the join identified by
+ ** pBuilder->pNew->iTab.  That table is guaranteed to be a virtual table.
++**
++** If there are no LEFT or CROSS JOIN joins in the query, both mPrereq and
++** mUnusable are set to 0. Otherwise, mPrereq is a mask of all FROM clause
++** entries that occur before the virtual table in the FROM clause and are
++** separated from it by at least one LEFT or CROSS JOIN. Similarly, the
++** mUnusable mask contains all FROM clause entries that occur after the
++** virtual table and are separated from it by at least one LEFT or 
++** CROSS JOIN. 
++**
++** For example, if the query were:
++**
++**   ... FROM t1, t2 LEFT JOIN t3, t4, vt CROSS JOIN t5, t6;
++**
++** then mPrereq corresponds to (t1, t2) and mUnusable to (t5, t6).
++**
++** All the tables in mPrereq must be scanned before the current virtual 
++** table. So any terms for which all prerequisites are satisfied by 
++** mPrereq may be specified as "usable" in all calls to xBestIndex. 
++** Conversely, all tables in mUnusable must be scanned after the current
++** virtual table, so any terms for which the prerequisites overlap with
++** mUnusable should always be configured as "not-usable" for xBestIndex.
+ */
+ static int whereLoopAddVirtual(
+   WhereLoopBuilder *pBuilder,  /* WHERE clause information */
+-  Bitmask mExtra
++  Bitmask mPrereq,             /* Tables that must be scanned before this one */
++  Bitmask mUnusable            /* Tables that must be scanned after this one */
+ ){
++  int rc = SQLITE_OK;          /* Return code */
+   WhereInfo *pWInfo;           /* WHERE analysis context */
+   Parse *pParse;               /* The parsing context */
+   WhereClause *pWC;            /* The WHERE clause */
+   struct SrcList_item *pSrc;   /* The FROM clause term to search */
+-  Table *pTab;
+-  sqlite3 *db;
+-  sqlite3_index_info *pIdxInfo;
+-  struct sqlite3_index_constraint *pIdxCons;
+-  struct sqlite3_index_constraint_usage *pUsage;
+-  WhereTerm *pTerm;
+-  int i, j;
+-  int iTerm, mxTerm;
+-  int nConstraint;
+-  int seenIn = 0;              /* True if an IN operator is seen */
+-  int seenVar = 0;             /* True if a non-constant constraint is seen */
+-  int iPhase;                  /* 0: const w/o IN, 1: const, 2: no IN,  2: IN */
++  sqlite3_index_info *p;       /* Object to pass to xBestIndex() */
++  int nConstraint;             /* Number of constraints in p */
++  int bIn;                     /* True if plan uses IN(...) operator */
+   WhereLoop *pNew;
+-  int rc = SQLITE_OK;
++  Bitmask mBest;               /* Tables used by best possible plan */
++  u16 mNoOmit;
+ 
++  assert( (mPrereq & mUnusable)==0 );
+   pWInfo = pBuilder->pWInfo;
+   pParse = pWInfo->pParse;
+-  db = pParse->db;
+   pWC = pBuilder->pWC;
+   pNew = pBuilder->pNew;
+   pSrc = &pWInfo->pTabList->a[pNew->iTab];
+-  pTab = pSrc->pTab;
+-  assert( IsVirtual(pTab) );
+-  pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pBuilder->pOrderBy);
+-  if( pIdxInfo==0 ) return SQLITE_NOMEM;
+-  pNew->prereq = 0;
++  assert( IsVirtual(pSrc->pTab) );
++  p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy, 
++      &mNoOmit);
++  if( p==0 ) return SQLITE_NOMEM_BKPT;
+   pNew->rSetup = 0;
+   pNew->wsFlags = WHERE_VIRTUALTABLE;
+   pNew->nLTerm = 0;
+   pNew->u.vtab.needFree = 0;
+-  pUsage = pIdxInfo->aConstraintUsage;
+-  nConstraint = pIdxInfo->nConstraint;
+-  if( whereLoopResize(db, pNew, nConstraint) ){
+-    sqlite3DbFree(db, pIdxInfo);
+-    return SQLITE_NOMEM;
+-  }
+-
+-  for(iPhase=0; iPhase<=3; iPhase++){
+-    if( !seenIn && (iPhase&1)!=0 ){
+-      iPhase++;
+-      if( iPhase>3 ) break;
+-    }
+-    if( !seenVar && iPhase>1 ) break;
+-    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
+-    for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
+-      j = pIdxCons->iTermOffset;
+-      pTerm = &pWC->a[j];
+-      switch( iPhase ){
+-        case 0:    /* Constants without IN operator */
+-          pIdxCons->usable = 0;
+-          if( (pTerm->eOperator & WO_IN)!=0 ){
+-            seenIn = 1;
+-          }
+-          if( pTerm->prereqRight!=0 ){
+-            seenVar = 1;
+-          }else if( (pTerm->eOperator & WO_IN)==0 ){
+-            pIdxCons->usable = 1;
+-          }
+-          break;
+-        case 1:    /* Constants with IN operators */
+-          assert( seenIn );
+-          pIdxCons->usable = (pTerm->prereqRight==0);
+-          break;
+-        case 2:    /* Variables without IN */
+-          assert( seenVar );
+-          pIdxCons->usable = (pTerm->eOperator & WO_IN)==0;
+-          break;
+-        default:   /* Variables with IN */
+-          assert( seenVar && seenIn );
+-          pIdxCons->usable = 1;
+-          break;
++  nConstraint = p->nConstraint;
++  if( whereLoopResize(pParse->db, pNew, nConstraint) ){
++    sqlite3DbFree(pParse->db, p);
++    return SQLITE_NOMEM_BKPT;
++  }
++
++  /* First call xBestIndex() with all constraints usable. */
++  WHERETRACE(0x40, ("  VirtualOne: all usable\n"));
++  rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
++
++  /* If the call to xBestIndex() with all terms enabled produced a plan
++  ** that does not require any source tables (IOW: a plan with mBest==0),
++  ** then there is no point in making any further calls to xBestIndex() 
++  ** since they will all return the same result (if the xBestIndex()
++  ** implementation is sane). */
++  if( rc==SQLITE_OK && (mBest = (pNew->prereq & ~mPrereq))!=0 ){
++    int seenZero = 0;             /* True if a plan with no prereqs seen */
++    int seenZeroNoIN = 0;         /* Plan with no prereqs and no IN(...) seen */
++    Bitmask mPrev = 0;
++    Bitmask mBestNoIn = 0;
++
++    /* If the plan produced by the earlier call uses an IN(...) term, call
++    ** xBestIndex again, this time with IN(...) terms disabled. */
++    if( bIn ){
++      WHERETRACE(0x40, ("  VirtualOne: all usable w/o IN\n"));
++      rc = whereLoopAddVirtualOne(
++          pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn);
++      assert( bIn==0 );
++      mBestNoIn = pNew->prereq & ~mPrereq;
++      if( mBestNoIn==0 ){
++        seenZero = 1;
++        seenZeroNoIN = 1;
+       }
+     }
+-    memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
+-    if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
+-    pIdxInfo->idxStr = 0;
+-    pIdxInfo->idxNum = 0;
+-    pIdxInfo->needToFreeIdxStr = 0;
+-    pIdxInfo->orderByConsumed = 0;
+-    pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
+-    pIdxInfo->estimatedRows = 25;
+-    rc = vtabBestIndex(pParse, pTab, pIdxInfo);
+-    if( rc ) goto whereLoopAddVtab_exit;
+-    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
+-    pNew->prereq = mExtra;
+-    mxTerm = -1;
+-    assert( pNew->nLSlot>=nConstraint );
+-    for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
+-    pNew->u.vtab.omitMask = 0;
+-    for(i=0; i<nConstraint; i++, pIdxCons++){
+-      if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
+-        j = pIdxCons->iTermOffset;
+-        if( iTerm>=nConstraint
+-         || j<0
+-         || j>=pWC->nTerm
+-         || pNew->aLTerm[iTerm]!=0
+-        ){
+-          rc = SQLITE_ERROR;
+-          sqlite3ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName);
+-          goto whereLoopAddVtab_exit;
+-        }
+-        testcase( iTerm==nConstraint-1 );
+-        testcase( j==0 );
+-        testcase( j==pWC->nTerm-1 );
+-        pTerm = &pWC->a[j];
+-        pNew->prereq |= pTerm->prereqRight;
+-        assert( iTerm<pNew->nLSlot );
+-        pNew->aLTerm[iTerm] = pTerm;
+-        if( iTerm>mxTerm ) mxTerm = iTerm;
+-        testcase( iTerm==15 );
+-        testcase( iTerm==16 );
+-        if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
+-        if( (pTerm->eOperator & WO_IN)!=0 ){
+-          if( pUsage[i].omit==0 ){
+-            /* Do not attempt to use an IN constraint if the virtual table
+-            ** says that the equivalent EQ constraint cannot be safely omitted.
+-            ** If we do attempt to use such a constraint, some rows might be
+-            ** repeated in the output. */
+-            break;
+-          }
+-          /* A virtual table that is constrained by an IN clause may not
+-          ** consume the ORDER BY clause because (1) the order of IN terms
+-          ** is not necessarily related to the order of output terms and
+-          ** (2) Multiple outputs from a single IN value will not merge
+-          ** together.  */
+-          pIdxInfo->orderByConsumed = 0;
+-        }
++
++    /* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq) 
++    ** in the set of terms that apply to the current virtual table.  */
++    while( rc==SQLITE_OK ){
++      int i;
++      Bitmask mNext = ALLBITS;
++      assert( mNext>0 );
++      for(i=0; i<nConstraint; i++){
++        Bitmask mThis = (
++            pWC->a[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq
++        );
++        if( mThis>mPrev && mThis<mNext ) mNext = mThis;
+       }
+-    }
+-    if( i>=nConstraint ){
+-      pNew->nLTerm = mxTerm+1;
+-      assert( pNew->nLTerm<=pNew->nLSlot );
+-      pNew->u.vtab.idxNum = pIdxInfo->idxNum;
+-      pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
+-      pIdxInfo->needToFreeIdxStr = 0;
+-      pNew->u.vtab.idxStr = pIdxInfo->idxStr;
+-      pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
+-                                      pIdxInfo->nOrderBy : 0);
+-      pNew->rSetup = 0;
+-      pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
+-      pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
+-      whereLoopInsert(pBuilder, pNew);
+-      if( pNew->u.vtab.needFree ){
+-        sqlite3_free(pNew->u.vtab.idxStr);
+-        pNew->u.vtab.needFree = 0;
++      mPrev = mNext;
++      if( mNext==ALLBITS ) break;
++      if( mNext==mBest || mNext==mBestNoIn ) continue;
++      WHERETRACE(0x40, ("  VirtualOne: mPrev=%04llx mNext=%04llx\n",
++                       (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
++      rc = whereLoopAddVirtualOne(
++          pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn);
++      if( pNew->prereq==mPrereq ){
++        seenZero = 1;
++        if( bIn==0 ) seenZeroNoIN = 1;
+       }
+     }
+-  }  
+ 
+-whereLoopAddVtab_exit:
+-  if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
+-  sqlite3DbFree(db, pIdxInfo);
++    /* If the calls to xBestIndex() in the above loop did not find a plan
++    ** that requires no source tables at all (i.e. one guaranteed to be
++    ** usable), make a call here with all source tables disabled */
++    if( rc==SQLITE_OK && seenZero==0 ){
++      WHERETRACE(0x40, ("  VirtualOne: all disabled\n"));
++      rc = whereLoopAddVirtualOne(
++          pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn);
++      if( bIn==0 ) seenZeroNoIN = 1;
++    }
++
++    /* If the calls to xBestIndex() have so far failed to find a plan
++    ** that requires no source tables at all and does not use an IN(...)
++    ** operator, make a final call to obtain one here.  */
++    if( rc==SQLITE_OK && seenZeroNoIN==0 ){
++      WHERETRACE(0x40, ("  VirtualOne: all disabled and w/o IN\n"));
++      rc = whereLoopAddVirtualOne(
++          pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn);
++    }
++  }
++
++  if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
++  sqlite3DbFreeNN(pParse->db, p);
+   return rc;
+ }
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+@@ -121669,7 +138026,11 @@
+ ** Add WhereLoop entries to handle OR terms.  This works for either
+ ** btrees or virtual tables.
+ */
+-static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){
++static int whereLoopAddOr(
++  WhereLoopBuilder *pBuilder, 
++  Bitmask mPrereq, 
++  Bitmask mUnusable
++){
+   WhereInfo *pWInfo = pBuilder->pWInfo;
+   WhereClause *pWC;
+   WhereLoop *pNew;
+@@ -121721,21 +138082,19 @@
+         WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n", 
+                    (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm));
+         if( sqlite3WhereTrace & 0x400 ){
+-          for(i=0; i<sSubBuild.pWC->nTerm; i++){
+-            whereTermPrint(&sSubBuild.pWC->a[i], i);
+-          }
++          sqlite3WhereClausePrint(sSubBuild.pWC);
+         }
+ #endif
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+         if( IsVirtual(pItem->pTab) ){
+-          rc = whereLoopAddVirtual(&sSubBuild, mExtra);
++          rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable);
+         }else
+ #endif
+         {
+-          rc = whereLoopAddBtree(&sSubBuild, mExtra);
++          rc = whereLoopAddBtree(&sSubBuild, mPrereq);
+         }
+         if( rc==SQLITE_OK ){
+-          rc = whereLoopAddOr(&sSubBuild, mExtra);
++          rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable);
+         }
+         assert( rc==SQLITE_OK || sCur.n==0 );
+         if( sCur.n==0 ){
+@@ -121792,44 +138151,57 @@
+ */
+ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
+   WhereInfo *pWInfo = pBuilder->pWInfo;
+-  Bitmask mExtra = 0;
++  Bitmask mPrereq = 0;
+   Bitmask mPrior = 0;
+   int iTab;
+   SrcList *pTabList = pWInfo->pTabList;
+   struct SrcList_item *pItem;
++  struct SrcList_item *pEnd = &pTabList->a[pWInfo->nLevel];
+   sqlite3 *db = pWInfo->pParse->db;
+-  int nTabList = pWInfo->nLevel;
+   int rc = SQLITE_OK;
+-  u8 priorJoinType = 0;
+   WhereLoop *pNew;
++  u8 priorJointype = 0;
+ 
+   /* Loop over the tables in the join, from left to right */
+   pNew = pBuilder->pNew;
+   whereLoopInit(pNew);
+-  for(iTab=0, pItem=pTabList->a; iTab<nTabList; iTab++, pItem++){
++  for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
++    Bitmask mUnusable = 0;
+     pNew->iTab = iTab;
+-    pNew->maskSelf = getMask(&pWInfo->sMaskSet, pItem->iCursor);
+-    if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){
+-      mExtra = mPrior;
++    pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
++    if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
++      /* This condition is true when pItem is the FROM clause term on the
++      ** right-hand-side of a LEFT or CROSS JOIN.  */
++      mPrereq = mPrior;
+     }
+-    priorJoinType = pItem->jointype;
++    priorJointype = pItem->fg.jointype;
++#ifndef SQLITE_OMIT_VIRTUALTABLE
+     if( IsVirtual(pItem->pTab) ){
+-      rc = whereLoopAddVirtual(pBuilder, mExtra);
+-    }else{
+-      rc = whereLoopAddBtree(pBuilder, mExtra);
++      struct SrcList_item *p;
++      for(p=&pItem[1]; p<pEnd; p++){
++        if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){
++          mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
++        }
++      }
++      rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable);
++    }else
++#endif /* SQLITE_OMIT_VIRTUALTABLE */
++    {
++      rc = whereLoopAddBtree(pBuilder, mPrereq);
+     }
+     if( rc==SQLITE_OK ){
+-      rc = whereLoopAddOr(pBuilder, mExtra);
++      rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
+     }
+     mPrior |= pNew->maskSelf;
+     if( rc || db->mallocFailed ) break;
+   }
++
+   whereLoopClear(db, pNew);
+   return rc;
+ }
+ 
+ /*
+-** Examine a WherePath (with the addition of the extra WhereLoop of the 5th
++** Examine a WherePath (with the addition of the extra WhereLoop of the 6th
+ ** parameters) to see if it outputs rows in the requested ORDER BY
+ ** (or GROUP BY) without requiring a separate sort operation.  Return N:
+ ** 
+@@ -121849,7 +138221,7 @@
+   WhereInfo *pWInfo,    /* The WHERE clause */
+   ExprList *pOrderBy,   /* ORDER BY or GROUP BY or DISTINCT clause to check */
+   WherePath *pPath,     /* The WherePath to check */
+-  u16 wctrlFlags,       /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */
++  u16 wctrlFlags,       /* WHERE_GROUPBY or _DISTINCTBY or _ORDERBY_LIMIT */
+   u16 nLoop,            /* Number of entries in pPath->aLoop[] */
+   WhereLoop *pLast,     /* Add this WhereLoop to the end of pPath->aLoop[] */
+   Bitmask *pRevMask     /* OUT: Mask of WhereLoops to run in reverse order */
+@@ -121860,6 +138232,7 @@
+   u8 isOrderDistinct;   /* All prior WhereLoops are order-distinct */
+   u8 distinctColumns;   /* True if the loop has UNIQUE NOT NULL columns */
+   u8 isMatch;           /* iColumn matches a term of the ORDER BY clause */
++  u16 eqOpMask;         /* Allowed equality operators */
+   u16 nKeyCol;          /* Number of key columns in pIndex */
+   u16 nColumn;          /* Total number of ordered columns in the index */
+   u16 nOrderBy;         /* Number terms in the ORDER BY clause */
+@@ -121910,12 +138283,21 @@
+   obDone = MASKBIT(nOrderBy)-1;
+   orderDistinctMask = 0;
+   ready = 0;
++  eqOpMask = WO_EQ | WO_IS | WO_ISNULL;
++  if( wctrlFlags & WHERE_ORDERBY_LIMIT ) eqOpMask |= WO_IN;
+   for(iLoop=0; isOrderDistinct && obSat<obDone && iLoop<=nLoop; iLoop++){
+     if( iLoop>0 ) ready |= pLoop->maskSelf;
+-    pLoop = iLoop<nLoop ? pPath->aLoop[iLoop] : pLast;
++    if( iLoop<nLoop ){
++      pLoop = pPath->aLoop[iLoop];
++      if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue;
++    }else{
++      pLoop = pLast;
++    }
+     if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
+       if( pLoop->u.vtab.isOrdered ) obSat = obDone;
+       break;
++    }else{
++      pLoop->u.btree.nIdxCol = 0;
+     }
+     iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;
+ 
+@@ -121929,10 +138311,18 @@
+       pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
+       if( pOBExpr->op!=TK_COLUMN ) continue;
+       if( pOBExpr->iTable!=iCur ) continue;
+-      pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
+-                       ~ready, WO_EQ|WO_ISNULL, 0);
++      pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
++                       ~ready, eqOpMask, 0);
+       if( pTerm==0 ) continue;
+-      if( (pTerm->eOperator&WO_EQ)!=0 && pOBExpr->iColumn>=0 ){
++      if( pTerm->eOperator==WO_IN ){
++        /* IN terms are only valid for sorting in the ORDER BY LIMIT 
++        ** optimization, and then only if they are actually used
++        ** by the query plan */
++        assert( wctrlFlags & WHERE_ORDERBY_LIMIT );
++        for(j=0; j<pLoop->nLTerm && pTerm!=pLoop->aLTerm[j]; j++){}
++        if( j>=pLoop->nLTerm ) continue;
++      }
++      if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){
+         const char *z1, *z2;
+         pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
+         if( !pColl ) pColl = db->pDfltColl;
+@@ -121941,6 +138331,7 @@
+         if( !pColl ) pColl = db->pDfltColl;
+         z2 = pColl->zName;
+         if( sqlite3StrICmp(z1, z2)!=0 ) continue;
++        testcase( pTerm->pExpr->op==TK_IS );
+       }
+       obSat |= MASKBIT(i);
+     }
+@@ -121956,7 +138347,8 @@
+         nKeyCol = pIndex->nKeyCol;
+         nColumn = pIndex->nColumn;
+         assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) );
+-        assert( pIndex->aiColumn[nColumn-1]==(-1) || !HasRowid(pIndex->pTable));
++        assert( pIndex->aiColumn[nColumn-1]==XN_ROWID
++                          || !HasRowid(pIndex->pTable));
+         isOrderDistinct = IsUniqueIndex(pIndex);
+       }
+ 
+@@ -121966,18 +138358,42 @@
+       rev = revSet = 0;
+       distinctColumns = 0;
+       for(j=0; j<nColumn; j++){
+-        u8 bOnce;   /* True to run the ORDER BY search loop */
++        u8 bOnce = 1; /* True to run the ORDER BY search loop */
+ 
+-        /* Skip over == and IS NULL terms */
+-        if( j<pLoop->u.btree.nEq
+-         && pLoop->nSkip==0
+-         && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
+-        ){
+-          if( i & WO_ISNULL ){
+-            testcase( isOrderDistinct );
+-            isOrderDistinct = 0;
++        assert( j>=pLoop->u.btree.nEq 
++            || (pLoop->aLTerm[j]==0)==(j<pLoop->nSkip)
++        );
++        if( j<pLoop->u.btree.nEq && j>=pLoop->nSkip ){
++          u16 eOp = pLoop->aLTerm[j]->eOperator;
++
++          /* Skip over == and IS and ISNULL terms.  (Also skip IN terms when
++          ** doing WHERE_ORDERBY_LIMIT processing). 
++          **
++          ** If the current term is a column of an ((?,?) IN (SELECT...)) 
++          ** expression for which the SELECT returns more than one column,
++          ** check that it is the only column used by this loop. Otherwise,
++          ** if it is one of two or more, none of the columns can be
++          ** considered to match an ORDER BY term.  */
++          if( (eOp & eqOpMask)!=0 ){
++            if( eOp & WO_ISNULL ){
++              testcase( isOrderDistinct );
++              isOrderDistinct = 0;
++            }
++            continue;  
++          }else if( ALWAYS(eOp & WO_IN) ){
++            /* ALWAYS() justification: eOp is an equality operator due to the
++            ** j<pLoop->u.btree.nEq constraint above.  Any equality other
++            ** than WO_IN is captured by the previous "if".  So this one
++            ** always has to be WO_IN. */
++            Expr *pX = pLoop->aLTerm[j]->pExpr;
++            for(i=j+1; i<pLoop->u.btree.nEq; i++){
++              if( pLoop->aLTerm[i]->pExpr==pX ){
++                assert( (pLoop->aLTerm[i]->eOperator & WO_IN) );
++                bOnce = 0;
++                break;
++              }
++            }
+           }
+-          continue;  
+         }
+ 
+         /* Get the column number in the table (iColumn) and sort order
+@@ -121988,7 +138404,7 @@
+           revIdx = pIndex->aSortOrder[j];
+           if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
+         }else{
+-          iColumn = -1;
++          iColumn = XN_ROWID;
+           revIdx = 0;
+         }
+ 
+@@ -122006,7 +138422,6 @@
+         /* Find the ORDER BY term that corresponds to the j-th column
+         ** of the index and mark that ORDER BY term off 
+         */
+-        bOnce = 1;
+         isMatch = 0;
+         for(i=0; bOnce && i<nOrderBy; i++){
+           if( MASKBIT(i) & obSat ) continue;
+@@ -122014,14 +138429,22 @@
+           testcase( wctrlFlags & WHERE_GROUPBY );
+           testcase( wctrlFlags & WHERE_DISTINCTBY );
+           if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
+-          if( pOBExpr->op!=TK_COLUMN ) continue;
+-          if( pOBExpr->iTable!=iCur ) continue;
+-          if( pOBExpr->iColumn!=iColumn ) continue;
++          if( iColumn>=(-1) ){
++            if( pOBExpr->op!=TK_COLUMN ) continue;
++            if( pOBExpr->iTable!=iCur ) continue;
++            if( pOBExpr->iColumn!=iColumn ) continue;
++          }else{
++            if( sqlite3ExprCompare(0,
++                  pOBExpr,pIndex->aColExpr->a[j].pExpr,iCur) ){
++              continue;
++            }
++          }
+           if( iColumn>=0 ){
+             pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
+             if( !pColl ) pColl = db->pDfltColl;
+             if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
+           }
++          pLoop->u.btree.nIdxCol = j+1;
+           isMatch = 1;
+           break;
+         }
+@@ -122037,7 +138460,7 @@
+           }
+         }
+         if( isMatch ){
+-          if( iColumn<0 ){
++          if( iColumn==XN_ROWID ){
+             testcase( distinctColumns==0 );
+             distinctColumns = 1;
+           }
+@@ -122065,7 +138488,7 @@
+         Bitmask mTerm;
+         if( MASKBIT(i) & obSat ) continue;
+         p = pOrderBy->a[i].pExpr;
+-        mTerm = exprTableUsage(&pWInfo->sMaskSet,p);
++        mTerm = sqlite3WhereExprUsage(&pWInfo->sMaskSet,p);
+         if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue;
+         if( (mTerm&~orderDistinctMask)==0 ){
+           obSat |= MASKBIT(i);
+@@ -122153,15 +138576,14 @@
+   LogEst rScale, rSortCost;
+   assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
+   rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
+-  rSortCost = nRow + estLog(nRow) + rScale + 16;
++  rSortCost = nRow + rScale + 16;
+ 
+-  /* TUNING: The cost of implementing DISTINCT using a B-TREE is
+-  ** similar but with a larger constant of proportionality. 
+-  ** Multiply by an additional factor of 3.0.  */
+-  if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
+-    rSortCost += 16;
++  /* Multiple by log(M) where M is the number of output rows.
++  ** Use the LIMIT for M if it is smaller */
++  if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimit<nRow ){
++    nRow = pWInfo->iLimit;
+   }
+-
++  rSortCost += estLog(nRow);
+   return rSortCost;
+ }
+ 
+@@ -122223,8 +138645,8 @@
+   /* Allocate and initialize space for aTo, aFrom and aSortCost[] */
+   nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
+   nSpace += sizeof(LogEst) * nOrderBy;
+-  pSpace = sqlite3DbMallocRaw(db, nSpace);
+-  if( pSpace==0 ) return SQLITE_NOMEM;
++  pSpace = sqlite3DbMallocRawNN(db, nSpace);
++  if( pSpace==0 ) return SQLITE_NOMEM_BKPT;
+   aTo = (WherePath*)pSpace;
+   aFrom = aTo+mxChoice;
+   memset(aFrom, 0, sizeof(aFrom[0]));
+@@ -122279,6 +138701,12 @@
+ 
+         if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
+         if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
++        if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<10 ){
++          /* Do not use an automatic index if the this loop is expected
++          ** to run less than 2 times. */
++          assert( 10==sqlite3LogEst(2) );
++          continue;
++        }
+         /* At this point, pWLoop is a candidate to be the next loop. 
+         ** Compute its cost */
+         rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
+@@ -122306,6 +138734,7 @@
+                rUnsorted, rCost));
+         }else{
+           rCost = rUnsorted;
++          rUnsorted -= 2;  /* TUNING:  Slight bias in favor of no-sort plans */
+         }
+ 
+         /* Check to see if pWLoop should be added to the set of
+@@ -122337,8 +138766,8 @@
+             ** this candidate as not viable. */
+ #ifdef WHERETRACE_ENABLED /* 0x4 */
+             if( sqlite3WhereTrace&0x4 ){
+-              sqlite3DebugPrintf("Skip   %s cost=%-3d,%3d order=%c\n",
+-                  wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
++              sqlite3DebugPrintf("Skip   %s cost=%-3d,%3d,%3d order=%c\n",
++                  wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
+                   isOrdered>=0 ? isOrdered+'0' : '?');
+             }
+ #endif
+@@ -122356,26 +138785,36 @@
+           pTo = &aTo[jj];
+ #ifdef WHERETRACE_ENABLED /* 0x4 */
+           if( sqlite3WhereTrace&0x4 ){
+-            sqlite3DebugPrintf("New    %s cost=%-3d,%3d order=%c\n",
+-                wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
++            sqlite3DebugPrintf("New    %s cost=%-3d,%3d,%3d order=%c\n",
++                wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
+                 isOrdered>=0 ? isOrdered+'0' : '?');
+           }
+ #endif
+         }else{
+           /* Control reaches here if best-so-far path pTo=aTo[jj] covers the
+-          ** same set of loops and has the sam isOrdered setting as the
++          ** same set of loops and has the same isOrdered setting as the
+           ** candidate path.  Check to see if the candidate should replace
+-          ** pTo or if the candidate should be skipped */
+-          if( pTo->rCost<rCost || (pTo->rCost==rCost && pTo->nRow<=nOut) ){
++          ** pTo or if the candidate should be skipped.
++          ** 
++          ** The conditional is an expanded vector comparison equivalent to:
++          **   (pTo->rCost,pTo->nRow,pTo->rUnsorted) <= (rCost,nOut,rUnsorted)
++          */
++          if( pTo->rCost<rCost 
++           || (pTo->rCost==rCost
++               && (pTo->nRow<nOut
++                   || (pTo->nRow==nOut && pTo->rUnsorted<=rUnsorted)
++                  )
++              )
++          ){
+ #ifdef WHERETRACE_ENABLED /* 0x4 */
+             if( sqlite3WhereTrace&0x4 ){
+               sqlite3DebugPrintf(
+-                  "Skip   %s cost=%-3d,%3d order=%c",
+-                  wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
++                  "Skip   %s cost=%-3d,%3d,%3d order=%c",
++                  wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
+                   isOrdered>=0 ? isOrdered+'0' : '?');
+-              sqlite3DebugPrintf("   vs %s cost=%-3d,%d order=%c\n",
++              sqlite3DebugPrintf("   vs %s cost=%-3d,%3d,%3d order=%c\n",
+                   wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
+-                  pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
++                  pTo->rUnsorted, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
+             }
+ #endif
+             /* Discard the candidate path from further consideration */
+@@ -122388,12 +138827,12 @@
+ #ifdef WHERETRACE_ENABLED /* 0x4 */
+           if( sqlite3WhereTrace&0x4 ){
+             sqlite3DebugPrintf(
+-                "Update %s cost=%-3d,%3d order=%c",
+-                wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
++                "Update %s cost=%-3d,%3d,%3d order=%c",
++                wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
+                 isOrdered>=0 ? isOrdered+'0' : '?');
+-            sqlite3DebugPrintf("  was %s cost=%-3d,%3d order=%c\n",
++            sqlite3DebugPrintf("  was %s cost=%-3d,%3d,%3d order=%c\n",
+                 wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
+-                pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
++                pTo->rUnsorted, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
+           }
+ #endif
+         }
+@@ -122448,7 +138887,7 @@
+ 
+   if( nFrom==0 ){
+     sqlite3ErrorMsg(pParse, "no query solution");
+-    sqlite3DbFree(db, pSpace);
++    sqlite3DbFreeNN(db, pSpace);
+     return SQLITE_ERROR;
+   }
+   
+@@ -122484,8 +138923,26 @@
+       }
+     }else{
+       pWInfo->nOBSat = pFrom->isOrdered;
+-      if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0;
+       pWInfo->revMask = pFrom->revLoop;
++      if( pWInfo->nOBSat<=0 ){
++        pWInfo->nOBSat = 0;
++        if( nLoop>0 ){
++          u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
++          if( (wsFlags & WHERE_ONEROW)==0 
++           && (wsFlags&(WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN)
++          ){
++            Bitmask m = 0;
++            int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom,
++                      WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m);
++            testcase( wsFlags & WHERE_IPK );
++            testcase( wsFlags & WHERE_COLUMN_IN );
++            if( rc==pWInfo->pOrderBy->nExpr ){
++              pWInfo->bOrderedInnerLoop = 1;
++              pWInfo->revMask = m;
++            }
++          }
++        }
++      }
+     }
+     if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
+         && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0
+@@ -122506,7 +138963,7 @@
+   pWInfo->nRowOut = pFrom->nRow;
+ 
+   /* Free temporary memory and return success */
+-  sqlite3DbFree(db, pSpace);
++  sqlite3DbFreeNN(db, pSpace);
+   return SQLITE_OK;
+ }
+ 
+@@ -122531,21 +138988,22 @@
+   int j;
+   Table *pTab;
+   Index *pIdx;
+-  
++
+   pWInfo = pBuilder->pWInfo;
+-  if( pWInfo->wctrlFlags & WHERE_FORCE_TABLE ) return 0;
++  if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0;
+   assert( pWInfo->pTabList->nSrc>=1 );
+   pItem = pWInfo->pTabList->a;
+   pTab = pItem->pTab;
+   if( IsVirtual(pTab) ) return 0;
+-  if( pItem->zIndex ) return 0;
++  if( pItem->fg.isIndexedBy ) return 0;
+   iCur = pItem->iCursor;
+   pWC = &pWInfo->sWC;
+   pLoop = pBuilder->pNew;
+   pLoop->wsFlags = 0;
+   pLoop->nSkip = 0;
+-  pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ, 0);
++  pTerm = sqlite3WhereFindTerm(pWC, iCur, -1, 0, WO_EQ|WO_IS, 0);
+   if( pTerm ){
++    testcase( pTerm->eOperator & WO_IS );
+     pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
+     pLoop->aLTerm[0] = pTerm;
+     pLoop->nLTerm = 1;
+@@ -122554,14 +139012,17 @@
+     pLoop->rRun = 33;  /* 33==sqlite3LogEst(10) */
+   }else{
+     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
++      int opMask;
+       assert( pLoop->aLTermSpace==pLoop->aLTerm );
+       if( !IsUniqueIndex(pIdx)
+        || pIdx->pPartIdxWhere!=0 
+        || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) 
+       ) continue;
++      opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ;
+       for(j=0; j<pIdx->nKeyCol; j++){
+-        pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
++        pTerm = sqlite3WhereFindTerm(pWC, iCur, j, 0, opMask, pIdx);
+         if( pTerm==0 ) break;
++        testcase( pTerm->eOperator & WO_IS );
+         pLoop->aLTerm[j] = pTerm;
+       }
+       if( j!=pIdx->nKeyCol ) continue;
+@@ -122580,7 +139041,8 @@
+   if( pLoop->wsFlags ){
+     pLoop->nOut = (LogEst)1;
+     pWInfo->a[0].pWLoop = pLoop;
+-    pLoop->maskSelf = getMask(&pWInfo->sMaskSet, iCur);
++    assert( pWInfo->sMaskSet.n==1 && iCur==pWInfo->sMaskSet.ix[0] );
++    pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */
+     pWInfo->a[0].iTabCur = iCur;
+     pWInfo->nRowOut = 1;
+     if( pWInfo->pOrderBy ) pWInfo->nOBSat =  pWInfo->pOrderBy->nExpr;
+@@ -122596,6 +139058,31 @@
+ }
+ 
+ /*
++** Helper function for exprIsDeterministic().
++*/
++static int exprNodeIsDeterministic(Walker *pWalker, Expr *pExpr){
++  if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_ConstFunc)==0 ){
++    pWalker->eCode = 0;
++    return WRC_Abort;
++  }
++  return WRC_Continue;
++}
++
++/*
++** Return true if the expression contains no non-deterministic SQL 
++** functions. Do not consider non-deterministic SQL functions that are 
++** part of sub-select statements.
++*/
++static int exprIsDeterministic(Expr *p){
++  Walker w;
++  memset(&w, 0, sizeof(w));
++  w.eCode = 1;
++  w.xExprCallback = exprNodeIsDeterministic;
++  sqlite3WalkExpr(&w, p);
++  return w.eCode;
++}
++
++/*
+ ** Generate the beginning of the loop used for WHERE clause processing.
+ ** The return value is a pointer to an opaque structure that contains
+ ** information needed to terminate the loop.  Later, the calling routine
+@@ -122676,7 +139163,7 @@
+ ** is called from an UPDATE or DELETE statement, then pOrderBy is NULL.
+ **
+ ** The iIdxCur parameter is the cursor number of an index.  If 
+-** WHERE_ONETABLE_ONLY is set, iIdxCur is the cursor number of an index
++** WHERE_OR_SUBCLAUSE is set, iIdxCur is the cursor number of an index
+ ** to use for OR clause processing.  The WHERE clause should use this
+ ** specific cursor.  If WHERE_ONEPASS_DESIRED is set, then iIdxCur is
+ ** the first cursor in an array of cursors for all indices.  iIdxCur should
+@@ -122684,13 +139171,14 @@
+ ** used.
+ */
+ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
+-  Parse *pParse,        /* The parser context */
+-  SrcList *pTabList,    /* FROM clause: A list of all tables to be scanned */
+-  Expr *pWhere,         /* The WHERE clause */
+-  ExprList *pOrderBy,   /* An ORDER BY (or GROUP BY) clause, or NULL */
+-  ExprList *pResultSet, /* Result set of the query */
+-  u16 wctrlFlags,       /* One of the WHERE_* flags defined in sqliteInt.h */
+-  int iIdxCur           /* If WHERE_ONETABLE_ONLY is set, index cursor number */
++  Parse *pParse,          /* The parser context */
++  SrcList *pTabList,      /* FROM clause: A list of all tables to be scanned */
++  Expr *pWhere,           /* The WHERE clause */
++  ExprList *pOrderBy,     /* An ORDER BY (or GROUP BY) clause, or NULL */
++  ExprList *pResultSet,   /* Query result set.  Req'd for DISTINCT */
++  u16 wctrlFlags,         /* The WHERE_* flags defined in sqliteInt.h */
++  int iAuxArg             /* If WHERE_OR_SUBCLAUSE is set, index cursor number
++                          ** If WHERE_USE_LIMIT, then the limit amount */
+ ){
+   int nByteWInfo;            /* Num. bytes allocated for WhereInfo struct */
+   int nTabList;              /* Number of elements in pTabList */
+@@ -122704,7 +139192,16 @@
+   int ii;                    /* Loop counter */
+   sqlite3 *db;               /* Database connection */
+   int rc;                    /* Return code */
++  u8 bFordelete = 0;         /* OPFLAG_FORDELETE or zero, as appropriate */
++
++  assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || (
++        (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 
++     && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 
++  ));
+ 
++  /* Only one of WHERE_OR_SUBCLAUSE or WHERE_USE_LIMIT */
++  assert( (wctrlFlags & WHERE_OR_SUBCLAUSE)==0
++            || (wctrlFlags & WHERE_USE_LIMIT)==0 );
+ 
+   /* Variable initialization */
+   db = pParse->db;
+@@ -122731,11 +139228,11 @@
+   }
+ 
+   /* This function normally generates a nested loop for all tables in 
+-  ** pTabList.  But if the WHERE_ONETABLE_ONLY flag is set, then we should
++  ** pTabList.  But if the WHERE_OR_SUBCLAUSE flag is set, then we should
+   ** only generate code for the first table in pTabList and assume that
+   ** any cursors associated with subsequent tables are uninitialized.
+   */
+-  nTabList = (wctrlFlags & WHERE_ONETABLE_ONLY) ? 1 : pTabList->nSrc;
++  nTabList = (wctrlFlags & WHERE_OR_SUBCLAUSE) ? 1 : pTabList->nSrc;
+ 
+   /* Allocate and initialize the WhereInfo structure that will become the
+   ** return value. A single allocation is used to store the WhereInfo
+@@ -122745,21 +139242,27 @@
+   ** some architectures. Hence the ROUND8() below.
+   */
+   nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
+-  pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop));
++  pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
+   if( db->mallocFailed ){
+     sqlite3DbFree(db, pWInfo);
+     pWInfo = 0;
+     goto whereBeginError;
+   }
+-  pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
+-  pWInfo->nLevel = nTabList;
+   pWInfo->pParse = pParse;
+   pWInfo->pTabList = pTabList;
+   pWInfo->pOrderBy = pOrderBy;
++  pWInfo->pWhere = pWhere;
+   pWInfo->pResultSet = pResultSet;
++  pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
++  pWInfo->nLevel = nTabList;
+   pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
+   pWInfo->wctrlFlags = wctrlFlags;
++  pWInfo->iLimit = iAuxArg;
+   pWInfo->savedNQueryLoop = pParse->nQueryLoop;
++  memset(&pWInfo->nOBSat, 0, 
++         offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
++  memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
++  assert( pWInfo->eOnePass==ONEPASS_OFF );  /* ONEPASS defaults to OFF */
+   pMaskSet = &pWInfo->sMaskSet;
+   sWLB.pWInfo = pWInfo;
+   sWLB.pWC = &pWInfo->sWC;
+@@ -122774,20 +139277,9 @@
+   ** subexpression is separated by an AND operator.
+   */
+   initMaskSet(pMaskSet);
+-  whereClauseInit(&pWInfo->sWC, pWInfo);
+-  whereSplit(&pWInfo->sWC, pWhere, TK_AND);
++  sqlite3WhereClauseInit(&pWInfo->sWC, pWInfo);
++  sqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND);
+     
+-  /* Special case: a WHERE clause that is constant.  Evaluate the
+-  ** expression and either jump over all of the code or fall thru.
+-  */
+-  for(ii=0; ii<sWLB.pWC->nTerm; ii++){
+-    if( nTabList==0 || sqlite3ExprIsConstantNotJoin(sWLB.pWC->a[ii].pExpr) ){
+-      sqlite3ExprIfFalse(pParse, sWLB.pWC->a[ii].pExpr, pWInfo->iBreak,
+-                         SQLITE_JUMPIFNULL);
+-      sWLB.pWC->a[ii].wtFlags |= TERM_CODED;
+-    }
+-  }
+-
+   /* Special case: No FROM clause
+   */
+   if( nTabList==0 ){
+@@ -122799,42 +139291,54 @@
+ 
+   /* Assign a bit from the bitmask to every term in the FROM clause.
+   **
+-  ** When assigning bitmask values to FROM clause cursors, it must be
+-  ** the case that if X is the bitmask for the N-th FROM clause term then
+-  ** the bitmask for all FROM clause terms to the left of the N-th term
+-  ** is (X-1).   An expression from the ON clause of a LEFT JOIN can use
+-  ** its Expr.iRightJoinTable value to find the bitmask of the right table
+-  ** of the join.  Subtracting one from the right table bitmask gives a
+-  ** bitmask for all tables to the left of the join.  Knowing the bitmask
+-  ** for all tables to the left of a left join is important.  Ticket #3015.
++  ** The N-th term of the FROM clause is assigned a bitmask of 1<<N.
++  **
++  ** The rule of the previous sentence ensures thta if X is the bitmask for
++  ** a table T, then X-1 is the bitmask for all other tables to the left of T.
++  ** Knowing the bitmask for all tables to the left of a left join is
++  ** important.  Ticket #3015.
+   **
+   ** Note that bitmasks are created for all pTabList->nSrc tables in
+   ** pTabList, not just the first nTabList tables.  nTabList is normally
+   ** equal to pTabList->nSrc but might be shortened to 1 if the
+-  ** WHERE_ONETABLE_ONLY flag is set.
++  ** WHERE_OR_SUBCLAUSE flag is set.
+   */
+   for(ii=0; ii<pTabList->nSrc; ii++){
+     createMask(pMaskSet, pTabList->a[ii].iCursor);
++    sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC);
+   }
+-#ifndef NDEBUG
++#ifdef SQLITE_DEBUG
+   {
+-    Bitmask toTheLeft = 0;
++    Bitmask mx = 0;
+     for(ii=0; ii<pTabList->nSrc; ii++){
+-      Bitmask m = getMask(pMaskSet, pTabList->a[ii].iCursor);
+-      assert( (m-1)==toTheLeft );
+-      toTheLeft |= m;
++      Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor);
++      assert( m>=mx );
++      mx = m;
+     }
+   }
+ #endif
+ 
+-  /* Analyze all of the subexpressions.  Note that exprAnalyze() might
+-  ** add new virtual terms onto the end of the WHERE clause.  We do not
+-  ** want to analyze these virtual terms, so start analyzing at the end
+-  ** and work forward so that the added virtual terms are never processed.
++  /* Analyze all of the subexpressions. */
++  sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
++  if( db->mallocFailed ) goto whereBeginError;
++
++  /* Special case: WHERE terms that do not refer to any tables in the join
++  ** (constant expressions). Evaluate each such term, and jump over all the
++  ** generated code if the result is not true.  
++  **
++  ** Do not do this if the expression contains non-deterministic functions
++  ** that are not within a sub-select. This is not strictly required, but
++  ** preserves SQLite's legacy behaviour in the following two cases:
++  **
++  **   FROM ... WHERE random()>0;           -- eval random() once per row
++  **   FROM ... WHERE (SELECT random())>0;  -- eval random() once overall
+   */
+-  exprAnalyzeAll(pTabList, &pWInfo->sWC);
+-  if( db->mallocFailed ){
+-    goto whereBeginError;
++  for(ii=0; ii<sWLB.pWC->nTerm; ii++){
++    WhereTerm *pT = &sWLB.pWC->a[ii];
++    if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){
++      sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL);
++      pT->wtFlags |= TERM_CODED;
++    }
+   }
+ 
+   if( wctrlFlags & WHERE_WANT_DISTINCT ){
+@@ -122849,14 +139353,16 @@
+   }
+ 
+   /* Construct the WhereLoop objects */
+-  WHERETRACE(0xffff,("*** Optimizer Start ***\n"));
+ #if defined(WHERETRACE_ENABLED)
+-  /* Display all terms of the WHERE clause */
+-  if( sqlite3WhereTrace & 0x100 ){
+-    int i;
+-    for(i=0; i<sWLB.pWC->nTerm; i++){
+-      whereTermPrint(&sWLB.pWC->a[i], i);
++  if( sqlite3WhereTrace & 0xffff ){
++    sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags);
++    if( wctrlFlags & WHERE_USE_LIMIT ){
++      sqlite3DebugPrintf(", limit: %d", iAuxArg);
+     }
++    sqlite3DebugPrintf(")\n");
++  }
++  if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
++    sqlite3WhereClausePrint(sWLB.pWC);
+   }
+ #endif
+ 
+@@ -122864,15 +139370,14 @@
+     rc = whereLoopAddAll(&sWLB);
+     if( rc ) goto whereBeginError;
+   
+-    /* Display all of the WhereLoop objects if wheretrace is enabled */
+-#ifdef WHERETRACE_ENABLED /* !=0 */
+-    if( sqlite3WhereTrace ){
++#ifdef WHERETRACE_ENABLED
++    if( sqlite3WhereTrace ){    /* Display all of the WhereLoop objects */
+       WhereLoop *p;
+       int i;
+-      static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
+-                                       "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
++      static const char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
++                                             "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
+       for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){
+-        p->cId = zLabel[i%sizeof(zLabel)];
++        p->cId = zLabel[i%(sizeof(zLabel)-1)];
+         whereLoopPrint(p, sWLB.pWC);
+       }
+     }
+@@ -122886,12 +139391,12 @@
+     }
+   }
+   if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
+-     pWInfo->revMask = (Bitmask)(-1);
++     pWInfo->revMask = ALLBITS;
+   }
+   if( pParse->nErr || NEVER(db->mallocFailed) ){
+     goto whereBeginError;
+   }
+-#ifdef WHERETRACE_ENABLED /* !=0 */
++#ifdef WHERETRACE_ENABLED
+   if( sqlite3WhereTrace ){
+     sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
+     if( pWInfo->nOBSat>0 ){
+@@ -122922,12 +139427,14 @@
+    && pResultSet!=0
+    && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
+   ){
+-    Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet);
+-    if( sWLB.pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, sWLB.pOrderBy);
++    Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
++    if( sWLB.pOrderBy ){
++      tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
++    }
+     while( pWInfo->nLevel>=2 ){
+       WhereTerm *pTerm, *pEnd;
+       pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
+-      if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break;
++      if( (pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 ) break;
+       if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
+        && (pLoop->wsFlags & WHERE_ONEROW)==0
+       ){
+@@ -122953,22 +139460,28 @@
+ 
+   /* If the caller is an UPDATE or DELETE statement that is requesting
+   ** to use a one-pass algorithm, determine if this is appropriate.
+-  ** The one-pass algorithm only works if the WHERE clause constrains
+-  ** the statement to update a single row.
+   */
+   assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
+-  if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 
+-   && (pWInfo->a[0].pWLoop->wsFlags & WHERE_ONEROW)!=0 ){
+-    pWInfo->okOnePass = 1;
+-    if( HasRowid(pTabList->a[0].pTab) ){
+-      pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY;
++  if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
++    int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
++    int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
++    if( bOnerow
++     || ((wctrlFlags & WHERE_ONEPASS_MULTIROW)!=0
++           && 0==(wsFlags & WHERE_VIRTUALTABLE))
++    ){
++      pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
++      if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
++        if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
++          bFordelete = OPFLAG_FORDELETE;
++        }
++        pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY);
++      }
+     }
+   }
+ 
+   /* Open all tables in the pTabList and any indices selected for
+   ** searching those tables.
+   */
+-  notReady = ~(Bitmask)0;
+   for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
+     Table *pTab;     /* Table to open */
+     int iDb;         /* Index of database containing table/index */
+@@ -122991,24 +139504,35 @@
+     }else
+ #endif
+     if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
+-         && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
++         && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
+       int op = OP_OpenRead;
+-      if( pWInfo->okOnePass ){
++      if( pWInfo->eOnePass!=ONEPASS_OFF ){
+         op = OP_OpenWrite;
+         pWInfo->aiCurOnePass[0] = pTabItem->iCursor;
+       };
+       sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
+       assert( pTabItem->iCursor==pLevel->iTabCur );
+-      testcase( !pWInfo->okOnePass && pTab->nCol==BMS-1 );
+-      testcase( !pWInfo->okOnePass && pTab->nCol==BMS );
+-      if( !pWInfo->okOnePass && pTab->nCol<BMS && HasRowid(pTab) ){
++      testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
++      testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
++      if( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol<BMS && HasRowid(pTab) ){
+         Bitmask b = pTabItem->colUsed;
+         int n = 0;
+         for(; b; b=b>>1, n++){}
+-        sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1, 
+-                            SQLITE_INT_TO_PTR(n), P4_INT32);
++        sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(n), P4_INT32);
+         assert( n<=pTab->nCol );
+       }
++#ifdef SQLITE_ENABLE_CURSOR_HINTS
++      if( pLoop->u.btree.pIndex!=0 ){
++        sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete);
++      }else
 +#endif
-+#if SQLITE_RTREE_INT_ONLY
-+  "RTREE_INT_ONLY",
++      {
++        sqlite3VdbeChangeP5(v, bFordelete);
++      }
++#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
++      sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0,
++                            (const u8*)&pTabItem->colUsed, P4_INT64);
 +#endif
-+#if SQLITE_SECURE_DELETE
-+  "SECURE_DELETE",
+     }else{
+       sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
+     }
+@@ -123016,18 +139540,18 @@
+       Index *pIx = pLoop->u.btree.pIndex;
+       int iIndexCur;
+       int op = OP_OpenRead;
+-      /* iIdxCur is always set if to a positive value if ONEPASS is possible */
+-      assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
++      /* iAuxArg is always set if to a positive value if ONEPASS is possible */
++      assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
+       if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx)
+-       && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0
++       && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0
+       ){
+         /* This is one term of an OR-optimization using the PRIMARY KEY of a
+         ** WITHOUT ROWID table.  No need for a separate index */
+         iIndexCur = pLevel->iTabCur;
+         op = 0;
+-      }else if( pWInfo->okOnePass ){
++      }else if( pWInfo->eOnePass!=ONEPASS_OFF ){
+         Index *pJ = pTabItem->pTab->pIndex;
+-        iIndexCur = iIdxCur;
++        iIndexCur = iAuxArg;
+         assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
+         while( ALWAYS(pJ) && pJ!=pIx ){
+           iIndexCur++;
+@@ -123035,9 +139559,9 @@
+         }
+         op = OP_OpenWrite;
+         pWInfo->aiCurOnePass[1] = iIndexCur;
+-      }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){
+-        iIndexCur = iIdxCur;
+-        if( wctrlFlags & WHERE_REOPEN_IDX ) op = OP_ReopenIdx;
++      }else if( iAuxArg && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ){
++        iIndexCur = iAuxArg;
++        op = OP_ReopenIdx;
+       }else{
+         iIndexCur = pParse->nTab++;
+       }
+@@ -123050,14 +139574,29 @@
+         if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0
+          && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
+          && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
++         && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
+         ){
+           sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */
+         }
+         VdbeComment((v, "%s", pIx->zName));
++#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
++        {
++          u64 colUsed = 0;
++          int ii, jj;
++          for(ii=0; ii<pIx->nColumn; ii++){
++            jj = pIx->aiColumn[ii];
++            if( jj<0 ) continue;
++            if( jj>63 ) jj = 63;
++            if( (pTabItem->colUsed & MASKBIT(jj))==0 ) continue;
++            colUsed |= ((u64)1)<<(ii<63 ? ii : 63);
++          }
++          sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0,
++                                (u8*)&colUsed, P4_INT64);
++        }
++#endif /* SQLITE_ENABLE_COLUMN_USED_MASK */
+       }
+     }
+     if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb);
+-    notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor);
+   }
+   pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
+   if( db->mallocFailed ) goto whereBeginError;
+@@ -123079,14 +139618,14 @@
+       if( db->mallocFailed ) goto whereBeginError;
+     }
+ #endif
+-    addrExplain = explainOneScan(
++    addrExplain = sqlite3WhereExplainOneScan(
+         pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags
+     );
+     pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
+-    notReady = codeOneLoopStart(pWInfo, ii, notReady);
++    notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady);
+     pWInfo->iContinue = pLevel->addrCont;
+-    if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_ONETABLE_ONLY)==0 ){
+-      addScanStatus(v, pTabList, pLevel, addrExplain);
++    if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){
++      sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain);
+     }
+   }
+ 
+@@ -123124,14 +139663,43 @@
+     int addr;
+     pLevel = &pWInfo->a[i];
+     pLoop = pLevel->pWLoop;
+-    sqlite3VdbeResolveLabel(v, pLevel->addrCont);
+     if( pLevel->op!=OP_Noop ){
++#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
++      int addrSeek = 0;
++      Index *pIdx;
++      int n;
++      if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
++       && (pLoop->wsFlags & WHERE_INDEXED)!=0
++       && (pIdx = pLoop->u.btree.pIndex)->hasStat1
++       && (n = pLoop->u.btree.nIdxCol)>0
++       && pIdx->aiRowLogEst[n]>=36
++      ){
++        int r1 = pParse->nMem+1;
++        int j, op;
++        for(j=0; j<n; j++){
++          sqlite3VdbeAddOp3(v, OP_Column, pLevel->iIdxCur, j, r1+j);
++        }
++        pParse->nMem += n+1;
++        op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT;
++        addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n);
++        VdbeCoverageIf(v, op==OP_SeekLT);
++        VdbeCoverageIf(v, op==OP_SeekGT);
++        sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
++      }
++#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
++      /* The common case: Advance to the next row */
++      sqlite3VdbeResolveLabel(v, pLevel->addrCont);
+       sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
+       sqlite3VdbeChangeP5(v, pLevel->p5);
+       VdbeCoverage(v);
+       VdbeCoverageIf(v, pLevel->op==OP_Next);
+       VdbeCoverageIf(v, pLevel->op==OP_Prev);
+       VdbeCoverageIf(v, pLevel->op==OP_VNext);
++#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
++      if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
 +#endif
-+#if SQLITE_SMALL_STACK
-+  "SMALL_STACK",
++    }else{
++      sqlite3VdbeResolveLabel(v, pLevel->addrCont);
+     }
+     if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
+       struct InLoop *pIn;
+@@ -123139,44 +139707,45 @@
+       sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
+       for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
+         sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
+-        sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
+-        VdbeCoverage(v);
+-        VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
+-        VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
++        if( pIn->eEndLoopOp!=OP_Noop ){
++          sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
++          VdbeCoverage(v);
++          VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
++          VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
++        }
+         sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
+       }
+     }
+     sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
+     if( pLevel->addrSkip ){
+-      sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrSkip);
++      sqlite3VdbeGoto(v, pLevel->addrSkip);
+       VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName));
+       sqlite3VdbeJumpHere(v, pLevel->addrSkip);
+       sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
+     }
++#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+     if( pLevel->addrLikeRep ){
+-      int op;
+-      if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){
+-        op = OP_DecrJumpZero;
+-      }else{
+-        op = OP_JumpZeroIncr;
+-      }
+-      sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep);
++      sqlite3VdbeAddOp2(v, OP_DecrJumpZero, (int)(pLevel->iLikeRepCntr>>1),
++                        pLevel->addrLikeRep);
+       VdbeCoverage(v);
+     }
 +#endif
-+#if SQLITE_SOUNDEX
-+  "SOUNDEX",
+     if( pLevel->iLeftJoin ){
++      int ws = pLoop->wsFlags;
+       addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
+-      assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
+-           || (pLoop->wsFlags & WHERE_INDEXED)!=0 );
+-      if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){
++      assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 );
++      if( (ws & WHERE_IDX_ONLY)==0 ){
+         sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
+       }
+-      if( pLoop->wsFlags & WHERE_INDEXED ){
++      if( (ws & WHERE_INDEXED) 
++       || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx) 
++      ){
+         sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
+       }
+       if( pLevel->op==OP_Return ){
+         sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst);
+       }else{
+-        sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst);
++        sqlite3VdbeGoto(v, pLevel->addrFirst);
+       }
+       sqlite3VdbeJumpHere(v, addr);
+     }
+@@ -123200,50 +139769,16 @@
+     pLoop = pLevel->pWLoop;
+ 
+     /* For a co-routine, change all OP_Column references to the table of
+-    ** the co-routine into OP_SCopy of result contained in a register.
++    ** the co-routine into OP_Copy of result contained in a register.
+     ** OP_Rowid becomes OP_Null.
+     */
+-    if( pTabItem->viaCoroutine && !db->mallocFailed ){
+-      last = sqlite3VdbeCurrentAddr(v);
+-      k = pLevel->addrBody;
+-      pOp = sqlite3VdbeGetOp(v, k);
+-      for(; k<last; k++, pOp++){
+-        if( pOp->p1!=pLevel->iTabCur ) continue;
+-        if( pOp->opcode==OP_Column ){
+-          pOp->opcode = OP_Copy;
+-          pOp->p1 = pOp->p2 + pTabItem->regResult;
+-          pOp->p2 = pOp->p3;
+-          pOp->p3 = 0;
+-        }else if( pOp->opcode==OP_Rowid ){
+-          pOp->opcode = OP_Null;
+-          pOp->p1 = 0;
+-          pOp->p3 = 0;
+-        }
+-      }
++    if( pTabItem->fg.viaCoroutine ){
++      testcase( pParse->db->mallocFailed );
++      translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
++                            pTabItem->regResult, 0);
+       continue;
+     }
+ 
+-    /* Close all of the cursors that were opened by sqlite3WhereBegin.
+-    ** Except, do not close cursors that will be reused by the OR optimization
+-    ** (WHERE_OMIT_OPEN_CLOSE).  And do not close the OP_OpenWrite cursors
+-    ** created for the ONEPASS optimization.
+-    */
+-    if( (pTab->tabFlags & TF_Ephemeral)==0
+-     && pTab->pSelect==0
+-     && (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
+-    ){
+-      int ws = pLoop->wsFlags;
+-      if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
+-        sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
+-      }
+-      if( (ws & WHERE_INDEXED)!=0
+-       && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 
+-       && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1]
+-      ){
+-        sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
+-      }
+-    }
+-
+     /* If this scan uses an index, make VDBE code substitutions to read data
+     ** from the index instead of from the table where possible.  In some cases
+     ** this optimization prevents the table from ever being read, which can
+@@ -123260,7 +139795,10 @@
+     }else if( pLoop->wsFlags & WHERE_MULTI_OR ){
+       pIdx = pLevel->u.pCovidx;
+     }
+-    if( pIdx && !db->mallocFailed ){
++    if( pIdx
++     && (pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable))
++     && !db->mallocFailed
++    ){
+       last = sqlite3VdbeCurrentAddr(v);
+       k = pLevel->addrBody;
+       pOp = sqlite3VdbeGetOp(v, k);
+@@ -123272,16 +139810,20 @@
+           if( !HasRowid(pTab) ){
+             Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+             x = pPk->aiColumn[x];
++            assert( x>=0 );
+           }
+           x = sqlite3ColumnOfIndex(pIdx, x);
+           if( x>=0 ){
+             pOp->p2 = x;
+             pOp->p1 = pLevel->iIdxCur;
+           }
+-          assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 );
++          assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 
++              || pWInfo->eOnePass );
+         }else if( pOp->opcode==OP_Rowid ){
+           pOp->p1 = pLevel->iIdxCur;
+           pOp->opcode = OP_IdxRowid;
++        }else if( pOp->opcode==OP_IfNullRow ){
++          pOp->p1 = pLevel->iIdxCur;
+         }
+       }
+     }
+@@ -123296,19 +139838,34 @@
+ 
+ /************** End of where.c ***********************************************/
+ /************** Begin file parse.c *******************************************/
+-/* Driver template for the LEMON parser generator.
+-** The author disclaims copyright to this source code.
++/*
++** 2000-05-29
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** Driver template for the LEMON parser generator.
++**
++** The "lemon" program processes an LALR(1) input grammar file, then uses
++** this template to construct a parser.  The "lemon" program inserts text
++** at each "%%" line.  Also, any "P-a-r-s-e" identifer prefix (without the
++** interstitial "-" characters) contained in this template is changed into
++** the value of the %name directive from the grammar.  Otherwise, the content
++** of this template is copied straight through into the generate parser
++** source file.
+ **
+-** This version of "lempar.c" is modified, slightly, for use by SQLite.
+-** The only modifications are the addition of a couple of NEVER()
+-** macros to disable tests that are needed in the case of a general
+-** LALR(1) grammar but which are always false in the
+-** specific grammar used by SQLite.
++** The following is the concatenation of all %include directives from the
++** input grammar file:
+ */
+-/* First off, code is included that follows the "include" declaration
+-** in the input grammar file. */
+ /* #include <stdio.h> */
++/************ Begin %include sections from the grammar ************************/
+ 
++/* #include "sqliteInt.h" */
+ 
+ /*
+ ** Disable all error recovery processing in the parser push-down
+@@ -123322,6 +139879,31 @@
+ #define yytestcase(X) testcase(X)
+ 
+ /*
++** Indicate that sqlite3ParserFree() will never be called with a null
++** pointer.
++*/
++#define YYPARSEFREENEVERNULL 1
++
++/*
++** In the amalgamation, the parse.c file generated by lemon and the
++** tokenize.c file are concatenated.  In that case, sqlite3RunParser()
++** has access to the the size of the yyParser object and so the parser
++** engine can be allocated from stack.  In that case, only the
++** sqlite3ParserInit() and sqlite3ParserFinalize() routines are invoked
++** and the sqlite3ParserAlloc() and sqlite3ParserFree() routines can be
++** omitted.
++*/
++#ifdef SQLITE_AMALGAMATION
++# define sqlite3Parser_ENGINEALWAYSONSTACK 1
 +#endif
-+#if SQLITE_SYSTEM_MALLOC
-+  "SYSTEM_MALLOC",
++
++/*
++** Alternative datatype for the argument to the malloc() routine passed
++** into sqlite3ParserAlloc().  The default is size_t.
++*/
++#define YYMALLOCARGTYPE  u64
++
++/*
+ ** An instance of this structure holds information about the
+ ** LIMIT clause of a SELECT statement.
+ */
+@@ -123331,15 +139913,6 @@
+ };
+ 
+ /*
+-** An instance of this structure is used to store the LIKE,
+-** GLOB, NOT LIKE, and NOT GLOB operators.
+-*/
+-struct LikeOp {
+-  Token eOperator;  /* "like" or "glob" or "regexp" */
+-  int bNot;         /* True if the NOT keyword is present */
+-};
+-
+-/*
+ ** An instance of the following structure describes the event of a
+ ** TRIGGER.  "a" is the event type, one of TK_UPDATE, TK_INSERT,
+ ** TK_DELETE, or TK_INSTEAD.  If the event is of the form
+@@ -123351,9 +139924,13 @@
+ struct TrigEvent { int a; IdList * b; };
+ 
+ /*
+-** An instance of this structure holds the ATTACH key and the key type.
++** Disable lookaside memory allocation for objects that might be
++** shared across database connections.
+ */
+-struct AttachKey { int type;  Token key; };
++static void disableLookaside(Parse *pParse){
++  pParse->disableLookaside++;
++  pParse->db->lookaside.bDisable++;
++}
+ 
+ 
+   /*
+@@ -123391,46 +139968,68 @@
+   ** new Expr to populate pOut.  Set the span of pOut to be the identifier
+   ** that created the expression.
+   */
+-  static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token *pValue){
+-    pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, pValue);
+-    pOut->zStart = pValue->z;
+-    pOut->zEnd = &pValue->z[pValue->n];
++  static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){
++    Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
++    if( p ){
++      memset(p, 0, sizeof(Expr));
++      p->op = (u8)op;
++      p->flags = EP_Leaf;
++      p->iAgg = -1;
++      p->u.zToken = (char*)&p[1];
++      memcpy(p->u.zToken, t.z, t.n);
++      p->u.zToken[t.n] = 0;
++      if( sqlite3Isquote(p->u.zToken[0]) ){
++        if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted;
++        sqlite3Dequote(p->u.zToken);
++      }
++#if SQLITE_MAX_EXPR_DEPTH>0
++      p->nHeight = 1;
++#endif  
++    }
++    pOut->pExpr = p;
++    pOut->zStart = t.z;
++    pOut->zEnd = &t.z[t.n];
+   }
+ 
+   /* This routine constructs a binary expression node out of two ExprSpan
+   ** objects and uses the result to populate a new ExprSpan object.
+   */
+   static void spanBinaryExpr(
+-    ExprSpan *pOut,     /* Write the result here */
+     Parse *pParse,      /* The parsing context.  Errors accumulate here */
+     int op,             /* The binary operation */
+-    ExprSpan *pLeft,    /* The left operand */
++    ExprSpan *pLeft,    /* The left operand, and output */
+     ExprSpan *pRight    /* The right operand */
+   ){
+-    pOut->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
+-    pOut->zStart = pLeft->zStart;
+-    pOut->zEnd = pRight->zEnd;
++    pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr);
++    pLeft->zEnd = pRight->zEnd;
++  }
++
++  /* If doNot is true, then add a TK_NOT Expr-node wrapper around the
++  ** outside of *ppExpr.
++  */
++  static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){
++    if( doNot ){
++      pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0);
++    }
+   }
+ 
+   /* Construct an expression node for a unary postfix operator
+   */
+   static void spanUnaryPostfix(
+-    ExprSpan *pOut,        /* Write the new expression node here */
+     Parse *pParse,         /* Parsing context to record errors */
+     int op,                /* The operator */
+-    ExprSpan *pOperand,    /* The operand */
++    ExprSpan *pOperand,    /* The operand, and output */
+     Token *pPostOp         /* The operand token for setting the span */
+   ){
+-    pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
+-    pOut->zStart = pOperand->zStart;
+-    pOut->zEnd = &pPostOp->z[pPostOp->n];
++    pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0);
++    pOperand->zEnd = &pPostOp->z[pPostOp->n];
+   }                           
+ 
+   /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
+   ** unary TK_ISNULL or TK_NOTNULL expression. */
+   static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
+     sqlite3 *db = pParse->db;
+-    if( pY && pA && pY->op==TK_NULL ){
++    if( pA && pY && pY->op==TK_NULL ){
+       pA->op = (u8)op;
+       sqlite3ExprDelete(db, pA->pRight);
+       pA->pRight = 0;
+@@ -123446,82 +140045,111 @@
+     ExprSpan *pOperand,    /* The operand */
+     Token *pPreOp         /* The operand token for setting the span */
+   ){
+-    pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
+     pOut->zStart = pPreOp->z;
++    pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0);
+     pOut->zEnd = pOperand->zEnd;
+   }
+-/* Next is all token values, in a form suitable for use by makeheaders.
+-** This section will be null unless lemon is run with the -m switch.
+-*/
+-/* 
+-** These constants (all generated automatically by the parser generator)
+-** specify the various kinds of tokens (terminals) that the parser
+-** understands. 
+-**
+-** Each symbol here is a terminal symbol in the grammar.
+-*/
+-/* Make sure the INTERFACE macro is defined.
+-*/
+-#ifndef INTERFACE
+-# define INTERFACE 1
+-#endif
+-/* The next thing included is series of defines which control
++
++  /* Add a single new term to an ExprList that is used to store a
++  ** list of identifiers.  Report an error if the ID list contains
++  ** a COLLATE clause or an ASC or DESC keyword, except ignore the
++  ** error while parsing a legacy schema.
++  */
++  static ExprList *parserAddExprIdListTerm(
++    Parse *pParse,
++    ExprList *pPrior,
++    Token *pIdToken,
++    int hasCollate,
++    int sortOrder
++  ){
++    ExprList *p = sqlite3ExprListAppend(pParse, pPrior, 0);
++    if( (hasCollate || sortOrder!=SQLITE_SO_UNDEFINED)
++        && pParse->db->init.busy==0
++    ){
++      sqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"",
++                         pIdToken->n, pIdToken->z);
++    }
++    sqlite3ExprListSetName(pParse, p, pIdToken, 1);
++    return p;
++  }
++/**************** End of %include directives **********************************/
++/* These constants specify the various numeric values for terminal symbols
++** in a format understandable to "makeheaders".  This section is blank unless
++** "lemon" is run with the "-m" command-line option.
++***************** Begin makeheaders token definitions *************************/
++/**************** End makeheaders token definitions ***************************/
++
++/* The next sections is a series of control #defines.
+ ** various aspects of the generated parser.
+-**    YYCODETYPE         is the data type used for storing terminal
+-**                       and nonterminal numbers.  "unsigned char" is
+-**                       used if there are fewer than 250 terminals
+-**                       and nonterminals.  "int" is used otherwise.
+-**    YYNOCODE           is a number of type YYCODETYPE which corresponds
+-**                       to no legal terminal or nonterminal number.  This
+-**                       number is used to fill in empty slots of the hash 
+-**                       table.
++**    YYCODETYPE         is the data type used to store the integer codes
++**                       that represent terminal and non-terminal symbols.
++**                       "unsigned char" is used if there are fewer than
++**                       256 symbols.  Larger types otherwise.
++**    YYNOCODE           is a number of type YYCODETYPE that is not used for
++**                       any terminal or nonterminal symbol.
+ **    YYFALLBACK         If defined, this indicates that one or more tokens
+-**                       have fall-back values which should be used if the
+-**                       original value of the token will not parse.
+-**    YYACTIONTYPE       is the data type used for storing terminal
+-**                       and nonterminal numbers.  "unsigned char" is
+-**                       used if there are fewer than 250 rules and
+-**                       states combined.  "int" is used otherwise.
+-**    sqlite3ParserTOKENTYPE     is the data type used for minor tokens given 
+-**                       directly to the parser from the tokenizer.
+-**    YYMINORTYPE        is the data type used for all minor tokens.
++**                       (also known as: "terminal symbols") have fall-back
++**                       values which should be used if the original symbol
++**                       would not parse.  This permits keywords to sometimes
++**                       be used as identifiers, for example.
++**    YYACTIONTYPE       is the data type used for "action codes" - numbers
++**                       that indicate what to do in response to the next
++**                       token.
++**    sqlite3ParserTOKENTYPE     is the data type used for minor type for terminal
++**                       symbols.  Background: A "minor type" is a semantic
++**                       value associated with a terminal or non-terminal
++**                       symbols.  For example, for an "ID" terminal symbol,
++**                       the minor type might be the name of the identifier.
++**                       Each non-terminal can have a different minor type.
++**                       Terminal symbols all have the same minor type, though.
++**                       This macros defines the minor type for terminal 
++**                       symbols.
++**    YYMINORTYPE        is the data type used for all minor types.
+ **                       This is typically a union of many types, one of
+ **                       which is sqlite3ParserTOKENTYPE.  The entry in the union
+-**                       for base tokens is called "yy0".
++**                       for terminal symbols is called "yy0".
+ **    YYSTACKDEPTH       is the maximum depth of the parser's stack.  If
+ **                       zero the stack is dynamically sized using realloc()
+ **    sqlite3ParserARG_SDECL     A static variable declaration for the %extra_argument
+ **    sqlite3ParserARG_PDECL     A parameter declaration for the %extra_argument
+ **    sqlite3ParserARG_STORE     Code to store %extra_argument into yypParser
+ **    sqlite3ParserARG_FETCH     Code to extract %extra_argument from yypParser
+-**    YYNSTATE           the combined number of states.
+-**    YYNRULE            the number of rules in the grammar
+ **    YYERRORSYMBOL      is the code number of the error symbol.  If not
+ **                       defined, then do no error processing.
++**    YYNSTATE           the combined number of states.
++**    YYNRULE            the number of rules in the grammar
++**    YY_MAX_SHIFT       Maximum value for shift actions
++**    YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
++**    YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
++**    YY_MIN_REDUCE      Maximum value for reduce actions
++**    YY_ERROR_ACTION    The yy_action[] code for syntax error
++**    YY_ACCEPT_ACTION   The yy_action[] code for accept
++**    YY_NO_ACTION       The yy_action[] code for no-op
+ */
++#ifndef INTERFACE
++# define INTERFACE 1
 +#endif
-+#if SQLITE_TCL
-+  "TCL",
++/************* Begin control #defines *****************************************/
+ #define YYCODETYPE unsigned char
+-#define YYNOCODE 254
++#define YYNOCODE 252
+ #define YYACTIONTYPE unsigned short int
+-#define YYWILDCARD 70
++#define YYWILDCARD 69
+ #define sqlite3ParserTOKENTYPE Token
+ typedef union {
+   int yyinit;
+   sqlite3ParserTOKENTYPE yy0;
+-  Select* yy3;
+-  ExprList* yy14;
+-  With* yy59;
+-  SrcList* yy65;
+-  struct LikeOp yy96;
+-  Expr* yy132;
+-  u8 yy186;
+-  int yy328;
+-  ExprSpan yy346;
+-  struct TrigEvent yy378;
+-  u16 yy381;
+-  IdList* yy408;
+-  struct {int value; int mask;} yy429;
+-  TriggerStep* yy473;
+-  struct LimitVal yy476;
++  Expr* yy72;
++  TriggerStep* yy145;
++  ExprList* yy148;
++  SrcList* yy185;
++  ExprSpan yy190;
++  int yy194;
++  Select* yy243;
++  IdList* yy254;
++  With* yy285;
++  struct TrigEvent yy332;
++  struct LimitVal yy354;
++  struct {int value; int mask;} yy497;
+ } YYMINORTYPE;
+ #ifndef YYSTACKDEPTH
+ #define YYSTACKDEPTH 100
+@@ -123530,16 +140158,18 @@
+ #define sqlite3ParserARG_PDECL ,Parse *pParse
+ #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
+ #define sqlite3ParserARG_STORE yypParser->pParse = pParse
+-#define YYNSTATE 642
+-#define YYNRULE 327
+ #define YYFALLBACK 1
+-#define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
+-#define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
+-#define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)
+-
+-/* The yyzerominor constant is used to initialize instances of
+-** YYMINORTYPE objects to zero. */
+-static const YYMINORTYPE yyzerominor = { 0 };
++#define YYNSTATE             455
++#define YYNRULE              329
++#define YY_MAX_SHIFT         454
++#define YY_MIN_SHIFTREDUCE   664
++#define YY_MAX_SHIFTREDUCE   992
++#define YY_MIN_REDUCE        993
++#define YY_MAX_REDUCE        1321
++#define YY_ERROR_ACTION      1322
++#define YY_ACCEPT_ACTION     1323
++#define YY_NO_ACTION         1324
++/************* End control #defines *******************************************/
+ 
+ /* Define the yytestcase() macro to be a no-op if is not already defined
+ ** otherwise.
+@@ -123562,29 +140192,37 @@
+ ** Suppose the action integer is N.  Then the action is determined as
+ ** follows
+ **
+-**   0 <= N < YYNSTATE                  Shift N.  That is, push the lookahead
++**   0 <= N <= YY_MAX_SHIFT             Shift N.  That is, push the lookahead
+ **                                      token onto the stack and goto state N.
+ **
+-**   YYNSTATE <= N < YYNSTATE+YYNRULE   Reduce by rule N-YYNSTATE.
++**   N between YY_MIN_SHIFTREDUCE       Shift to an arbitrary state then
++**     and YY_MAX_SHIFTREDUCE           reduce by rule N-YY_MIN_SHIFTREDUCE.
++**
++**   N between YY_MIN_REDUCE            Reduce by rule N-YY_MIN_REDUCE
++**     and YY_MAX_REDUCE
+ **
+-**   N == YYNSTATE+YYNRULE              A syntax error has occurred.
++**   N == YY_ERROR_ACTION               A syntax error has occurred.
+ **
+-**   N == YYNSTATE+YYNRULE+1            The parser accepts its input.
++**   N == YY_ACCEPT_ACTION              The parser accepts its input.
+ **
+-**   N == YYNSTATE+YYNRULE+2            No such action.  Denotes unused
++**   N == YY_NO_ACTION                  No such action.  Denotes unused
+ **                                      slots in the yy_action[] table.
+ **
+ ** The action table is constructed as a single large table named yy_action[].
+-** Given state S and lookahead X, the action is computed as
++** Given state S and lookahead X, the action is computed as either:
+ **
+-**      yy_action[ yy_shift_ofst[S] + X ]
++**    (A)   N = yy_action[ yy_shift_ofst[S] + X ]
++**    (B)   N = yy_default[S]
+ **
+-** If the index value yy_shift_ofst[S]+X is out of range or if the value
+-** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
+-** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
+-** and that yy_default[S] should be used instead.  
++** The (A) formula is preferred.  The B formula is used instead if:
++**    (1)  The yy_shift_ofst[S]+X value is out of range, or
++**    (2)  yy_lookahead[yy_shift_ofst[S]+X] is not equal to X, or
++**    (3)  yy_shift_ofst[S] equal YY_SHIFT_USE_DFLT.
++** (Implementation note: YY_SHIFT_USE_DFLT is chosen so that
++** YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X.
++** Hence only tests (1) and (2) need to be evaluated.)
+ **
+-** The formula above is for computing the action when the lookahead is
++** The formulas above are for computing the action when the lookahead is
+ ** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
+ ** a reduce action) then the yy_reduce_ofst[] array is used in place of
+ ** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
+@@ -123600,468 +140238,470 @@
+ **  yy_reduce_ofst[]   For each state, the offset into yy_action for
+ **                     shifting non-terminals after a reduce.
+ **  yy_default[]       Default action for each state.
+-*/
+-#define YY_ACTTAB_COUNT (1497)
++**
++*********** Begin parsing tables **********************************************/
++#define YY_ACTTAB_COUNT (1565)
+ static const YYACTIONTYPE yy_action[] = {
+- /*     0 */   306,  212,  432,  955,  639,  191,  955,  295,  559,   88,
+- /*    10 */    88,   88,   88,   81,   86,   86,   86,   86,   85,   85,
+- /*    20 */    84,   84,   84,   83,  330,  185,  184,  183,  635,  635,
+- /*    30 */   292,  606,  606,   88,   88,   88,   88,  683,   86,   86,
+- /*    40 */    86,   86,   85,   85,   84,   84,   84,   83,  330,   16,
+- /*    50 */   436,  597,   89,   90,   80,  600,  599,  601,  601,   87,
+- /*    60 */    87,   88,   88,   88,   88,  684,   86,   86,   86,   86,
+- /*    70 */    85,   85,   84,   84,   84,   83,  330,  306,  559,   84,
+- /*    80 */    84,   84,   83,  330,   65,   86,   86,   86,   86,   85,
+- /*    90 */    85,   84,   84,   84,   83,  330,  635,  635,  634,  633,
+- /*   100 */   182,  682,  550,  379,  376,  375,   17,  322,  606,  606,
+- /*   110 */   371,  198,  479,   91,  374,   82,   79,  165,   85,   85,
+- /*   120 */    84,   84,   84,   83,  330,  598,  635,  635,  107,   89,
+- /*   130 */    90,   80,  600,  599,  601,  601,   87,   87,   88,   88,
+- /*   140 */    88,   88,  186,   86,   86,   86,   86,   85,   85,   84,
+- /*   150 */    84,   84,   83,  330,  306,  594,  594,  142,  328,  327,
+- /*   160 */   484,  249,  344,  238,  635,  635,  634,  633,  585,  448,
+- /*   170 */   526,  525,  229,  388,    1,  394,  450,  584,  449,  635,
+- /*   180 */   635,  635,  635,  319,  395,  606,  606,  199,  157,  273,
+- /*   190 */   382,  268,  381,  187,  635,  635,  634,  633,  311,  555,
+- /*   200 */   266,  593,  593,  266,  347,  588,   89,   90,   80,  600,
+- /*   210 */   599,  601,  601,   87,   87,   88,   88,   88,   88,  478,
+- /*   220 */    86,   86,   86,   86,   85,   85,   84,   84,   84,   83,
+- /*   230 */   330,  306,  272,  536,  634,  633,  146,  610,  197,  310,
+- /*   240 */   575,  182,  482,  271,  379,  376,  375,  506,   21,  634,
+- /*   250 */   633,  634,  633,  635,  635,  374,  611,  574,  548,  440,
+- /*   260 */   111,  563,  606,  606,  634,  633,  324,  479,  608,  608,
+- /*   270 */   608,  300,  435,  573,  119,  407,  210,  162,  562,  883,
+- /*   280 */   592,  592,  306,   89,   90,   80,  600,  599,  601,  601,
+- /*   290 */    87,   87,   88,   88,   88,   88,  506,   86,   86,   86,
+- /*   300 */    86,   85,   85,   84,   84,   84,   83,  330,  620,  111,
+- /*   310 */   635,  635,  361,  606,  606,  358,  249,  349,  248,  433,
+- /*   320 */   243,  479,  586,  634,  633,  195,  611,   93,  119,  221,
+- /*   330 */   575,  497,  534,  534,   89,   90,   80,  600,  599,  601,
+- /*   340 */   601,   87,   87,   88,   88,   88,   88,  574,   86,   86,
+- /*   350 */    86,   86,   85,   85,   84,   84,   84,   83,  330,  306,
+- /*   360 */    77,  429,  638,  573,  589,  530,  240,  230,  242,  105,
+- /*   370 */   249,  349,  248,  515,  588,  208,  460,  529,  564,  173,
+- /*   380 */   634,  633,  970,  144,  430,    2,  424,  228,  380,  557,
+- /*   390 */   606,  606,  190,  153,  159,  158,  514,   51,  632,  631,
+- /*   400 */   630,   71,  536,  432,  954,  196,  610,  954,  614,   45,
+- /*   410 */    18,   89,   90,   80,  600,  599,  601,  601,   87,   87,
+- /*   420 */    88,   88,   88,   88,  261,   86,   86,   86,   86,   85,
+- /*   430 */    85,   84,   84,   84,   83,  330,  306,  608,  608,  608,
+- /*   440 */   542,  424,  402,  385,  241,  506,  451,  320,  211,  543,
+- /*   450 */   164,  436,  386,  293,  451,  587,  108,  496,  111,  334,
+- /*   460 */   391,  591,  424,  614,   27,  452,  453,  606,  606,   72,
+- /*   470 */   257,   70,  259,  452,  339,  342,  564,  582,   68,  415,
+- /*   480 */   469,  328,  327,   62,  614,   45,  110,  393,   89,   90,
+- /*   490 */    80,  600,  599,  601,  601,   87,   87,   88,   88,   88,
+- /*   500 */    88,  152,   86,   86,   86,   86,   85,   85,   84,   84,
+- /*   510 */    84,   83,  330,  306,  110,  499,  520,  538,  402,  389,
+- /*   520 */   424,  110,  566,  500,  593,  593,  454,   82,   79,  165,
+- /*   530 */   424,  591,  384,  564,  340,  615,  188,  162,  424,  350,
+- /*   540 */   616,  424,  614,   44,  606,  606,  445,  582,  300,  434,
+- /*   550 */   151,   19,  614,    9,  568,  580,  348,  615,  469,  567,
+- /*   560 */   614,   26,  616,  614,   45,   89,   90,   80,  600,  599,
+- /*   570 */   601,  601,   87,   87,   88,   88,   88,   88,  411,   86,
+- /*   580 */    86,   86,   86,   85,   85,   84,   84,   84,   83,  330,
+- /*   590 */   306,  579,  110,  578,  521,  282,  433,  398,  400,  255,
+- /*   600 */   486,   82,   79,  165,  487,  164,   82,   79,  165,  488,
+- /*   610 */   488,  364,  387,  424,  544,  544,  509,  350,  362,  155,
+- /*   620 */   191,  606,  606,  559,  642,  640,  333,   82,   79,  165,
+- /*   630 */   305,  564,  507,  312,  357,  614,   45,  329,  596,  595,
+- /*   640 */   194,  337,   89,   90,   80,  600,  599,  601,  601,   87,
+- /*   650 */    87,   88,   88,   88,   88,  424,   86,   86,   86,   86,
+- /*   660 */    85,   85,   84,   84,   84,   83,  330,  306,   20,  323,
+- /*   670 */   150,  263,  211,  543,  421,  596,  595,  614,   22,  424,
+- /*   680 */   193,  424,  284,  424,  391,  424,  509,  424,  577,  424,
+- /*   690 */   186,  335,  424,  559,  424,  313,  120,  546,  606,  606,
+- /*   700 */    67,  614,   47,  614,   50,  614,   48,  614,  100,  614,
+- /*   710 */    99,  614,  101,  576,  614,  102,  614,  109,  326,   89,
+- /*   720 */    90,   80,  600,  599,  601,  601,   87,   87,   88,   88,
+- /*   730 */    88,   88,  424,   86,   86,   86,   86,   85,   85,   84,
+- /*   740 */    84,   84,   83,  330,  306,  424,  311,  424,  585,   54,
+- /*   750 */   424,  516,  517,  590,  614,  112,  424,  584,  424,  572,
+- /*   760 */   424,  195,  424,  571,  424,   67,  424,  614,   94,  614,
+- /*   770 */    98,  424,  614,   97,  264,  606,  606,  195,  614,   46,
+- /*   780 */   614,   96,  614,   30,  614,   49,  614,  115,  614,  114,
+- /*   790 */   418,  229,  388,  614,  113,  306,   89,   90,   80,  600,
+- /*   800 */   599,  601,  601,   87,   87,   88,   88,   88,   88,  424,
+- /*   810 */    86,   86,   86,   86,   85,   85,   84,   84,   84,   83,
+- /*   820 */   330,  119,  424,  590,  110,  372,  606,  606,  195,   53,
+- /*   830 */   250,  614,   29,  195,  472,  438,  729,  190,  302,  498,
+- /*   840 */    14,  523,  641,    2,  614,   43,  306,   89,   90,   80,
+- /*   850 */   600,  599,  601,  601,   87,   87,   88,   88,   88,   88,
+- /*   860 */   424,   86,   86,   86,   86,   85,   85,   84,   84,   84,
+- /*   870 */    83,  330,  424,  613,  964,  964,  354,  606,  606,  420,
+- /*   880 */   312,   64,  614,   42,  391,  355,  283,  437,  301,  255,
+- /*   890 */   414,  410,  495,  492,  614,   28,  471,  306,   89,   90,
+- /*   900 */    80,  600,  599,  601,  601,   87,   87,   88,   88,   88,
+- /*   910 */    88,  424,   86,   86,   86,   86,   85,   85,   84,   84,
+- /*   920 */    84,   83,  330,  424,  110,  110,  110,  110,  606,  606,
+- /*   930 */   110,  254,   13,  614,   41,  532,  531,  283,  481,  531,
+- /*   940 */   457,  284,  119,  561,  356,  614,   40,  284,  306,   89,
+- /*   950 */    78,   80,  600,  599,  601,  601,   87,   87,   88,   88,
+- /*   960 */    88,   88,  424,   86,   86,   86,   86,   85,   85,   84,
+- /*   970 */    84,   84,   83,  330,  110,  424,  341,  220,  555,  606,
+- /*   980 */   606,  351,  555,  318,  614,   95,  413,  255,   83,  330,
+- /*   990 */   284,  284,  255,  640,  333,  356,  255,  614,   39,  306,
+- /*  1000 */   356,   90,   80,  600,  599,  601,  601,   87,   87,   88,
+- /*  1010 */    88,   88,   88,  424,   86,   86,   86,   86,   85,   85,
+- /*  1020 */    84,   84,   84,   83,  330,  424,  317,  316,  141,  465,
+- /*  1030 */   606,  606,  219,  619,  463,  614,   10,  417,  462,  255,
+- /*  1040 */   189,  510,  553,  351,  207,  363,  161,  614,   38,  315,
+- /*  1050 */   218,  255,  255,   80,  600,  599,  601,  601,   87,   87,
+- /*  1060 */    88,   88,   88,   88,  424,   86,   86,   86,   86,   85,
+- /*  1070 */    85,   84,   84,   84,   83,  330,   76,  419,  255,    3,
+- /*  1080 */   878,  461,  424,  247,  331,  331,  614,   37,  217,   76,
+- /*  1090 */   419,  390,    3,  216,  215,  422,    4,  331,  331,  424,
+- /*  1100 */   547,   12,  424,  545,  614,   36,  424,  541,  422,  424,
+- /*  1110 */   540,  424,  214,  424,  408,  424,  539,  403,  605,  605,
+- /*  1120 */   237,  614,   25,  119,  614,   24,  588,  408,  614,   45,
+- /*  1130 */   118,  614,   35,  614,   34,  614,   33,  614,   23,  588,
+- /*  1140 */    60,  223,  603,  602,  513,  378,   73,   74,  140,  139,
+- /*  1150 */   424,  110,  265,   75,  426,  425,   59,  424,  610,   73,
+- /*  1160 */    74,  549,  402,  404,  424,  373,   75,  426,  425,  604,
+- /*  1170 */   138,  610,  614,   11,  392,   76,  419,  181,    3,  614,
+- /*  1180 */    32,  271,  369,  331,  331,  493,  614,   31,  149,  608,
+- /*  1190 */   608,  608,  607,   15,  422,  365,  614,    8,  137,  489,
+- /*  1200 */   136,  190,  608,  608,  608,  607,   15,  485,  176,  135,
+- /*  1210 */     7,  252,  477,  408,  174,  133,  175,  474,   57,   56,
+- /*  1220 */   132,  130,  119,   76,  419,  588,    3,  468,  245,  464,
+- /*  1230 */   171,  331,  331,  125,  123,  456,  447,  122,  446,  104,
+- /*  1240 */   336,  231,  422,  166,  154,   73,   74,  332,  116,  431,
+- /*  1250 */   121,  309,   75,  426,  425,  222,  106,  610,  308,  637,
+- /*  1260 */   204,  408,  629,  627,  628,    6,  200,  428,  427,  290,
+- /*  1270 */   203,  622,  201,  588,   62,   63,  289,   66,  419,  399,
+- /*  1280 */     3,  401,  288,   92,  143,  331,  331,  287,  608,  608,
+- /*  1290 */   608,  607,   15,   73,   74,  227,  422,  325,   69,  416,
+- /*  1300 */    75,  426,  425,  612,  412,  610,  192,   61,  569,  209,
+- /*  1310 */   396,  226,  278,  225,  383,  408,  527,  558,  276,  533,
+- /*  1320 */   552,  528,  321,  523,  370,  508,  180,  588,  494,  179,
+- /*  1330 */   366,  117,  253,  269,  522,  503,  608,  608,  608,  607,
+- /*  1340 */    15,  551,  502,   58,  274,  524,  178,   73,   74,  304,
+- /*  1350 */   501,  368,  303,  206,   75,  426,  425,  491,  360,  610,
+- /*  1360 */   213,  177,  483,  131,  345,  298,  297,  296,  202,  294,
+- /*  1370 */   480,  490,  466,  134,  172,  129,  444,  346,  470,  128,
+- /*  1380 */   314,  459,  103,  127,  126,  148,  124,  167,  443,  235,
+- /*  1390 */   608,  608,  608,  607,   15,  442,  439,  623,  234,  299,
+- /*  1400 */   145,  583,  291,  377,  581,  160,  119,  156,  270,  636,
+- /*  1410 */   971,  169,  279,  626,  520,  625,  473,  624,  170,  621,
+- /*  1420 */   618,  119,  168,   55,  409,  423,  537,  609,  286,  285,
+- /*  1430 */   405,  570,  560,  556,    5,   52,  458,  554,  147,  267,
+- /*  1440 */   519,  504,  518,  406,  262,  239,  260,  512,  343,  511,
+- /*  1450 */   258,  353,  565,  256,  224,  251,  359,  277,  275,  476,
+- /*  1460 */   475,  246,  352,  244,  467,  455,  236,  233,  232,  307,
+- /*  1470 */   441,  281,  205,  163,  397,  280,  535,  505,  330,  617,
+- /*  1480 */   971,  971,  971,  971,  367,  971,  971,  971,  971,  971,
+- /*  1490 */   971,  971,  971,  971,  971,  971,  338,
++ /*     0 */   324,  410,  342,  747,  747,  203,  939,  353,  969,   98,
++ /*    10 */    98,   98,   98,   91,   96,   96,   96,   96,   95,   95,
++ /*    20 */    94,   94,   94,   93,  350, 1323,  155,  155,    2,  808,
++ /*    30 */   971,  971,   98,   98,   98,   98,   20,   96,   96,   96,
++ /*    40 */    96,   95,   95,   94,   94,   94,   93,  350,   92,   89,
++ /*    50 */   178,   99,  100,   90,  847,  850,  839,  839,   97,   97,
++ /*    60 */    98,   98,   98,   98,  350,   96,   96,   96,   96,   95,
++ /*    70 */    95,   94,   94,   94,   93,  350,  324,  339,  969,  262,
++ /*    80 */   364,  251,  212,  169,  287,  404,  282,  403,  199,  786,
++ /*    90 */   242,  411,   21,  950,  378,  280,   93,  350,  787,   95,
++ /*   100 */    95,   94,   94,   94,   93,  350,  971,  971,   96,   96,
++ /*   110 */    96,   96,   95,   95,   94,   94,   94,   93,  350,  808,
++ /*   120 */   328,  242,  411, 1235,  826, 1235,  132,   99,  100,   90,
++ /*   130 */   847,  850,  839,  839,   97,   97,   98,   98,   98,   98,
++ /*   140 */   449,   96,   96,   96,   96,   95,   95,   94,   94,   94,
++ /*   150 */    93,  350,  324,  819,  348,  347,  120,  818,  120,   75,
++ /*   160 */    52,   52,  950,  951,  952, 1084,  977,  146,  360,  262,
++ /*   170 */   369,  261,  950,  975,  954,  976,   92,   89,  178,  370,
++ /*   180 */   230,  370,  971,  971, 1141,  360,  359,  101,  818,  818,
++ /*   190 */   820,  383,   24, 1286,  380,  427,  412,  368,  978,  379,
++ /*   200 */   978, 1032,  324,   99,  100,   90,  847,  850,  839,  839,
++ /*   210 */    97,   97,   98,   98,   98,   98,  372,   96,   96,   96,
++ /*   220 */    96,   95,   95,   94,   94,   94,   93,  350,  950,  132,
++ /*   230 */   890,  449,  971,  971,  890,   60,   94,   94,   94,   93,
++ /*   240 */   350,  950,  951,  952,  954,  103,  360,  950,  384,  333,
++ /*   250 */   697,   52,   52,   99,  100,   90,  847,  850,  839,  839,
++ /*   260 */    97,   97,   98,   98,   98,   98, 1022,   96,   96,   96,
++ /*   270 */    96,   95,   95,   94,   94,   94,   93,  350,  324,  454,
++ /*   280 */   995,  449,  227,   61,  157,  243,  343,  114, 1025, 1211,
++ /*   290 */   147,  826,  950,  372, 1071,  950,  319,  950,  951,  952,
++ /*   300 */   194,   10,   10,  401,  398,  397, 1211, 1213,  971,  971,
++ /*   310 */   757,  171,  170,  157,  396,  336,  950,  951,  952,  697,
++ /*   320 */   819,  310,  153,  950,  818,  320,   82,   23,   80,   99,
++ /*   330 */   100,   90,  847,  850,  839,  839,   97,   97,   98,   98,
++ /*   340 */    98,   98,  888,   96,   96,   96,   96,   95,   95,   94,
++ /*   350 */    94,   94,   93,  350,  324,  818,  818,  820,  277,  231,
++ /*   360 */   300,  950,  951,  952,  950,  951,  952, 1211,  194,   25,
++ /*   370 */   449,  401,  398,  397,  950,  354,  300,  449,  950,   74,
++ /*   380 */   449,    1,  396,  132,  971,  971,  950,  224,  224,  808,
++ /*   390 */    10,   10,  950,  951,  952, 1290,  132,   52,   52,  414,
++ /*   400 */    52,   52, 1063, 1063,  338,   99,  100,   90,  847,  850,
++ /*   410 */   839,  839,   97,   97,   98,   98,   98,   98, 1114,   96,
++ /*   420 */    96,   96,   96,   95,   95,   94,   94,   94,   93,  350,
++ /*   430 */   324, 1113,  427,  417,  701,  427,  426, 1260, 1260,  262,
++ /*   440 */   369,  261,  950,  950,  951,  952,  752,  950,  951,  952,
++ /*   450 */   449,  751,  449, 1058, 1037,  950,  951,  952,  442,  706,
++ /*   460 */   971,  971, 1058,  393,   92,   89,  178,  446,  446,  446,
++ /*   470 */    51,   51,   52,   52,  438,  773, 1024,   92,   89,  178,
++ /*   480 */   172,   99,  100,   90,  847,  850,  839,  839,   97,   97,
++ /*   490 */    98,   98,   98,   98,  198,   96,   96,   96,   96,   95,
++ /*   500 */    95,   94,   94,   94,   93,  350,  324,  427,  407,  909,
++ /*   510 */   694,  950,  951,  952,   92,   89,  178,  224,  224,  157,
++ /*   520 */   241,  221,  418,  299,  771,  910,  415,  374,  449,  414,
++ /*   530 */    58,  323, 1061, 1061, 1242,  378,  971,  971,  378,  772,
++ /*   540 */   448,  911,  362,  735,  296,  681,    9,    9,   52,   52,
++ /*   550 */   234,  329,  234,  256,  416,  736,  280,   99,  100,   90,
++ /*   560 */   847,  850,  839,  839,   97,   97,   98,   98,   98,   98,
++ /*   570 */   449,   96,   96,   96,   96,   95,   95,   94,   94,   94,
++ /*   580 */    93,  350,  324,  422,   72,  449,  827,  120,  367,  449,
++ /*   590 */    10,   10,    5,  301,  203,  449,  177,  969,  253,  419,
++ /*   600 */   255,  771,  200,  175,  233,   10,   10,  836,  836,   36,
++ /*   610 */    36, 1289,  971,  971,  724,   37,   37,  348,  347,  424,
++ /*   620 */   203,  260,  771,  969,  232,  930, 1316,  870,  337, 1316,
++ /*   630 */   421,  848,  851,   99,  100,   90,  847,  850,  839,  839,
++ /*   640 */    97,   97,   98,   98,   98,   98,  268,   96,   96,   96,
++ /*   650 */    96,   95,   95,   94,   94,   94,   93,  350,  324,  840,
++ /*   660 */   449,  978,  813,  978, 1200,  449,  909,  969,  715,  349,
++ /*   670 */   349,  349,  928,  177,  449,  930, 1317,  254,  198, 1317,
++ /*   680 */    12,   12,  910,  402,  449,   27,   27,  250,  971,  971,
++ /*   690 */   118,  716,  162,  969,   38,   38,  268,  176,  911,  771,
++ /*   700 */   432, 1265,  939,  353,   39,   39,  316,  991,  324,   99,
++ /*   710 */   100,   90,  847,  850,  839,  839,   97,   97,   98,   98,
++ /*   720 */    98,   98,  928,   96,   96,   96,   96,   95,   95,   94,
++ /*   730 */    94,   94,   93,  350,  449,  329,  449,  357,  971,  971,
++ /*   740 */  1041,  316,  929,  340,  893,  893,  386,  669,  670,  671,
++ /*   750 */   275, 1318,  317,  992,   40,   40,   41,   41,  268,   99,
++ /*   760 */   100,   90,  847,  850,  839,  839,   97,   97,   98,   98,
++ /*   770 */    98,   98,  449,   96,   96,   96,   96,   95,   95,   94,
++ /*   780 */    94,   94,   93,  350,  324,  449,  355,  449,  992,  449,
++ /*   790 */  1016,  330,   42,   42,  786,  270,  449,  273,  449,  228,
++ /*   800 */   449,  298,  449,  787,  449,   28,   28,   29,   29,   31,
++ /*   810 */    31,  449, 1141,  449,  971,  971,   43,   43,   44,   44,
++ /*   820 */    45,   45,   11,   11,   46,   46,  887,   78,  887,  268,
++ /*   830 */   268,  105,  105,   47,   47,   99,  100,   90,  847,  850,
++ /*   840 */   839,  839,   97,   97,   98,   98,   98,   98,  449,   96,
++ /*   850 */    96,   96,   96,   95,   95,   94,   94,   94,   93,  350,
++ /*   860 */   324,  449,  117,  449, 1073,  158,  449,  691,   48,   48,
++ /*   870 */   229, 1241,  449, 1250,  449,  414,  449,  334,  449,  245,
++ /*   880 */   449,   33,   33,   49,   49,  449,   50,   50,  246, 1141,
++ /*   890 */   971,  971,   34,   34,  122,  122,  123,  123,  124,  124,
++ /*   900 */    56,   56,  268,   81,  249,   35,   35,  197,  196,  195,
++ /*   910 */   324,   99,  100,   90,  847,  850,  839,  839,   97,   97,
++ /*   920 */    98,   98,   98,   98,  449,   96,   96,   96,   96,   95,
++ /*   930 */    95,   94,   94,   94,   93,  350,  449,  691,  449, 1141,
++ /*   940 */   971,  971,  968, 1207,  106,  106,  268, 1209,  268, 1266,
++ /*   950 */     2,  886,  268,  886,  335, 1040,   53,   53,  107,  107,
++ /*   960 */   324,   99,  100,   90,  847,  850,  839,  839,   97,   97,
++ /*   970 */    98,   98,   98,   98,  449,   96,   96,   96,   96,   95,
++ /*   980 */    95,   94,   94,   94,   93,  350,  449, 1070,  449, 1066,
++ /*   990 */   971,  971, 1039,  267,  108,  108,  445,  330,  331,  133,
++ /*  1000 */   223,  175,  301,  225,  385, 1255,  104,  104,  121,  121,
++ /*  1010 */   324,   99,   88,   90,  847,  850,  839,  839,   97,   97,
++ /*  1020 */    98,   98,   98,   98, 1141,   96,   96,   96,   96,   95,
++ /*  1030 */    95,   94,   94,   94,   93,  350,  449,  346,  449,  167,
++ /*  1040 */   971,  971,  925,  810,  371,  318,  202,  202,  373,  263,
++ /*  1050 */   394,  202,   74,  208,  721,  722,  119,  119,  112,  112,
++ /*  1060 */   324,  406,  100,   90,  847,  850,  839,  839,   97,   97,
++ /*  1070 */    98,   98,   98,   98,  449,   96,   96,   96,   96,   95,
++ /*  1080 */    95,   94,   94,   94,   93,  350,  449,  752,  449,  344,
++ /*  1090 */   971,  971,  751,  278,  111,  111,   74,  714,  713,  704,
++ /*  1100 */   286,  877,  749, 1279,  257,   77,  109,  109,  110,  110,
++ /*  1110 */  1230,  285, 1134,   90,  847,  850,  839,  839,   97,   97,
++ /*  1120 */    98,   98,   98,   98, 1233,   96,   96,   96,   96,   95,
++ /*  1130 */    95,   94,   94,   94,   93,  350,   86,  444,  449,    3,
++ /*  1140 */  1193,  449, 1069,  132,  351,  120, 1013,   86,  444,  780,
++ /*  1150 */     3, 1091,  202,  376,  447,  351, 1229,  120,   55,   55,
++ /*  1160 */   449,   57,   57,  822,  873,  447,  449,  208,  449,  704,
++ /*  1170 */   449,  877,  237,  433,  435,  120,  439,  428,  361,  120,
++ /*  1180 */    54,   54,  132,  449,  433,  826,   52,   52,   26,   26,
++ /*  1190 */    30,   30,  381,  132,  408,  443,  826,  689,  264,  389,
++ /*  1200 */   116,  269,  272,   32,   32,   83,   84,  120,  274,  120,
++ /*  1210 */   120,  276,   85,  351,  451,  450,   83,   84,  818, 1054,
++ /*  1220 */  1038,  427,  429,   85,  351,  451,  450,  120,  120,  818,
++ /*  1230 */   377,  218,  281,  822, 1107, 1140,   86,  444,  409,    3,
++ /*  1240 */  1087, 1098,  430,  431,  351,  302,  303, 1146, 1021,  818,
++ /*  1250 */   818,  820,  821,   19,  447, 1015, 1004, 1003, 1005, 1273,
++ /*  1260 */   818,  818,  820,  821,   19,  289,  159,  291,  293,    7,
++ /*  1270 */   315,  173,  259,  433, 1129,  363,  252, 1232,  375, 1037,
++ /*  1280 */   295,  434,  168,  986,  399,  826,  284, 1204, 1203,  205,
++ /*  1290 */  1276,  308, 1249,   86,  444,  983,    3, 1247,  332,  144,
++ /*  1300 */   130,  351,   72,  135,   59,   83,   84,  756,  137,  365,
++ /*  1310 */  1126,  447,   85,  351,  451,  450,  139,  226,  818,  140,
++ /*  1320 */   156,   62,  314,  314,  313,  215,  311,  366,  392,  678,
++ /*  1330 */   433,  185,  141, 1234,  142,  160,  148, 1136, 1198,  382,
++ /*  1340 */   189,   67,  826,  180,  388,  248, 1218, 1099,  219,  818,
++ /*  1350 */   818,  820,  821,   19,  247,  190,  266,  154,  390,  271,
++ /*  1360 */   191,  192,   83,   84, 1006,  405, 1057,  182,  321,   85,
++ /*  1370 */   351,  451,  450, 1056,  183,  818,  341,  132,  181,  706,
++ /*  1380 */  1055,  420,   76,  444, 1029,    3,  322, 1028,  283, 1048,
++ /*  1390 */   351, 1095, 1027, 1288, 1047,   71,  204,    6,  288,  290,
++ /*  1400 */   447, 1096, 1094, 1093,   79,  292,  818,  818,  820,  821,
++ /*  1410 */    19,  294,  297,  437,  345,  441,  102, 1184, 1077,  433,
++ /*  1420 */   238,  425,   73,  305,  239,  304,  325,  240,  423,  306,
++ /*  1430 */   307,  826,  213, 1012,   22,  945,  452,  214,  216,  217,
++ /*  1440 */   453, 1001,  115,  996,  125,  126,  235,  127,  665,  352,
++ /*  1450 */   326,   83,   84,  358,  166,  244,  179,  327,   85,  351,
++ /*  1460 */   451,  450,  134,  356,  818,  113,  885,  806,  883,  136,
++ /*  1470 */   128,  138,  738,  258,  184,  899,  143,  145,   63,   64,
++ /*  1480 */    65,   66,  129,  902,  187,  186,  898,    8,   13,  188,
++ /*  1490 */   265,  891,  149,  202,  980,  818,  818,  820,  821,   19,
++ /*  1500 */   150,  387,  161,  680,  285,  391,  151,  395,  400,  193,
++ /*  1510 */    68,   14,  236,  279,   15,   69,  717,  825,  131,  824,
++ /*  1520 */   853,   70,  746,   16,  413,  750,    4,  174,  220,  222,
++ /*  1530 */   152,  779,  857,  774,  201,   77,   74,  868,   17,  854,
++ /*  1540 */   852,  908,   18,  907,  207,  206,  934,  163,  436,  210,
++ /*  1550 */   935,  164,  209,  165,  440,  856,  823,  690,   87,  211,
++ /*  1560 */   309,  312, 1281,  940, 1280,
+ };
+ static const YYCODETYPE yy_lookahead[] = {
+- /*     0 */    19,   22,   22,   23,    1,   24,   26,   15,   27,   80,
+- /*    10 */    81,   82,   83,   84,   85,   86,   87,   88,   89,   90,
+- /*    20 */    91,   92,   93,   94,   95,  108,  109,  110,   27,   28,
+- /*    30 */    23,   50,   51,   80,   81,   82,   83,  122,   85,   86,
+- /*    40 */    87,   88,   89,   90,   91,   92,   93,   94,   95,   22,
+- /*    50 */    70,   23,   71,   72,   73,   74,   75,   76,   77,   78,
+- /*    60 */    79,   80,   81,   82,   83,  122,   85,   86,   87,   88,
+- /*    70 */    89,   90,   91,   92,   93,   94,   95,   19,   97,   91,
+- /*    80 */    92,   93,   94,   95,   26,   85,   86,   87,   88,   89,
+- /*    90 */    90,   91,   92,   93,   94,   95,   27,   28,   97,   98,
+- /*   100 */    99,  122,  211,  102,  103,  104,   79,   19,   50,   51,
+- /*   110 */    19,  122,   59,   55,  113,  224,  225,  226,   89,   90,
+- /*   120 */    91,   92,   93,   94,   95,   23,   27,   28,   26,   71,
+- /*   130 */    72,   73,   74,   75,   76,   77,   78,   79,   80,   81,
+- /*   140 */    82,   83,   51,   85,   86,   87,   88,   89,   90,   91,
+- /*   150 */    92,   93,   94,   95,   19,  132,  133,   58,   89,   90,
+- /*   160 */    21,  108,  109,  110,   27,   28,   97,   98,   33,  100,
+- /*   170 */     7,    8,  119,  120,   22,   19,  107,   42,  109,   27,
+- /*   180 */    28,   27,   28,   95,   28,   50,   51,   99,  100,  101,
+- /*   190 */   102,  103,  104,  105,   27,   28,   97,   98,  107,  152,
+- /*   200 */   112,  132,  133,  112,   65,   69,   71,   72,   73,   74,
+- /*   210 */    75,   76,   77,   78,   79,   80,   81,   82,   83,   11,
+- /*   220 */    85,   86,   87,   88,   89,   90,   91,   92,   93,   94,
+- /*   230 */    95,   19,  101,   97,   97,   98,   24,  101,  122,  157,
+- /*   240 */    12,   99,  103,  112,  102,  103,  104,  152,   22,   97,
+- /*   250 */    98,   97,   98,   27,   28,  113,   27,   29,   91,  164,
+- /*   260 */   165,  124,   50,   51,   97,   98,  219,   59,  132,  133,
+- /*   270 */   134,   22,   23,   45,   66,   47,  212,  213,  124,  140,
+- /*   280 */   132,  133,   19,   71,   72,   73,   74,   75,   76,   77,
+- /*   290 */    78,   79,   80,   81,   82,   83,  152,   85,   86,   87,
+- /*   300 */    88,   89,   90,   91,   92,   93,   94,   95,  164,  165,
+- /*   310 */    27,   28,  230,   50,   51,  233,  108,  109,  110,   70,
+- /*   320 */    16,   59,   23,   97,   98,   26,   97,   22,   66,  185,
+- /*   330 */    12,  187,   27,   28,   71,   72,   73,   74,   75,   76,
+- /*   340 */    77,   78,   79,   80,   81,   82,   83,   29,   85,   86,
+- /*   350 */    87,   88,   89,   90,   91,   92,   93,   94,   95,   19,
+- /*   360 */    22,  148,  149,   45,   23,   47,   62,  154,   64,  156,
+- /*   370 */   108,  109,  110,   37,   69,   23,  163,   59,   26,   26,
+- /*   380 */    97,   98,  144,  145,  146,  147,  152,  200,   52,   23,
+- /*   390 */    50,   51,   26,   22,   89,   90,   60,  210,    7,    8,
+- /*   400 */     9,  138,   97,   22,   23,   26,  101,   26,  174,  175,
+- /*   410 */   197,   71,   72,   73,   74,   75,   76,   77,   78,   79,
+- /*   420 */    80,   81,   82,   83,   16,   85,   86,   87,   88,   89,
+- /*   430 */    90,   91,   92,   93,   94,   95,   19,  132,  133,  134,
+- /*   440 */    23,  152,  208,  209,  140,  152,  152,  111,  195,  196,
+- /*   450 */    98,   70,  163,  160,  152,   23,   22,  164,  165,  246,
+- /*   460 */   207,   27,  152,  174,  175,  171,  172,   50,   51,  137,
+- /*   470 */    62,  139,   64,  171,  172,  222,  124,   27,  138,   24,
+- /*   480 */   163,   89,   90,  130,  174,  175,  197,  163,   71,   72,
+- /*   490 */    73,   74,   75,   76,   77,   78,   79,   80,   81,   82,
+- /*   500 */    83,   22,   85,   86,   87,   88,   89,   90,   91,   92,
+- /*   510 */    93,   94,   95,   19,  197,  181,  182,   23,  208,  209,
+- /*   520 */   152,  197,   26,  189,  132,  133,  232,  224,  225,  226,
+- /*   530 */   152,   97,   91,   26,  232,  116,  212,  213,  152,  222,
+- /*   540 */   121,  152,  174,  175,   50,   51,  243,   97,   22,   23,
+- /*   550 */    22,  234,  174,  175,  177,   23,  239,  116,  163,  177,
+- /*   560 */   174,  175,  121,  174,  175,   71,   72,   73,   74,   75,
+- /*   570 */    76,   77,   78,   79,   80,   81,   82,   83,   24,   85,
+- /*   580 */    86,   87,   88,   89,   90,   91,   92,   93,   94,   95,
+- /*   590 */    19,   23,  197,   11,   23,  227,   70,  208,  220,  152,
+- /*   600 */    31,  224,  225,  226,   35,   98,  224,  225,  226,  108,
+- /*   610 */   109,  110,  115,  152,  117,  118,   27,  222,   49,  123,
+- /*   620 */    24,   50,   51,   27,    0,    1,    2,  224,  225,  226,
+- /*   630 */   166,  124,  168,  169,  239,  174,  175,  170,  171,  172,
+- /*   640 */    22,  194,   71,   72,   73,   74,   75,   76,   77,   78,
+- /*   650 */    79,   80,   81,   82,   83,  152,   85,   86,   87,   88,
+- /*   660 */    89,   90,   91,   92,   93,   94,   95,   19,   22,  208,
+- /*   670 */    24,   23,  195,  196,  170,  171,  172,  174,  175,  152,
+- /*   680 */    26,  152,  152,  152,  207,  152,   97,  152,   23,  152,
+- /*   690 */    51,  244,  152,   97,  152,  247,  248,   23,   50,   51,
+- /*   700 */    26,  174,  175,  174,  175,  174,  175,  174,  175,  174,
+- /*   710 */   175,  174,  175,   23,  174,  175,  174,  175,  188,   71,
+- /*   720 */    72,   73,   74,   75,   76,   77,   78,   79,   80,   81,
+- /*   730 */    82,   83,  152,   85,   86,   87,   88,   89,   90,   91,
+- /*   740 */    92,   93,   94,   95,   19,  152,  107,  152,   33,   24,
+- /*   750 */   152,  100,  101,   27,  174,  175,  152,   42,  152,   23,
+- /*   760 */   152,   26,  152,   23,  152,   26,  152,  174,  175,  174,
+- /*   770 */   175,  152,  174,  175,   23,   50,   51,   26,  174,  175,
+- /*   780 */   174,  175,  174,  175,  174,  175,  174,  175,  174,  175,
+- /*   790 */   163,  119,  120,  174,  175,   19,   71,   72,   73,   74,
+- /*   800 */    75,   76,   77,   78,   79,   80,   81,   82,   83,  152,
+- /*   810 */    85,   86,   87,   88,   89,   90,   91,   92,   93,   94,
+- /*   820 */    95,   66,  152,   97,  197,   23,   50,   51,   26,   53,
+- /*   830 */    23,  174,  175,   26,   23,   23,   23,   26,   26,   26,
+- /*   840 */    36,  106,  146,  147,  174,  175,   19,   71,   72,   73,
+- /*   850 */    74,   75,   76,   77,   78,   79,   80,   81,   82,   83,
+- /*   860 */   152,   85,   86,   87,   88,   89,   90,   91,   92,   93,
+- /*   870 */    94,   95,  152,  196,  119,  120,   19,   50,   51,  168,
+- /*   880 */   169,   26,  174,  175,  207,   28,  152,  249,  250,  152,
+- /*   890 */   163,  163,  163,  163,  174,  175,  163,   19,   71,   72,
+- /*   900 */    73,   74,   75,   76,   77,   78,   79,   80,   81,   82,
+- /*   910 */    83,  152,   85,   86,   87,   88,   89,   90,   91,   92,
+- /*   920 */    93,   94,   95,  152,  197,  197,  197,  197,   50,   51,
+- /*   930 */   197,  194,   36,  174,  175,  191,  192,  152,  191,  192,
+- /*   940 */   163,  152,   66,  124,  152,  174,  175,  152,   19,   71,
+- /*   950 */    72,   73,   74,   75,   76,   77,   78,   79,   80,   81,
+- /*   960 */    82,   83,  152,   85,   86,   87,   88,   89,   90,   91,
+- /*   970 */    92,   93,   94,   95,  197,  152,  100,  188,  152,   50,
+- /*   980 */    51,  152,  152,  188,  174,  175,  252,  152,   94,   95,
+- /*   990 */   152,  152,  152,    1,    2,  152,  152,  174,  175,   19,
+- /*  1000 */   152,   72,   73,   74,   75,   76,   77,   78,   79,   80,
+- /*  1010 */    81,   82,   83,  152,   85,   86,   87,   88,   89,   90,
+- /*  1020 */    91,   92,   93,   94,   95,  152,  188,  188,   22,  194,
+- /*  1030 */    50,   51,  240,  173,  194,  174,  175,  252,  194,  152,
+- /*  1040 */    36,  181,   28,  152,   23,  219,  122,  174,  175,  219,
+- /*  1050 */   221,  152,  152,   73,   74,   75,   76,   77,   78,   79,
+- /*  1060 */    80,   81,   82,   83,  152,   85,   86,   87,   88,   89,
+- /*  1070 */    90,   91,   92,   93,   94,   95,   19,   20,  152,   22,
+- /*  1080 */    23,  194,  152,  240,   27,   28,  174,  175,  240,   19,
+- /*  1090 */    20,   26,   22,  194,  194,   38,   22,   27,   28,  152,
+- /*  1100 */    23,   22,  152,  116,  174,  175,  152,   23,   38,  152,
+- /*  1110 */    23,  152,  221,  152,   57,  152,   23,  163,   50,   51,
+- /*  1120 */   194,  174,  175,   66,  174,  175,   69,   57,  174,  175,
+- /*  1130 */    40,  174,  175,  174,  175,  174,  175,  174,  175,   69,
+- /*  1140 */    22,   53,   74,   75,   30,   53,   89,   90,   22,   22,
+- /*  1150 */   152,  197,   23,   96,   97,   98,   22,  152,  101,   89,
+- /*  1160 */    90,   91,  208,  209,  152,   53,   96,   97,   98,  101,
+- /*  1170 */    22,  101,  174,  175,  152,   19,   20,  105,   22,  174,
+- /*  1180 */   175,  112,   19,   27,   28,   20,  174,  175,   24,  132,
+- /*  1190 */   133,  134,  135,  136,   38,   44,  174,  175,  107,   61,
+- /*  1200 */    54,   26,  132,  133,  134,  135,  136,   54,  107,   22,
+- /*  1210 */     5,  140,    1,   57,   36,  111,  122,   28,   79,   79,
+- /*  1220 */   131,  123,   66,   19,   20,   69,   22,    1,   16,   20,
+- /*  1230 */   125,   27,   28,  123,  111,  120,   23,  131,   23,   16,
+- /*  1240 */    68,  142,   38,   15,   22,   89,   90,    3,  167,    4,
+- /*  1250 */   248,  251,   96,   97,   98,  180,  180,  101,  251,  151,
+- /*  1260 */     6,   57,  151,   13,  151,   26,   25,  151,  161,  202,
+- /*  1270 */   153,  162,  153,   69,  130,  128,  203,   19,   20,  127,
+- /*  1280 */    22,  126,  204,  129,   22,   27,   28,  205,  132,  133,
+- /*  1290 */   134,  135,  136,   89,   90,  231,   38,   95,  137,  179,
+- /*  1300 */    96,   97,   98,  206,  179,  101,  122,  107,  159,  159,
+- /*  1310 */   125,  231,  216,  228,  107,   57,  184,  217,  216,  176,
+- /*  1320 */   217,  176,   48,  106,   18,  184,  158,   69,  159,  158,
+- /*  1330 */    46,   71,  237,  176,  176,  176,  132,  133,  134,  135,
+- /*  1340 */   136,  217,  176,  137,  216,  178,  158,   89,   90,  179,
+- /*  1350 */   176,  159,  179,  159,   96,   97,   98,  159,  159,  101,
+- /*  1360 */     5,  158,  202,   22,   18,   10,   11,   12,   13,   14,
+- /*  1370 */   190,  238,   17,  190,  158,  193,   41,  159,  202,  193,
+- /*  1380 */   159,  202,  245,  193,  193,  223,  190,   32,  159,   34,
+- /*  1390 */   132,  133,  134,  135,  136,  159,   39,  155,   43,  150,
+- /*  1400 */   223,  177,  201,  178,  177,  186,   66,  199,  177,  152,
+- /*  1410 */   253,   56,  215,  152,  182,  152,  202,  152,   63,  152,
+- /*  1420 */   152,   66,   67,  242,  229,  152,  174,  152,  152,  152,
+- /*  1430 */   152,  152,  152,  152,  199,  242,  202,  152,  198,  152,
+- /*  1440 */   152,  152,  183,  192,  152,  215,  152,  183,  215,  183,
+- /*  1450 */   152,  241,  214,  152,  211,  152,  152,  211,  211,  152,
+- /*  1460 */   152,  241,  152,  152,  152,  152,  152,  152,  152,  114,
+- /*  1470 */   152,  152,  235,  152,  152,  152,  174,  187,   95,  174,
+- /*  1480 */   253,  253,  253,  253,  236,  253,  253,  253,  253,  253,
+- /*  1490 */   253,  253,  253,  253,  253,  253,  141,
+-};
+-#define YY_SHIFT_USE_DFLT (-86)
+-#define YY_SHIFT_COUNT (429)
+-#define YY_SHIFT_MIN   (-85)
+-#define YY_SHIFT_MAX   (1383)
++ /*     0 */    19,  115,   19,  117,  118,   24,    1,    2,   27,   79,
++ /*    10 */    80,   81,   82,   83,   84,   85,   86,   87,   88,   89,
++ /*    20 */    90,   91,   92,   93,   94,  144,  145,  146,  147,   58,
++ /*    30 */    49,   50,   79,   80,   81,   82,   22,   84,   85,   86,
++ /*    40 */    87,   88,   89,   90,   91,   92,   93,   94,  221,  222,
++ /*    50 */   223,   70,   71,   72,   73,   74,   75,   76,   77,   78,
++ /*    60 */    79,   80,   81,   82,   94,   84,   85,   86,   87,   88,
++ /*    70 */    89,   90,   91,   92,   93,   94,   19,   94,   97,  108,
++ /*    80 */   109,  110,   99,  100,  101,  102,  103,  104,  105,   32,
++ /*    90 */   119,  120,   78,   27,  152,  112,   93,   94,   41,   88,
++ /*   100 */    89,   90,   91,   92,   93,   94,   49,   50,   84,   85,
++ /*   110 */    86,   87,   88,   89,   90,   91,   92,   93,   94,   58,
++ /*   120 */   157,  119,  120,  163,   68,  163,   65,   70,   71,   72,
++ /*   130 */    73,   74,   75,   76,   77,   78,   79,   80,   81,   82,
++ /*   140 */   152,   84,   85,   86,   87,   88,   89,   90,   91,   92,
++ /*   150 */    93,   94,   19,   97,   88,   89,  196,  101,  196,   26,
++ /*   160 */   172,  173,   96,   97,   98,  210,  100,   22,  152,  108,
++ /*   170 */   109,  110,   27,  107,   27,  109,  221,  222,  223,  219,
++ /*   180 */   238,  219,   49,   50,  152,  169,  170,   54,  132,  133,
++ /*   190 */   134,  228,  232,  171,  231,  207,  208,  237,  132,  237,
++ /*   200 */   134,  179,   19,   70,   71,   72,   73,   74,   75,   76,
++ /*   210 */    77,   78,   79,   80,   81,   82,  152,   84,   85,   86,
++ /*   220 */    87,   88,   89,   90,   91,   92,   93,   94,   27,   65,
++ /*   230 */    30,  152,   49,   50,   34,   52,   90,   91,   92,   93,
++ /*   240 */    94,   96,   97,   98,   97,   22,  230,   27,   48,  217,
++ /*   250 */    27,  172,  173,   70,   71,   72,   73,   74,   75,   76,
++ /*   260 */    77,   78,   79,   80,   81,   82,  172,   84,   85,   86,
++ /*   270 */    87,   88,   89,   90,   91,   92,   93,   94,   19,  148,
++ /*   280 */   149,  152,  218,   24,  152,  154,  207,  156,  172,  152,
++ /*   290 */    22,   68,   27,  152,  163,   27,  164,   96,   97,   98,
++ /*   300 */    99,  172,  173,  102,  103,  104,  169,  170,   49,   50,
++ /*   310 */    90,   88,   89,  152,  113,  186,   96,   97,   98,   96,
++ /*   320 */    97,  160,   57,   27,  101,  164,  137,  196,  139,   70,
++ /*   330 */    71,   72,   73,   74,   75,   76,   77,   78,   79,   80,
++ /*   340 */    81,   82,   11,   84,   85,   86,   87,   88,   89,   90,
++ /*   350 */    91,   92,   93,   94,   19,  132,  133,  134,   23,  218,
++ /*   360 */   152,   96,   97,   98,   96,   97,   98,  230,   99,   22,
++ /*   370 */   152,  102,  103,  104,   27,  244,  152,  152,   27,   26,
++ /*   380 */   152,   22,  113,   65,   49,   50,   27,  194,  195,   58,
++ /*   390 */   172,  173,   96,   97,   98,  185,   65,  172,  173,  206,
++ /*   400 */   172,  173,  190,  191,  186,   70,   71,   72,   73,   74,
++ /*   410 */    75,   76,   77,   78,   79,   80,   81,   82,  175,   84,
++ /*   420 */    85,   86,   87,   88,   89,   90,   91,   92,   93,   94,
++ /*   430 */    19,  175,  207,  208,   23,  207,  208,  119,  120,  108,
++ /*   440 */   109,  110,   27,   96,   97,   98,  116,   96,   97,   98,
++ /*   450 */   152,  121,  152,  179,  180,   96,   97,   98,  250,  106,
++ /*   460 */    49,   50,  188,   19,  221,  222,  223,  168,  169,  170,
++ /*   470 */   172,  173,  172,  173,  250,  124,  172,  221,  222,  223,
++ /*   480 */    26,   70,   71,   72,   73,   74,   75,   76,   77,   78,
++ /*   490 */    79,   80,   81,   82,   50,   84,   85,   86,   87,   88,
++ /*   500 */    89,   90,   91,   92,   93,   94,   19,  207,  208,   12,
++ /*   510 */    23,   96,   97,   98,  221,  222,  223,  194,  195,  152,
++ /*   520 */   199,   23,   19,  225,   26,   28,  152,  152,  152,  206,
++ /*   530 */   209,  164,  190,  191,  241,  152,   49,   50,  152,  124,
++ /*   540 */   152,   44,  219,   46,  152,   21,  172,  173,  172,  173,
++ /*   550 */   183,  107,  185,   16,  163,   58,  112,   70,   71,   72,
++ /*   560 */    73,   74,   75,   76,   77,   78,   79,   80,   81,   82,
++ /*   570 */   152,   84,   85,   86,   87,   88,   89,   90,   91,   92,
++ /*   580 */    93,   94,   19,  207,  130,  152,   23,  196,   64,  152,
++ /*   590 */   172,  173,   22,  152,   24,  152,   98,   27,   61,   96,
++ /*   600 */    63,   26,  211,  212,  186,  172,  173,   49,   50,  172,
++ /*   610 */   173,   23,   49,   50,   26,  172,  173,   88,   89,  186,
++ /*   620 */    24,  238,  124,   27,  238,   22,   23,  103,  187,   26,
++ /*   630 */   152,   73,   74,   70,   71,   72,   73,   74,   75,   76,
++ /*   640 */    77,   78,   79,   80,   81,   82,  152,   84,   85,   86,
++ /*   650 */    87,   88,   89,   90,   91,   92,   93,   94,   19,  101,
++ /*   660 */   152,  132,   23,  134,  140,  152,   12,   97,   36,  168,
++ /*   670 */   169,  170,   69,   98,  152,   22,   23,  140,   50,   26,
++ /*   680 */   172,  173,   28,   51,  152,  172,  173,  193,   49,   50,
++ /*   690 */    22,   59,   24,   97,  172,  173,  152,  152,   44,  124,
++ /*   700 */    46,    0,    1,    2,  172,  173,   22,   23,   19,   70,
++ /*   710 */    71,   72,   73,   74,   75,   76,   77,   78,   79,   80,
++ /*   720 */    81,   82,   69,   84,   85,   86,   87,   88,   89,   90,
++ /*   730 */    91,   92,   93,   94,  152,  107,  152,  193,   49,   50,
++ /*   740 */   181,   22,   23,  111,  108,  109,  110,    7,    8,    9,
++ /*   750 */    16,  247,  248,   69,  172,  173,  172,  173,  152,   70,
++ /*   760 */    71,   72,   73,   74,   75,   76,   77,   78,   79,   80,
++ /*   770 */    81,   82,  152,   84,   85,   86,   87,   88,   89,   90,
++ /*   780 */    91,   92,   93,   94,   19,  152,  242,  152,   69,  152,
++ /*   790 */   166,  167,  172,  173,   32,   61,  152,   63,  152,  193,
++ /*   800 */   152,  152,  152,   41,  152,  172,  173,  172,  173,  172,
++ /*   810 */   173,  152,  152,  152,   49,   50,  172,  173,  172,  173,
++ /*   820 */   172,  173,  172,  173,  172,  173,  132,  138,  134,  152,
++ /*   830 */   152,  172,  173,  172,  173,   70,   71,   72,   73,   74,
++ /*   840 */    75,   76,   77,   78,   79,   80,   81,   82,  152,   84,
++ /*   850 */    85,   86,   87,   88,   89,   90,   91,   92,   93,   94,
++ /*   860 */    19,  152,   22,  152,  195,   24,  152,   27,  172,  173,
++ /*   870 */   193,  193,  152,  152,  152,  206,  152,  217,  152,  152,
++ /*   880 */   152,  172,  173,  172,  173,  152,  172,  173,  152,  152,
++ /*   890 */    49,   50,  172,  173,  172,  173,  172,  173,  172,  173,
++ /*   900 */   172,  173,  152,  138,  152,  172,  173,  108,  109,  110,
++ /*   910 */    19,   70,   71,   72,   73,   74,   75,   76,   77,   78,
++ /*   920 */    79,   80,   81,   82,  152,   84,   85,   86,   87,   88,
++ /*   930 */    89,   90,   91,   92,   93,   94,  152,   97,  152,  152,
++ /*   940 */    49,   50,   26,  193,  172,  173,  152,  152,  152,  146,
++ /*   950 */   147,  132,  152,  134,  217,  181,  172,  173,  172,  173,
++ /*   960 */    19,   70,   71,   72,   73,   74,   75,   76,   77,   78,
++ /*   970 */    79,   80,   81,   82,  152,   84,   85,   86,   87,   88,
++ /*   980 */    89,   90,   91,   92,   93,   94,  152,  193,  152,  193,
++ /*   990 */    49,   50,  181,  193,  172,  173,  166,  167,  245,  246,
++ /*  1000 */   211,  212,  152,   22,  217,  152,  172,  173,  172,  173,
++ /*  1010 */    19,   70,   71,   72,   73,   74,   75,   76,   77,   78,
++ /*  1020 */    79,   80,   81,   82,  152,   84,   85,   86,   87,   88,
++ /*  1030 */    89,   90,   91,   92,   93,   94,  152,  187,  152,  123,
++ /*  1040 */    49,   50,   23,   23,   23,   26,   26,   26,   23,   23,
++ /*  1050 */    23,   26,   26,   26,    7,    8,  172,  173,  172,  173,
++ /*  1060 */    19,   90,   71,   72,   73,   74,   75,   76,   77,   78,
++ /*  1070 */    79,   80,   81,   82,  152,   84,   85,   86,   87,   88,
++ /*  1080 */    89,   90,   91,   92,   93,   94,  152,  116,  152,  217,
++ /*  1090 */    49,   50,  121,   23,  172,  173,   26,  100,  101,   27,
++ /*  1100 */   101,   27,   23,  122,  152,   26,  172,  173,  172,  173,
++ /*  1110 */   152,  112,  163,   72,   73,   74,   75,   76,   77,   78,
++ /*  1120 */    79,   80,   81,   82,  163,   84,   85,   86,   87,   88,
++ /*  1130 */    89,   90,   91,   92,   93,   94,   19,   20,  152,   22,
++ /*  1140 */    23,  152,  163,   65,   27,  196,  163,   19,   20,   23,
++ /*  1150 */    22,  213,   26,   19,   37,   27,  152,  196,  172,  173,
++ /*  1160 */   152,  172,  173,   27,   23,   37,  152,   26,  152,   97,
++ /*  1170 */   152,   97,  210,   56,  163,  196,  163,  163,  100,  196,
++ /*  1180 */   172,  173,   65,  152,   56,   68,  172,  173,  172,  173,
++ /*  1190 */   172,  173,  152,   65,  163,  163,   68,   23,  152,  234,
++ /*  1200 */    26,  152,  152,  172,  173,   88,   89,  196,  152,  196,
++ /*  1210 */   196,  152,   95,   96,   97,   98,   88,   89,  101,  152,
++ /*  1220 */   152,  207,  208,   95,   96,   97,   98,  196,  196,  101,
++ /*  1230 */    96,  233,  152,   97,  152,  152,   19,   20,  207,   22,
++ /*  1240 */   152,  152,  152,  191,   27,  152,  152,  152,  152,  132,
++ /*  1250 */   133,  134,  135,  136,   37,  152,  152,  152,  152,  152,
++ /*  1260 */   132,  133,  134,  135,  136,  210,  197,  210,  210,  198,
++ /*  1270 */   150,  184,  239,   56,  201,  214,  214,  201,  239,  180,
++ /*  1280 */   214,  227,  198,   38,  176,   68,  175,  175,  175,  122,
++ /*  1290 */   155,  200,  159,   19,   20,   40,   22,  159,  159,   22,
++ /*  1300 */    70,   27,  130,  243,  240,   88,   89,   90,  189,   18,
++ /*  1310 */   201,   37,   95,   96,   97,   98,  192,    5,  101,  192,
++ /*  1320 */   220,  240,   10,   11,   12,   13,   14,  159,   18,   17,
++ /*  1330 */    56,  158,  192,  201,  192,  220,  189,  189,  201,  159,
++ /*  1340 */   158,  137,   68,   31,   45,   33,  236,  159,  159,  132,
++ /*  1350 */   133,  134,  135,  136,   42,  158,  235,   22,  177,  159,
++ /*  1360 */   158,  158,   88,   89,  159,  107,  174,   55,  177,   95,
++ /*  1370 */    96,   97,   98,  174,   62,  101,   47,   65,   66,  106,
++ /*  1380 */   174,  125,   19,   20,  174,   22,  177,  176,  174,  182,
++ /*  1390 */    27,  216,  174,  174,  182,  107,  159,   22,  215,  215,
++ /*  1400 */    37,  216,  216,  216,  137,  215,  132,  133,  134,  135,
++ /*  1410 */   136,  215,  159,  177,   94,  177,  129,  224,  205,   56,
++ /*  1420 */   226,  126,  128,  203,  229,  204,  114,  229,  127,  202,
++ /*  1430 */   201,   68,   25,  162,   26,   13,  161,  153,  153,    6,
++ /*  1440 */   151,  151,  178,  151,  165,  165,  178,  165,    4,    3,
++ /*  1450 */   249,   88,   89,  141,   22,  142,   15,  249,   95,   96,
++ /*  1460 */    97,   98,  246,   67,  101,   16,   23,  120,   23,  131,
++ /*  1470 */   111,  123,   20,   16,  125,    1,  123,  131,   78,   78,
++ /*  1480 */    78,   78,  111,   96,  122,   35,    1,    5,   22,  107,
++ /*  1490 */   140,   53,   53,   26,   60,  132,  133,  134,  135,  136,
++ /*  1500 */   107,   43,   24,   20,  112,   19,   22,   52,   52,  105,
++ /*  1510 */    22,   22,   52,   23,   22,   22,   29,   23,   39,   23,
++ /*  1520 */    23,   26,  116,   22,   26,   23,   22,  122,   23,   23,
++ /*  1530 */    22,   96,   11,  124,   35,   26,   26,   23,   35,   23,
++ /*  1540 */    23,   23,   35,   23,   22,   26,   23,   22,   24,  122,
++ /*  1550 */    23,   22,   26,   22,   24,   23,   23,   23,   22,  122,
++ /*  1560 */    23,   15,  122,    1,  122,
++};
++#define YY_SHIFT_USE_DFLT (1565)
++#define YY_SHIFT_COUNT    (454)
++#define YY_SHIFT_MIN      (-114)
++#define YY_SHIFT_MAX      (1562)
+ static const short yy_shift_ofst[] = {
+- /*     0 */   992, 1057, 1355, 1156, 1204, 1204,    1,  262,  -19,  135,
+- /*    10 */   135,  776, 1204, 1204, 1204, 1204,   69,   69,   53,  208,
+- /*    20 */   283,  755,   58,  725,  648,  571,  494,  417,  340,  263,
+- /*    30 */   212,  827,  827,  827,  827,  827,  827,  827,  827,  827,
+- /*    40 */   827,  827,  827,  827,  827,  827,  878,  827,  929,  980,
+- /*    50 */   980, 1070, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+- /*    60 */  1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+- /*    70 */  1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+- /*    80 */  1258, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+- /*    90 */  1204, 1204, 1204, 1204,  -71,  -47,  -47,  -47,  -47,  -47,
+- /*   100 */     0,   29,  -12,  283,  283,  139,   91,  392,  392,  894,
+- /*   110 */   672,  726, 1383,  -86,  -86,  -86,   88,  318,  318,   99,
+- /*   120 */   381,  -20,  283,  283,  283,  283,  283,  283,  283,  283,
+- /*   130 */   283,  283,  283,  283,  283,  283,  283,  283,  283,  283,
+- /*   140 */   283,  283,  283,  283,  624,  876,  726,  672, 1340, 1340,
+- /*   150 */  1340, 1340, 1340, 1340,  -86,  -86,  -86,  305,  136,  136,
+- /*   160 */   142,  167,  226,  154,  137,  152,  283,  283,  283,  283,
+- /*   170 */   283,  283,  283,  283,  283,  283,  283,  283,  283,  283,
+- /*   180 */   283,  283,  283,  336,  336,  336,  283,  283,  352,  283,
+- /*   190 */   283,  283,  283,  283,  228,  283,  283,  283,  283,  283,
+- /*   200 */   283,  283,  283,  283,  283,  501,  569,  596,  596,  596,
+- /*   210 */   507,  497,  441,  391,  353,  156,  156,  857,  353,  857,
+- /*   220 */   735,  813,  639,  715,  156,  332,  715,  715,  496,  419,
+- /*   230 */   646, 1357, 1184, 1184, 1335, 1335, 1184, 1341, 1260, 1144,
+- /*   240 */  1346, 1346, 1346, 1346, 1184, 1306, 1144, 1341, 1260, 1260,
+- /*   250 */  1144, 1184, 1306, 1206, 1284, 1184, 1184, 1306, 1184, 1306,
+- /*   260 */  1184, 1306, 1262, 1207, 1207, 1207, 1274, 1262, 1207, 1217,
+- /*   270 */  1207, 1274, 1207, 1207, 1185, 1200, 1185, 1200, 1185, 1200,
+- /*   280 */  1184, 1184, 1161, 1262, 1202, 1202, 1262, 1154, 1155, 1147,
+- /*   290 */  1152, 1144, 1241, 1239, 1250, 1250, 1254, 1254, 1254, 1254,
+- /*   300 */   -86,  -86,  -86,  -86,  -86,  -86, 1068,  304,  526,  249,
+- /*   310 */   408,  -83,  434,  812,   27,  811,  807,  802,  751,  589,
+- /*   320 */   651,  163,  131,  674,  366,  450,  299,  148,   23,  102,
+- /*   330 */   229,  -21, 1245, 1244, 1222, 1099, 1228, 1172, 1223, 1215,
+- /*   340 */  1213, 1115, 1106, 1123, 1110, 1209, 1105, 1212, 1226, 1098,
+- /*   350 */  1089, 1140, 1139, 1104, 1189, 1178, 1094, 1211, 1205, 1187,
+- /*   360 */  1101, 1071, 1153, 1175, 1146, 1138, 1151, 1091, 1164, 1165,
+- /*   370 */  1163, 1069, 1072, 1148, 1112, 1134, 1127, 1129, 1126, 1092,
+- /*   380 */  1114, 1118, 1088, 1090, 1093, 1087, 1084,  987, 1079, 1077,
+- /*   390 */  1074, 1065,  924, 1021, 1014, 1004, 1006,  819,  739,  896,
+- /*   400 */   855,  804,  739,  740,  736,  690,  654,  665,  618,  582,
+- /*   410 */   568,  528,  554,  379,  532,  479,  455,  379,  432,  371,
+- /*   420 */   341,   28,  338,  116,  -11,  -57,  -85,    7,   -8,    3,
+-};
+-#define YY_REDUCE_USE_DFLT (-110)
+-#define YY_REDUCE_COUNT (305)
+-#define YY_REDUCE_MIN   (-109)
+-#define YY_REDUCE_MAX   (1323)
++ /*     0 */     5, 1117, 1312, 1128, 1274, 1274, 1274, 1274,   61,  -19,
++ /*    10 */    57,   57,  183, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
++ /*    20 */    66,   66,  201,  -29,  331,  318,  133,  259,  335,  411,
++ /*    30 */   487,  563,  639,  689,  765,  841,  891,  891,  891,  891,
++ /*    40 */   891,  891,  891,  891,  891,  891,  891,  891,  891,  891,
++ /*    50 */   891,  891,  891,  941,  891,  991, 1041, 1041, 1217, 1274,
++ /*    60 */  1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
++ /*    70 */  1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
++ /*    80 */  1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
++ /*    90 */  1363, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
++ /*   100 */  1274, 1274, 1274, 1274,  -70,  -47,  -47,  -47,  -47,  -47,
++ /*   110 */    24,   11,  146,  296,  524,  444,  529,  529,  296,    3,
++ /*   120 */     2,  -30, 1565, 1565, 1565,  -17,  -17,  -17,  145,  145,
++ /*   130 */   497,  497,  265,  603,  653,  296,  296,  296,  296,  296,
++ /*   140 */   296,  296,  296,  296,  296,  296,  296,  296,  296,  296,
++ /*   150 */   296,  296,  296,  296,  296,  701, 1078,  147,  147,    2,
++ /*   160 */   164,  164,  164,  164,  164,  164, 1565, 1565, 1565,  223,
++ /*   170 */    56,   56,  268,  269,  220,  347,  351,  415,  359,  296,
++ /*   180 */   296,  296,  296,  296,  296,  296,  296,  296,  296,  296,
++ /*   190 */   296,  296,  296,  296,  296,  632,  632,  632,  296,  296,
++ /*   200 */   498,  296,  296,  296,  570,  296,  296,  654,  296,  296,
++ /*   210 */   296,  296,  296,  296,  296,  296,  296,  296,  636,  200,
++ /*   220 */   596,  596,  596,  575, -114,  971,  740,  454,  503,  503,
++ /*   230 */  1134,  454, 1134,  353,  588,  628,  762,  503,  189,  762,
++ /*   240 */   762,  916,  330,  668, 1245, 1167, 1167, 1255, 1255, 1167,
++ /*   250 */  1277, 1230, 1172, 1291, 1291, 1291, 1291, 1167, 1310, 1172,
++ /*   260 */  1277, 1230, 1230, 1172, 1167, 1310, 1204, 1299, 1167, 1167,
++ /*   270 */  1310, 1335, 1167, 1310, 1167, 1310, 1335, 1258, 1258, 1258,
++ /*   280 */  1329, 1335, 1258, 1273, 1258, 1329, 1258, 1258, 1256, 1288,
++ /*   290 */  1256, 1288, 1256, 1288, 1256, 1288, 1167, 1375, 1167, 1267,
++ /*   300 */  1335, 1320, 1320, 1335, 1287, 1295, 1294, 1301, 1172, 1407,
++ /*   310 */  1408, 1422, 1422, 1433, 1433, 1433, 1565, 1565, 1565, 1565,
++ /*   320 */  1565, 1565, 1565, 1565,  558,  537,  684,  719,  734,  799,
++ /*   330 */   840, 1019,   14, 1020, 1021, 1025, 1026, 1027, 1070, 1072,
++ /*   340 */   997, 1047,  999, 1079, 1126, 1074, 1141,  694,  819, 1174,
++ /*   350 */  1136,  981, 1444, 1446, 1432, 1313, 1441, 1396, 1449, 1443,
++ /*   360 */  1445, 1347, 1338, 1359, 1348, 1452, 1349, 1457, 1474, 1353,
++ /*   370 */  1346, 1400, 1401, 1402, 1403, 1371, 1387, 1450, 1362, 1485,
++ /*   380 */  1482, 1466, 1382, 1350, 1438, 1467, 1439, 1434, 1458, 1393,
++ /*   390 */  1478, 1483, 1486, 1392, 1404, 1484, 1455, 1488, 1489, 1490,
++ /*   400 */  1492, 1456, 1487, 1493, 1460, 1479, 1494, 1496, 1497, 1495,
++ /*   410 */  1406, 1501, 1502, 1504, 1498, 1405, 1505, 1506, 1435, 1499,
++ /*   420 */  1508, 1409, 1509, 1503, 1510, 1507, 1514, 1509, 1516, 1517,
++ /*   430 */  1518, 1519, 1520, 1522, 1521, 1523, 1525, 1524, 1526, 1527,
++ /*   440 */  1529, 1530, 1526, 1532, 1531, 1533, 1534, 1536, 1427, 1437,
++ /*   450 */  1440, 1442, 1537, 1546, 1562,
++};
++#define YY_REDUCE_USE_DFLT (-174)
++#define YY_REDUCE_COUNT (323)
++#define YY_REDUCE_MIN   (-173)
++#define YY_REDUCE_MAX   (1292)
+ static const short yy_reduce_ofst[] = {
+- /*     0 */   238,  954,  213,  289,  310,  234,  144,  317, -109,  382,
+- /*    10 */   377,  303,  461,  389,  378,  368,  302,  294,  253,  395,
+- /*    20 */   293,  324,  403,  403,  403,  403,  403,  403,  403,  403,
+- /*    30 */   403,  403,  403,  403,  403,  403,  403,  403,  403,  403,
+- /*    40 */   403,  403,  403,  403,  403,  403,  403,  403,  403,  403,
+- /*    50 */   403, 1022, 1012, 1005,  998,  963,  961,  959,  957,  950,
+- /*    60 */   947,  930,  912,  873,  861,  823,  810,  771,  759,  720,
+- /*    70 */   708,  670,  657,  619,  614,  612,  610,  608,  606,  604,
+- /*    80 */   598,  595,  593,  580,  542,  540,  537,  535,  533,  531,
+- /*    90 */   529,  527,  503,  386,  403,  403,  403,  403,  403,  403,
+- /*   100 */   403,  403,  403,   95,  447,   82,  334,  504,  467,  403,
+- /*   110 */   477,  464,  403,  403,  403,  403,  860,  747,  744,  785,
+- /*   120 */   638,  638,  926,  891,  900,  899,  887,  844,  840,  835,
+- /*   130 */   848,  830,  843,  829,  792,  839,  826,  737,  838,  795,
+- /*   140 */   789,   47,  734,  530,  696,  777,  711,  677,  733,  730,
+- /*   150 */   729,  728,  727,  627,  448,   64,  187, 1305, 1302, 1252,
+- /*   160 */  1290, 1273, 1323, 1322, 1321, 1319, 1318, 1316, 1315, 1314,
+- /*   170 */  1313, 1312, 1311, 1310, 1308, 1307, 1304, 1303, 1301, 1298,
+- /*   180 */  1294, 1292, 1289, 1266, 1264, 1259, 1288, 1287, 1238, 1285,
+- /*   190 */  1281, 1280, 1279, 1278, 1251, 1277, 1276, 1275, 1273, 1268,
+- /*   200 */  1267, 1265, 1263, 1261, 1257, 1248, 1237, 1247, 1246, 1243,
+- /*   210 */  1238, 1240, 1235, 1249, 1234, 1233, 1230, 1220, 1214, 1210,
+- /*   220 */  1225, 1219, 1232, 1231, 1197, 1195, 1227, 1224, 1201, 1208,
+- /*   230 */  1242, 1137, 1236, 1229, 1193, 1181, 1221, 1177, 1196, 1179,
+- /*   240 */  1191, 1190, 1186, 1182, 1218, 1216, 1176, 1162, 1183, 1180,
+- /*   250 */  1160, 1199, 1203, 1133, 1095, 1198, 1194, 1188, 1192, 1171,
+- /*   260 */  1169, 1168, 1173, 1174, 1166, 1159, 1141, 1170, 1158, 1167,
+- /*   270 */  1157, 1132, 1145, 1143, 1124, 1128, 1103, 1102, 1100, 1096,
+- /*   280 */  1150, 1149, 1085, 1125, 1080, 1064, 1120, 1097, 1082, 1078,
+- /*   290 */  1073, 1067, 1109, 1107, 1119, 1117, 1116, 1113, 1111, 1108,
+- /*   300 */  1007, 1000, 1002, 1076, 1075, 1081,
++ /*     0 */  -119, 1014,  131, 1031,  -12,  225,  228,  300,  -40,  -45,
++ /*    10 */   243,  256,  293,  129,  218,  418,   79,  376,  433,  298,
++ /*    20 */    16,  137,  367,  323,  -38,  391, -173, -173, -173, -173,
++ /*    30 */  -173, -173, -173, -173, -173, -173, -173, -173, -173, -173,
++ /*    40 */  -173, -173, -173, -173, -173, -173, -173, -173, -173, -173,
++ /*    50 */  -173, -173, -173, -173, -173, -173, -173, -173,  374,  437,
++ /*    60 */   443,  508,  513,  522,  532,  582,  584,  620,  633,  635,
++ /*    70 */   637,  644,  646,  648,  650,  652,  659,  661,  696,  709,
++ /*    80 */   711,  714,  720,  722,  724,  726,  728,  733,  772,  784,
++ /*    90 */   786,  822,  834,  836,  884,  886,  922,  934,  936,  986,
++ /*   100 */   989, 1008, 1016, 1018, -173, -173, -173, -173, -173, -173,
++ /*   110 */  -173, -173, -173,  544,  -37,  274,  299,  501,  161, -173,
++ /*   120 */   193, -173, -173, -173, -173,   22,   22,   22,   64,  141,
++ /*   130 */   212,  342,  208,  504,  504,  132,  494,  606,  677,  678,
++ /*   140 */   750,  794,  796,  -58,   32,  383,  660,  737,  386,  787,
++ /*   150 */   800,  441,  872,  224,  850,  803,  949,  624,  830,  669,
++ /*   160 */   961,  979,  983, 1011, 1013, 1032,  753,  789,  321,   94,
++ /*   170 */   116,  304,  375,  210,  388,  392,  478,  545,  649,  721,
++ /*   180 */   727,  736,  752,  795,  853,  952,  958, 1004, 1040, 1046,
++ /*   190 */  1049, 1050, 1056, 1059, 1067,  559,  774,  811, 1068, 1080,
++ /*   200 */   938, 1082, 1083, 1088,  962, 1089, 1090, 1052, 1093, 1094,
++ /*   210 */  1095,  388, 1096, 1103, 1104, 1105, 1106, 1107,  965,  998,
++ /*   220 */  1055, 1057, 1058,  938, 1069, 1071, 1120, 1073, 1061, 1062,
++ /*   230 */  1033, 1076, 1039, 1108, 1087, 1099, 1111, 1066, 1054, 1112,
++ /*   240 */  1113, 1091, 1084, 1135, 1060, 1133, 1138, 1064, 1081, 1139,
++ /*   250 */  1100, 1119, 1109, 1124, 1127, 1140, 1142, 1168, 1173, 1132,
++ /*   260 */  1115, 1147, 1148, 1137, 1180, 1182, 1110, 1121, 1188, 1189,
++ /*   270 */  1197, 1181, 1200, 1202, 1205, 1203, 1191, 1192, 1199, 1206,
++ /*   280 */  1207, 1209, 1210, 1211, 1214, 1212, 1218, 1219, 1175, 1183,
++ /*   290 */  1185, 1184, 1186, 1190, 1187, 1196, 1237, 1193, 1253, 1194,
++ /*   300 */  1236, 1195, 1198, 1238, 1213, 1221, 1220, 1227, 1229, 1271,
++ /*   310 */  1275, 1284, 1285, 1289, 1290, 1292, 1201, 1208, 1216, 1279,
++ /*   320 */  1280, 1264, 1268, 1282,
+ };
+ static const YYACTIONTYPE yy_default[] = {
+- /*     0 */   647,  964,  964,  964,  878,  878,  969,  964,  774,  802,
+- /*    10 */   802,  938,  969,  969,  969,  876,  969,  969,  969,  964,
+- /*    20 */   969,  778,  808,  969,  969,  969,  969,  969,  969,  969,
+- /*    30 */   969,  937,  939,  816,  815,  918,  789,  813,  806,  810,
+- /*    40 */   879,  872,  873,  871,  875,  880,  969,  809,  841,  856,
+- /*    50 */   840,  969,  969,  969,  969,  969,  969,  969,  969,  969,
+- /*    60 */   969,  969,  969,  969,  969,  969,  969,  969,  969,  969,
+- /*    70 */   969,  969,  969,  969,  969,  969,  969,  969,  969,  969,
+- /*    80 */   969,  969,  969,  969,  969,  969,  969,  969,  969,  969,
+- /*    90 */   969,  969,  969,  969,  850,  855,  862,  854,  851,  843,
+- /*   100 */   842,  844,  845,  969,  969,  673,  739,  969,  969,  846,
+- /*   110 */   969,  685,  847,  859,  858,  857,  680,  969,  969,  969,
+- /*   120 */   969,  969,  969,  969,  969,  969,  969,  969,  969,  969,
+- /*   130 */   969,  969,  969,  969,  969,  969,  969,  969,  969,  969,
+- /*   140 */   969,  969,  969,  969,  647,  964,  969,  969,  964,  964,
+- /*   150 */   964,  964,  964,  964,  956,  778,  768,  969,  969,  969,
+- /*   160 */   969,  969,  969,  969,  969,  969,  969,  944,  942,  969,
+- /*   170 */   891,  969,  969,  969,  969,  969,  969,  969,  969,  969,
+- /*   180 */   969,  969,  969,  969,  969,  969,  969,  969,  969,  969,
+- /*   190 */   969,  969,  969,  969,  969,  969,  969,  969,  969,  969,
+- /*   200 */   969,  969,  969,  969,  653,  969,  911,  774,  774,  774,
+- /*   210 */   776,  754,  766,  655,  812,  791,  791,  923,  812,  923,
+- /*   220 */   710,  733,  707,  802,  791,  874,  802,  802,  775,  766,
+- /*   230 */   969,  949,  782,  782,  941,  941,  782,  821,  743,  812,
+- /*   240 */   750,  750,  750,  750,  782,  670,  812,  821,  743,  743,
+- /*   250 */   812,  782,  670,  917,  915,  782,  782,  670,  782,  670,
+- /*   260 */   782,  670,  884,  741,  741,  741,  725,  884,  741,  710,
+- /*   270 */   741,  725,  741,  741,  795,  790,  795,  790,  795,  790,
+- /*   280 */   782,  782,  969,  884,  888,  888,  884,  807,  796,  805,
+- /*   290 */   803,  812,  676,  728,  663,  663,  652,  652,  652,  652,
+- /*   300 */   961,  961,  956,  712,  712,  695,  969,  969,  969,  969,
+- /*   310 */   969,  969,  687,  969,  893,  969,  969,  969,  969,  969,
+- /*   320 */   969,  969,  969,  969,  969,  969,  969,  969,  969,  969,
+- /*   330 */   969,  828,  969,  648,  951,  969,  969,  948,  969,  969,
+- /*   340 */   969,  969,  969,  969,  969,  969,  969,  969,  969,  969,
+- /*   350 */   969,  969,  969,  969,  969,  969,  921,  969,  969,  969,
+- /*   360 */   969,  969,  969,  914,  913,  969,  969,  969,  969,  969,
+- /*   370 */   969,  969,  969,  969,  969,  969,  969,  969,  969,  969,
+- /*   380 */   969,  969,  969,  969,  969,  969,  969,  757,  969,  969,
+- /*   390 */   969,  761,  969,  969,  969,  969,  969,  969,  804,  969,
+- /*   400 */   797,  969,  877,  969,  969,  969,  969,  969,  969,  969,
+- /*   410 */   969,  969,  969,  966,  969,  969,  969,  965,  969,  969,
+- /*   420 */   969,  969,  969,  830,  969,  829,  833,  969,  661,  969,
+- /*   430 */   644,  649,  960,  963,  962,  959,  958,  957,  952,  950,
+- /*   440 */   947,  946,  945,  943,  940,  936,  897,  895,  902,  901,
+- /*   450 */   900,  899,  898,  896,  894,  892,  818,  817,  814,  811,
+- /*   460 */   753,  935,  890,  752,  749,  748,  669,  953,  920,  929,
+- /*   470 */   928,  927,  822,  926,  925,  924,  922,  919,  906,  820,
+- /*   480 */   819,  744,  882,  881,  672,  910,  909,  908,  912,  916,
+- /*   490 */   907,  784,  751,  671,  668,  675,  679,  731,  732,  740,
+- /*   500 */   738,  737,  736,  735,  734,  730,  681,  686,  724,  709,
+- /*   510 */   708,  717,  716,  722,  721,  720,  719,  718,  715,  714,
+- /*   520 */   713,  706,  705,  711,  704,  727,  726,  723,  703,  747,
+- /*   530 */   746,  745,  742,  702,  701,  700,  833,  699,  698,  838,
+- /*   540 */   837,  866,  826,  755,  759,  758,  762,  763,  771,  770,
+- /*   550 */   769,  780,  781,  793,  792,  824,  823,  794,  779,  773,
+- /*   560 */   772,  788,  787,  786,  785,  777,  767,  799,  798,  868,
+- /*   570 */   783,  867,  865,  934,  933,  932,  931,  930,  870,  967,
+- /*   580 */   968,  887,  889,  886,  801,  800,  885,  869,  839,  836,
+- /*   590 */   690,  691,  905,  904,  903,  693,  692,  689,  688,  863,
+- /*   600 */   860,  852,  864,  861,  853,  849,  848,  834,  832,  831,
+- /*   610 */   827,  835,  760,  756,  825,  765,  764,  697,  696,  694,
+- /*   620 */   678,  677,  674,  667,  665,  664,  666,  662,  660,  659,
+- /*   630 */   658,  657,  656,  684,  683,  682,  654,  651,  650,  646,
+- /*   640 */   645,  643,
++ /*     0 */  1270, 1260, 1260, 1260, 1193, 1193, 1193, 1193, 1260, 1088,
++ /*    10 */  1117, 1117, 1244, 1322, 1322, 1322, 1322, 1322, 1322, 1192,
++ /*    20 */  1322, 1322, 1322, 1322, 1260, 1092, 1123, 1322, 1322, 1322,
++ /*    30 */  1322, 1194, 1195, 1322, 1322, 1322, 1243, 1245, 1133, 1132,
++ /*    40 */  1131, 1130, 1226, 1104, 1128, 1121, 1125, 1194, 1188, 1189,
++ /*    50 */  1187, 1191, 1195, 1322, 1124, 1158, 1172, 1157, 1322, 1322,
++ /*    60 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*    70 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*    80 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*    90 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*   100 */  1322, 1322, 1322, 1322, 1166, 1171, 1178, 1170, 1167, 1160,
++ /*   110 */  1159, 1161, 1162, 1322, 1011, 1059, 1322, 1322, 1322, 1163,
++ /*   120 */  1322, 1164, 1175, 1174, 1173, 1251, 1278, 1277, 1322, 1322,
++ /*   130 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*   140 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*   150 */  1322, 1322, 1322, 1322, 1322, 1270, 1260, 1017, 1017, 1322,
++ /*   160 */  1260, 1260, 1260, 1260, 1260, 1260, 1256, 1092, 1083, 1322,
++ /*   170 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*   180 */  1248, 1246, 1322, 1208, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*   190 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*   200 */  1322, 1322, 1322, 1322, 1088, 1322, 1322, 1322, 1322, 1322,
++ /*   210 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1272, 1322, 1221,
++ /*   220 */  1088, 1088, 1088, 1090, 1072, 1082,  997, 1127, 1106, 1106,
++ /*   230 */  1311, 1127, 1311, 1034, 1292, 1031, 1117, 1106, 1190, 1117,
++ /*   240 */  1117, 1089, 1082, 1322, 1314, 1097, 1097, 1313, 1313, 1097,
++ /*   250 */  1138, 1062, 1127, 1068, 1068, 1068, 1068, 1097, 1008, 1127,
++ /*   260 */  1138, 1062, 1062, 1127, 1097, 1008, 1225, 1308, 1097, 1097,
++ /*   270 */  1008, 1201, 1097, 1008, 1097, 1008, 1201, 1060, 1060, 1060,
++ /*   280 */  1049, 1201, 1060, 1034, 1060, 1049, 1060, 1060, 1110, 1105,
++ /*   290 */  1110, 1105, 1110, 1105, 1110, 1105, 1097, 1196, 1097, 1322,
++ /*   300 */  1201, 1205, 1205, 1201, 1122, 1111, 1120, 1118, 1127, 1014,
++ /*   310 */  1052, 1275, 1275, 1271, 1271, 1271, 1319, 1319, 1256, 1287,
++ /*   320 */  1287, 1036, 1036, 1287, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*   330 */  1282, 1322, 1210, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*   340 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*   350 */  1322, 1143, 1322,  993, 1253, 1322, 1322, 1252, 1322, 1322,
++ /*   360 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*   370 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1310, 1322,
++ /*   380 */  1322, 1322, 1322, 1322, 1322, 1224, 1223, 1322, 1322, 1322,
++ /*   390 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*   400 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
++ /*   410 */  1074, 1322, 1322, 1322, 1296, 1322, 1322, 1322, 1322, 1322,
++ /*   420 */  1322, 1322, 1119, 1322, 1112, 1322, 1322, 1301, 1322, 1322,
++ /*   430 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1262, 1322,
++ /*   440 */  1322, 1322, 1261, 1322, 1322, 1322, 1322, 1322, 1145, 1322,
++ /*   450 */  1144, 1148, 1322, 1002, 1322,
+ };
++/********** End of lemon-generated parsing tables *****************************/
+ 
+-/* The next table maps tokens into fallback tokens.  If a construct
+-** like the following:
++/* The next table maps tokens (terminal symbols) into fallback tokens.  
++** If a construct like the following:
+ ** 
+ **      %fallback ID X Y Z.
+ **
+@@ -124069,6 +140709,10 @@
+ ** and Z.  Whenever one of the tokens X, Y, or Z is input to the parser
+ ** but it does not parse, the type of the token is changed to ID and
+ ** the parse is retried before an error is thrown.
++**
++** This feature can be used, for example, to cause some keywords in a language
++** to revert to identifiers if they keyword does not apply in the context where
++** it appears.
+ */
+ #ifdef YYFALLBACK
+ static const YYCODETYPE yyFallback[] = {
+@@ -124100,7 +140744,6 @@
+    27,  /*    WITHOUT => ID */
+     0,  /*      COMMA => nothing */
+     0,  /*         ID => nothing */
+-    0,  /*    INDEXED => nothing */
+    27,  /*      ABORT => ID */
+    27,  /*     ACTION => ID */
+    27,  /*      AFTER => ID */
+@@ -124156,9 +140799,13 @@
+ **   +  The semantic value stored at this level of the stack.  This is
+ **      the information used by the action routines in the grammar.
+ **      It is sometimes called the "minor" token.
++**
++** After the "shift" half of a SHIFTREDUCE action, the stateno field
++** actually contains the reduce action for the second half of the
++** SHIFTREDUCE.
+ */
+ struct yyStackEntry {
+-  YYACTIONTYPE stateno;  /* The state-number */
++  YYACTIONTYPE stateno;  /* The state-number, or reduce action in SHIFTREDUCE */
+   YYCODETYPE major;      /* The major token value.  This is the code
+                          ** number for the token at this stack level */
+   YYMINORTYPE minor;     /* The user-supplied minor token value.  This
+@@ -124169,17 +140816,21 @@
+ /* The state of the parser is completely contained in an instance of
+ ** the following structure */
+ struct yyParser {
+-  int yyidx;                    /* Index of top element in stack */
++  yyStackEntry *yytos;          /* Pointer to top element of the stack */
+ #ifdef YYTRACKMAXSTACKDEPTH
+-  int yyidxMax;                 /* Maximum value of yyidx */
++  int yyhwm;                    /* High-water mark of the stack */
+ #endif
++#ifndef YYNOERRORRECOVERY
+   int yyerrcnt;                 /* Shifts left before out of the error */
 +#endif
-+#if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc)
-+  "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
+   sqlite3ParserARG_SDECL                /* A place to hold %extra_argument */
+ #if YYSTACKDEPTH<=0
+   int yystksz;                  /* Current side of the stack */
+   yyStackEntry *yystack;        /* The parser's stack */
++  yyStackEntry yystk0;          /* First stack entry */
+ #else
+   yyStackEntry yystack[YYSTACKDEPTH];  /* The parser's stack */
++  yyStackEntry *yystackEnd;            /* Last entry in the stack */
+ #endif
+ };
+ typedef struct yyParser yyParser;
+@@ -124227,24 +140878,24 @@
+   "TABLE",         "CREATE",        "IF",            "NOT",         
+   "EXISTS",        "TEMP",          "LP",            "RP",          
+   "AS",            "WITHOUT",       "COMMA",         "ID",          
+-  "INDEXED",       "ABORT",         "ACTION",        "AFTER",       
+-  "ANALYZE",       "ASC",           "ATTACH",        "BEFORE",      
+-  "BY",            "CASCADE",       "CAST",          "COLUMNKW",    
+-  "CONFLICT",      "DATABASE",      "DESC",          "DETACH",      
+-  "EACH",          "FAIL",          "FOR",           "IGNORE",      
+-  "INITIALLY",     "INSTEAD",       "LIKE_KW",       "MATCH",       
+-  "NO",            "KEY",           "OF",            "OFFSET",      
+-  "PRAGMA",        "RAISE",         "RECURSIVE",     "REPLACE",     
+-  "RESTRICT",      "ROW",           "TRIGGER",       "VACUUM",      
+-  "VIEW",          "VIRTUAL",       "WITH",          "REINDEX",     
+-  "RENAME",        "CTIME_KW",      "ANY",           "OR",          
+-  "AND",           "IS",            "BETWEEN",       "IN",          
+-  "ISNULL",        "NOTNULL",       "NE",            "EQ",          
+-  "GT",            "LE",            "LT",            "GE",          
+-  "ESCAPE",        "BITAND",        "BITOR",         "LSHIFT",      
+-  "RSHIFT",        "PLUS",          "MINUS",         "STAR",        
+-  "SLASH",         "REM",           "CONCAT",        "COLLATE",     
+-  "BITNOT",        "STRING",        "JOIN_KW",       "CONSTRAINT",  
++  "ABORT",         "ACTION",        "AFTER",         "ANALYZE",     
++  "ASC",           "ATTACH",        "BEFORE",        "BY",          
++  "CASCADE",       "CAST",          "COLUMNKW",      "CONFLICT",    
++  "DATABASE",      "DESC",          "DETACH",        "EACH",        
++  "FAIL",          "FOR",           "IGNORE",        "INITIALLY",   
++  "INSTEAD",       "LIKE_KW",       "MATCH",         "NO",          
++  "KEY",           "OF",            "OFFSET",        "PRAGMA",      
++  "RAISE",         "RECURSIVE",     "REPLACE",       "RESTRICT",    
++  "ROW",           "TRIGGER",       "VACUUM",        "VIEW",        
++  "VIRTUAL",       "WITH",          "REINDEX",       "RENAME",      
++  "CTIME_KW",      "ANY",           "OR",            "AND",         
++  "IS",            "BETWEEN",       "IN",            "ISNULL",      
++  "NOTNULL",       "NE",            "EQ",            "GT",          
++  "LE",            "LT",            "GE",            "ESCAPE",      
++  "BITAND",        "BITOR",         "LSHIFT",        "RSHIFT",      
++  "PLUS",          "MINUS",         "STAR",          "SLASH",       
++  "REM",           "CONCAT",        "COLLATE",       "BITNOT",      
++  "INDEXED",       "STRING",        "JOIN_KW",       "CONSTRAINT",  
+   "DEFAULT",       "NULL",          "PRIMARY",       "UNIQUE",      
+   "CHECK",         "REFERENCES",    "AUTOINCR",      "ON",          
+   "INSERT",        "DELETE",        "UPDATE",        "SET",         
+@@ -124253,7 +140904,7 @@
+   "VALUES",        "DISTINCT",      "DOT",           "FROM",        
+   "JOIN",          "USING",         "ORDER",         "GROUP",       
+   "HAVING",        "LIMIT",         "WHERE",         "INTO",        
+-  "INTEGER",       "FLOAT",         "BLOB",          "VARIABLE",    
++  "FLOAT",         "BLOB",          "INTEGER",       "VARIABLE",    
+   "CASE",          "WHEN",          "THEN",          "ELSE",        
+   "INDEX",         "ALTER",         "ADD",           "error",       
+   "input",         "cmdlist",       "ecmd",          "explain",     
+@@ -124261,29 +140912,28 @@
+   "nm",            "savepoint_opt",  "create_table",  "create_table_args",
+   "createkw",      "temp",          "ifnotexists",   "dbnm",        
+   "columnlist",    "conslist_opt",  "table_options",  "select",      
+-  "column",        "columnid",      "type",          "carglist",    
+-  "typetoken",     "typename",      "signed",        "plus_num",    
+-  "minus_num",     "ccons",         "term",          "expr",        
+-  "onconf",        "sortorder",     "autoinc",       "idxlist_opt", 
+-  "refargs",       "defer_subclause",  "refarg",        "refact",      
+-  "init_deferred_pred_opt",  "conslist",      "tconscomma",    "tcons",       
+-  "idxlist",       "defer_subclause_opt",  "orconf",        "resolvetype", 
+-  "raisetype",     "ifexists",      "fullname",      "selectnowith",
+-  "oneselect",     "with",          "multiselect_op",  "distinct",    
+-  "selcollist",    "from",          "where_opt",     "groupby_opt", 
+-  "having_opt",    "orderby_opt",   "limit_opt",     "values",      
+-  "nexprlist",     "exprlist",      "sclp",          "as",          
+-  "seltablist",    "stl_prefix",    "joinop",        "indexed_opt", 
+-  "on_opt",        "using_opt",     "joinop2",       "idlist",      
+-  "sortlist",      "setlist",       "insert_cmd",    "inscollist_opt",
+-  "likeop",        "between_op",    "in_op",         "case_operand",
+-  "case_exprlist",  "case_else",     "uniqueflag",    "collate",     
+-  "nmnum",         "trigger_decl",  "trigger_cmd_list",  "trigger_time",
+-  "trigger_event",  "foreach_clause",  "when_clause",   "trigger_cmd", 
+-  "trnm",          "tridxby",       "database_kw_opt",  "key_opt",     
+-  "add_column_fullname",  "kwcolumn_opt",  "create_vtab",   "vtabarglist", 
+-  "vtabarg",       "vtabargtoken",  "lp",            "anylist",     
+-  "wqlist",      
++  "columnname",    "carglist",      "typetoken",     "typename",    
++  "signed",        "plus_num",      "minus_num",     "ccons",       
++  "term",          "expr",          "onconf",        "sortorder",   
++  "autoinc",       "eidlist_opt",   "refargs",       "defer_subclause",
++  "refarg",        "refact",        "init_deferred_pred_opt",  "conslist",    
++  "tconscomma",    "tcons",         "sortlist",      "eidlist",     
++  "defer_subclause_opt",  "orconf",        "resolvetype",   "raisetype",   
++  "ifexists",      "fullname",      "selectnowith",  "oneselect",   
++  "with",          "multiselect_op",  "distinct",      "selcollist",  
++  "from",          "where_opt",     "groupby_opt",   "having_opt",  
++  "orderby_opt",   "limit_opt",     "values",        "nexprlist",   
++  "exprlist",      "sclp",          "as",            "seltablist",  
++  "stl_prefix",    "joinop",        "indexed_opt",   "on_opt",      
++  "using_opt",     "idlist",        "setlist",       "insert_cmd",  
++  "idlist_opt",    "likeop",        "between_op",    "in_op",       
++  "paren_exprlist",  "case_operand",  "case_exprlist",  "case_else",   
++  "uniqueflag",    "collate",       "nmnum",         "trigger_decl",
++  "trigger_cmd_list",  "trigger_time",  "trigger_event",  "foreach_clause",
++  "when_clause",   "trigger_cmd",   "trnm",          "tridxby",     
++  "database_kw_opt",  "key_opt",       "add_column_fullname",  "kwcolumn_opt",
++  "create_vtab",   "vtabarglist",   "vtabarg",       "vtabargtoken",
++  "lp",            "anylist",       "wqlist",      
+ };
+ #endif /* NDEBUG */
+ 
+@@ -124291,360 +140941,409 @@
+ /* For tracing reduce actions, the names of all rules are required.
+ */
+ static const char *const yyRuleName[] = {
+- /*   0 */ "input ::= cmdlist",
+- /*   1 */ "cmdlist ::= cmdlist ecmd",
+- /*   2 */ "cmdlist ::= ecmd",
+- /*   3 */ "ecmd ::= SEMI",
+- /*   4 */ "ecmd ::= explain cmdx SEMI",
+- /*   5 */ "explain ::=",
+- /*   6 */ "explain ::= EXPLAIN",
+- /*   7 */ "explain ::= EXPLAIN QUERY PLAN",
+- /*   8 */ "cmdx ::= cmd",
+- /*   9 */ "cmd ::= BEGIN transtype trans_opt",
+- /*  10 */ "trans_opt ::=",
+- /*  11 */ "trans_opt ::= TRANSACTION",
+- /*  12 */ "trans_opt ::= TRANSACTION nm",
+- /*  13 */ "transtype ::=",
+- /*  14 */ "transtype ::= DEFERRED",
+- /*  15 */ "transtype ::= IMMEDIATE",
+- /*  16 */ "transtype ::= EXCLUSIVE",
+- /*  17 */ "cmd ::= COMMIT trans_opt",
+- /*  18 */ "cmd ::= END trans_opt",
+- /*  19 */ "cmd ::= ROLLBACK trans_opt",
+- /*  20 */ "savepoint_opt ::= SAVEPOINT",
+- /*  21 */ "savepoint_opt ::=",
+- /*  22 */ "cmd ::= SAVEPOINT nm",
+- /*  23 */ "cmd ::= RELEASE savepoint_opt nm",
+- /*  24 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm",
+- /*  25 */ "cmd ::= create_table create_table_args",
+- /*  26 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm",
+- /*  27 */ "createkw ::= CREATE",
+- /*  28 */ "ifnotexists ::=",
+- /*  29 */ "ifnotexists ::= IF NOT EXISTS",
+- /*  30 */ "temp ::= TEMP",
+- /*  31 */ "temp ::=",
+- /*  32 */ "create_table_args ::= LP columnlist conslist_opt RP table_options",
+- /*  33 */ "create_table_args ::= AS select",
+- /*  34 */ "table_options ::=",
+- /*  35 */ "table_options ::= WITHOUT nm",
+- /*  36 */ "columnlist ::= columnlist COMMA column",
+- /*  37 */ "columnlist ::= column",
+- /*  38 */ "column ::= columnid type carglist",
+- /*  39 */ "columnid ::= nm",
+- /*  40 */ "nm ::= ID|INDEXED",
+- /*  41 */ "nm ::= STRING",
+- /*  42 */ "nm ::= JOIN_KW",
+- /*  43 */ "type ::=",
+- /*  44 */ "type ::= typetoken",
+- /*  45 */ "typetoken ::= typename",
+- /*  46 */ "typetoken ::= typename LP signed RP",
+- /*  47 */ "typetoken ::= typename LP signed COMMA signed RP",
+- /*  48 */ "typename ::= ID|STRING",
+- /*  49 */ "typename ::= typename ID|STRING",
+- /*  50 */ "signed ::= plus_num",
+- /*  51 */ "signed ::= minus_num",
+- /*  52 */ "carglist ::= carglist ccons",
+- /*  53 */ "carglist ::=",
+- /*  54 */ "ccons ::= CONSTRAINT nm",
+- /*  55 */ "ccons ::= DEFAULT term",
+- /*  56 */ "ccons ::= DEFAULT LP expr RP",
+- /*  57 */ "ccons ::= DEFAULT PLUS term",
+- /*  58 */ "ccons ::= DEFAULT MINUS term",
+- /*  59 */ "ccons ::= DEFAULT ID|INDEXED",
+- /*  60 */ "ccons ::= NULL onconf",
+- /*  61 */ "ccons ::= NOT NULL onconf",
+- /*  62 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+- /*  63 */ "ccons ::= UNIQUE onconf",
+- /*  64 */ "ccons ::= CHECK LP expr RP",
+- /*  65 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
+- /*  66 */ "ccons ::= defer_subclause",
+- /*  67 */ "ccons ::= COLLATE ID|STRING",
+- /*  68 */ "autoinc ::=",
+- /*  69 */ "autoinc ::= AUTOINCR",
+- /*  70 */ "refargs ::=",
+- /*  71 */ "refargs ::= refargs refarg",
+- /*  72 */ "refarg ::= MATCH nm",
+- /*  73 */ "refarg ::= ON INSERT refact",
+- /*  74 */ "refarg ::= ON DELETE refact",
+- /*  75 */ "refarg ::= ON UPDATE refact",
+- /*  76 */ "refact ::= SET NULL",
+- /*  77 */ "refact ::= SET DEFAULT",
+- /*  78 */ "refact ::= CASCADE",
+- /*  79 */ "refact ::= RESTRICT",
+- /*  80 */ "refact ::= NO ACTION",
+- /*  81 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+- /*  82 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+- /*  83 */ "init_deferred_pred_opt ::=",
+- /*  84 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+- /*  85 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+- /*  86 */ "conslist_opt ::=",
+- /*  87 */ "conslist_opt ::= COMMA conslist",
+- /*  88 */ "conslist ::= conslist tconscomma tcons",
+- /*  89 */ "conslist ::= tcons",
+- /*  90 */ "tconscomma ::= COMMA",
+- /*  91 */ "tconscomma ::=",
+- /*  92 */ "tcons ::= CONSTRAINT nm",
+- /*  93 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
+- /*  94 */ "tcons ::= UNIQUE LP idxlist RP onconf",
+- /*  95 */ "tcons ::= CHECK LP expr RP onconf",
+- /*  96 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
+- /*  97 */ "defer_subclause_opt ::=",
+- /*  98 */ "defer_subclause_opt ::= defer_subclause",
+- /*  99 */ "onconf ::=",
+- /* 100 */ "onconf ::= ON CONFLICT resolvetype",
+- /* 101 */ "orconf ::=",
+- /* 102 */ "orconf ::= OR resolvetype",
+- /* 103 */ "resolvetype ::= raisetype",
+- /* 104 */ "resolvetype ::= IGNORE",
+- /* 105 */ "resolvetype ::= REPLACE",
+- /* 106 */ "cmd ::= DROP TABLE ifexists fullname",
+- /* 107 */ "ifexists ::= IF EXISTS",
+- /* 108 */ "ifexists ::=",
+- /* 109 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select",
+- /* 110 */ "cmd ::= DROP VIEW ifexists fullname",
+- /* 111 */ "cmd ::= select",
+- /* 112 */ "select ::= with selectnowith",
+- /* 113 */ "selectnowith ::= oneselect",
+- /* 114 */ "selectnowith ::= selectnowith multiselect_op oneselect",
+- /* 115 */ "multiselect_op ::= UNION",
+- /* 116 */ "multiselect_op ::= UNION ALL",
+- /* 117 */ "multiselect_op ::= EXCEPT|INTERSECT",
+- /* 118 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt 
limit_opt",
+- /* 119 */ "oneselect ::= values",
+- /* 120 */ "values ::= VALUES LP nexprlist RP",
+- /* 121 */ "values ::= values COMMA LP exprlist RP",
+- /* 122 */ "distinct ::= DISTINCT",
+- /* 123 */ "distinct ::= ALL",
+- /* 124 */ "distinct ::=",
+- /* 125 */ "sclp ::= selcollist COMMA",
+- /* 126 */ "sclp ::=",
+- /* 127 */ "selcollist ::= sclp expr as",
+- /* 128 */ "selcollist ::= sclp STAR",
+- /* 129 */ "selcollist ::= sclp nm DOT STAR",
+- /* 130 */ "as ::= AS nm",
+- /* 131 */ "as ::= ID|STRING",
+- /* 132 */ "as ::=",
+- /* 133 */ "from ::=",
+- /* 134 */ "from ::= FROM seltablist",
+- /* 135 */ "stl_prefix ::= seltablist joinop",
+- /* 136 */ "stl_prefix ::=",
+- /* 137 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+- /* 138 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+- /* 139 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+- /* 140 */ "dbnm ::=",
+- /* 141 */ "dbnm ::= DOT nm",
+- /* 142 */ "fullname ::= nm dbnm",
+- /* 143 */ "joinop ::= COMMA|JOIN",
+- /* 144 */ "joinop ::= JOIN_KW JOIN",
+- /* 145 */ "joinop ::= JOIN_KW nm JOIN",
+- /* 146 */ "joinop ::= JOIN_KW nm nm JOIN",
+- /* 147 */ "on_opt ::= ON expr",
+- /* 148 */ "on_opt ::=",
+- /* 149 */ "indexed_opt ::=",
+- /* 150 */ "indexed_opt ::= INDEXED BY nm",
+- /* 151 */ "indexed_opt ::= NOT INDEXED",
+- /* 152 */ "using_opt ::= USING LP idlist RP",
+- /* 153 */ "using_opt ::=",
+- /* 154 */ "orderby_opt ::=",
+- /* 155 */ "orderby_opt ::= ORDER BY sortlist",
+- /* 156 */ "sortlist ::= sortlist COMMA expr sortorder",
+- /* 157 */ "sortlist ::= expr sortorder",
+- /* 158 */ "sortorder ::= ASC",
+- /* 159 */ "sortorder ::= DESC",
+- /* 160 */ "sortorder ::=",
+- /* 161 */ "groupby_opt ::=",
+- /* 162 */ "groupby_opt ::= GROUP BY nexprlist",
+- /* 163 */ "having_opt ::=",
+- /* 164 */ "having_opt ::= HAVING expr",
+- /* 165 */ "limit_opt ::=",
+- /* 166 */ "limit_opt ::= LIMIT expr",
+- /* 167 */ "limit_opt ::= LIMIT expr OFFSET expr",
+- /* 168 */ "limit_opt ::= LIMIT expr COMMA expr",
+- /* 169 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt",
+- /* 170 */ "where_opt ::=",
+- /* 171 */ "where_opt ::= WHERE expr",
+- /* 172 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt",
+- /* 173 */ "setlist ::= setlist COMMA nm EQ expr",
+- /* 174 */ "setlist ::= nm EQ expr",
+- /* 175 */ "cmd ::= with insert_cmd INTO fullname inscollist_opt select",
+- /* 176 */ "cmd ::= with insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
+- /* 177 */ "insert_cmd ::= INSERT orconf",
+- /* 178 */ "insert_cmd ::= REPLACE",
+- /* 179 */ "inscollist_opt ::=",
+- /* 180 */ "inscollist_opt ::= LP idlist RP",
+- /* 181 */ "idlist ::= idlist COMMA nm",
+- /* 182 */ "idlist ::= nm",
+- /* 183 */ "expr ::= term",
+- /* 184 */ "expr ::= LP expr RP",
+- /* 185 */ "term ::= NULL",
+- /* 186 */ "expr ::= ID|INDEXED",
+- /* 187 */ "expr ::= JOIN_KW",
+- /* 188 */ "expr ::= nm DOT nm",
+- /* 189 */ "expr ::= nm DOT nm DOT nm",
+- /* 190 */ "term ::= INTEGER|FLOAT|BLOB",
+- /* 191 */ "term ::= STRING",
+- /* 192 */ "expr ::= VARIABLE",
+- /* 193 */ "expr ::= expr COLLATE ID|STRING",
+- /* 194 */ "expr ::= CAST LP expr AS typetoken RP",
+- /* 195 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+- /* 196 */ "expr ::= ID|INDEXED LP STAR RP",
+- /* 197 */ "term ::= CTIME_KW",
+- /* 198 */ "expr ::= expr AND expr",
+- /* 199 */ "expr ::= expr OR expr",
+- /* 200 */ "expr ::= expr LT|GT|GE|LE expr",
+- /* 201 */ "expr ::= expr EQ|NE expr",
+- /* 202 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+- /* 203 */ "expr ::= expr PLUS|MINUS expr",
+- /* 204 */ "expr ::= expr STAR|SLASH|REM expr",
+- /* 205 */ "expr ::= expr CONCAT expr",
+- /* 206 */ "likeop ::= LIKE_KW|MATCH",
+- /* 207 */ "likeop ::= NOT LIKE_KW|MATCH",
+- /* 208 */ "expr ::= expr likeop expr",
+- /* 209 */ "expr ::= expr likeop expr ESCAPE expr",
+- /* 210 */ "expr ::= expr ISNULL|NOTNULL",
+- /* 211 */ "expr ::= expr NOT NULL",
+- /* 212 */ "expr ::= expr IS expr",
+- /* 213 */ "expr ::= expr IS NOT expr",
+- /* 214 */ "expr ::= NOT expr",
+- /* 215 */ "expr ::= BITNOT expr",
+- /* 216 */ "expr ::= MINUS expr",
+- /* 217 */ "expr ::= PLUS expr",
+- /* 218 */ "between_op ::= BETWEEN",
+- /* 219 */ "between_op ::= NOT BETWEEN",
+- /* 220 */ "expr ::= expr between_op expr AND expr",
+- /* 221 */ "in_op ::= IN",
+- /* 222 */ "in_op ::= NOT IN",
+- /* 223 */ "expr ::= expr in_op LP exprlist RP",
+- /* 224 */ "expr ::= LP select RP",
+- /* 225 */ "expr ::= expr in_op LP select RP",
+- /* 226 */ "expr ::= expr in_op nm dbnm",
+- /* 227 */ "expr ::= EXISTS LP select RP",
+- /* 228 */ "expr ::= CASE case_operand case_exprlist case_else END",
+- /* 229 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+- /* 230 */ "case_exprlist ::= WHEN expr THEN expr",
+- /* 231 */ "case_else ::= ELSE expr",
+- /* 232 */ "case_else ::=",
+- /* 233 */ "case_operand ::= expr",
+- /* 234 */ "case_operand ::=",
+- /* 235 */ "exprlist ::= nexprlist",
+- /* 236 */ "exprlist ::=",
+- /* 237 */ "nexprlist ::= nexprlist COMMA expr",
+- /* 238 */ "nexprlist ::= expr",
+- /* 239 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt",
+- /* 240 */ "uniqueflag ::= UNIQUE",
+- /* 241 */ "uniqueflag ::=",
+- /* 242 */ "idxlist_opt ::=",
+- /* 243 */ "idxlist_opt ::= LP idxlist RP",
+- /* 244 */ "idxlist ::= idxlist COMMA nm collate sortorder",
+- /* 245 */ "idxlist ::= nm collate sortorder",
+- /* 246 */ "collate ::=",
+- /* 247 */ "collate ::= COLLATE ID|STRING",
+- /* 248 */ "cmd ::= DROP INDEX ifexists fullname",
+- /* 249 */ "cmd ::= VACUUM",
+- /* 250 */ "cmd ::= VACUUM nm",
+- /* 251 */ "cmd ::= PRAGMA nm dbnm",
+- /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+- /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+- /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+- /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+- /* 256 */ "nmnum ::= plus_num",
+- /* 257 */ "nmnum ::= nm",
+- /* 258 */ "nmnum ::= ON",
+- /* 259 */ "nmnum ::= DELETE",
+- /* 260 */ "nmnum ::= DEFAULT",
+- /* 261 */ "plus_num ::= PLUS INTEGER|FLOAT",
+- /* 262 */ "plus_num ::= INTEGER|FLOAT",
+- /* 263 */ "minus_num ::= MINUS INTEGER|FLOAT",
+- /* 264 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+- /* 265 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname 
foreach_clause when_clause",
+- /* 266 */ "trigger_time ::= BEFORE",
+- /* 267 */ "trigger_time ::= AFTER",
+- /* 268 */ "trigger_time ::= INSTEAD OF",
+- /* 269 */ "trigger_time ::=",
+- /* 270 */ "trigger_event ::= DELETE|INSERT",
+- /* 271 */ "trigger_event ::= UPDATE",
+- /* 272 */ "trigger_event ::= UPDATE OF idlist",
+- /* 273 */ "foreach_clause ::=",
+- /* 274 */ "foreach_clause ::= FOR EACH ROW",
+- /* 275 */ "when_clause ::=",
+- /* 276 */ "when_clause ::= WHEN expr",
+- /* 277 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+- /* 278 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+- /* 279 */ "trnm ::= nm",
+- /* 280 */ "trnm ::= nm DOT nm",
+- /* 281 */ "tridxby ::=",
+- /* 282 */ "tridxby ::= INDEXED BY nm",
+- /* 283 */ "tridxby ::= NOT INDEXED",
+- /* 284 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
+- /* 285 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select",
+- /* 286 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
+- /* 287 */ "trigger_cmd ::= select",
+- /* 288 */ "expr ::= RAISE LP IGNORE RP",
+- /* 289 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+- /* 290 */ "raisetype ::= ROLLBACK",
+- /* 291 */ "raisetype ::= ABORT",
+- /* 292 */ "raisetype ::= FAIL",
+- /* 293 */ "cmd ::= DROP TRIGGER ifexists fullname",
+- /* 294 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+- /* 295 */ "cmd ::= DETACH database_kw_opt expr",
+- /* 296 */ "key_opt ::=",
+- /* 297 */ "key_opt ::= KEY expr",
+- /* 298 */ "database_kw_opt ::= DATABASE",
+- /* 299 */ "database_kw_opt ::=",
+- /* 300 */ "cmd ::= REINDEX",
+- /* 301 */ "cmd ::= REINDEX nm dbnm",
+- /* 302 */ "cmd ::= ANALYZE",
+- /* 303 */ "cmd ::= ANALYZE nm dbnm",
+- /* 304 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+- /* 305 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
+- /* 306 */ "add_column_fullname ::= fullname",
+- /* 307 */ "kwcolumn_opt ::=",
+- /* 308 */ "kwcolumn_opt ::= COLUMNKW",
+- /* 309 */ "cmd ::= create_vtab",
+- /* 310 */ "cmd ::= create_vtab LP vtabarglist RP",
+- /* 311 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+- /* 312 */ "vtabarglist ::= vtabarg",
+- /* 313 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+- /* 314 */ "vtabarg ::=",
+- /* 315 */ "vtabarg ::= vtabarg vtabargtoken",
+- /* 316 */ "vtabargtoken ::= ANY",
+- /* 317 */ "vtabargtoken ::= lp anylist RP",
+- /* 318 */ "lp ::= LP",
+- /* 319 */ "anylist ::=",
+- /* 320 */ "anylist ::= anylist LP anylist RP",
+- /* 321 */ "anylist ::= anylist ANY",
+- /* 322 */ "with ::=",
+- /* 323 */ "with ::= WITH wqlist",
+- /* 324 */ "with ::= WITH RECURSIVE wqlist",
+- /* 325 */ "wqlist ::= nm idxlist_opt AS LP select RP",
+- /* 326 */ "wqlist ::= wqlist COMMA nm idxlist_opt AS LP select RP",
++ /*   0 */ "explain ::= EXPLAIN",
++ /*   1 */ "explain ::= EXPLAIN QUERY PLAN",
++ /*   2 */ "cmdx ::= cmd",
++ /*   3 */ "cmd ::= BEGIN transtype trans_opt",
++ /*   4 */ "transtype ::=",
++ /*   5 */ "transtype ::= DEFERRED",
++ /*   6 */ "transtype ::= IMMEDIATE",
++ /*   7 */ "transtype ::= EXCLUSIVE",
++ /*   8 */ "cmd ::= COMMIT|END trans_opt",
++ /*   9 */ "cmd ::= ROLLBACK trans_opt",
++ /*  10 */ "cmd ::= SAVEPOINT nm",
++ /*  11 */ "cmd ::= RELEASE savepoint_opt nm",
++ /*  12 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm",
++ /*  13 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm",
++ /*  14 */ "createkw ::= CREATE",
++ /*  15 */ "ifnotexists ::=",
++ /*  16 */ "ifnotexists ::= IF NOT EXISTS",
++ /*  17 */ "temp ::= TEMP",
++ /*  18 */ "temp ::=",
++ /*  19 */ "create_table_args ::= LP columnlist conslist_opt RP table_options",
++ /*  20 */ "create_table_args ::= AS select",
++ /*  21 */ "table_options ::=",
++ /*  22 */ "table_options ::= WITHOUT nm",
++ /*  23 */ "columnname ::= nm typetoken",
++ /*  24 */ "typetoken ::=",
++ /*  25 */ "typetoken ::= typename LP signed RP",
++ /*  26 */ "typetoken ::= typename LP signed COMMA signed RP",
++ /*  27 */ "typename ::= typename ID|STRING",
++ /*  28 */ "ccons ::= CONSTRAINT nm",
++ /*  29 */ "ccons ::= DEFAULT term",
++ /*  30 */ "ccons ::= DEFAULT LP expr RP",
++ /*  31 */ "ccons ::= DEFAULT PLUS term",
++ /*  32 */ "ccons ::= DEFAULT MINUS term",
++ /*  33 */ "ccons ::= DEFAULT ID|INDEXED",
++ /*  34 */ "ccons ::= NOT NULL onconf",
++ /*  35 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
++ /*  36 */ "ccons ::= UNIQUE onconf",
++ /*  37 */ "ccons ::= CHECK LP expr RP",
++ /*  38 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
++ /*  39 */ "ccons ::= defer_subclause",
++ /*  40 */ "ccons ::= COLLATE ID|STRING",
++ /*  41 */ "autoinc ::=",
++ /*  42 */ "autoinc ::= AUTOINCR",
++ /*  43 */ "refargs ::=",
++ /*  44 */ "refargs ::= refargs refarg",
++ /*  45 */ "refarg ::= MATCH nm",
++ /*  46 */ "refarg ::= ON INSERT refact",
++ /*  47 */ "refarg ::= ON DELETE refact",
++ /*  48 */ "refarg ::= ON UPDATE refact",
++ /*  49 */ "refact ::= SET NULL",
++ /*  50 */ "refact ::= SET DEFAULT",
++ /*  51 */ "refact ::= CASCADE",
++ /*  52 */ "refact ::= RESTRICT",
++ /*  53 */ "refact ::= NO ACTION",
++ /*  54 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
++ /*  55 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
++ /*  56 */ "init_deferred_pred_opt ::=",
++ /*  57 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
++ /*  58 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
++ /*  59 */ "conslist_opt ::=",
++ /*  60 */ "tconscomma ::= COMMA",
++ /*  61 */ "tcons ::= CONSTRAINT nm",
++ /*  62 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
++ /*  63 */ "tcons ::= UNIQUE LP sortlist RP onconf",
++ /*  64 */ "tcons ::= CHECK LP expr RP onconf",
++ /*  65 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
++ /*  66 */ "defer_subclause_opt ::=",
++ /*  67 */ "onconf ::=",
++ /*  68 */ "onconf ::= ON CONFLICT resolvetype",
++ /*  69 */ "orconf ::=",
++ /*  70 */ "orconf ::= OR resolvetype",
++ /*  71 */ "resolvetype ::= IGNORE",
++ /*  72 */ "resolvetype ::= REPLACE",
++ /*  73 */ "cmd ::= DROP TABLE ifexists fullname",
++ /*  74 */ "ifexists ::= IF EXISTS",
++ /*  75 */ "ifexists ::=",
++ /*  76 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
++ /*  77 */ "cmd ::= DROP VIEW ifexists fullname",
++ /*  78 */ "cmd ::= select",
++ /*  79 */ "select ::= with selectnowith",
++ /*  80 */ "selectnowith ::= selectnowith multiselect_op oneselect",
++ /*  81 */ "multiselect_op ::= UNION",
++ /*  82 */ "multiselect_op ::= UNION ALL",
++ /*  83 */ "multiselect_op ::= EXCEPT|INTERSECT",
++ /*  84 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt 
limit_opt",
++ /*  85 */ "values ::= VALUES LP nexprlist RP",
++ /*  86 */ "values ::= values COMMA LP exprlist RP",
++ /*  87 */ "distinct ::= DISTINCT",
++ /*  88 */ "distinct ::= ALL",
++ /*  89 */ "distinct ::=",
++ /*  90 */ "sclp ::=",
++ /*  91 */ "selcollist ::= sclp expr as",
++ /*  92 */ "selcollist ::= sclp STAR",
++ /*  93 */ "selcollist ::= sclp nm DOT STAR",
++ /*  94 */ "as ::= AS nm",
++ /*  95 */ "as ::=",
++ /*  96 */ "from ::=",
++ /*  97 */ "from ::= FROM seltablist",
++ /*  98 */ "stl_prefix ::= seltablist joinop",
++ /*  99 */ "stl_prefix ::=",
++ /* 100 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
++ /* 101 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
++ /* 102 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
++ /* 103 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
++ /* 104 */ "dbnm ::=",
++ /* 105 */ "dbnm ::= DOT nm",
++ /* 106 */ "fullname ::= nm dbnm",
++ /* 107 */ "joinop ::= COMMA|JOIN",
++ /* 108 */ "joinop ::= JOIN_KW JOIN",
++ /* 109 */ "joinop ::= JOIN_KW nm JOIN",
++ /* 110 */ "joinop ::= JOIN_KW nm nm JOIN",
++ /* 111 */ "on_opt ::= ON expr",
++ /* 112 */ "on_opt ::=",
++ /* 113 */ "indexed_opt ::=",
++ /* 114 */ "indexed_opt ::= INDEXED BY nm",
++ /* 115 */ "indexed_opt ::= NOT INDEXED",
++ /* 116 */ "using_opt ::= USING LP idlist RP",
++ /* 117 */ "using_opt ::=",
++ /* 118 */ "orderby_opt ::=",
++ /* 119 */ "orderby_opt ::= ORDER BY sortlist",
++ /* 120 */ "sortlist ::= sortlist COMMA expr sortorder",
++ /* 121 */ "sortlist ::= expr sortorder",
++ /* 122 */ "sortorder ::= ASC",
++ /* 123 */ "sortorder ::= DESC",
++ /* 124 */ "sortorder ::=",
++ /* 125 */ "groupby_opt ::=",
++ /* 126 */ "groupby_opt ::= GROUP BY nexprlist",
++ /* 127 */ "having_opt ::=",
++ /* 128 */ "having_opt ::= HAVING expr",
++ /* 129 */ "limit_opt ::=",
++ /* 130 */ "limit_opt ::= LIMIT expr",
++ /* 131 */ "limit_opt ::= LIMIT expr OFFSET expr",
++ /* 132 */ "limit_opt ::= LIMIT expr COMMA expr",
++ /* 133 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt",
++ /* 134 */ "where_opt ::=",
++ /* 135 */ "where_opt ::= WHERE expr",
++ /* 136 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt",
++ /* 137 */ "setlist ::= setlist COMMA nm EQ expr",
++ /* 138 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
++ /* 139 */ "setlist ::= nm EQ expr",
++ /* 140 */ "setlist ::= LP idlist RP EQ expr",
++ /* 141 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select",
++ /* 142 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES",
++ /* 143 */ "insert_cmd ::= INSERT orconf",
++ /* 144 */ "insert_cmd ::= REPLACE",
++ /* 145 */ "idlist_opt ::=",
++ /* 146 */ "idlist_opt ::= LP idlist RP",
++ /* 147 */ "idlist ::= idlist COMMA nm",
++ /* 148 */ "idlist ::= nm",
++ /* 149 */ "expr ::= LP expr RP",
++ /* 150 */ "expr ::= ID|INDEXED",
++ /* 151 */ "expr ::= JOIN_KW",
++ /* 152 */ "expr ::= nm DOT nm",
++ /* 153 */ "expr ::= nm DOT nm DOT nm",
++ /* 154 */ "term ::= NULL|FLOAT|BLOB",
++ /* 155 */ "term ::= STRING",
++ /* 156 */ "term ::= INTEGER",
++ /* 157 */ "expr ::= VARIABLE",
++ /* 158 */ "expr ::= expr COLLATE ID|STRING",
++ /* 159 */ "expr ::= CAST LP expr AS typetoken RP",
++ /* 160 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
++ /* 161 */ "expr ::= ID|INDEXED LP STAR RP",
++ /* 162 */ "term ::= CTIME_KW",
++ /* 163 */ "expr ::= LP nexprlist COMMA expr RP",
++ /* 164 */ "expr ::= expr AND expr",
++ /* 165 */ "expr ::= expr OR expr",
++ /* 166 */ "expr ::= expr LT|GT|GE|LE expr",
++ /* 167 */ "expr ::= expr EQ|NE expr",
++ /* 168 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
++ /* 169 */ "expr ::= expr PLUS|MINUS expr",
++ /* 170 */ "expr ::= expr STAR|SLASH|REM expr",
++ /* 171 */ "expr ::= expr CONCAT expr",
++ /* 172 */ "likeop ::= NOT LIKE_KW|MATCH",
++ /* 173 */ "expr ::= expr likeop expr",
++ /* 174 */ "expr ::= expr likeop expr ESCAPE expr",
++ /* 175 */ "expr ::= expr ISNULL|NOTNULL",
++ /* 176 */ "expr ::= expr NOT NULL",
++ /* 177 */ "expr ::= expr IS expr",
++ /* 178 */ "expr ::= expr IS NOT expr",
++ /* 179 */ "expr ::= NOT expr",
++ /* 180 */ "expr ::= BITNOT expr",
++ /* 181 */ "expr ::= MINUS expr",
++ /* 182 */ "expr ::= PLUS expr",
++ /* 183 */ "between_op ::= BETWEEN",
++ /* 184 */ "between_op ::= NOT BETWEEN",
++ /* 185 */ "expr ::= expr between_op expr AND expr",
++ /* 186 */ "in_op ::= IN",
++ /* 187 */ "in_op ::= NOT IN",
++ /* 188 */ "expr ::= expr in_op LP exprlist RP",
++ /* 189 */ "expr ::= LP select RP",
++ /* 190 */ "expr ::= expr in_op LP select RP",
++ /* 191 */ "expr ::= expr in_op nm dbnm paren_exprlist",
++ /* 192 */ "expr ::= EXISTS LP select RP",
++ /* 193 */ "expr ::= CASE case_operand case_exprlist case_else END",
++ /* 194 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
++ /* 195 */ "case_exprlist ::= WHEN expr THEN expr",
++ /* 196 */ "case_else ::= ELSE expr",
++ /* 197 */ "case_else ::=",
++ /* 198 */ "case_operand ::= expr",
++ /* 199 */ "case_operand ::=",
++ /* 200 */ "exprlist ::=",
++ /* 201 */ "nexprlist ::= nexprlist COMMA expr",
++ /* 202 */ "nexprlist ::= expr",
++ /* 203 */ "paren_exprlist ::=",
++ /* 204 */ "paren_exprlist ::= LP exprlist RP",
++ /* 205 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
++ /* 206 */ "uniqueflag ::= UNIQUE",
++ /* 207 */ "uniqueflag ::=",
++ /* 208 */ "eidlist_opt ::=",
++ /* 209 */ "eidlist_opt ::= LP eidlist RP",
++ /* 210 */ "eidlist ::= eidlist COMMA nm collate sortorder",
++ /* 211 */ "eidlist ::= nm collate sortorder",
++ /* 212 */ "collate ::=",
++ /* 213 */ "collate ::= COLLATE ID|STRING",
++ /* 214 */ "cmd ::= DROP INDEX ifexists fullname",
++ /* 215 */ "cmd ::= VACUUM",
++ /* 216 */ "cmd ::= VACUUM nm",
++ /* 217 */ "cmd ::= PRAGMA nm dbnm",
++ /* 218 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
++ /* 219 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
++ /* 220 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
++ /* 221 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
++ /* 222 */ "plus_num ::= PLUS INTEGER|FLOAT",
++ /* 223 */ "minus_num ::= MINUS INTEGER|FLOAT",
++ /* 224 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
++ /* 225 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname 
foreach_clause when_clause",
++ /* 226 */ "trigger_time ::= BEFORE|AFTER",
++ /* 227 */ "trigger_time ::= INSTEAD OF",
++ /* 228 */ "trigger_time ::=",
++ /* 229 */ "trigger_event ::= DELETE|INSERT",
++ /* 230 */ "trigger_event ::= UPDATE",
++ /* 231 */ "trigger_event ::= UPDATE OF idlist",
++ /* 232 */ "when_clause ::=",
++ /* 233 */ "when_clause ::= WHEN expr",
++ /* 234 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
++ /* 235 */ "trigger_cmd_list ::= trigger_cmd SEMI",
++ /* 236 */ "trnm ::= nm DOT nm",
++ /* 237 */ "tridxby ::= INDEXED BY nm",
++ /* 238 */ "tridxby ::= NOT INDEXED",
++ /* 239 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
++ /* 240 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
++ /* 241 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
++ /* 242 */ "trigger_cmd ::= select",
++ /* 243 */ "expr ::= RAISE LP IGNORE RP",
++ /* 244 */ "expr ::= RAISE LP raisetype COMMA nm RP",
++ /* 245 */ "raisetype ::= ROLLBACK",
++ /* 246 */ "raisetype ::= ABORT",
++ /* 247 */ "raisetype ::= FAIL",
++ /* 248 */ "cmd ::= DROP TRIGGER ifexists fullname",
++ /* 249 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
++ /* 250 */ "cmd ::= DETACH database_kw_opt expr",
++ /* 251 */ "key_opt ::=",
++ /* 252 */ "key_opt ::= KEY expr",
++ /* 253 */ "cmd ::= REINDEX",
++ /* 254 */ "cmd ::= REINDEX nm dbnm",
++ /* 255 */ "cmd ::= ANALYZE",
++ /* 256 */ "cmd ::= ANALYZE nm dbnm",
++ /* 257 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
++ /* 258 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
++ /* 259 */ "add_column_fullname ::= fullname",
++ /* 260 */ "cmd ::= create_vtab",
++ /* 261 */ "cmd ::= create_vtab LP vtabarglist RP",
++ /* 262 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
++ /* 263 */ "vtabarg ::=",
++ /* 264 */ "vtabargtoken ::= ANY",
++ /* 265 */ "vtabargtoken ::= lp anylist RP",
++ /* 266 */ "lp ::= LP",
++ /* 267 */ "with ::=",
++ /* 268 */ "with ::= WITH wqlist",
++ /* 269 */ "with ::= WITH RECURSIVE wqlist",
++ /* 270 */ "wqlist ::= nm eidlist_opt AS LP select RP",
++ /* 271 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
++ /* 272 */ "input ::= cmdlist",
++ /* 273 */ "cmdlist ::= cmdlist ecmd",
++ /* 274 */ "cmdlist ::= ecmd",
++ /* 275 */ "ecmd ::= SEMI",
++ /* 276 */ "ecmd ::= explain cmdx SEMI",
++ /* 277 */ "explain ::=",
++ /* 278 */ "trans_opt ::=",
++ /* 279 */ "trans_opt ::= TRANSACTION",
++ /* 280 */ "trans_opt ::= TRANSACTION nm",
++ /* 281 */ "savepoint_opt ::= SAVEPOINT",
++ /* 282 */ "savepoint_opt ::=",
++ /* 283 */ "cmd ::= create_table create_table_args",
++ /* 284 */ "columnlist ::= columnlist COMMA columnname carglist",
++ /* 285 */ "columnlist ::= columnname carglist",
++ /* 286 */ "nm ::= ID|INDEXED",
++ /* 287 */ "nm ::= STRING",
++ /* 288 */ "nm ::= JOIN_KW",
++ /* 289 */ "typetoken ::= typename",
++ /* 290 */ "typename ::= ID|STRING",
++ /* 291 */ "signed ::= plus_num",
++ /* 292 */ "signed ::= minus_num",
++ /* 293 */ "carglist ::= carglist ccons",
++ /* 294 */ "carglist ::=",
++ /* 295 */ "ccons ::= NULL onconf",
++ /* 296 */ "conslist_opt ::= COMMA conslist",
++ /* 297 */ "conslist ::= conslist tconscomma tcons",
++ /* 298 */ "conslist ::= tcons",
++ /* 299 */ "tconscomma ::=",
++ /* 300 */ "defer_subclause_opt ::= defer_subclause",
++ /* 301 */ "resolvetype ::= raisetype",
++ /* 302 */ "selectnowith ::= oneselect",
++ /* 303 */ "oneselect ::= values",
++ /* 304 */ "sclp ::= selcollist COMMA",
++ /* 305 */ "as ::= ID|STRING",
++ /* 306 */ "expr ::= term",
++ /* 307 */ "likeop ::= LIKE_KW|MATCH",
++ /* 308 */ "exprlist ::= nexprlist",
++ /* 309 */ "nmnum ::= plus_num",
++ /* 310 */ "nmnum ::= nm",
++ /* 311 */ "nmnum ::= ON",
++ /* 312 */ "nmnum ::= DELETE",
++ /* 313 */ "nmnum ::= DEFAULT",
++ /* 314 */ "plus_num ::= INTEGER|FLOAT",
++ /* 315 */ "foreach_clause ::=",
++ /* 316 */ "foreach_clause ::= FOR EACH ROW",
++ /* 317 */ "trnm ::= nm",
++ /* 318 */ "tridxby ::=",
++ /* 319 */ "database_kw_opt ::= DATABASE",
++ /* 320 */ "database_kw_opt ::=",
++ /* 321 */ "kwcolumn_opt ::=",
++ /* 322 */ "kwcolumn_opt ::= COLUMNKW",
++ /* 323 */ "vtabarglist ::= vtabarg",
++ /* 324 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
++ /* 325 */ "vtabarg ::= vtabarg vtabargtoken",
++ /* 326 */ "anylist ::=",
++ /* 327 */ "anylist ::= anylist LP anylist RP",
++ /* 328 */ "anylist ::= anylist ANY",
+ };
+ #endif /* NDEBUG */
+ 
+ 
+ #if YYSTACKDEPTH<=0
+ /*
+-** Try to increase the size of the parser stack.
++** Try to increase the size of the parser stack.  Return the number
++** of errors.  Return 0 on success.
+ */
+-static void yyGrowStack(yyParser *p){
++static int yyGrowStack(yyParser *p){
+   int newSize;
++  int idx;
+   yyStackEntry *pNew;
+ 
+   newSize = p->yystksz*2 + 100;
+-  pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
++  idx = p->yytos ? (int)(p->yytos - p->yystack) : 0;
++  if( p->yystack==&p->yystk0 ){
++    pNew = malloc(newSize*sizeof(pNew[0]));
++    if( pNew ) pNew[0] = p->yystk0;
++  }else{
++    pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
++  }
+   if( pNew ){
+     p->yystack = pNew;
+-    p->yystksz = newSize;
++    p->yytos = &p->yystack[idx];
+ #ifndef NDEBUG
+     if( yyTraceFILE ){
+-      fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
+-              yyTracePrompt, p->yystksz);
++      fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
++              yyTracePrompt, p->yystksz, newSize);
+     }
+ #endif
++    p->yystksz = newSize;
+   }
++  return pNew==0; 
+ }
+ #endif
+ 
++/* Datatype of the argument to the memory allocated passed as the
++** second argument to sqlite3ParserAlloc() below.  This can be changed by
++** putting an appropriate #define in the %include section of the input
++** grammar.
++*/
++#ifndef YYMALLOCARGTYPE
++# define YYMALLOCARGTYPE size_t
 +#endif
-+#if SQLITE_TEST
-+  "TEST",
++
++/* Initialize a new parser that has already been allocated.
++*/
++SQLITE_PRIVATE void sqlite3ParserInit(void *yypParser){
++  yyParser *pParser = (yyParser*)yypParser;
++#ifdef YYTRACKMAXSTACKDEPTH
++  pParser->yyhwm = 0;
 +#endif
-+#if defined(SQLITE_THREADSAFE)
-+  "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
++#if YYSTACKDEPTH<=0
++  pParser->yytos = NULL;
++  pParser->yystack = NULL;
++  pParser->yystksz = 0;
++  if( yyGrowStack(pParser) ){
++    pParser->yystack = &pParser->yystk0;
++    pParser->yystksz = 1;
++  }
 +#endif
-+#if SQLITE_USE_ALLOCA
-+  "USE_ALLOCA",
++#ifndef YYNOERRORRECOVERY
++  pParser->yyerrcnt = -1;
 +#endif
-+#if SQLITE_USER_AUTHENTICATION
-+  "USER_AUTHENTICATION",
++  pParser->yytos = pParser->yystack;
++  pParser->yystack[0].stateno = 0;
++  pParser->yystack[0].major = 0;
++#if YYSTACKDEPTH>0
++  pParser->yystackEnd = &pParser->yystack[YYSTACKDEPTH-1];
 +#endif
-+#if SQLITE_WIN32_MALLOC
-+  "WIN32_MALLOC",
++}
++
++#ifndef sqlite3Parser_ENGINEALWAYSONSTACK
+ /* 
+ ** This function allocates a new parser.
+ ** The only argument is a pointer to a function which works like
+@@ -124657,27 +141356,21 @@
+ ** A pointer to a parser.  This pointer is used in subsequent calls
+ ** to sqlite3Parser and sqlite3ParserFree.
+ */
+-SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(u64)){
++SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){
+   yyParser *pParser;
+-  pParser = (yyParser*)(*mallocProc)( (u64)sizeof(yyParser) );
+-  if( pParser ){
+-    pParser->yyidx = -1;
+-#ifdef YYTRACKMAXSTACKDEPTH
+-    pParser->yyidxMax = 0;
+-#endif
+-#if YYSTACKDEPTH<=0
+-    pParser->yystack = NULL;
+-    pParser->yystksz = 0;
+-    yyGrowStack(pParser);
+-#endif
+-  }
++  pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
++  if( pParser ) sqlite3ParserInit(pParser);
+   return pParser;
+ }
++#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */
+ 
+-/* The following function deletes the value associated with a
+-** symbol.  The symbol can be either a terminal or nonterminal.
+-** "yymajor" is the symbol code, and "yypminor" is a pointer to
+-** the value.
++
++/* The following function deletes the "minor type" or semantic value
++** associated with a symbol.  The symbol can be either a terminal
++** or nonterminal. "yymajor" is the symbol code, and "yypminor" is
++** a pointer to the value to be deleted.  The code used to do the 
++** deletions is derived from the %destructor and/or %token_destructor
++** directives of the input grammar.
+ */
+ static void yy_destructor(
+   yyParser *yypParser,    /* The parser */
+@@ -124693,81 +141386,84 @@
+     ** being destroyed before it is finished parsing.
+     **
+     ** Note: during a reduce, the only symbols destroyed are those
+-    ** which appear on the RHS of the rule, but which are not used
++    ** which appear on the RHS of the rule, but which are *not* used
+     ** inside the C code.
+     */
++/********* Begin destructor definitions ***************************************/
+     case 163: /* select */
+-    case 195: /* selectnowith */
+-    case 196: /* oneselect */
+-    case 207: /* values */
++    case 194: /* selectnowith */
++    case 195: /* oneselect */
++    case 206: /* values */
+ {
+-sqlite3SelectDelete(pParse->db, (yypminor->yy3));
++sqlite3SelectDelete(pParse->db, (yypminor->yy243));
+ }
+       break;
+-    case 174: /* term */
+-    case 175: /* expr */
++    case 172: /* term */
++    case 173: /* expr */
+ {
+-sqlite3ExprDelete(pParse->db, (yypminor->yy346).pExpr);
++sqlite3ExprDelete(pParse->db, (yypminor->yy190).pExpr);
+ }
+       break;
+-    case 179: /* idxlist_opt */
+-    case 188: /* idxlist */
+-    case 200: /* selcollist */
+-    case 203: /* groupby_opt */
+-    case 205: /* orderby_opt */
+-    case 208: /* nexprlist */
+-    case 209: /* exprlist */
+-    case 210: /* sclp */
+-    case 220: /* sortlist */
+-    case 221: /* setlist */
+-    case 228: /* case_exprlist */
++    case 177: /* eidlist_opt */
++    case 186: /* sortlist */
++    case 187: /* eidlist */
++    case 199: /* selcollist */
++    case 202: /* groupby_opt */
++    case 204: /* orderby_opt */
++    case 207: /* nexprlist */
++    case 208: /* exprlist */
++    case 209: /* sclp */
++    case 218: /* setlist */
++    case 224: /* paren_exprlist */
++    case 226: /* case_exprlist */
+ {
+-sqlite3ExprListDelete(pParse->db, (yypminor->yy14));
++sqlite3ExprListDelete(pParse->db, (yypminor->yy148));
+ }
+       break;
+-    case 194: /* fullname */
+-    case 201: /* from */
+-    case 212: /* seltablist */
+-    case 213: /* stl_prefix */
++    case 193: /* fullname */
++    case 200: /* from */
++    case 211: /* seltablist */
++    case 212: /* stl_prefix */
+ {
+-sqlite3SrcListDelete(pParse->db, (yypminor->yy65));
++sqlite3SrcListDelete(pParse->db, (yypminor->yy185));
+ }
+       break;
+-    case 197: /* with */
+-    case 252: /* wqlist */
++    case 196: /* with */
++    case 250: /* wqlist */
+ {
+-sqlite3WithDelete(pParse->db, (yypminor->yy59));
++sqlite3WithDelete(pParse->db, (yypminor->yy285));
+ }
+       break;
+-    case 202: /* where_opt */
+-    case 204: /* having_opt */
+-    case 216: /* on_opt */
+-    case 227: /* case_operand */
+-    case 229: /* case_else */
+-    case 238: /* when_clause */
+-    case 243: /* key_opt */
++    case 201: /* where_opt */
++    case 203: /* having_opt */
++    case 215: /* on_opt */
++    case 225: /* case_operand */
++    case 227: /* case_else */
++    case 236: /* when_clause */
++    case 241: /* key_opt */
+ {
+-sqlite3ExprDelete(pParse->db, (yypminor->yy132));
++sqlite3ExprDelete(pParse->db, (yypminor->yy72));
+ }
+       break;
+-    case 217: /* using_opt */
+-    case 219: /* idlist */
+-    case 223: /* inscollist_opt */
++    case 216: /* using_opt */
++    case 217: /* idlist */
++    case 220: /* idlist_opt */
+ {
+-sqlite3IdListDelete(pParse->db, (yypminor->yy408));
++sqlite3IdListDelete(pParse->db, (yypminor->yy254));
+ }
+       break;
+-    case 234: /* trigger_cmd_list */
+-    case 239: /* trigger_cmd */
++    case 232: /* trigger_cmd_list */
++    case 237: /* trigger_cmd */
+ {
+-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy473));
++sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy145));
+ }
+       break;
+-    case 236: /* trigger_event */
++    case 234: /* trigger_event */
+ {
+-sqlite3IdListDelete(pParse->db, (yypminor->yy378).b);
++sqlite3IdListDelete(pParse->db, (yypminor->yy332).b);
+ }
+       break;
++/********* End destructor definitions *****************************************/
+     default:  break;   /* If no destructor action specified: do nothing */
+   }
+ }
+@@ -124777,55 +141473,53 @@
+ **
+ ** If there is a destructor routine associated with the token which
+ ** is popped from the stack, then call it.
+-**
+-** Return the major token number for the symbol popped.
+ */
+-static int yy_pop_parser_stack(yyParser *pParser){
+-  YYCODETYPE yymajor;
+-  yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
+-
+-  /* There is no mechanism by which the parser stack can be popped below
+-  ** empty in SQLite.  */
+-  if( NEVER(pParser->yyidx<0) ) return 0;
++static void yy_pop_parser_stack(yyParser *pParser){
++  yyStackEntry *yytos;
++  assert( pParser->yytos!=0 );
++  assert( pParser->yytos > pParser->yystack );
++  yytos = pParser->yytos--;
+ #ifndef NDEBUG
+-  if( yyTraceFILE && pParser->yyidx>=0 ){
++  if( yyTraceFILE ){
+     fprintf(yyTraceFILE,"%sPopping %s\n",
+       yyTracePrompt,
+       yyTokenName[yytos->major]);
+   }
+ #endif
+-  yymajor = yytos->major;
+-  yy_destructor(pParser, yymajor, &yytos->minor);
+-  pParser->yyidx--;
+-  return yymajor;
++  yy_destructor(pParser, yytos->major, &yytos->minor);
++}
++
++/*
++** Clear all secondary memory allocations from the parser
++*/
++SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){
++  yyParser *pParser = (yyParser*)p;
++  while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser);
++#if YYSTACKDEPTH<=0
++  if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack);
 +#endif
-+#if SQLITE_ZERO_MALLOC
-+  "ZERO_MALLOC"
+ }
+ 
++#ifndef sqlite3Parser_ENGINEALWAYSONSTACK
+ /* 
+-** Deallocate and destroy a parser.  Destructors are all called for
++** Deallocate and destroy a parser.  Destructors are called for
+ ** all stack elements before shutting the parser down.
+ **
+-** Inputs:
+-** <ul>
+-** <li>  A pointer to the parser.  This should be a pointer
+-**       obtained from sqlite3ParserAlloc.
+-** <li>  A pointer to a function used to reclaim memory obtained
+-**       from malloc.
+-** </ul>
++** If the YYPARSEFREENEVERNULL macro exists (for example because it
++** is defined in a %include section of the input grammar) then it is
++** assumed that the input pointer is never NULL.
+ */
+ SQLITE_PRIVATE void sqlite3ParserFree(
+   void *p,                    /* The parser to be deleted */
+   void (*freeProc)(void*)     /* Function used to reclaim memory */
+ ){
+-  yyParser *pParser = (yyParser*)p;
+-  /* In SQLite, we never try to destroy a parser that was not successfully
+-  ** created in the first place. */
+-  if( NEVER(pParser==0) ) return;
+-  while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
+-#if YYSTACKDEPTH<=0
+-  free(pParser->yystack);
++#ifndef YYPARSEFREENEVERNULL
++  if( p==0 ) return;
+ #endif
+-  (*freeProc)((void*)pParser);
++  sqlite3ParserFinalize(p);
++  (*freeProc)(p);
+ }
++#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */
+ 
+ /*
+ ** Return the peak depth of the stack for a parser.
+@@ -124833,33 +141527,28 @@
+ #ifdef YYTRACKMAXSTACKDEPTH
+ SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){
+   yyParser *pParser = (yyParser*)p;
+-  return pParser->yyidxMax;
++  return pParser->yyhwm;
+ }
+ #endif
+ 
+ /*
+ ** Find the appropriate action for a parser given the terminal
+ ** look-ahead token iLookAhead.
+-**
+-** If the look-ahead token is YYNOCODE, then check to see if the action is
+-** independent of the look-ahead.  If it is, return the action, otherwise
+-** return YY_NO_ACTION.
+ */
+-static int yy_find_shift_action(
++static unsigned int yy_find_shift_action(
+   yyParser *pParser,        /* The parser */
+   YYCODETYPE iLookAhead     /* The look-ahead token */
+ ){
+   int i;
+-  int stateno = pParser->yystack[pParser->yyidx].stateno;
++  int stateno = pParser->yytos->stateno;
+  
+-  if( stateno>YY_SHIFT_COUNT
+-   || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
+-    return yy_default[stateno];
+-  }
+-  assert( iLookAhead!=YYNOCODE );
+-  i += iLookAhead;
+-  if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
+-    if( iLookAhead>0 ){
++  if( stateno>=YY_MIN_REDUCE ) return stateno;
++  assert( stateno <= YY_SHIFT_COUNT );
++  do{
++    i = yy_shift_ofst[stateno];
++    assert( iLookAhead!=YYNOCODE );
++    i += iLookAhead;
++    if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
+ #ifdef YYFALLBACK
+       YYCODETYPE iFallback;            /* Fallback token */
+       if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
+@@ -124870,7 +141559,9 @@
+              yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
+         }
+ #endif
+-        return yy_find_shift_action(pParser, iFallback);
++        assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
++        iLookAhead = iFallback;
++        continue;
+       }
+ #endif
+ #ifdef YYWILDCARD
+@@ -124883,32 +141574,29 @@
+ #if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
+           j<YY_ACTTAB_COUNT &&
+ #endif
+-          yy_lookahead[j]==YYWILDCARD
++          yy_lookahead[j]==YYWILDCARD && iLookAhead>0
+         ){
+ #ifndef NDEBUG
+           if( yyTraceFILE ){
+             fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
+-               yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
++               yyTracePrompt, yyTokenName[iLookAhead],
++               yyTokenName[YYWILDCARD]);
+           }
+ #endif /* NDEBUG */
+           return yy_action[j];
+         }
+       }
+ #endif /* YYWILDCARD */
++      return yy_default[stateno];
++    }else{
++      return yy_action[i];
+     }
+-    return yy_default[stateno];
+-  }else{
+-    return yy_action[i];
+-  }
++  }while(1);
+ }
+ 
+ /*
+ ** Find the appropriate action for a parser given the non-terminal
+ ** look-ahead token iLookAhead.
+-**
+-** If the look-ahead token is YYNOCODE, then check to see if the action is
+-** independent of the look-ahead.  If it is, return the action, otherwise
+-** return YY_NO_ACTION.
+ */
+ static int yy_find_reduce_action(
+   int stateno,              /* Current state number */
+@@ -124940,403 +141628,421 @@
+ /*
+ ** The following routine is called if the stack overflows.
+ */
+-static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
++static void yyStackOverflow(yyParser *yypParser){
+    sqlite3ParserARG_FETCH;
+-   yypParser->yyidx--;
+ #ifndef NDEBUG
+    if( yyTraceFILE ){
+      fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
+    }
+ #endif
+-   while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
++   while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
+    /* Here code is inserted which will execute if the parser
+    ** stack every overflows */
++/******** Begin %stack_overflow code ******************************************/
+ 
+-  UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */
+   sqlite3ErrorMsg(pParse, "parser stack overflow");
++/******** End %stack_overflow code ********************************************/
+    sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
+ }
+ 
+ /*
++** Print tracing information for a SHIFT action
++*/
++#ifndef NDEBUG
++static void yyTraceShift(yyParser *yypParser, int yyNewState){
++  if( yyTraceFILE ){
++    if( yyNewState<YYNSTATE ){
++      fprintf(yyTraceFILE,"%sShift '%s', go to state %d\n",
++         yyTracePrompt,yyTokenName[yypParser->yytos->major],
++         yyNewState);
++    }else{
++      fprintf(yyTraceFILE,"%sShift '%s'\n",
++         yyTracePrompt,yyTokenName[yypParser->yytos->major]);
++    }
++  }
++}
++#else
++# define yyTraceShift(X,Y)
 +#endif
-+};
 +
 +/*
-+** Given the name of a compile-time option, return true if that option
-+** was used and false if not.
-+**
-+** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
-+** is not required for a match.
-+*/
-+SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){
-+  int i, n;
-+
-+#if SQLITE_ENABLE_API_ARMOR
-+  if( zOptName==0 ){
-+    (void)SQLITE_MISUSE_BKPT;
-+    return 0;
+ ** Perform a shift action.
+ */
+ static void yy_shift(
+   yyParser *yypParser,          /* The parser to be shifted */
+   int yyNewState,               /* The new state to shift in */
+   int yyMajor,                  /* The major token to shift in */
+-  YYMINORTYPE *yypMinor         /* Pointer to the minor token to shift in */
++  sqlite3ParserTOKENTYPE yyMinor        /* The minor token to shift in */
+ ){
+   yyStackEntry *yytos;
+-  yypParser->yyidx++;
++  yypParser->yytos++;
+ #ifdef YYTRACKMAXSTACKDEPTH
+-  if( yypParser->yyidx>yypParser->yyidxMax ){
+-    yypParser->yyidxMax = yypParser->yyidx;
++  if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
++    yypParser->yyhwm++;
++    assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) );
+   }
+ #endif
+ #if YYSTACKDEPTH>0 
+-  if( yypParser->yyidx>=YYSTACKDEPTH ){
+-    yyStackOverflow(yypParser, yypMinor);
++  if( yypParser->yytos>yypParser->yystackEnd ){
++    yypParser->yytos--;
++    yyStackOverflow(yypParser);
+     return;
+   }
+ #else
+-  if( yypParser->yyidx>=yypParser->yystksz ){
+-    yyGrowStack(yypParser);
+-    if( yypParser->yyidx>=yypParser->yystksz ){
+-      yyStackOverflow(yypParser, yypMinor);
++  if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){
++    if( yyGrowStack(yypParser) ){
++      yypParser->yytos--;
++      yyStackOverflow(yypParser);
+       return;
+     }
+   }
+ #endif
+-  yytos = &yypParser->yystack[yypParser->yyidx];
++  if( yyNewState > YY_MAX_SHIFT ){
++    yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
 +  }
++  yytos = yypParser->yytos;
+   yytos->stateno = (YYACTIONTYPE)yyNewState;
+   yytos->major = (YYCODETYPE)yyMajor;
+-  yytos->minor = *yypMinor;
+-#ifndef NDEBUG
+-  if( yyTraceFILE && yypParser->yyidx>0 ){
+-    int i;
+-    fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
+-    fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
+-    for(i=1; i<=yypParser->yyidx; i++)
+-      fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
+-    fprintf(yyTraceFILE,"\n");
+-  }
+-#endif
++  yytos->minor.yy0 = yyMinor;
++  yyTraceShift(yypParser, yyNewState);
+ }
+ 
+ /* The following table contains information about every rule that
+ ** is used during the reduce.
+ */
+ static const struct {
+-  YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
+-  unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
++  YYCODETYPE lhs;       /* Symbol on the left-hand side of the rule */
++  signed char nrhs;     /* Negative of the number of RHS symbols in the rule */
+ } yyRuleInfo[] = {
+-  { 144, 1 },
+-  { 145, 2 },
+-  { 145, 1 },
+-  { 146, 1 },
+-  { 146, 3 },
+-  { 147, 0 },
+-  { 147, 1 },
+-  { 147, 3 },
+-  { 148, 1 },
+-  { 149, 3 },
+-  { 151, 0 },
+-  { 151, 1 },
+-  { 151, 2 },
++  { 147, -1 },
++  { 147, -3 },
++  { 148, -1 },
++  { 149, -3 },
+   { 150, 0 },
+-  { 150, 1 },
+-  { 150, 1 },
+-  { 150, 1 },
+-  { 149, 2 },
+-  { 149, 2 },
+-  { 149, 2 },
+-  { 153, 1 },
+-  { 153, 0 },
+-  { 149, 2 },
+-  { 149, 3 },
+-  { 149, 5 },
+-  { 149, 2 },
+-  { 154, 6 },
+-  { 156, 1 },
++  { 150, -1 },
++  { 150, -1 },
++  { 150, -1 },
++  { 149, -2 },
++  { 149, -2 },
++  { 149, -2 },
++  { 149, -3 },
++  { 149, -5 },
++  { 154, -6 },
++  { 156, -1 },
+   { 158, 0 },
+-  { 158, 3 },
+-  { 157, 1 },
++  { 158, -3 },
++  { 157, -1 },
+   { 157, 0 },
+-  { 155, 5 },
+-  { 155, 2 },
++  { 155, -5 },
++  { 155, -2 },
+   { 162, 0 },
+-  { 162, 2 },
+-  { 160, 3 },
+-  { 160, 1 },
+-  { 164, 3 },
+-  { 165, 1 },
+-  { 152, 1 },
+-  { 152, 1 },
+-  { 152, 1 },
++  { 162, -2 },
++  { 164, -2 },
+   { 166, 0 },
+-  { 166, 1 },
+-  { 168, 1 },
+-  { 168, 4 },
+-  { 168, 6 },
+-  { 169, 1 },
+-  { 169, 2 },
+-  { 170, 1 },
+-  { 170, 1 },
+-  { 167, 2 },
+-  { 167, 0 },
+-  { 173, 2 },
+-  { 173, 2 },
+-  { 173, 4 },
+-  { 173, 3 },
+-  { 173, 3 },
+-  { 173, 2 },
+-  { 173, 2 },
+-  { 173, 3 },
+-  { 173, 5 },
+-  { 173, 2 },
+-  { 173, 4 },
+-  { 173, 4 },
+-  { 173, 1 },
+-  { 173, 2 },
++  { 166, -4 },
++  { 166, -6 },
++  { 167, -2 },
++  { 171, -2 },
++  { 171, -2 },
++  { 171, -4 },
++  { 171, -3 },
++  { 171, -3 },
++  { 171, -2 },
++  { 171, -3 },
++  { 171, -5 },
++  { 171, -2 },
++  { 171, -4 },
++  { 171, -4 },
++  { 171, -1 },
++  { 171, -2 },
++  { 176, 0 },
++  { 176, -1 },
+   { 178, 0 },
+-  { 178, 1 },
+-  { 180, 0 },
+-  { 180, 2 },
+-  { 182, 2 },
+-  { 182, 3 },
+-  { 182, 3 },
+-  { 182, 3 },
+-  { 183, 2 },
+-  { 183, 2 },
+-  { 183, 1 },
+-  { 183, 1 },
+-  { 183, 2 },
+-  { 181, 3 },
+-  { 181, 2 },
+-  { 184, 0 },
+-  { 184, 2 },
+-  { 184, 2 },
++  { 178, -2 },
++  { 180, -2 },
++  { 180, -3 },
++  { 180, -3 },
++  { 180, -3 },
++  { 181, -2 },
++  { 181, -2 },
++  { 181, -1 },
++  { 181, -1 },
++  { 181, -2 },
++  { 179, -3 },
++  { 179, -2 },
++  { 182, 0 },
++  { 182, -2 },
++  { 182, -2 },
+   { 161, 0 },
+-  { 161, 2 },
+-  { 185, 3 },
+-  { 185, 1 },
+-  { 186, 1 },
+-  { 186, 0 },
+-  { 187, 2 },
+-  { 187, 7 },
+-  { 187, 5 },
+-  { 187, 5 },
+-  { 187, 10 },
++  { 184, -1 },
++  { 185, -2 },
++  { 185, -7 },
++  { 185, -5 },
++  { 185, -5 },
++  { 185, -10 },
++  { 188, 0 },
++  { 174, 0 },
++  { 174, -3 },
+   { 189, 0 },
+-  { 189, 1 },
+-  { 176, 0 },
+-  { 176, 3 },
+-  { 190, 0 },
+-  { 190, 2 },
+-  { 191, 1 },
+-  { 191, 1 },
+-  { 191, 1 },
+-  { 149, 4 },
+-  { 193, 2 },
+-  { 193, 0 },
+-  { 149, 8 },
+-  { 149, 4 },
+-  { 149, 1 },
+-  { 163, 2 },
+-  { 195, 1 },
+-  { 195, 3 },
+-  { 198, 1 },
+-  { 198, 2 },
+-  { 198, 1 },
+-  { 196, 9 },
+-  { 196, 1 },
+-  { 207, 4 },
+-  { 207, 5 },
+-  { 199, 1 },
+-  { 199, 1 },
+-  { 199, 0 },
+-  { 210, 2 },
++  { 189, -2 },
++  { 190, -1 },
++  { 190, -1 },
++  { 149, -4 },
++  { 192, -2 },
++  { 192, 0 },
++  { 149, -9 },
++  { 149, -4 },
++  { 149, -1 },
++  { 163, -2 },
++  { 194, -3 },
++  { 197, -1 },
++  { 197, -2 },
++  { 197, -1 },
++  { 195, -9 },
++  { 206, -4 },
++  { 206, -5 },
++  { 198, -1 },
++  { 198, -1 },
++  { 198, 0 },
++  { 209, 0 },
++  { 199, -3 },
++  { 199, -2 },
++  { 199, -4 },
++  { 210, -2 },
+   { 210, 0 },
+-  { 200, 3 },
+-  { 200, 2 },
+-  { 200, 4 },
+-  { 211, 2 },
+-  { 211, 1 },
+-  { 211, 0 },
+-  { 201, 0 },
+-  { 201, 2 },
+-  { 213, 2 },
+-  { 213, 0 },
+-  { 212, 7 },
+-  { 212, 7 },
+-  { 212, 7 },
++  { 200, 0 },
++  { 200, -2 },
++  { 212, -2 },
++  { 212, 0 },
++  { 211, -7 },
++  { 211, -9 },
++  { 211, -7 },
++  { 211, -7 },
+   { 159, 0 },
+-  { 159, 2 },
+-  { 194, 2 },
+-  { 214, 1 },
+-  { 214, 2 },
+-  { 214, 3 },
+-  { 214, 4 },
+-  { 216, 2 },
+-  { 216, 0 },
++  { 159, -2 },
++  { 193, -2 },
++  { 213, -1 },
++  { 213, -2 },
++  { 213, -3 },
++  { 213, -4 },
++  { 215, -2 },
+   { 215, 0 },
+-  { 215, 3 },
+-  { 215, 2 },
+-  { 217, 4 },
+-  { 217, 0 },
+-  { 205, 0 },
+-  { 205, 3 },
+-  { 220, 4 },
+-  { 220, 2 },
+-  { 177, 1 },
+-  { 177, 1 },
+-  { 177, 0 },
+-  { 203, 0 },
+-  { 203, 3 },
++  { 214, 0 },
++  { 214, -3 },
++  { 214, -2 },
++  { 216, -4 },
++  { 216, 0 },
+   { 204, 0 },
+-  { 204, 2 },
+-  { 206, 0 },
+-  { 206, 2 },
+-  { 206, 4 },
+-  { 206, 4 },
+-  { 149, 6 },
++  { 204, -3 },
++  { 186, -4 },
++  { 186, -2 },
++  { 175, -1 },
++  { 175, -1 },
++  { 175, 0 },
+   { 202, 0 },
+-  { 202, 2 },
+-  { 149, 8 },
+-  { 221, 5 },
+-  { 221, 3 },
+-  { 149, 6 },
+-  { 149, 7 },
+-  { 222, 2 },
+-  { 222, 1 },
+-  { 223, 0 },
+-  { 223, 3 },
+-  { 219, 3 },
+-  { 219, 1 },
+-  { 175, 1 },
+-  { 175, 3 },
+-  { 174, 1 },
+-  { 175, 1 },
+-  { 175, 1 },
+-  { 175, 3 },
+-  { 175, 5 },
+-  { 174, 1 },
+-  { 174, 1 },
+-  { 175, 1 },
+-  { 175, 3 },
+-  { 175, 6 },
+-  { 175, 5 },
+-  { 175, 4 },
+-  { 174, 1 },
+-  { 175, 3 },
+-  { 175, 3 },
+-  { 175, 3 },
+-  { 175, 3 },
+-  { 175, 3 },
+-  { 175, 3 },
+-  { 175, 3 },
+-  { 175, 3 },
+-  { 224, 1 },
+-  { 224, 2 },
+-  { 175, 3 },
+-  { 175, 5 },
+-  { 175, 2 },
+-  { 175, 3 },
+-  { 175, 3 },
+-  { 175, 4 },
+-  { 175, 2 },
+-  { 175, 2 },
+-  { 175, 2 },
+-  { 175, 2 },
+-  { 225, 1 },
+-  { 225, 2 },
+-  { 175, 5 },
+-  { 226, 1 },
+-  { 226, 2 },
+-  { 175, 5 },
+-  { 175, 3 },
+-  { 175, 5 },
+-  { 175, 4 },
+-  { 175, 4 },
+-  { 175, 5 },
+-  { 228, 5 },
+-  { 228, 4 },
+-  { 229, 2 },
+-  { 229, 0 },
+-  { 227, 1 },
++  { 202, -3 },
++  { 203, 0 },
++  { 203, -2 },
++  { 205, 0 },
++  { 205, -2 },
++  { 205, -4 },
++  { 205, -4 },
++  { 149, -6 },
++  { 201, 0 },
++  { 201, -2 },
++  { 149, -8 },
++  { 218, -5 },
++  { 218, -7 },
++  { 218, -3 },
++  { 218, -5 },
++  { 149, -6 },
++  { 149, -7 },
++  { 219, -2 },
++  { 219, -1 },
++  { 220, 0 },
++  { 220, -3 },
++  { 217, -3 },
++  { 217, -1 },
++  { 173, -3 },
++  { 173, -1 },
++  { 173, -1 },
++  { 173, -3 },
++  { 173, -5 },
++  { 172, -1 },
++  { 172, -1 },
++  { 172, -1 },
++  { 173, -1 },
++  { 173, -3 },
++  { 173, -6 },
++  { 173, -5 },
++  { 173, -4 },
++  { 172, -1 },
++  { 173, -5 },
++  { 173, -3 },
++  { 173, -3 },
++  { 173, -3 },
++  { 173, -3 },
++  { 173, -3 },
++  { 173, -3 },
++  { 173, -3 },
++  { 173, -3 },
++  { 221, -2 },
++  { 173, -3 },
++  { 173, -5 },
++  { 173, -2 },
++  { 173, -3 },
++  { 173, -3 },
++  { 173, -4 },
++  { 173, -2 },
++  { 173, -2 },
++  { 173, -2 },
++  { 173, -2 },
++  { 222, -1 },
++  { 222, -2 },
++  { 173, -5 },
++  { 223, -1 },
++  { 223, -2 },
++  { 173, -5 },
++  { 173, -3 },
++  { 173, -5 },
++  { 173, -5 },
++  { 173, -4 },
++  { 173, -5 },
++  { 226, -5 },
++  { 226, -4 },
++  { 227, -2 },
+   { 227, 0 },
+-  { 209, 1 },
+-  { 209, 0 },
+-  { 208, 3 },
+-  { 208, 1 },
+-  { 149, 12 },
+-  { 230, 1 },
+-  { 230, 0 },
+-  { 179, 0 },
+-  { 179, 3 },
+-  { 188, 5 },
+-  { 188, 3 },
+-  { 231, 0 },
+-  { 231, 2 },
+-  { 149, 4 },
+-  { 149, 1 },
+-  { 149, 2 },
+-  { 149, 3 },
+-  { 149, 5 },
+-  { 149, 6 },
+-  { 149, 5 },
+-  { 149, 6 },
+-  { 232, 1 },
+-  { 232, 1 },
+-  { 232, 1 },
+-  { 232, 1 },
+-  { 232, 1 },
+-  { 171, 2 },
+-  { 171, 1 },
+-  { 172, 2 },
+-  { 149, 5 },
+-  { 233, 11 },
+-  { 235, 1 },
+-  { 235, 1 },
+-  { 235, 2 },
+-  { 235, 0 },
+-  { 236, 1 },
+-  { 236, 1 },
+-  { 236, 3 },
+-  { 237, 0 },
+-  { 237, 3 },
+-  { 238, 0 },
+-  { 238, 2 },
+-  { 234, 3 },
+-  { 234, 2 },
+-  { 240, 1 },
+-  { 240, 3 },
++  { 225, -1 },
++  { 225, 0 },
++  { 208, 0 },
++  { 207, -3 },
++  { 207, -1 },
++  { 224, 0 },
++  { 224, -3 },
++  { 149, -12 },
++  { 228, -1 },
++  { 228, 0 },
++  { 177, 0 },
++  { 177, -3 },
++  { 187, -5 },
++  { 187, -3 },
++  { 229, 0 },
++  { 229, -2 },
++  { 149, -4 },
++  { 149, -1 },
++  { 149, -2 },
++  { 149, -3 },
++  { 149, -5 },
++  { 149, -6 },
++  { 149, -5 },
++  { 149, -6 },
++  { 169, -2 },
++  { 170, -2 },
++  { 149, -5 },
++  { 231, -11 },
++  { 233, -1 },
++  { 233, -2 },
++  { 233, 0 },
++  { 234, -1 },
++  { 234, -1 },
++  { 234, -3 },
++  { 236, 0 },
++  { 236, -2 },
++  { 232, -3 },
++  { 232, -2 },
++  { 238, -3 },
++  { 239, -3 },
++  { 239, -2 },
++  { 237, -7 },
++  { 237, -5 },
++  { 237, -5 },
++  { 237, -1 },
++  { 173, -4 },
++  { 173, -6 },
++  { 191, -1 },
++  { 191, -1 },
++  { 191, -1 },
++  { 149, -4 },
++  { 149, -6 },
++  { 149, -3 },
+   { 241, 0 },
+-  { 241, 3 },
+-  { 241, 2 },
+-  { 239, 7 },
+-  { 239, 5 },
+-  { 239, 5 },
+-  { 239, 1 },
+-  { 175, 4 },
+-  { 175, 6 },
+-  { 192, 1 },
+-  { 192, 1 },
+-  { 192, 1 },
+-  { 149, 4 },
+-  { 149, 6 },
+-  { 149, 3 },
++  { 241, -2 },
++  { 149, -1 },
++  { 149, -3 },
++  { 149, -1 },
++  { 149, -3 },
++  { 149, -6 },
++  { 149, -7 },
++  { 242, -1 },
++  { 149, -1 },
++  { 149, -4 },
++  { 244, -8 },
++  { 246, 0 },
++  { 247, -1 },
++  { 247, -3 },
++  { 248, -1 },
++  { 196, 0 },
++  { 196, -2 },
++  { 196, -3 },
++  { 250, -6 },
++  { 250, -8 },
++  { 144, -1 },
++  { 145, -2 },
++  { 145, -1 },
++  { 146, -1 },
++  { 146, -3 },
++  { 147, 0 },
++  { 151, 0 },
++  { 151, -1 },
++  { 151, -2 },
++  { 153, -1 },
++  { 153, 0 },
++  { 149, -2 },
++  { 160, -4 },
++  { 160, -2 },
++  { 152, -1 },
++  { 152, -1 },
++  { 152, -1 },
++  { 166, -1 },
++  { 167, -1 },
++  { 168, -1 },
++  { 168, -1 },
++  { 165, -2 },
++  { 165, 0 },
++  { 171, -2 },
++  { 161, -2 },
++  { 183, -3 },
++  { 183, -1 },
++  { 184, 0 },
++  { 188, -1 },
++  { 190, -1 },
++  { 194, -1 },
++  { 195, -1 },
++  { 209, -2 },
++  { 210, -1 },
++  { 173, -1 },
++  { 221, -1 },
++  { 208, -1 },
++  { 230, -1 },
++  { 230, -1 },
++  { 230, -1 },
++  { 230, -1 },
++  { 230, -1 },
++  { 169, -1 },
++  { 235, 0 },
++  { 235, -3 },
++  { 238, -1 },
++  { 239, 0 },
++  { 240, -1 },
++  { 240, 0 },
+   { 243, 0 },
+-  { 243, 2 },
+-  { 242, 1 },
+-  { 242, 0 },
+-  { 149, 1 },
+-  { 149, 3 },
+-  { 149, 1 },
+-  { 149, 3 },
+-  { 149, 6 },
+-  { 149, 6 },
+-  { 244, 1 },
+-  { 245, 0 },
+-  { 245, 1 },
+-  { 149, 1 },
+-  { 149, 4 },
+-  { 246, 8 },
+-  { 247, 1 },
+-  { 247, 3 },
+-  { 248, 0 },
+-  { 248, 2 },
+-  { 249, 1 },
+-  { 249, 3 },
+-  { 250, 1 },
+-  { 251, 0 },
+-  { 251, 4 },
+-  { 251, 2 },
+-  { 197, 0 },
+-  { 197, 2 },
+-  { 197, 3 },
+-  { 252, 6 },
+-  { 252, 8 },
++  { 243, -1 },
++  { 245, -1 },
++  { 245, -3 },
++  { 246, -2 },
++  { 249, 0 },
++  { 249, -4 },
++  { 249, -2 },
+ };
+ 
+ static void yy_accept(yyParser*);  /* Forward Declaration */
+@@ -125347,40 +142053,47 @@
+ */
+ static void yy_reduce(
+   yyParser *yypParser,         /* The parser */
+-  int yyruleno                 /* Number of the rule by which to reduce */
++  unsigned int yyruleno        /* Number of the rule by which to reduce */
+ ){
+   int yygoto;                     /* The next state */
+   int yyact;                      /* The next action */
+-  YYMINORTYPE yygotominor;        /* The LHS of the rule reduced */
+   yyStackEntry *yymsp;            /* The top of the parser's stack */
+   int yysize;                     /* Amount to pop the stack */
+   sqlite3ParserARG_FETCH;
+-  yymsp = &yypParser->yystack[yypParser->yyidx];
++  yymsp = yypParser->yytos;
+ #ifndef NDEBUG
+-  if( yyTraceFILE && yyruleno>=0 
+-        && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
+-    fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
+-      yyRuleName[yyruleno]);
++  if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
++    yysize = yyRuleInfo[yyruleno].nrhs;
++    fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt,
++      yyRuleName[yyruleno], yymsp[yysize].stateno);
+   }
+ #endif /* NDEBUG */
+ 
+-  /* Silence complaints from purify about yygotominor being uninitialized
+-  ** in some cases when it is copied into the stack after the following
+-  ** switch.  yygotominor is uninitialized when a rule reduces that does
+-  ** not set the value of its left-hand side nonterminal.  Leaving the
+-  ** value of the nonterminal uninitialized is utterly harmless as long
+-  ** as the value is never used.  So really the only thing this code
+-  ** accomplishes is to quieten purify.  
+-  **
+-  ** 2007-01-16:  The wireshark project (www.wireshark.org) reports that
+-  ** without this code, their parser segfaults.  I'm not sure what there
+-  ** parser is doing to make this happen.  This is the second bug report
+-  ** from wireshark this week.  Clearly they are stressing Lemon in ways
+-  ** that it has not been previously stressed...  (SQLite ticket #2172)
+-  */
+-  /*memset(&yygotominor, 0, sizeof(yygotominor));*/
+-  yygotominor = yyzerominor;
+-
++  /* Check that the stack is large enough to grow by a single entry
++  ** if the RHS of the rule is empty.  This ensures that there is room
++  ** enough on the stack to push the LHS value */
++  if( yyRuleInfo[yyruleno].nrhs==0 ){
++#ifdef YYTRACKMAXSTACKDEPTH
++    if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
++      yypParser->yyhwm++;
++      assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack));
++    }
 +#endif
-+  if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
-+  n = sqlite3Strlen30(zOptName);
-+
-+  /* Since ArraySize(azCompileOpt) is normally in single digits, a
-+  ** linear search is adequate.  No need for a binary search. */
-+  for(i=0; i<ArraySize(azCompileOpt); i++){
-+    if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
-+     && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
-+    ){
-+      return 1;
++#if YYSTACKDEPTH>0 
++    if( yypParser->yytos>=yypParser->yystackEnd ){
++      yyStackOverflow(yypParser);
++      return;
 +    }
++#else
++    if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
++      if( yyGrowStack(yypParser) ){
++        yyStackOverflow(yypParser);
++        return;
++      }
++      yymsp = yypParser->yytos;
++    }
++#endif
 +  }
-+  return 0;
+ 
+   switch( yyruleno ){
+   /* Beginning here are the reduction cases.  A typical example
+@@ -125391,326 +142104,286 @@
+   **  #line <lineno> <thisfile>
+   **     break;
+   */
+-      case 5: /* explain ::= */
+-{ sqlite3BeginParse(pParse, 0); }
+-        break;
+-      case 6: /* explain ::= EXPLAIN */
+-{ sqlite3BeginParse(pParse, 1); }
++/********** Begin reduce actions **********************************************/
++        YYMINORTYPE yylhsminor;
++      case 0: /* explain ::= EXPLAIN */
++{ pParse->explain = 1; }
+         break;
+-      case 7: /* explain ::= EXPLAIN QUERY PLAN */
+-{ sqlite3BeginParse(pParse, 2); }
++      case 1: /* explain ::= EXPLAIN QUERY PLAN */
++{ pParse->explain = 2; }
+         break;
+-      case 8: /* cmdx ::= cmd */
++      case 2: /* cmdx ::= cmd */
+ { sqlite3FinishCoding(pParse); }
+         break;
+-      case 9: /* cmd ::= BEGIN transtype trans_opt */
+-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy328);}
++      case 3: /* cmd ::= BEGIN transtype trans_opt */
++{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy194);}
+         break;
+-      case 13: /* transtype ::= */
+-{yygotominor.yy328 = TK_DEFERRED;}
++      case 4: /* transtype ::= */
++{yymsp[1].minor.yy194 = TK_DEFERRED;}
+         break;
+-      case 14: /* transtype ::= DEFERRED */
+-      case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
+-      case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
+-      case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115);
+-      case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117);
+-{yygotominor.yy328 = yymsp[0].major;}
+-        break;
+-      case 17: /* cmd ::= COMMIT trans_opt */
+-      case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18);
+-{sqlite3CommitTransaction(pParse);}
++      case 5: /* transtype ::= DEFERRED */
++      case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
++      case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
++{yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-X*/}
++        break;
++      case 8: /* cmd ::= COMMIT|END trans_opt */
++      case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
++{sqlite3EndTransaction(pParse,yymsp[-1].major);}
+         break;
+-      case 19: /* cmd ::= ROLLBACK trans_opt */
+-{sqlite3RollbackTransaction(pParse);}
+-        break;
+-      case 22: /* cmd ::= SAVEPOINT nm */
++      case 10: /* cmd ::= SAVEPOINT nm */
+ {
+   sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0);
+ }
+         break;
+-      case 23: /* cmd ::= RELEASE savepoint_opt nm */
++      case 11: /* cmd ::= RELEASE savepoint_opt nm */
+ {
+   sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0);
+ }
+         break;
+-      case 24: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
++      case 12: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+ {
+   sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
+ }
+         break;
+-      case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
++      case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+ {
+-   
sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy328,0,0,yymsp[-2].minor.yy328);
++   
sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy194,0,0,yymsp[-2].minor.yy194);
+ }
+         break;
+-      case 27: /* createkw ::= CREATE */
+-{
+-  pParse->db->lookaside.bEnabled = 0;
+-  yygotominor.yy0 = yymsp[0].minor.yy0;
+-}
++      case 14: /* createkw ::= CREATE */
++{disableLookaside(pParse);}
+         break;
+-      case 28: /* ifnotexists ::= */
+-      case 31: /* temp ::= */ yytestcase(yyruleno==31);
+-      case 68: /* autoinc ::= */ yytestcase(yyruleno==68);
+-      case 81: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==81);
+-      case 83: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==83);
+-      case 85: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==85);
+-      case 97: /* defer_subclause_opt ::= */ yytestcase(yyruleno==97);
+-      case 108: /* ifexists ::= */ yytestcase(yyruleno==108);
+-      case 218: /* between_op ::= BETWEEN */ yytestcase(yyruleno==218);
+-      case 221: /* in_op ::= IN */ yytestcase(yyruleno==221);
+-{yygotominor.yy328 = 0;}
+-        break;
+-      case 29: /* ifnotexists ::= IF NOT EXISTS */
+-      case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
+-      case 69: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==69);
+-      case 84: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==84);
+-      case 107: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==107);
+-      case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219);
+-      case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222);
+-{yygotominor.yy328 = 1;}
++      case 15: /* ifnotexists ::= */
++      case 18: /* temp ::= */ yytestcase(yyruleno==18);
++      case 21: /* table_options ::= */ yytestcase(yyruleno==21);
++      case 41: /* autoinc ::= */ yytestcase(yyruleno==41);
++      case 56: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==56);
++      case 66: /* defer_subclause_opt ::= */ yytestcase(yyruleno==66);
++      case 75: /* ifexists ::= */ yytestcase(yyruleno==75);
++      case 89: /* distinct ::= */ yytestcase(yyruleno==89);
++      case 212: /* collate ::= */ yytestcase(yyruleno==212);
++{yymsp[1].minor.yy194 = 0;}
++        break;
++      case 16: /* ifnotexists ::= IF NOT EXISTS */
++{yymsp[-2].minor.yy194 = 1;}
++        break;
++      case 17: /* temp ::= TEMP */
++      case 42: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==42);
++{yymsp[0].minor.yy194 = 1;}
+         break;
+-      case 32: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
++      case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
+ {
+-  sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy186,0);
++  sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy194,0);
+ }
+         break;
+-      case 33: /* create_table_args ::= AS select */
++      case 20: /* create_table_args ::= AS select */
+ {
+-  sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy3);
+-  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
++  sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy243);
++  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243);
+ }
+         break;
+-      case 34: /* table_options ::= */
+-{yygotominor.yy186 = 0;}
+-        break;
+-      case 35: /* table_options ::= WITHOUT nm */
++      case 22: /* table_options ::= WITHOUT nm */
+ {
+   if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
+-    yygotominor.yy186 = TF_WithoutRowid;
++    yymsp[-1].minor.yy194 = TF_WithoutRowid | TF_NoVisibleRowid;
+   }else{
+-    yygotominor.yy186 = 0;
++    yymsp[-1].minor.yy194 = 0;
+     sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
+   }
+ }
+         break;
+-      case 38: /* column ::= columnid type carglist */
+-{
+-  yygotominor.yy0.z = yymsp[-2].minor.yy0.z;
+-  yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
+-}
+-        break;
+-      case 39: /* columnid ::= nm */
+-{
+-  sqlite3AddColumn(pParse,&yymsp[0].minor.yy0);
+-  yygotominor.yy0 = yymsp[0].minor.yy0;
+-  pParse->constraintName.n = 0;
+-}
+-        break;
+-      case 40: /* nm ::= ID|INDEXED */
+-      case 41: /* nm ::= STRING */ yytestcase(yyruleno==41);
+-      case 42: /* nm ::= JOIN_KW */ yytestcase(yyruleno==42);
+-      case 45: /* typetoken ::= typename */ yytestcase(yyruleno==45);
+-      case 48: /* typename ::= ID|STRING */ yytestcase(yyruleno==48);
+-      case 130: /* as ::= AS nm */ yytestcase(yyruleno==130);
+-      case 131: /* as ::= ID|STRING */ yytestcase(yyruleno==131);
+-      case 141: /* dbnm ::= DOT nm */ yytestcase(yyruleno==141);
+-      case 150: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==150);
+-      case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247);
+-      case 256: /* nmnum ::= plus_num */ yytestcase(yyruleno==256);
+-      case 257: /* nmnum ::= nm */ yytestcase(yyruleno==257);
+-      case 258: /* nmnum ::= ON */ yytestcase(yyruleno==258);
+-      case 259: /* nmnum ::= DELETE */ yytestcase(yyruleno==259);
+-      case 260: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==260);
+-      case 261: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==261);
+-      case 262: /* plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==262);
+-      case 263: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==263);
+-      case 279: /* trnm ::= nm */ yytestcase(yyruleno==279);
+-{yygotominor.yy0 = yymsp[0].minor.yy0;}
++      case 23: /* columnname ::= nm typetoken */
++{sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
+         break;
+-      case 44: /* type ::= typetoken */
+-{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
++      case 24: /* typetoken ::= */
++      case 59: /* conslist_opt ::= */ yytestcase(yyruleno==59);
++      case 95: /* as ::= */ yytestcase(yyruleno==95);
++{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
+         break;
+-      case 46: /* typetoken ::= typename LP signed RP */
++      case 25: /* typetoken ::= typename LP signed RP */
+ {
+-  yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
+-  yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
++  yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
+ }
+         break;
+-      case 47: /* typetoken ::= typename LP signed COMMA signed RP */
++      case 26: /* typetoken ::= typename LP signed COMMA signed RP */
+ {
+-  yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
+-  yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
++  yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
+ }
+         break;
+-      case 49: /* typename ::= typename ID|STRING */
+-{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; 
yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
++      case 27: /* typename ::= typename ID|STRING */
++{yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
+         break;
+-      case 54: /* ccons ::= CONSTRAINT nm */
+-      case 92: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==92);
++      case 28: /* ccons ::= CONSTRAINT nm */
++      case 61: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==61);
+ {pParse->constraintName = yymsp[0].minor.yy0;}
+         break;
+-      case 55: /* ccons ::= DEFAULT term */
+-      case 57: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==57);
+-{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy346);}
++      case 29: /* ccons ::= DEFAULT term */
++      case 31: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==31);
++{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy190);}
+         break;
+-      case 56: /* ccons ::= DEFAULT LP expr RP */
+-{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy346);}
++      case 30: /* ccons ::= DEFAULT LP expr RP */
++{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy190);}
+         break;
+-      case 58: /* ccons ::= DEFAULT MINUS term */
++      case 32: /* ccons ::= DEFAULT MINUS term */
+ {
+   ExprSpan v;
+-  v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy346.pExpr, 0, 0);
++  v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy190.pExpr, 0);
+   v.zStart = yymsp[-1].minor.yy0.z;
+-  v.zEnd = yymsp[0].minor.yy346.zEnd;
++  v.zEnd = yymsp[0].minor.yy190.zEnd;
+   sqlite3AddDefaultValue(pParse,&v);
+ }
+         break;
+-      case 59: /* ccons ::= DEFAULT ID|INDEXED */
++      case 33: /* ccons ::= DEFAULT ID|INDEXED */
+ {
+   ExprSpan v;
+-  spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0);
++  spanExpr(&v, pParse, TK_STRING, yymsp[0].minor.yy0);
+   sqlite3AddDefaultValue(pParse,&v);
+ }
+         break;
+-      case 61: /* ccons ::= NOT NULL onconf */
+-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy328);}
++      case 34: /* ccons ::= NOT NULL onconf */
++{sqlite3AddNotNull(pParse, yymsp[0].minor.yy194);}
+         break;
+-      case 62: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy328,yymsp[0].minor.yy328,yymsp[-2].minor.yy328);}
++      case 35: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
++{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy194,yymsp[0].minor.yy194,yymsp[-2].minor.yy194);}
+         break;
+-      case 63: /* ccons ::= UNIQUE onconf */
+-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy328,0,0,0,0);}
++      case 36: /* ccons ::= UNIQUE onconf */
++{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy194,0,0,0,0,
++                                   SQLITE_IDXTYPE_UNIQUE);}
+         break;
+-      case 64: /* ccons ::= CHECK LP expr RP */
+-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy346.pExpr);}
++      case 37: /* ccons ::= CHECK LP expr RP */
++{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy190.pExpr);}
+         break;
+-      case 65: /* ccons ::= REFERENCES nm idxlist_opt refargs */
+-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy328);}
++      case 38: /* ccons ::= REFERENCES nm eidlist_opt refargs */
++{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy148,yymsp[0].minor.yy194);}
+         break;
+-      case 66: /* ccons ::= defer_subclause */
+-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy328);}
++      case 39: /* ccons ::= defer_subclause */
++{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy194);}
+         break;
+-      case 67: /* ccons ::= COLLATE ID|STRING */
++      case 40: /* ccons ::= COLLATE ID|STRING */
+ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
+         break;
+-      case 70: /* refargs ::= */
+-{ yygotominor.yy328 = OE_None*0x0101; /* EV: R-19803-45884 */}
++      case 43: /* refargs ::= */
++{ yymsp[1].minor.yy194 = OE_None*0x0101; /* EV: R-19803-45884 */}
++        break;
++      case 44: /* refargs ::= refargs refarg */
++{ yymsp[-1].minor.yy194 = (yymsp[-1].minor.yy194 & ~yymsp[0].minor.yy497.mask) | 
yymsp[0].minor.yy497.value; }
+         break;
+-      case 71: /* refargs ::= refargs refarg */
+-{ yygotominor.yy328 = (yymsp[-1].minor.yy328 & ~yymsp[0].minor.yy429.mask) | yymsp[0].minor.yy429.value; }
++      case 45: /* refarg ::= MATCH nm */
++{ yymsp[-1].minor.yy497.value = 0;     yymsp[-1].minor.yy497.mask = 0x000000; }
+         break;
+-      case 72: /* refarg ::= MATCH nm */
+-      case 73: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==73);
+-{ yygotominor.yy429.value = 0;     yygotominor.yy429.mask = 0x000000; }
++      case 46: /* refarg ::= ON INSERT refact */
++{ yymsp[-2].minor.yy497.value = 0;     yymsp[-2].minor.yy497.mask = 0x000000; }
+         break;
+-      case 74: /* refarg ::= ON DELETE refact */
+-{ yygotominor.yy429.value = yymsp[0].minor.yy328;     yygotominor.yy429.mask = 0x0000ff; }
++      case 47: /* refarg ::= ON DELETE refact */
++{ yymsp[-2].minor.yy497.value = yymsp[0].minor.yy194;     yymsp[-2].minor.yy497.mask = 0x0000ff; }
+         break;
+-      case 75: /* refarg ::= ON UPDATE refact */
+-{ yygotominor.yy429.value = yymsp[0].minor.yy328<<8;  yygotominor.yy429.mask = 0x00ff00; }
++      case 48: /* refarg ::= ON UPDATE refact */
++{ yymsp[-2].minor.yy497.value = yymsp[0].minor.yy194<<8;  yymsp[-2].minor.yy497.mask = 0x00ff00; }
+         break;
+-      case 76: /* refact ::= SET NULL */
+-{ yygotominor.yy328 = OE_SetNull;  /* EV: R-33326-45252 */}
++      case 49: /* refact ::= SET NULL */
++{ yymsp[-1].minor.yy194 = OE_SetNull;  /* EV: R-33326-45252 */}
+         break;
+-      case 77: /* refact ::= SET DEFAULT */
+-{ yygotominor.yy328 = OE_SetDflt;  /* EV: R-33326-45252 */}
++      case 50: /* refact ::= SET DEFAULT */
++{ yymsp[-1].minor.yy194 = OE_SetDflt;  /* EV: R-33326-45252 */}
+         break;
+-      case 78: /* refact ::= CASCADE */
+-{ yygotominor.yy328 = OE_Cascade;  /* EV: R-33326-45252 */}
++      case 51: /* refact ::= CASCADE */
++{ yymsp[0].minor.yy194 = OE_Cascade;  /* EV: R-33326-45252 */}
+         break;
+-      case 79: /* refact ::= RESTRICT */
+-{ yygotominor.yy328 = OE_Restrict; /* EV: R-33326-45252 */}
++      case 52: /* refact ::= RESTRICT */
++{ yymsp[0].minor.yy194 = OE_Restrict; /* EV: R-33326-45252 */}
+         break;
+-      case 80: /* refact ::= NO ACTION */
+-{ yygotominor.yy328 = OE_None;     /* EV: R-33326-45252 */}
++      case 53: /* refact ::= NO ACTION */
++{ yymsp[-1].minor.yy194 = OE_None;     /* EV: R-33326-45252 */}
+         break;
+-      case 82: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+-      case 98: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==98);
+-      case 100: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==100);
+-      case 103: /* resolvetype ::= raisetype */ yytestcase(yyruleno==103);
+-{yygotominor.yy328 = yymsp[0].minor.yy328;}
++      case 54: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
++{yymsp[-2].minor.yy194 = 0;}
+         break;
+-      case 86: /* conslist_opt ::= */
+-{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
++      case 55: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
++      case 70: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==70);
++      case 143: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==143);
++{yymsp[-1].minor.yy194 = yymsp[0].minor.yy194;}
+         break;
+-      case 87: /* conslist_opt ::= COMMA conslist */
+-{yygotominor.yy0 = yymsp[-1].minor.yy0;}
++      case 57: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
++      case 74: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==74);
++      case 184: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==184);
++      case 187: /* in_op ::= NOT IN */ yytestcase(yyruleno==187);
++      case 213: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==213);
++{yymsp[-1].minor.yy194 = 1;}
+         break;
+-      case 90: /* tconscomma ::= COMMA */
++      case 58: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
++{yymsp[-1].minor.yy194 = 0;}
++        break;
++      case 60: /* tconscomma ::= COMMA */
+ {pParse->constraintName.n = 0;}
+         break;
+-      case 93: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
+-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy328,yymsp[-2].minor.yy328,0);}
++      case 62: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
++{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy148,yymsp[0].minor.yy194,yymsp[-2].minor.yy194,0);}
+         break;
+-      case 94: /* tcons ::= UNIQUE LP idxlist RP onconf */
+-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy328,0,0,0,0);}
++      case 63: /* tcons ::= UNIQUE LP sortlist RP onconf */
++{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy148,yymsp[0].minor.yy194,0,0,0,0,
++                                       SQLITE_IDXTYPE_UNIQUE);}
+         break;
+-      case 95: /* tcons ::= CHECK LP expr RP onconf */
+-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy346.pExpr);}
++      case 64: /* tcons ::= CHECK LP expr RP onconf */
++{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy190.pExpr);}
+         break;
+-      case 96: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt 
*/
++      case 65: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt 
*/
+ {
+-    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, 
yymsp[-1].minor.yy328);
+-    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy328);
++    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy148, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, 
yymsp[-1].minor.yy194);
++    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy194);
+ }
+         break;
+-      case 99: /* onconf ::= */
+-{yygotominor.yy328 = OE_Default;}
+-        break;
+-      case 101: /* orconf ::= */
+-{yygotominor.yy186 = OE_Default;}
++      case 67: /* onconf ::= */
++      case 69: /* orconf ::= */ yytestcase(yyruleno==69);
++{yymsp[1].minor.yy194 = OE_Default;}
+         break;
+-      case 102: /* orconf ::= OR resolvetype */
+-{yygotominor.yy186 = (u8)yymsp[0].minor.yy328;}
++      case 68: /* onconf ::= ON CONFLICT resolvetype */
++{yymsp[-2].minor.yy194 = yymsp[0].minor.yy194;}
+         break;
+-      case 104: /* resolvetype ::= IGNORE */
+-{yygotominor.yy328 = OE_Ignore;}
++      case 71: /* resolvetype ::= IGNORE */
++{yymsp[0].minor.yy194 = OE_Ignore;}
+         break;
+-      case 105: /* resolvetype ::= REPLACE */
+-{yygotominor.yy328 = OE_Replace;}
++      case 72: /* resolvetype ::= REPLACE */
++      case 144: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==144);
++{yymsp[0].minor.yy194 = OE_Replace;}
+         break;
+-      case 106: /* cmd ::= DROP TABLE ifexists fullname */
++      case 73: /* cmd ::= DROP TABLE ifexists fullname */
+ {
+-  sqlite3DropTable(pParse, yymsp[0].minor.yy65, 0, yymsp[-1].minor.yy328);
++  sqlite3DropTable(pParse, yymsp[0].minor.yy185, 0, yymsp[-1].minor.yy194);
+ }
+         break;
+-      case 109: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
++      case 76: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ {
+-  sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, 
yymsp[0].minor.yy3, yymsp[-6].minor.yy328, yymsp[-4].minor.yy328);
++  sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, 
yymsp[-2].minor.yy148, yymsp[0].minor.yy243, yymsp[-7].minor.yy194, yymsp[-5].minor.yy194);
+ }
+         break;
+-      case 110: /* cmd ::= DROP VIEW ifexists fullname */
++      case 77: /* cmd ::= DROP VIEW ifexists fullname */
+ {
+-  sqlite3DropTable(pParse, yymsp[0].minor.yy65, 1, yymsp[-1].minor.yy328);
++  sqlite3DropTable(pParse, yymsp[0].minor.yy185, 1, yymsp[-1].minor.yy194);
+ }
+         break;
+-      case 111: /* cmd ::= select */
++      case 78: /* cmd ::= select */
+ {
+   SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
+-  sqlite3Select(pParse, yymsp[0].minor.yy3, &dest);
+-  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
++  sqlite3Select(pParse, yymsp[0].minor.yy243, &dest);
++  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243);
+ }
+         break;
+-      case 112: /* select ::= with selectnowith */
++      case 79: /* select ::= with selectnowith */
+ {
+-  Select *p = yymsp[0].minor.yy3;
++  Select *p = yymsp[0].minor.yy243;
+   if( p ){
+-    p->pWith = yymsp[-1].minor.yy59;
++    p->pWith = yymsp[-1].minor.yy285;
+     parserDoubleLinkSelect(pParse, p);
+   }else{
+-    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59);
++    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy285);
+   }
+-  yygotominor.yy3 = p;
++  yymsp[-1].minor.yy243 = p; /*A-overwrites-W*/
+ }
+         break;
+-      case 113: /* selectnowith ::= oneselect */
+-      case 119: /* oneselect ::= values */ yytestcase(yyruleno==119);
+-{yygotominor.yy3 = yymsp[0].minor.yy3;}
+-        break;
+-      case 114: /* selectnowith ::= selectnowith multiselect_op oneselect */
++      case 80: /* selectnowith ::= selectnowith multiselect_op oneselect */
+ {
+-  Select *pRhs = yymsp[0].minor.yy3;
++  Select *pRhs = yymsp[0].minor.yy243;
++  Select *pLhs = yymsp[-2].minor.yy243;
+   if( pRhs && pRhs->pPrior ){
+     SrcList *pFrom;
+     Token x;
+@@ -125720,22 +142393,30 @@
+     pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
+   }
+   if( pRhs ){
+-    pRhs->op = (u8)yymsp[-1].minor.yy328;
+-    pRhs->pPrior = yymsp[-2].minor.yy3;
++    pRhs->op = (u8)yymsp[-1].minor.yy194;
++    pRhs->pPrior = pLhs;
++    if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
+     pRhs->selFlags &= ~SF_MultiValue;
+-    if( yymsp[-1].minor.yy328!=TK_ALL ) pParse->hasCompound = 1;
++    if( yymsp[-1].minor.yy194!=TK_ALL ) pParse->hasCompound = 1;
+   }else{
+-    sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy3);
++    sqlite3SelectDelete(pParse->db, pLhs);
+   }
+-  yygotominor.yy3 = pRhs;
++  yymsp[-2].minor.yy243 = pRhs;
+ }
+         break;
+-      case 116: /* multiselect_op ::= UNION ALL */
+-{yygotominor.yy328 = TK_ALL;}
++      case 81: /* multiselect_op ::= UNION */
++      case 83: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==83);
++{yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-OP*/}
++        break;
++      case 82: /* multiselect_op ::= UNION ALL */
++{yymsp[-1].minor.yy194 = TK_ALL;}
+         break;
+-      case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt 
orderby_opt limit_opt */
++      case 84: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt 
orderby_opt limit_opt */
+ {
+-  yygotominor.yy3 = 
sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy65,yymsp[-4].minor.yy132,yymsp[-3].minor.yy14,yymsp[-2].minor.yy132,yymsp[-1].minor.yy14,yymsp[-7].minor.yy381,yymsp[0].minor.yy476.pLimit,yymsp[0].minor.yy476.pOffset);
++#if SELECTTRACE_ENABLED
++  Token s = yymsp[-8].minor.yy0; /*A-overwrites-S*/
++#endif
++  yymsp[-8].minor.yy243 = 
sqlite3SelectNew(pParse,yymsp[-6].minor.yy148,yymsp[-5].minor.yy185,yymsp[-4].minor.yy72,yymsp[-3].minor.yy148,yymsp[-2].minor.yy72,yymsp[-1].minor.yy148,yymsp[-7].minor.yy194,yymsp[0].minor.yy354.pLimit,yymsp[0].minor.yy354.pOffset);
+ #if SELECTTRACE_ENABLED
+   /* Populate the Select.zSelName[] string that is used to help with
+   ** query planner debugging, to differentiate between multiple Select
+@@ -125746,445 +142427,483 @@
+   ** comment to be the zSelName value.  Otherwise, the label is #N where
+   ** is an integer that is incremented with each SELECT statement seen.
+   */
+-  if( yygotominor.yy3!=0 ){
+-    const char *z = yymsp[-8].minor.yy0.z+6;
++  if( yymsp[-8].minor.yy243!=0 ){
++    const char *z = s.z+6;
+     int i;
+-    sqlite3_snprintf(sizeof(yygotominor.yy3->zSelName), yygotominor.yy3->zSelName, "#%d",
++    sqlite3_snprintf(sizeof(yymsp[-8].minor.yy243->zSelName), yymsp[-8].minor.yy243->zSelName, "#%d",
+                      ++pParse->nSelect);
+     while( z[0]==' ' ) z++;
+     if( z[0]=='/' && z[1]=='*' ){
+       z += 2;
+       while( z[0]==' ' ) z++;
+       for(i=0; sqlite3Isalnum(z[i]); i++){}
+-      sqlite3_snprintf(sizeof(yygotominor.yy3->zSelName), yygotominor.yy3->zSelName, "%.*s", i, z);
++      sqlite3_snprintf(sizeof(yymsp[-8].minor.yy243->zSelName), yymsp[-8].minor.yy243->zSelName, "%.*s", i, 
z);
+     }
+   }
+ #endif /* SELECTRACE_ENABLED */
+ }
+         break;
+-      case 120: /* values ::= VALUES LP nexprlist RP */
++      case 85: /* values ::= VALUES LP nexprlist RP */
+ {
+-  yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
++  yymsp[-3].minor.yy243 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy148,0,0,0,0,0,SF_Values,0,0);
+ }
+         break;
+-      case 121: /* values ::= values COMMA LP exprlist RP */
++      case 86: /* values ::= values COMMA LP exprlist RP */
+ {
+-  Select *pRight, *pLeft = yymsp[-4].minor.yy3;
+-  pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
++  Select *pRight, *pLeft = yymsp[-4].minor.yy243;
++  pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy148,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
+   if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
+   if( pRight ){
+     pRight->op = TK_ALL;
+-    pLeft = yymsp[-4].minor.yy3;
+     pRight->pPrior = pLeft;
+-    yygotominor.yy3 = pRight;
++    yymsp[-4].minor.yy243 = pRight;
+   }else{
+-    yygotominor.yy3 = pLeft;
++    yymsp[-4].minor.yy243 = pLeft;
+   }
+ }
+         break;
+-      case 122: /* distinct ::= DISTINCT */
+-{yygotominor.yy381 = SF_Distinct;}
++      case 87: /* distinct ::= DISTINCT */
++{yymsp[0].minor.yy194 = SF_Distinct;}
+         break;
+-      case 123: /* distinct ::= ALL */
+-      case 124: /* distinct ::= */ yytestcase(yyruleno==124);
+-{yygotominor.yy381 = 0;}
++      case 88: /* distinct ::= ALL */
++{yymsp[0].minor.yy194 = SF_All;}
+         break;
+-      case 125: /* sclp ::= selcollist COMMA */
+-      case 243: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==243);
+-{yygotominor.yy14 = yymsp[-1].minor.yy14;}
++      case 90: /* sclp ::= */
++      case 118: /* orderby_opt ::= */ yytestcase(yyruleno==118);
++      case 125: /* groupby_opt ::= */ yytestcase(yyruleno==125);
++      case 200: /* exprlist ::= */ yytestcase(yyruleno==200);
++      case 203: /* paren_exprlist ::= */ yytestcase(yyruleno==203);
++      case 208: /* eidlist_opt ::= */ yytestcase(yyruleno==208);
++{yymsp[1].minor.yy148 = 0;}
+         break;
+-      case 126: /* sclp ::= */
+-      case 154: /* orderby_opt ::= */ yytestcase(yyruleno==154);
+-      case 161: /* groupby_opt ::= */ yytestcase(yyruleno==161);
+-      case 236: /* exprlist ::= */ yytestcase(yyruleno==236);
+-      case 242: /* idxlist_opt ::= */ yytestcase(yyruleno==242);
+-{yygotominor.yy14 = 0;}
+-        break;
+-      case 127: /* selcollist ::= sclp expr as */
++      case 91: /* selcollist ::= sclp expr as */
+ {
+-   yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, yymsp[-1].minor.yy346.pExpr);
+-   if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[0].minor.yy0, 1);
+-   sqlite3ExprListSetSpan(pParse,yygotominor.yy14,&yymsp[-1].minor.yy346);
++   yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy148, 
yymsp[-1].minor.yy190.pExpr);
++   if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-2].minor.yy148, &yymsp[0].minor.yy0, 
1);
++   sqlite3ExprListSetSpan(pParse,yymsp[-2].minor.yy148,&yymsp[-1].minor.yy190);
+ }
+         break;
+-      case 128: /* selcollist ::= sclp STAR */
++      case 92: /* selcollist ::= sclp STAR */
+ {
+-  Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0);
+-  yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy14, p);
++  Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
++  yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p);
+ }
+         break;
+-      case 129: /* selcollist ::= sclp nm DOT STAR */
++      case 93: /* selcollist ::= sclp nm DOT STAR */
+ {
+-  Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
+-  Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
+-  Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
+-  yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, pDot);
+-}
++  Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
++  Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
++  Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
++  yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot);
++}
++        break;
++      case 94: /* as ::= AS nm */
++      case 105: /* dbnm ::= DOT nm */ yytestcase(yyruleno==105);
++      case 222: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==222);
++      case 223: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==223);
++{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
+         break;
+-      case 132: /* as ::= */
+-{yygotominor.yy0.n = 0;}
++      case 96: /* from ::= */
++{yymsp[1].minor.yy185 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy185));}
+         break;
+-      case 133: /* from ::= */
+-{yygotominor.yy65 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy65));}
+-        break;
+-      case 134: /* from ::= FROM seltablist */
++      case 97: /* from ::= FROM seltablist */
+ {
+-  yygotominor.yy65 = yymsp[0].minor.yy65;
+-  sqlite3SrcListShiftJoinType(yygotominor.yy65);
++  yymsp[-1].minor.yy185 = yymsp[0].minor.yy185;
++  sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy185);
+ }
+         break;
+-      case 135: /* stl_prefix ::= seltablist joinop */
++      case 98: /* stl_prefix ::= seltablist joinop */
+ {
+-   yygotominor.yy65 = yymsp[-1].minor.yy65;
+-   if( ALWAYS(yygotominor.yy65 && yygotominor.yy65->nSrc>0) ) 
yygotominor.yy65->a[yygotominor.yy65->nSrc-1].jointype = (u8)yymsp[0].minor.yy328;
++   if( ALWAYS(yymsp[-1].minor.yy185 && yymsp[-1].minor.yy185->nSrc>0) ) 
yymsp[-1].minor.yy185->a[yymsp[-1].minor.yy185->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy194;
+ }
+         break;
+-      case 136: /* stl_prefix ::= */
+-{yygotominor.yy65 = 0;}
++      case 99: /* stl_prefix ::= */
++{yymsp[1].minor.yy185 = 0;}
++        break;
++      case 100: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
++{
++  yymsp[-6].minor.yy185 = 
sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
++  sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy185, &yymsp[-2].minor.yy0);
++}
+         break;
+-      case 137: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
++      case 101: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ {
+-  yygotominor.yy65 = 
sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
+-  sqlite3SrcListIndexedBy(pParse, yygotominor.yy65, &yymsp[-2].minor.yy0);
++  yymsp[-8].minor.yy185 = 
sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy185,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
++  sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy185, yymsp[-4].minor.yy148);
+ }
+         break;
+-      case 138: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
++      case 102: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ {
+-    yygotominor.yy65 = 
sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy3,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
++    yymsp[-6].minor.yy185 = 
sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy243,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
+   }
+         break;
+-      case 139: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
++      case 103: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ {
+-    if( yymsp[-6].minor.yy65==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy132==0 && 
yymsp[0].minor.yy408==0 ){
+-      yygotominor.yy65 = yymsp[-4].minor.yy65;
+-    }else if( yymsp[-4].minor.yy65->nSrc==1 ){
+-      yygotominor.yy65 = 
sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
+-      if( yygotominor.yy65 ){
+-        struct SrcList_item *pNew = &yygotominor.yy65->a[yygotominor.yy65->nSrc-1];
+-        struct SrcList_item *pOld = yymsp[-4].minor.yy65->a;
++    if( yymsp[-6].minor.yy185==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy72==0 && 
yymsp[0].minor.yy254==0 ){
++      yymsp[-6].minor.yy185 = yymsp[-4].minor.yy185;
++    }else if( yymsp[-4].minor.yy185->nSrc==1 ){
++      yymsp[-6].minor.yy185 = 
sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
++      if( yymsp[-6].minor.yy185 ){
++        struct SrcList_item *pNew = &yymsp[-6].minor.yy185->a[yymsp[-6].minor.yy185->nSrc-1];
++        struct SrcList_item *pOld = yymsp[-4].minor.yy185->a;
+         pNew->zName = pOld->zName;
+         pNew->zDatabase = pOld->zDatabase;
+         pNew->pSelect = pOld->pSelect;
+         pOld->zName = pOld->zDatabase = 0;
+         pOld->pSelect = 0;
+       }
+-      sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy65);
++      sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy185);
+     }else{
+       Select *pSubquery;
+-      sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy65);
+-      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy65,0,0,0,0,SF_NestedFrom,0,0);
+-      yygotominor.yy65 = 
sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
++      sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy185);
++      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy185,0,0,0,0,SF_NestedFrom,0,0);
++      yymsp[-6].minor.yy185 = 
sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
+     }
+   }
+         break;
+-      case 140: /* dbnm ::= */
+-      case 149: /* indexed_opt ::= */ yytestcase(yyruleno==149);
+-{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
++      case 104: /* dbnm ::= */
++      case 113: /* indexed_opt ::= */ yytestcase(yyruleno==113);
++{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
+         break;
+-      case 142: /* fullname ::= nm dbnm */
+-{yygotominor.yy65 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
++      case 106: /* fullname ::= nm dbnm */
++{yymsp[-1].minor.yy185 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); 
/*A-overwrites-X*/}
+         break;
+-      case 143: /* joinop ::= COMMA|JOIN */
+-{ yygotominor.yy328 = JT_INNER; }
++      case 107: /* joinop ::= COMMA|JOIN */
++{ yymsp[0].minor.yy194 = JT_INNER; }
+         break;
+-      case 144: /* joinop ::= JOIN_KW JOIN */
+-{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
++      case 108: /* joinop ::= JOIN_KW JOIN */
++{yymsp[-1].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0);  /*X-overwrites-A*/}
+         break;
+-      case 145: /* joinop ::= JOIN_KW nm JOIN */
+-{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
++      case 109: /* joinop ::= JOIN_KW nm JOIN */
++{yymsp[-2].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); 
/*X-overwrites-A*/}
+         break;
+-      case 146: /* joinop ::= JOIN_KW nm nm JOIN */
+-{ yygotominor.yy328 = 
sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
++      case 110: /* joinop ::= JOIN_KW nm nm JOIN */
++{yymsp[-3].minor.yy194 = 
sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
+         break;
+-      case 147: /* on_opt ::= ON expr */
+-      case 164: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==164);
+-      case 171: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==171);
+-      case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231);
+-      case 233: /* case_operand ::= expr */ yytestcase(yyruleno==233);
+-{yygotominor.yy132 = yymsp[0].minor.yy346.pExpr;}
++      case 111: /* on_opt ::= ON expr */
++      case 128: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==128);
++      case 135: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==135);
++      case 196: /* case_else ::= ELSE expr */ yytestcase(yyruleno==196);
++{yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr;}
+         break;
+-      case 148: /* on_opt ::= */
+-      case 163: /* having_opt ::= */ yytestcase(yyruleno==163);
+-      case 170: /* where_opt ::= */ yytestcase(yyruleno==170);
+-      case 232: /* case_else ::= */ yytestcase(yyruleno==232);
+-      case 234: /* case_operand ::= */ yytestcase(yyruleno==234);
+-{yygotominor.yy132 = 0;}
++      case 112: /* on_opt ::= */
++      case 127: /* having_opt ::= */ yytestcase(yyruleno==127);
++      case 134: /* where_opt ::= */ yytestcase(yyruleno==134);
++      case 197: /* case_else ::= */ yytestcase(yyruleno==197);
++      case 199: /* case_operand ::= */ yytestcase(yyruleno==199);
++{yymsp[1].minor.yy72 = 0;}
+         break;
+-      case 151: /* indexed_opt ::= NOT INDEXED */
+-{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
++      case 114: /* indexed_opt ::= INDEXED BY nm */
++{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
+         break;
+-      case 152: /* using_opt ::= USING LP idlist RP */
+-      case 180: /* inscollist_opt ::= LP idlist RP */ yytestcase(yyruleno==180);
+-{yygotominor.yy408 = yymsp[-1].minor.yy408;}
++      case 115: /* indexed_opt ::= NOT INDEXED */
++{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
+         break;
+-      case 153: /* using_opt ::= */
+-      case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179);
+-{yygotominor.yy408 = 0;}
++      case 116: /* using_opt ::= USING LP idlist RP */
++{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;}
+         break;
+-      case 155: /* orderby_opt ::= ORDER BY sortlist */
+-      case 162: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==162);
+-      case 235: /* exprlist ::= nexprlist */ yytestcase(yyruleno==235);
+-{yygotominor.yy14 = yymsp[0].minor.yy14;}
++      case 117: /* using_opt ::= */
++      case 145: /* idlist_opt ::= */ yytestcase(yyruleno==145);
++{yymsp[1].minor.yy254 = 0;}
+         break;
+-      case 156: /* sortlist ::= sortlist COMMA expr sortorder */
++      case 119: /* orderby_opt ::= ORDER BY sortlist */
++      case 126: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==126);
++{yymsp[-2].minor.yy148 = yymsp[0].minor.yy148;}
++        break;
++      case 120: /* sortlist ::= sortlist COMMA expr sortorder */
+ {
+-  yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14,yymsp[-1].minor.yy346.pExpr);
+-  if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = 
(u8)yymsp[0].minor.yy328;
++  yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148,yymsp[-1].minor.yy190.pExpr);
++  sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy148,yymsp[0].minor.yy194);
+ }
+         break;
+-      case 157: /* sortlist ::= expr sortorder */
++      case 121: /* sortlist ::= expr sortorder */
+ {
+-  yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy346.pExpr);
+-  if( yygotominor.yy14 && ALWAYS(yygotominor.yy14->a) ) yygotominor.yy14->a[0].sortOrder = 
(u8)yymsp[0].minor.yy328;
++  yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy190.pExpr); /*A-overwrites-Y*/
++  sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy148,yymsp[0].minor.yy194);
+ }
+         break;
+-      case 158: /* sortorder ::= ASC */
+-      case 160: /* sortorder ::= */ yytestcase(yyruleno==160);
+-{yygotominor.yy328 = SQLITE_SO_ASC;}
++      case 122: /* sortorder ::= ASC */
++{yymsp[0].minor.yy194 = SQLITE_SO_ASC;}
++        break;
++      case 123: /* sortorder ::= DESC */
++{yymsp[0].minor.yy194 = SQLITE_SO_DESC;}
+         break;
+-      case 159: /* sortorder ::= DESC */
+-{yygotominor.yy328 = SQLITE_SO_DESC;}
++      case 124: /* sortorder ::= */
++{yymsp[1].minor.yy194 = SQLITE_SO_UNDEFINED;}
+         break;
+-      case 165: /* limit_opt ::= */
+-{yygotominor.yy476.pLimit = 0; yygotominor.yy476.pOffset = 0;}
++      case 129: /* limit_opt ::= */
++{yymsp[1].minor.yy354.pLimit = 0; yymsp[1].minor.yy354.pOffset = 0;}
+         break;
+-      case 166: /* limit_opt ::= LIMIT expr */
+-{yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr; yygotominor.yy476.pOffset = 0;}
++      case 130: /* limit_opt ::= LIMIT expr */
++{yymsp[-1].minor.yy354.pLimit = yymsp[0].minor.yy190.pExpr; yymsp[-1].minor.yy354.pOffset = 0;}
+         break;
+-      case 167: /* limit_opt ::= LIMIT expr OFFSET expr */
+-{yygotominor.yy476.pLimit = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pOffset = 
yymsp[0].minor.yy346.pExpr;}
++      case 131: /* limit_opt ::= LIMIT expr OFFSET expr */
++{yymsp[-3].minor.yy354.pLimit = yymsp[-2].minor.yy190.pExpr; yymsp[-3].minor.yy354.pOffset = 
yymsp[0].minor.yy190.pExpr;}
+         break;
+-      case 168: /* limit_opt ::= LIMIT expr COMMA expr */
+-{yygotominor.yy476.pOffset = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pLimit = 
yymsp[0].minor.yy346.pExpr;}
++      case 132: /* limit_opt ::= LIMIT expr COMMA expr */
++{yymsp[-3].minor.yy354.pOffset = yymsp[-2].minor.yy190.pExpr; yymsp[-3].minor.yy354.pLimit = 
yymsp[0].minor.yy190.pExpr;}
+         break;
+-      case 169: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */
++      case 133: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */
+ {
+-  sqlite3WithPush(pParse, yymsp[-5].minor.yy59, 1);
+-  sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy65, &yymsp[-1].minor.yy0);
+-  sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy65,yymsp[0].minor.yy132);
++  sqlite3WithPush(pParse, yymsp[-5].minor.yy285, 1);
++  sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy185, &yymsp[-1].minor.yy0);
++  sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy185,yymsp[0].minor.yy72);
+ }
+         break;
+-      case 172: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */
++      case 136: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */
+ {
+-  sqlite3WithPush(pParse, yymsp[-7].minor.yy59, 1);
+-  sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy65, &yymsp[-3].minor.yy0);
+-  sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy14,"set list"); 
+-  
sqlite3Update(pParse,yymsp[-4].minor.yy65,yymsp[-1].minor.yy14,yymsp[0].minor.yy132,yymsp[-5].minor.yy186);
++  sqlite3WithPush(pParse, yymsp[-7].minor.yy285, 1);
++  sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy185, &yymsp[-3].minor.yy0);
++  sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy148,"set list"); 
++  
sqlite3Update(pParse,yymsp[-4].minor.yy185,yymsp[-1].minor.yy148,yymsp[0].minor.yy72,yymsp[-5].minor.yy194);
+ }
+         break;
+-      case 173: /* setlist ::= setlist COMMA nm EQ expr */
++      case 137: /* setlist ::= setlist COMMA nm EQ expr */
+ {
+-  yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy346.pExpr);
+-  sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
++  yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
++  sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, 1);
+ }
+         break;
+-      case 174: /* setlist ::= nm EQ expr */
++      case 138: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
+ {
+-  yygotominor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy346.pExpr);
+-  sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
++  yymsp[-6].minor.yy148 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy148, yymsp[-3].minor.yy254, 
yymsp[0].minor.yy190.pExpr);
+ }
+         break;
+-      case 175: /* cmd ::= with insert_cmd INTO fullname inscollist_opt select */
++      case 139: /* setlist ::= nm EQ expr */
+ {
+-  sqlite3WithPush(pParse, yymsp[-5].minor.yy59, 1);
+-  sqlite3Insert(pParse, yymsp[-2].minor.yy65, yymsp[0].minor.yy3, yymsp[-1].minor.yy408, 
yymsp[-4].minor.yy186);
++  yylhsminor.yy148 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy190.pExpr);
++  sqlite3ExprListSetName(pParse, yylhsminor.yy148, &yymsp[-2].minor.yy0, 1);
+ }
++  yymsp[-2].minor.yy148 = yylhsminor.yy148;
+         break;
+-      case 176: /* cmd ::= with insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
++      case 140: /* setlist ::= LP idlist RP EQ expr */
+ {
+-  sqlite3WithPush(pParse, yymsp[-6].minor.yy59, 1);
+-  sqlite3Insert(pParse, yymsp[-3].minor.yy65, 0, yymsp[-2].minor.yy408, yymsp[-5].minor.yy186);
++  yymsp[-4].minor.yy148 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, 
yymsp[0].minor.yy190.pExpr);
+ }
+         break;
+-      case 177: /* insert_cmd ::= INSERT orconf */
+-{yygotominor.yy186 = yymsp[0].minor.yy186;}
++      case 141: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */
++{
++  sqlite3WithPush(pParse, yymsp[-5].minor.yy285, 1);
++  sqlite3Insert(pParse, yymsp[-2].minor.yy185, yymsp[0].minor.yy243, yymsp[-1].minor.yy254, 
yymsp[-4].minor.yy194);
 +}
-+
-+/*
-+** Return the N-th compile-time option string.  If N is out of range,
-+** return a NULL pointer.
-+*/
-+SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N){
-+  if( N>=0 && N<ArraySize(azCompileOpt) ){
-+    return azCompileOpt[N];
+         break;
+-      case 178: /* insert_cmd ::= REPLACE */
+-{yygotominor.yy186 = OE_Replace;}
++      case 142: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */
++{
++  sqlite3WithPush(pParse, yymsp[-6].minor.yy285, 1);
++  sqlite3Insert(pParse, yymsp[-3].minor.yy185, 0, yymsp[-2].minor.yy254, yymsp[-5].minor.yy194);
++}
+         break;
+-      case 181: /* idlist ::= idlist COMMA nm */
+-{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy408,&yymsp[0].minor.yy0);}
++      case 146: /* idlist_opt ::= LP idlist RP */
++{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;}
+         break;
+-      case 182: /* idlist ::= nm */
+-{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
++      case 147: /* idlist ::= idlist COMMA nm */
++{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
+         break;
+-      case 183: /* expr ::= term */
+-{yygotominor.yy346 = yymsp[0].minor.yy346;}
++      case 148: /* idlist ::= nm */
++{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
+         break;
+-      case 184: /* expr ::= LP expr RP */
+-{yygotominor.yy346.pExpr = yymsp[-1].minor.yy346.pExpr; 
spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
++      case 149: /* expr ::= LP expr RP */
++{spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/  
yymsp[-2].minor.yy190.pExpr = yymsp[-1].minor.yy190.pExpr;}
+         break;
+-      case 185: /* term ::= NULL */
+-      case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190);
+-      case 191: /* term ::= STRING */ yytestcase(yyruleno==191);
+-{spanExpr(&yygotominor.yy346, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
++      case 150: /* expr ::= ID|INDEXED */
++      case 151: /* expr ::= JOIN_KW */ yytestcase(yyruleno==151);
++{spanExpr(&yymsp[0].minor.yy190,pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+         break;
+-      case 186: /* expr ::= ID|INDEXED */
+-      case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187);
+-{spanExpr(&yygotominor.yy346, pParse, TK_ID, &yymsp[0].minor.yy0);}
++      case 152: /* expr ::= nm DOT nm */
++{
++  Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
++  Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
++  spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
++  yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
++}
+         break;
+-      case 188: /* expr ::= nm DOT nm */
++      case 153: /* expr ::= nm DOT nm DOT nm */
+ {
+-  Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
+-  Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
+-  yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
+-  spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
++  Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
++  Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
++  Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
++  Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
++  spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
++  yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
+ }
+         break;
+-      case 189: /* expr ::= nm DOT nm DOT nm */
++      case 154: /* term ::= NULL|FLOAT|BLOB */
++      case 155: /* term ::= STRING */ yytestcase(yyruleno==155);
++{spanExpr(&yymsp[0].minor.yy190,pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
++        break;
++      case 156: /* term ::= INTEGER */
+ {
+-  Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
+-  Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
+-  Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
+-  Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
+-  yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
+-  spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
++  yylhsminor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
++  yylhsminor.yy190.zStart = yymsp[0].minor.yy0.z;
++  yylhsminor.yy190.zEnd = yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n;
+ }
++  yymsp[0].minor.yy190 = yylhsminor.yy190;
+         break;
+-      case 192: /* expr ::= VARIABLE */
++      case 157: /* expr ::= VARIABLE */
+ {
+-  if( yymsp[0].minor.yy0.n>=2 && yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1]) ){
++  if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
++    u32 n = yymsp[0].minor.yy0.n;
++    spanExpr(&yymsp[0].minor.yy190, pParse, TK_VARIABLE, yymsp[0].minor.yy0);
++    sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr, n);
++  }else{
+     /* When doing a nested parse, one can include terms in an expression
+     ** that look like this:   #1 #2 ...  These terms refer to registers
+     ** in the virtual machine.  #N is the N-th register. */
++    Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
++    assert( t.n>=2 );
++    spanSet(&yymsp[0].minor.yy190, &t, &t);
+     if( pParse->nested==0 ){
+-      sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
+-      yygotominor.yy346.pExpr = 0;
++      sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
++      yymsp[0].minor.yy190.pExpr = 0;
+     }else{
+-      yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
+-      if( yygotominor.yy346.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], 
&yygotominor.yy346.pExpr->iTable);
++      yymsp[0].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
++      if( yymsp[0].minor.yy190.pExpr ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy190.pExpr->iTable);
+     }
+-  }else{
+-    spanExpr(&yygotominor.yy346, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
+-    sqlite3ExprAssignVarNumber(pParse, yygotominor.yy346.pExpr);
+   }
+-  spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+ }
+         break;
+-      case 193: /* expr ::= expr COLLATE ID|STRING */
++      case 158: /* expr ::= expr COLLATE ID|STRING */
+ {
+-  yygotominor.yy346.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy346.pExpr, 
&yymsp[0].minor.yy0, 1);
+-  yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart;
+-  yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
++  yymsp[-2].minor.yy190.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy190.pExpr, 
&yymsp[0].minor.yy0, 1);
++  yymsp[-2].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ }
+         break;
+-      case 194: /* expr ::= CAST LP expr AS typetoken RP */
++      case 159: /* expr ::= CAST LP expr AS typetoken RP */
+ {
+-  yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy346.pExpr, 0, 
&yymsp[-1].minor.yy0);
+-  spanSet(&yygotominor.yy346,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
++  spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
++  yymsp[-5].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
++  sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, 0);
+ }
+         break;
+-      case 195: /* expr ::= ID|INDEXED LP distinct exprlist RP */
++      case 160: /* expr ::= ID|INDEXED LP distinct exprlist RP */
+ {
+-  if( yymsp[-1].minor.yy14 && yymsp[-1].minor.yy14->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
++  if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
+     sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
+   }
+-  yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0);
+-  spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+-  if( yymsp[-2].minor.yy381 && yygotominor.yy346.pExpr ){
+-    yygotominor.yy346.pExpr->flags |= EP_Distinct;
++  yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0);
++  spanSet(&yylhsminor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
++  if( yymsp[-2].minor.yy194==SF_Distinct && yylhsminor.yy190.pExpr ){
++    yylhsminor.yy190.pExpr->flags |= EP_Distinct;
+   }
+ }
++  yymsp[-4].minor.yy190 = yylhsminor.yy190;
+         break;
+-      case 196: /* expr ::= ID|INDEXED LP STAR RP */
++      case 161: /* expr ::= ID|INDEXED LP STAR RP */
+ {
+-  yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
+-  spanSet(&yygotominor.yy346,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
++  yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
++  spanSet(&yylhsminor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+ }
++  yymsp[-3].minor.yy190 = yylhsminor.yy190;
+         break;
+-      case 197: /* term ::= CTIME_KW */
++      case 162: /* term ::= CTIME_KW */
+ {
+-  yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
+-  spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
++  yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
++  spanSet(&yylhsminor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+ }
++  yymsp[0].minor.yy190 = yylhsminor.yy190;
+         break;
+-      case 198: /* expr ::= expr AND expr */
+-      case 199: /* expr ::= expr OR expr */ yytestcase(yyruleno==199);
+-      case 200: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==200);
+-      case 201: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==201);
+-      case 202: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==202);
+-      case 203: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==203);
+-      case 204: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==204);
+-      case 205: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==205);
+-{spanBinaryExpr(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346);}
++      case 163: /* expr ::= LP nexprlist COMMA expr RP */
++{
++  ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy148, yymsp[-1].minor.yy190.pExpr);
++  yylhsminor.yy190.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
++  if( yylhsminor.yy190.pExpr ){
++    yylhsminor.yy190.pExpr->x.pList = pList;
++    spanSet(&yylhsminor.yy190, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
++  }else{
++    sqlite3ExprListDelete(pParse->db, pList);
 +  }
-+  return 0;
 +}
++  yymsp[-4].minor.yy190 = yylhsminor.yy190;
+         break;
+-      case 206: /* likeop ::= LIKE_KW|MATCH */
+-{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.bNot = 0;}
++      case 164: /* expr ::= expr AND expr */
++      case 165: /* expr ::= expr OR expr */ yytestcase(yyruleno==165);
++      case 166: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==166);
++      case 167: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==167);
++      case 168: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==168);
++      case 169: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==169);
++      case 170: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==170);
++      case 171: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==171);
++{spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);}
+         break;
+-      case 207: /* likeop ::= NOT LIKE_KW|MATCH */
+-{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.bNot = 1;}
++      case 172: /* likeop ::= NOT LIKE_KW|MATCH */
++{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; 
/*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
+         break;
+-      case 208: /* expr ::= expr likeop expr */
++      case 173: /* expr ::= expr likeop expr */
+ {
+   ExprList *pList;
+-  pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy346.pExpr);
+-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy346.pExpr);
+-  yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy96.eOperator);
+-  if( yymsp[-1].minor.yy96.bNot ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, 
yygotominor.yy346.pExpr, 0, 0);
+-  yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart;
+-  yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd;
+-  if( yygotominor.yy346.pExpr ) yygotominor.yy346.pExpr->flags |= EP_InfixFunc;
++  int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
++  yymsp[-1].minor.yy0.n &= 0x7fffffff;
++  pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy190.pExpr);
++  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy190.pExpr);
++  yymsp[-2].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0);
++  exprNot(pParse, bNot, &yymsp[-2].minor.yy190);
++  yymsp[-2].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
++  if( yymsp[-2].minor.yy190.pExpr ) yymsp[-2].minor.yy190.pExpr->flags |= EP_InfixFunc;
+ }
+         break;
+-      case 209: /* expr ::= expr likeop expr ESCAPE expr */
++      case 174: /* expr ::= expr likeop expr ESCAPE expr */
+ {
+   ExprList *pList;
+-  pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr);
+-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy346.pExpr);
+-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr);
+-  yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy96.eOperator);
+-  if( yymsp[-3].minor.yy96.bNot ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, 
yygotominor.yy346.pExpr, 0, 0);
+-  yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
+-  yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd;
+-  if( yygotominor.yy346.pExpr ) yygotominor.yy346.pExpr->flags |= EP_InfixFunc;
++  int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
++  yymsp[-3].minor.yy0.n &= 0x7fffffff;
++  pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
++  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy190.pExpr);
++  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
++  yymsp[-4].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0);
++  exprNot(pParse, bNot, &yymsp[-4].minor.yy190);
++  yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
++  if( yymsp[-4].minor.yy190.pExpr ) yymsp[-4].minor.yy190.pExpr->flags |= EP_InfixFunc;
+ }
+         break;
+-      case 210: /* expr ::= expr ISNULL|NOTNULL */
+-{spanUnaryPostfix(&yygotominor.yy346,pParse,yymsp[0].major,&yymsp[-1].minor.yy346,&yymsp[0].minor.yy0);}
++      case 175: /* expr ::= expr ISNULL|NOTNULL */
++{spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);}
+         break;
+-      case 211: /* expr ::= expr NOT NULL */
+-{spanUnaryPostfix(&yygotominor.yy346,pParse,TK_NOTNULL,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy0);}
++      case 176: /* expr ::= expr NOT NULL */
++{spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
+         break;
+-      case 212: /* expr ::= expr IS expr */
++      case 177: /* expr ::= expr IS expr */
+ {
+-  spanBinaryExpr(&yygotominor.yy346,pParse,TK_IS,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346);
+-  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy346.pExpr, yygotominor.yy346.pExpr, TK_ISNULL);
++  spanBinaryExpr(pParse,TK_IS,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);
++  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-2].minor.yy190.pExpr, TK_ISNULL);
+ }
+         break;
+-      case 213: /* expr ::= expr IS NOT expr */
++      case 178: /* expr ::= expr IS NOT expr */
+ {
+-  spanBinaryExpr(&yygotominor.yy346,pParse,TK_ISNOT,&yymsp[-3].minor.yy346,&yymsp[0].minor.yy346);
+-  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy346.pExpr, yygotominor.yy346.pExpr, TK_NOTNULL);
++  spanBinaryExpr(pParse,TK_ISNOT,&yymsp[-3].minor.yy190,&yymsp[0].minor.yy190);
++  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, TK_NOTNULL);
+ }
+         break;
+-      case 214: /* expr ::= NOT expr */
+-      case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215);
+-{spanUnaryPrefix(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);}
++      case 179: /* expr ::= NOT expr */
++      case 180: /* expr ::= BITNOT expr */ yytestcase(yyruleno==180);
++{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
+         break;
+-      case 216: /* expr ::= MINUS expr */
+-{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UMINUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);}
++      case 181: /* expr ::= MINUS expr */
++{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
+         break;
+-      case 217: /* expr ::= PLUS expr */
+-{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UPLUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);}
++      case 182: /* expr ::= PLUS expr */
++{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
+         break;
+-      case 220: /* expr ::= expr between_op expr AND expr */
++      case 183: /* between_op ::= BETWEEN */
++      case 186: /* in_op ::= IN */ yytestcase(yyruleno==186);
++{yymsp[0].minor.yy194 = 0;}
++        break;
++      case 185: /* expr ::= expr between_op expr AND expr */
+ {
+-  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr);
+-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr);
+-  yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy346.pExpr, 0, 0);
+-  if( yygotominor.yy346.pExpr ){
+-    yygotominor.yy346.pExpr->x.pList = pList;
++  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
++  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
++  yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy190.pExpr, 0);
++  if( yymsp[-4].minor.yy190.pExpr ){
++    yymsp[-4].minor.yy190.pExpr->x.pList = pList;
+   }else{
+     sqlite3ExprListDelete(pParse->db, pList);
+   } 
+-  if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, 
yygotominor.yy346.pExpr, 0, 0);
+-  yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
+-  yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd;
++  exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
++  yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
+ }
+         break;
+-      case 223: /* expr ::= expr in_op LP exprlist RP */
++      case 188: /* expr ::= expr in_op LP exprlist RP */
+ {
+-    if( yymsp[-1].minor.yy14==0 ){
++    if( yymsp[-1].minor.yy148==0 ){
+       /* Expressions of the form
+       **
+       **      expr1 IN ()
+@@ -126193,9 +142912,9 @@
+       ** simplify to constants 0 (false) and 1 (true), respectively,
+       ** regardless of the value of expr1.
+       */
+-      yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, 
&sqlite3IntTokens[yymsp[-3].minor.yy328]);
+-      sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy346.pExpr);
+-    }else if( yymsp[-1].minor.yy14->nExpr==1 ){
++      sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy190.pExpr);
++      yymsp[-4].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, 
TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy194],1);
++    }else if( yymsp[-1].minor.yy148->nExpr==1 ){
+       /* Expressions of the form:
+       **
+       **      expr1 IN (?1)
+@@ -126212,434 +142931,422 @@
+       ** affinity or the collating sequence to use for comparison.  Otherwise,
+       ** the semantics would be subtly different from IN or NOT IN.
+       */
+-      Expr *pRHS = yymsp[-1].minor.yy14->a[0].pExpr;
+-      yymsp[-1].minor.yy14->a[0].pExpr = 0;
+-      sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14);
++      Expr *pRHS = yymsp[-1].minor.yy148->a[0].pExpr;
++      yymsp[-1].minor.yy148->a[0].pExpr = 0;
++      sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
+       /* pRHS cannot be NULL because a malloc error would have been detected
+       ** before now and control would have never reached this point */
+       if( ALWAYS(pRHS) ){
+         pRHS->flags &= ~EP_Collate;
+         pRHS->flags |= EP_Generic;
+       }
+-      yygotominor.yy346.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy328 ? TK_NE : TK_EQ, 
yymsp[-4].minor.yy346.pExpr, pRHS, 0);
++      yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy194 ? TK_NE : TK_EQ, 
yymsp[-4].minor.yy190.pExpr, pRHS);
+     }else{
+-      yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0);
+-      if( yygotominor.yy346.pExpr ){
+-        yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy14;
+-        sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
++      yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0);
++      if( yymsp[-4].minor.yy190.pExpr ){
++        yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy148;
++        sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy190.pExpr);
+       }else{
+-        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14);
++        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
+       }
+-      if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, 
yygotominor.yy346.pExpr, 0, 0);
++      exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
+     }
+-    yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
+-    yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
++    yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+   }
+         break;
+-      case 224: /* expr ::= LP select RP */
++      case 189: /* expr ::= LP select RP */
+ {
+-    yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
+-    if( yygotominor.yy346.pExpr ){
+-      yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3;
+-      ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery);
+-      sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
+-    }else{
+-      sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
+-    }
+-    yygotominor.yy346.zStart = yymsp[-2].minor.yy0.z;
+-    yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
++    spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
++    yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
++    sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy190.pExpr, yymsp[-1].minor.yy243);
+   }
+         break;
+-      case 225: /* expr ::= expr in_op LP select RP */
++      case 190: /* expr ::= expr in_op LP select RP */
+ {
+-    yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0);
+-    if( yygotominor.yy346.pExpr ){
+-      yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3;
+-      ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery);
+-      sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
+-    }else{
+-      sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
+-    }
+-    if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, 
yygotominor.yy346.pExpr, 0, 0);
+-    yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
+-    yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
++    yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0);
++    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, yymsp[-1].minor.yy243);
++    exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
++    yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+   }
+         break;
+-      case 226: /* expr ::= expr in_op nm dbnm */
++      case 191: /* expr ::= expr in_op nm dbnm paren_exprlist */
+ {
+-    SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
+-    yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy346.pExpr, 0, 0);
+-    if( yygotominor.yy346.pExpr ){
+-      yygotominor.yy346.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
+-      ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery);
+-      sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
+-    }else{
+-      sqlite3SrcListDelete(pParse->db, pSrc);
+-    }
+-    if( yymsp[-2].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, 
yygotominor.yy346.pExpr, 0, 0);
+-    yygotominor.yy346.zStart = yymsp[-3].minor.yy346.zStart;
+-    yygotominor.yy346.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : 
&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
++    SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
++    Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
++    if( yymsp[0].minor.yy148 )  sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy148);
++    yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0);
++    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, pSelect);
++    exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
++    yymsp[-4].minor.yy190.zEnd = yymsp[-1].minor.yy0.z ? &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n] : 
&yymsp[-2].minor.yy0.z[yymsp[-2].minor.yy0.n];
+   }
+         break;
+-      case 227: /* expr ::= EXISTS LP select RP */
++      case 192: /* expr ::= EXISTS LP select RP */
+ {
+-    Expr *p = yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+-    if( p ){
+-      p->x.pSelect = yymsp[-1].minor.yy3;
+-      ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
+-      sqlite3ExprSetHeightAndFlags(pParse, p);
+-    }else{
+-      sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
+-    }
+-    yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z;
+-    yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
++    Expr *p;
++    spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
++    p = yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
++    sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy243);
+   }
+         break;
+-      case 228: /* expr ::= CASE case_operand case_exprlist case_else END */
++      case 193: /* expr ::= CASE case_operand case_exprlist case_else END */
+ {
+-  yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy132, 0, 0);
+-  if( yygotominor.yy346.pExpr ){
+-    yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy132 ? 
sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy132) : yymsp[-2].minor.yy14;
+-    sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
++  spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);  /*A-overwrites-C*/
++  yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, 0);
++  if( yymsp[-4].minor.yy190.pExpr ){
++    yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy72 ? 
sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[-1].minor.yy72) : yymsp[-2].minor.yy148;
++    sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy190.pExpr);
+   }else{
+-    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14);
+-    sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy132);
++    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148);
++    sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72);
+   }
+-  yygotominor.yy346.zStart = yymsp[-4].minor.yy0.z;
+-  yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ }
+         break;
+-      case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
++      case 194: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ {
+-  yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy346.pExpr);
+-  yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr);
++  yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy190.pExpr);
++  yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
+ }
+         break;
+-      case 230: /* case_exprlist ::= WHEN expr THEN expr */
++      case 195: /* case_exprlist ::= WHEN expr THEN expr */
+ {
+-  yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr);
+-  yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr);
++  yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
++  yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, yymsp[0].minor.yy190.pExpr);
+ }
+         break;
+-      case 237: /* nexprlist ::= nexprlist COMMA expr */
+-{yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy346.pExpr);}
++      case 198: /* case_operand ::= expr */
++{yymsp[0].minor.yy72 = yymsp[0].minor.yy190.pExpr; /*A-overwrites-X*/}
++        break;
++      case 201: /* nexprlist ::= nexprlist COMMA expr */
++{yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);}
+         break;
+-      case 238: /* nexprlist ::= expr */
+-{yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy346.pExpr);}
++      case 202: /* nexprlist ::= expr */
++{yymsp[0].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr); /*A-overwrites-Y*/}
+         break;
+-      case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */
++      case 204: /* paren_exprlist ::= LP exprlist RP */
++      case 209: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==209);
++{yymsp[-2].minor.yy148 = yymsp[-1].minor.yy148;}
++        break;
++      case 205: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ {
+   sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, 
+-                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, 
yymsp[-10].minor.yy328,
+-                      &yymsp[-11].minor.yy0, yymsp[0].minor.yy132, SQLITE_SO_ASC, yymsp[-8].minor.yy328);
++                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy148, 
yymsp[-10].minor.yy194,
++                      &yymsp[-11].minor.yy0, yymsp[0].minor.yy72, SQLITE_SO_ASC, yymsp[-8].minor.yy194, 
SQLITE_IDXTYPE_APPDEF);
+ }
+         break;
+-      case 240: /* uniqueflag ::= UNIQUE */
+-      case 291: /* raisetype ::= ABORT */ yytestcase(yyruleno==291);
+-{yygotominor.yy328 = OE_Abort;}
++      case 206: /* uniqueflag ::= UNIQUE */
++      case 246: /* raisetype ::= ABORT */ yytestcase(yyruleno==246);
++{yymsp[0].minor.yy194 = OE_Abort;}
+         break;
+-      case 241: /* uniqueflag ::= */
+-{yygotominor.yy328 = OE_None;}
++      case 207: /* uniqueflag ::= */
++{yymsp[1].minor.yy194 = OE_None;}
+         break;
+-      case 244: /* idxlist ::= idxlist COMMA nm collate sortorder */
++      case 210: /* eidlist ::= eidlist COMMA nm collate sortorder */
+ {
+-  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1);
+-  yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, p);
+-  sqlite3ExprListSetName(pParse,yygotominor.yy14,&yymsp[-2].minor.yy0,1);
+-  sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index");
+-  if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = 
(u8)yymsp[0].minor.yy328;
++  yymsp[-4].minor.yy148 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, 
yymsp[-1].minor.yy194, yymsp[0].minor.yy194);
+ }
+         break;
+-      case 245: /* idxlist ::= nm collate sortorder */
++      case 211: /* eidlist ::= nm collate sortorder */
+ {
+-  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1);
+-  yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, p);
+-  sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
+-  sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index");
+-  if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = 
(u8)yymsp[0].minor.yy328;
++  yymsp[-2].minor.yy148 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, 
yymsp[0].minor.yy194); /*A-overwrites-Y*/
+ }
+         break;
+-      case 246: /* collate ::= */
+-{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
++      case 214: /* cmd ::= DROP INDEX ifexists fullname */
++{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
+         break;
+-      case 248: /* cmd ::= DROP INDEX ifexists fullname */
+-{sqlite3DropIndex(pParse, yymsp[0].minor.yy65, yymsp[-1].minor.yy328);}
++      case 215: /* cmd ::= VACUUM */
++{sqlite3Vacuum(pParse,0);}
+         break;
+-      case 249: /* cmd ::= VACUUM */
+-      case 250: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==250);
+-{sqlite3Vacuum(pParse);}
++      case 216: /* cmd ::= VACUUM nm */
++{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
+         break;
+-      case 251: /* cmd ::= PRAGMA nm dbnm */
++      case 217: /* cmd ::= PRAGMA nm dbnm */
+ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
+         break;
+-      case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
++      case 218: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
+         break;
+-      case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
++      case 219: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
+         break;
+-      case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
++      case 220: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
+         break;
+-      case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
++      case 221: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
+         break;
+-      case 264: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
++      case 224: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ {
+   Token all;
+   all.z = yymsp[-3].minor.yy0.z;
+   all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
+-  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy473, &all);
++  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy145, &all);
+ }
+         break;
+-      case 265: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname 
foreach_clause when_clause */
++      case 225: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname 
foreach_clause when_clause */
+ {
+-  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy328, 
yymsp[-4].minor.yy378.a, yymsp[-4].minor.yy378.b, yymsp[-2].minor.yy65, yymsp[0].minor.yy132, 
yymsp[-10].minor.yy328, yymsp[-8].minor.yy328);
+-  yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
++  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy194, 
yymsp[-4].minor.yy332.a, yymsp[-4].minor.yy332.b, yymsp[-2].minor.yy185, yymsp[0].minor.yy72, 
yymsp[-10].minor.yy194, yymsp[-8].minor.yy194);
++  yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); 
/*A-overwrites-T*/
+ }
+         break;
+-      case 266: /* trigger_time ::= BEFORE */
+-      case 269: /* trigger_time ::= */ yytestcase(yyruleno==269);
+-{ yygotominor.yy328 = TK_BEFORE; }
++      case 226: /* trigger_time ::= BEFORE|AFTER */
++{ yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-X*/ }
+         break;
+-      case 267: /* trigger_time ::= AFTER */
+-{ yygotominor.yy328 = TK_AFTER;  }
++      case 227: /* trigger_time ::= INSTEAD OF */
++{ yymsp[-1].minor.yy194 = TK_INSTEAD;}
+         break;
+-      case 268: /* trigger_time ::= INSTEAD OF */
+-{ yygotominor.yy328 = TK_INSTEAD;}
++      case 228: /* trigger_time ::= */
++{ yymsp[1].minor.yy194 = TK_BEFORE; }
+         break;
+-      case 270: /* trigger_event ::= DELETE|INSERT */
+-      case 271: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==271);
+-{yygotominor.yy378.a = yymsp[0].major; yygotominor.yy378.b = 0;}
++      case 229: /* trigger_event ::= DELETE|INSERT */
++      case 230: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==230);
++{yymsp[0].minor.yy332.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy332.b = 0;}
+         break;
+-      case 272: /* trigger_event ::= UPDATE OF idlist */
+-{yygotominor.yy378.a = TK_UPDATE; yygotominor.yy378.b = yymsp[0].minor.yy408;}
++      case 231: /* trigger_event ::= UPDATE OF idlist */
++{yymsp[-2].minor.yy332.a = TK_UPDATE; yymsp[-2].minor.yy332.b = yymsp[0].minor.yy254;}
+         break;
+-      case 275: /* when_clause ::= */
+-      case 296: /* key_opt ::= */ yytestcase(yyruleno==296);
+-{ yygotominor.yy132 = 0; }
++      case 232: /* when_clause ::= */
++      case 251: /* key_opt ::= */ yytestcase(yyruleno==251);
++{ yymsp[1].minor.yy72 = 0; }
+         break;
+-      case 276: /* when_clause ::= WHEN expr */
+-      case 297: /* key_opt ::= KEY expr */ yytestcase(yyruleno==297);
+-{ yygotominor.yy132 = yymsp[0].minor.yy346.pExpr; }
++      case 233: /* when_clause ::= WHEN expr */
++      case 252: /* key_opt ::= KEY expr */ yytestcase(yyruleno==252);
++{ yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr; }
+         break;
+-      case 277: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
++      case 234: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ {
+-  assert( yymsp[-2].minor.yy473!=0 );
+-  yymsp[-2].minor.yy473->pLast->pNext = yymsp[-1].minor.yy473;
+-  yymsp[-2].minor.yy473->pLast = yymsp[-1].minor.yy473;
+-  yygotominor.yy473 = yymsp[-2].minor.yy473;
++  assert( yymsp[-2].minor.yy145!=0 );
++  yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145;
++  yymsp[-2].minor.yy145->pLast = yymsp[-1].minor.yy145;
+ }
+         break;
+-      case 278: /* trigger_cmd_list ::= trigger_cmd SEMI */
++      case 235: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ { 
+-  assert( yymsp[-1].minor.yy473!=0 );
+-  yymsp[-1].minor.yy473->pLast = yymsp[-1].minor.yy473;
+-  yygotominor.yy473 = yymsp[-1].minor.yy473;
++  assert( yymsp[-1].minor.yy145!=0 );
++  yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
+ }
+         break;
+-      case 280: /* trnm ::= nm DOT nm */
++      case 236: /* trnm ::= nm DOT nm */
+ {
+-  yygotominor.yy0 = yymsp[0].minor.yy0;
++  yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
+   sqlite3ErrorMsg(pParse, 
+         "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
+         "statements within triggers");
+ }
+         break;
+-      case 282: /* tridxby ::= INDEXED BY nm */
++      case 237: /* tridxby ::= INDEXED BY nm */
+ {
+   sqlite3ErrorMsg(pParse,
+         "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
+         "within triggers");
+ }
+         break;
+-      case 283: /* tridxby ::= NOT INDEXED */
++      case 238: /* tridxby ::= NOT INDEXED */
+ {
+   sqlite3ErrorMsg(pParse,
+         "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
+         "within triggers");
+ }
+         break;
+-      case 284: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
+-{ yygotominor.yy473 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy14, 
yymsp[0].minor.yy132, yymsp[-5].minor.yy186); }
++      case 239: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
++{yymsp[-6].minor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy148, 
yymsp[0].minor.yy72, yymsp[-5].minor.yy194);}
+         break;
+-      case 285: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
+-{yygotominor.yy473 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy408, 
yymsp[0].minor.yy3, yymsp[-4].minor.yy186);}
++      case 240: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
++{yymsp[-4].minor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy254, 
yymsp[0].minor.yy243, yymsp[-4].minor.yy194);/*A-overwrites-R*/}
+         break;
+-      case 286: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
+-{yygotominor.yy473 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy132);}
++      case 241: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
++{yymsp[-4].minor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy72);}
+         break;
+-      case 287: /* trigger_cmd ::= select */
+-{yygotominor.yy473 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy3); }
++      case 242: /* trigger_cmd ::= select */
++{yymsp[0].minor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); /*A-overwrites-X*/}
+         break;
+-      case 288: /* expr ::= RAISE LP IGNORE RP */
++      case 243: /* expr ::= RAISE LP IGNORE RP */
+ {
+-  yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); 
+-  if( yygotominor.yy346.pExpr ){
+-    yygotominor.yy346.pExpr->affinity = OE_Ignore;
++  spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);  /*A-overwrites-X*/
++  yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0); 
++  if( yymsp[-3].minor.yy190.pExpr ){
++    yymsp[-3].minor.yy190.pExpr->affinity = OE_Ignore;
+   }
+-  yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z;
+-  yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ }
+         break;
+-      case 289: /* expr ::= RAISE LP raisetype COMMA nm RP */
++      case 244: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ {
+-  yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); 
+-  if( yygotominor.yy346.pExpr ) {
+-    yygotominor.yy346.pExpr->affinity = (char)yymsp[-3].minor.yy328;
++  spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);  /*A-overwrites-X*/
++  yymsp[-5].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); 
++  if( yymsp[-5].minor.yy190.pExpr ) {
++    yymsp[-5].minor.yy190.pExpr->affinity = (char)yymsp[-3].minor.yy194;
+   }
+-  yygotominor.yy346.zStart = yymsp[-5].minor.yy0.z;
+-  yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ }
+         break;
+-      case 290: /* raisetype ::= ROLLBACK */
+-{yygotominor.yy328 = OE_Rollback;}
++      case 245: /* raisetype ::= ROLLBACK */
++{yymsp[0].minor.yy194 = OE_Rollback;}
+         break;
+-      case 292: /* raisetype ::= FAIL */
+-{yygotominor.yy328 = OE_Fail;}
++      case 247: /* raisetype ::= FAIL */
++{yymsp[0].minor.yy194 = OE_Fail;}
+         break;
+-      case 293: /* cmd ::= DROP TRIGGER ifexists fullname */
++      case 248: /* cmd ::= DROP TRIGGER ifexists fullname */
+ {
+-  sqlite3DropTrigger(pParse,yymsp[0].minor.yy65,yymsp[-1].minor.yy328);
++  sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194);
+ }
+         break;
+-      case 294: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
++      case 249: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ {
+-  sqlite3Attach(pParse, yymsp[-3].minor.yy346.pExpr, yymsp[-1].minor.yy346.pExpr, yymsp[0].minor.yy132);
++  sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72);
+ }
+         break;
+-      case 295: /* cmd ::= DETACH database_kw_opt expr */
++      case 250: /* cmd ::= DETACH database_kw_opt expr */
+ {
+-  sqlite3Detach(pParse, yymsp[0].minor.yy346.pExpr);
++  sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr);
+ }
+         break;
+-      case 300: /* cmd ::= REINDEX */
++      case 253: /* cmd ::= REINDEX */
+ {sqlite3Reindex(pParse, 0, 0);}
+         break;
+-      case 301: /* cmd ::= REINDEX nm dbnm */
++      case 254: /* cmd ::= REINDEX nm dbnm */
+ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
+         break;
+-      case 302: /* cmd ::= ANALYZE */
++      case 255: /* cmd ::= ANALYZE */
+ {sqlite3Analyze(pParse, 0, 0);}
+         break;
+-      case 303: /* cmd ::= ANALYZE nm dbnm */
++      case 256: /* cmd ::= ANALYZE nm dbnm */
+ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
+         break;
+-      case 304: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
++      case 257: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ {
+-  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy65,&yymsp[0].minor.yy0);
++  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0);
+ }
+         break;
+-      case 305: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
++      case 258: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ {
+-  sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
++  yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
++  sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
+ }
+         break;
+-      case 306: /* add_column_fullname ::= fullname */
++      case 259: /* add_column_fullname ::= fullname */
+ {
+-  pParse->db->lookaside.bEnabled = 0;
+-  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy65);
++  disableLookaside(pParse);
++  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185);
+ }
+         break;
+-      case 309: /* cmd ::= create_vtab */
++      case 260: /* cmd ::= create_vtab */
+ {sqlite3VtabFinishParse(pParse,0);}
+         break;
+-      case 310: /* cmd ::= create_vtab LP vtabarglist RP */
++      case 261: /* cmd ::= create_vtab LP vtabarglist RP */
+ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
+         break;
+-      case 311: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
++      case 262: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ {
+-    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, 
yymsp[-4].minor.yy328);
++    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, 
yymsp[-4].minor.yy194);
+ }
+         break;
+-      case 314: /* vtabarg ::= */
++      case 263: /* vtabarg ::= */
+ {sqlite3VtabArgInit(pParse);}
+         break;
+-      case 316: /* vtabargtoken ::= ANY */
+-      case 317: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==317);
+-      case 318: /* lp ::= LP */ yytestcase(yyruleno==318);
++      case 264: /* vtabargtoken ::= ANY */
++      case 265: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==265);
++      case 266: /* lp ::= LP */ yytestcase(yyruleno==266);
+ {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
+         break;
+-      case 322: /* with ::= */
+-{yygotominor.yy59 = 0;}
++      case 267: /* with ::= */
++{yymsp[1].minor.yy285 = 0;}
++        break;
++      case 268: /* with ::= WITH wqlist */
++{ yymsp[-1].minor.yy285 = yymsp[0].minor.yy285; }
+         break;
+-      case 323: /* with ::= WITH wqlist */
+-      case 324: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==324);
+-{ yygotominor.yy59 = yymsp[0].minor.yy59; }
++      case 269: /* with ::= WITH RECURSIVE wqlist */
++{ yymsp[-2].minor.yy285 = yymsp[0].minor.yy285; }
+         break;
+-      case 325: /* wqlist ::= nm idxlist_opt AS LP select RP */
++      case 270: /* wqlist ::= nm eidlist_opt AS LP select RP */
+ {
+-  yygotominor.yy59 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, 
yymsp[-1].minor.yy3);
++  yymsp[-5].minor.yy285 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, 
yymsp[-1].minor.yy243); /*A-overwrites-X*/
+ }
+         break;
+-      case 326: /* wqlist ::= wqlist COMMA nm idxlist_opt AS LP select RP */
++      case 271: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ {
+-  yygotominor.yy59 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy59, &yymsp[-5].minor.yy0, 
yymsp[-4].minor.yy14, yymsp[-1].minor.yy3);
++  yymsp[-7].minor.yy285 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy285, &yymsp[-5].minor.yy0, 
yymsp[-4].minor.yy148, yymsp[-1].minor.yy243);
+ }
+         break;
+       default:
+-      /* (0) input ::= cmdlist */ yytestcase(yyruleno==0);
+-      /* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1);
+-      /* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2);
+-      /* (3) ecmd ::= SEMI */ yytestcase(yyruleno==3);
+-      /* (4) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==4);
+-      /* (10) trans_opt ::= */ yytestcase(yyruleno==10);
+-      /* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11);
+-      /* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12);
+-      /* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20);
+-      /* (21) savepoint_opt ::= */ yytestcase(yyruleno==21);
+-      /* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25);
+-      /* (36) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==36);
+-      /* (37) columnlist ::= column */ yytestcase(yyruleno==37);
+-      /* (43) type ::= */ yytestcase(yyruleno==43);
+-      /* (50) signed ::= plus_num */ yytestcase(yyruleno==50);
+-      /* (51) signed ::= minus_num */ yytestcase(yyruleno==51);
+-      /* (52) carglist ::= carglist ccons */ yytestcase(yyruleno==52);
+-      /* (53) carglist ::= */ yytestcase(yyruleno==53);
+-      /* (60) ccons ::= NULL onconf */ yytestcase(yyruleno==60);
+-      /* (88) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==88);
+-      /* (89) conslist ::= tcons */ yytestcase(yyruleno==89);
+-      /* (91) tconscomma ::= */ yytestcase(yyruleno==91);
+-      /* (273) foreach_clause ::= */ yytestcase(yyruleno==273);
+-      /* (274) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==274);
+-      /* (281) tridxby ::= */ yytestcase(yyruleno==281);
+-      /* (298) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==298);
+-      /* (299) database_kw_opt ::= */ yytestcase(yyruleno==299);
+-      /* (307) kwcolumn_opt ::= */ yytestcase(yyruleno==307);
+-      /* (308) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==308);
+-      /* (312) vtabarglist ::= vtabarg */ yytestcase(yyruleno==312);
+-      /* (313) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==313);
+-      /* (315) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==315);
+-      /* (319) anylist ::= */ yytestcase(yyruleno==319);
+-      /* (320) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==320);
+-      /* (321) anylist ::= anylist ANY */ yytestcase(yyruleno==321);
++      /* (272) input ::= cmdlist */ yytestcase(yyruleno==272);
++      /* (273) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==273);
++      /* (274) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=274);
++      /* (275) ecmd ::= SEMI */ yytestcase(yyruleno==275);
++      /* (276) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==276);
++      /* (277) explain ::= */ yytestcase(yyruleno==277);
++      /* (278) trans_opt ::= */ yytestcase(yyruleno==278);
++      /* (279) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==279);
++      /* (280) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==280);
++      /* (281) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==281);
++      /* (282) savepoint_opt ::= */ yytestcase(yyruleno==282);
++      /* (283) cmd ::= create_table create_table_args */ yytestcase(yyruleno==283);
++      /* (284) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==284);
++      /* (285) columnlist ::= columnname carglist */ yytestcase(yyruleno==285);
++      /* (286) nm ::= ID|INDEXED */ yytestcase(yyruleno==286);
++      /* (287) nm ::= STRING */ yytestcase(yyruleno==287);
++      /* (288) nm ::= JOIN_KW */ yytestcase(yyruleno==288);
++      /* (289) typetoken ::= typename */ yytestcase(yyruleno==289);
++      /* (290) typename ::= ID|STRING */ yytestcase(yyruleno==290);
++      /* (291) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=291);
++      /* (292) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=292);
++      /* (293) carglist ::= carglist ccons */ yytestcase(yyruleno==293);
++      /* (294) carglist ::= */ yytestcase(yyruleno==294);
++      /* (295) ccons ::= NULL onconf */ yytestcase(yyruleno==295);
++      /* (296) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==296);
++      /* (297) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==297);
++      /* (298) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=298);
++      /* (299) tconscomma ::= */ yytestcase(yyruleno==299);
++      /* (300) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=300);
++      /* (301) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=301);
++      /* (302) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=302);
++      /* (303) oneselect ::= values */ yytestcase(yyruleno==303);
++      /* (304) sclp ::= selcollist COMMA */ yytestcase(yyruleno==304);
++      /* (305) as ::= ID|STRING */ yytestcase(yyruleno==305);
++      /* (306) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=306);
++      /* (307) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==307);
++      /* (308) exprlist ::= nexprlist */ yytestcase(yyruleno==308);
++      /* (309) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=309);
++      /* (310) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=310);
++      /* (311) nmnum ::= ON */ yytestcase(yyruleno==311);
++      /* (312) nmnum ::= DELETE */ yytestcase(yyruleno==312);
++      /* (313) nmnum ::= DEFAULT */ yytestcase(yyruleno==313);
++      /* (314) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==314);
++      /* (315) foreach_clause ::= */ yytestcase(yyruleno==315);
++      /* (316) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==316);
++      /* (317) trnm ::= nm */ yytestcase(yyruleno==317);
++      /* (318) tridxby ::= */ yytestcase(yyruleno==318);
++      /* (319) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==319);
++      /* (320) database_kw_opt ::= */ yytestcase(yyruleno==320);
++      /* (321) kwcolumn_opt ::= */ yytestcase(yyruleno==321);
++      /* (322) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==322);
++      /* (323) vtabarglist ::= vtabarg */ yytestcase(yyruleno==323);
++      /* (324) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==324);
++      /* (325) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==325);
++      /* (326) anylist ::= */ yytestcase(yyruleno==326);
++      /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327);
++      /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328);
+         break;
++/********** End reduce actions ************************************************/
+   };
+-  assert( yyruleno>=0 && yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
++  assert( yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
+   yygoto = yyRuleInfo[yyruleno].lhs;
+   yysize = yyRuleInfo[yyruleno].nrhs;
+-  yypParser->yyidx -= yysize;
+-  yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
+-  if( yyact < YYNSTATE ){
+-#ifdef NDEBUG
+-    /* If we are not debugging and the reduce action popped at least
+-    ** one element off the stack, then we can push the new element back
+-    ** onto the stack here, and skip the stack overflow test in yy_shift().
+-    ** That gives a significant speed improvement. */
+-    if( yysize ){
+-      yypParser->yyidx++;
+-      yymsp -= yysize-1;
+-      yymsp->stateno = (YYACTIONTYPE)yyact;
+-      yymsp->major = (YYCODETYPE)yygoto;
+-      yymsp->minor = yygotominor;
+-    }else
+-#endif
+-    {
+-      yy_shift(yypParser,yyact,yygoto,&yygotominor);
+-    }
+-  }else{
+-    assert( yyact == YYNSTATE + YYNRULE + 1 );
++  yyact = yy_find_reduce_action(yymsp[yysize].stateno,(YYCODETYPE)yygoto);
 +
-+#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
++  /* There are no SHIFTREDUCE actions on nonterminals because the table
++  ** generator has simplified them to pure REDUCE actions. */
++  assert( !(yyact>YY_MAX_SHIFT && yyact<=YY_MAX_SHIFTREDUCE) );
 +
-+/************** End of ctime.c ***********************************************/
-+/************** Begin file status.c ******************************************/
-+/*
-+** 2008 June 18
-+**
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
-+**
-+**    May you do good and not evil.
-+**    May you find forgiveness for yourself and forgive others.
-+**    May you share freely, never taking more than you give.
-+**
-+*************************************************************************
-+**
-+** This module implements the sqlite3_status() interface and related
-+** functionality.
-+*/
-+/************** Include vdbeInt.h in the middle of status.c ******************/
-+/************** Begin file vdbeInt.h *****************************************/
-+/*
-+** 2003 September 6
-+**
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
-+**
-+**    May you do good and not evil.
-+**    May you find forgiveness for yourself and forgive others.
-+**    May you share freely, never taking more than you give.
++  /* It is not possible for a REDUCE to be followed by an error */
++  assert( yyact!=YY_ERROR_ACTION );
++
++  if( yyact==YY_ACCEPT_ACTION ){
++    yypParser->yytos += yysize;
+     yy_accept(yypParser);
++  }else{
++    yymsp += yysize+1;
++    yypParser->yytos = yymsp;
++    yymsp->stateno = (YYACTIONTYPE)yyact;
++    yymsp->major = (YYCODETYPE)yygoto;
++    yyTraceShift(yypParser, yyact);
+   }
+ }
+ 
+@@ -126656,9 +143363,11 @@
+     fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
+   }
+ #endif
+-  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
++  while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
+   /* Here code is inserted which will be executed whenever the
+   ** parser fails */
++/************ Begin %parse_failure code ***************************************/
++/************ End %parse_failure code *****************************************/
+   sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+ }
+ #endif /* YYNOERRORRECOVERY */
+@@ -126669,14 +143378,16 @@
+ static void yy_syntax_error(
+   yyParser *yypParser,           /* The parser */
+   int yymajor,                   /* The major type of the error token */
+-  YYMINORTYPE yyminor            /* The minor type of the error token */
++  sqlite3ParserTOKENTYPE yyminor         /* The minor type of the error token */
+ ){
+   sqlite3ParserARG_FETCH;
+-#define TOKEN (yyminor.yy0)
++#define TOKEN yyminor
++/************ Begin %syntax_error code ****************************************/
+ 
+   UNUSED_PARAMETER(yymajor);  /* Silence some compiler warnings */
+   assert( TOKEN.z[0] );  /* The tokenizer always gives us a token */
+   sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
++/************ End %syntax_error code ******************************************/
+   sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+ }
+ 
+@@ -126692,9 +143403,14 @@
+     fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
+   }
+ #endif
+-  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
++#ifndef YYNOERRORRECOVERY
++  yypParser->yyerrcnt = -1;
++#endif
++  assert( yypParser->yytos==yypParser->yystack );
+   /* Here code is inserted which will be executed whenever the
+   ** parser accepts */
++/*********** Begin %parse_accept code *****************************************/
++/*********** End %parse_accept code *******************************************/
+   sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+ }
+ 
+@@ -126724,7 +143440,7 @@
+   sqlite3ParserARG_PDECL               /* Optional %extra_argument parameter */
+ ){
+   YYMINORTYPE yyminorunion;
+-  int yyact;            /* The parser action. */
++  unsigned int yyact;   /* The parser action. */
+ #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
+   int yyendofinput;     /* True if we are at the end of input */
+ #endif
+@@ -126733,23 +143449,8 @@
+ #endif
+   yyParser *yypParser;  /* The parser */
+ 
+-  /* (re)initialize the parser, if necessary */
+   yypParser = (yyParser*)yyp;
+-  if( yypParser->yyidx<0 ){
+-#if YYSTACKDEPTH<=0
+-    if( yypParser->yystksz <=0 ){
+-      /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/
+-      yyminorunion = yyzerominor;
+-      yyStackOverflow(yypParser, &yyminorunion);
+-      return;
+-    }
+-#endif
+-    yypParser->yyidx = 0;
+-    yypParser->yyerrcnt = -1;
+-    yypParser->yystack[0].stateno = 0;
+-    yypParser->yystack[0].major = 0;
+-  }
+-  yyminorunion.yy0 = yyminor;
++  assert( yypParser->yytos!=0 );
+ #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
+   yyendofinput = (yymajor==0);
+ #endif
+@@ -126757,20 +143458,23 @@
+ 
+ #ifndef NDEBUG
+   if( yyTraceFILE ){
+-    fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
++    fprintf(yyTraceFILE,"%sInput '%s'\n",yyTracePrompt,yyTokenName[yymajor]);
+   }
+ #endif
+ 
+   do{
+     yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
+-    if( yyact<YYNSTATE ){
+-      yy_shift(yypParser,yyact,yymajor,&yyminorunion);
++    if( yyact <= YY_MAX_SHIFTREDUCE ){
++      yy_shift(yypParser,yyact,yymajor,yyminor);
++#ifndef YYNOERRORRECOVERY
+       yypParser->yyerrcnt--;
++#endif
+       yymajor = YYNOCODE;
+-    }else if( yyact < YYNSTATE + YYNRULE ){
+-      yy_reduce(yypParser,yyact-YYNSTATE);
++    }else if( yyact <= YY_MAX_REDUCE ){
++      yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
+     }else{
+       assert( yyact == YY_ERROR_ACTION );
++      yyminorunion.yy0 = yyminor;
+ #ifdef YYERRORSYMBOL
+       int yymx;
+ #endif
+@@ -126800,9 +143504,9 @@
+       **
+       */
+       if( yypParser->yyerrcnt<0 ){
+-        yy_syntax_error(yypParser,yymajor,yyminorunion);
++        yy_syntax_error(yypParser,yymajor,yyminor);
+       }
+-      yymx = yypParser->yystack[yypParser->yyidx].major;
++      yymx = yypParser->yytos->major;
+       if( yymx==YYERRORSYMBOL || yyerrorhit ){
+ #ifndef NDEBUG
+         if( yyTraceFILE ){
+@@ -126810,26 +143514,26 @@
+              yyTracePrompt,yyTokenName[yymajor]);
+         }
+ #endif
+-        yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion);
++        yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
+         yymajor = YYNOCODE;
+       }else{
+-         while(
+-          yypParser->yyidx >= 0 &&
+-          yymx != YYERRORSYMBOL &&
+-          (yyact = yy_find_reduce_action(
+-                        yypParser->yystack[yypParser->yyidx].stateno,
+-                        YYERRORSYMBOL)) >= YYNSTATE
++        while( yypParser->yytos >= yypParser->yystack
++            && yymx != YYERRORSYMBOL
++            && (yyact = yy_find_reduce_action(
++                        yypParser->yytos->stateno,
++                        YYERRORSYMBOL)) >= YY_MIN_REDUCE
+         ){
+           yy_pop_parser_stack(yypParser);
+         }
+-        if( yypParser->yyidx < 0 || yymajor==0 ){
++        if( yypParser->yytos < yypParser->yystack || yymajor==0 ){
+           yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
+           yy_parse_failed(yypParser);
++#ifndef YYNOERRORRECOVERY
++          yypParser->yyerrcnt = -1;
++#endif
+           yymajor = YYNOCODE;
+         }else if( yymx!=YYERRORSYMBOL ){
+-          YYMINORTYPE u2;
+-          u2.YYERRSYMDT = 0;
+-          yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
++          yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor);
+         }
+       }
+       yypParser->yyerrcnt = 3;
+@@ -126842,7 +143546,7 @@
+       ** Applications can set this macro (for example inside %include) if
+       ** they intend to abandon the parse upon the first syntax error seen.
+       */
+-      yy_syntax_error(yypParser,yymajor,yyminorunion);
++      yy_syntax_error(yypParser,yymajor, yyminor);
+       yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
+       yymajor = YYNOCODE;
+       
+@@ -126857,17 +143561,32 @@
+       ** three input tokens have been successfully shifted.
+       */
+       if( yypParser->yyerrcnt<=0 ){
+-        yy_syntax_error(yypParser,yymajor,yyminorunion);
++        yy_syntax_error(yypParser,yymajor, yyminor);
+       }
+       yypParser->yyerrcnt = 3;
+       yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
+       if( yyendofinput ){
+         yy_parse_failed(yypParser);
++#ifndef YYNOERRORRECOVERY
++        yypParser->yyerrcnt = -1;
++#endif
+       }
+       yymajor = YYNOCODE;
+ #endif
+     }
+-  }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
++  }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack );
++#ifndef NDEBUG
++  if( yyTraceFILE ){
++    yyStackEntry *i;
++    char cDiv = '[';
++    fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt);
++    for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){
++      fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]);
++      cDiv = ' ';
++    }
++    fprintf(yyTraceFILE,"]\n");
++  }
++#endif
+   return;
+ }
+ 
+@@ -126890,14 +143609,95 @@
+ ** individual tokens and sends those tokens one-by-one over to the
+ ** parser for analysis.
+ */
++/* #include "sqliteInt.h" */
+ /* #include <stdlib.h> */
+ 
++/* Character classes for tokenizing
 +**
-+*************************************************************************
-+** This is the header file for information that is private to the
-+** VDBE.  This information used to all be at the top of the single
-+** source code file "vdbe.c".  When that file became too big (over
-+** 6000 lines long) it was split up into several smaller files and
-+** this header information was factored out.
-+*/
-+#ifndef _VDBEINT_H_
-+#define _VDBEINT_H_
-+
-+/*
-+** The maximum number of times that a statement will try to reparse
-+** itself before giving up and returning SQLITE_SCHEMA.
++** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented
++** using a lookup table, whereas a switch() directly on c uses a binary search.
++** The lookup table is much faster.  To maximize speed, and to ensure that
++** a lookup table is used, all of the classes need to be small integers and
++** all of them need to be used within the switch.
 +*/
-+#ifndef SQLITE_MAX_SCHEMA_RETRY
-+# define SQLITE_MAX_SCHEMA_RETRY 50
++#define CC_X          0    /* The letter 'x', or start of BLOB literal */
++#define CC_KYWD       1    /* Alphabetics or '_'.  Usable in a keyword */
++#define CC_ID         2    /* unicode characters usable in IDs */
++#define CC_DIGIT      3    /* Digits */
++#define CC_DOLLAR     4    /* '$' */
++#define CC_VARALPHA   5    /* '@', '#', ':'.  Alphabetic SQL variables */
++#define CC_VARNUM     6    /* '?'.  Numeric SQL variables */
++#define CC_SPACE      7    /* Space characters */
++#define CC_QUOTE      8    /* '"', '\'', or '`'.  String literals, quoted ids */
++#define CC_QUOTE2     9    /* '['.   [...] style quoted ids */
++#define CC_PIPE      10    /* '|'.   Bitwise OR or concatenate */
++#define CC_MINUS     11    /* '-'.  Minus or SQL-style comment */
++#define CC_LT        12    /* '<'.  Part of < or <= or <> */
++#define CC_GT        13    /* '>'.  Part of > or >= */
++#define CC_EQ        14    /* '='.  Part of = or == */
++#define CC_BANG      15    /* '!'.  Part of != */
++#define CC_SLASH     16    /* '/'.  / or c-style comment */
++#define CC_LP        17    /* '(' */
++#define CC_RP        18    /* ')' */
++#define CC_SEMI      19    /* ';' */
++#define CC_PLUS      20    /* '+' */
++#define CC_STAR      21    /* '*' */
++#define CC_PERCENT   22    /* '%' */
++#define CC_COMMA     23    /* ',' */
++#define CC_AND       24    /* '&' */
++#define CC_TILDA     25    /* '~' */
++#define CC_DOT       26    /* '.' */
++#define CC_ILLEGAL   27    /* Illegal character */
++
++static const unsigned char aiClass[] = {
++#ifdef SQLITE_ASCII
++/*         x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xa  xb  xc  xd  xe  xf */
++/* 0x */   27, 27, 27, 27, 27, 27, 27, 27, 27,  7,  7, 27,  7,  7, 27, 27,
++/* 1x */   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
++/* 2x */    7, 15,  8,  5,  4, 22, 24,  8, 17, 18, 21, 20, 23, 11, 26, 16,
++/* 3x */    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  5, 19, 12, 14, 13,  6,
++/* 4x */    5,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
++/* 5x */    1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1,  9, 27, 27, 27,  1,
++/* 6x */    8,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
++/* 7x */    1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1, 27, 10, 27, 25, 27,
++/* 8x */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
++/* 9x */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
++/* Ax */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
++/* Bx */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
++/* Cx */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
++/* Dx */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
++/* Ex */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
++/* Fx */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2
 +#endif
++#ifdef SQLITE_EBCDIC
++/*         x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xa  xb  xc  xd  xe  xf */
++/* 0x */   27, 27, 27, 27, 27,  7, 27, 27, 27, 27, 27, 27,  7,  7, 27, 27,
++/* 1x */   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
++/* 2x */   27, 27, 27, 27, 27,  7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
++/* 3x */   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
++/* 4x */    7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 12, 17, 20, 10,
++/* 5x */   24, 27, 27, 27, 27, 27, 27, 27, 27, 27, 15,  4, 21, 18, 19, 27,
++/* 6x */   11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22,  1, 13,  6,
++/* 7x */   27, 27, 27, 27, 27, 27, 27, 27, 27,  8,  5,  5,  5,  8, 14,  8,
++/* 8x */   27,  1,  1,  1,  1,  1,  1,  1,  1,  1, 27, 27, 27, 27, 27, 27,
++/* 9x */   27,  1,  1,  1,  1,  1,  1,  1,  1,  1, 27, 27, 27, 27, 27, 27,
++/* Ax */   27, 25,  1,  1,  1,  1,  1,  0,  1,  1, 27, 27, 27, 27, 27, 27,
++/* Bx */   27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  9, 27, 27, 27, 27, 27,
++/* Cx */   27,  1,  1,  1,  1,  1,  1,  1,  1,  1, 27, 27, 27, 27, 27, 27,
++/* Dx */   27,  1,  1,  1,  1,  1,  1,  1,  1,  1, 27, 27, 27, 27, 27, 27,
++/* Ex */   27, 27,  1,  1,  1,  1,  1,  0,  1,  1, 27, 27, 27, 27, 27, 27,
++/* Fx */    3,  3,  3,  3,  3,  3,  3,  3,  3,  3, 27, 27, 27, 27, 27, 27,
++#endif
++};
 +
-+/*
-+** SQL is translated into a sequence of instructions to be
-+** executed by a virtual machine.  Each instruction is an instance
-+** of the following structure.
-+*/
-+typedef struct VdbeOp Op;
-+
-+/*
-+** Boolean values
-+*/
-+typedef unsigned Bool;
-+
-+/* Opaque type used by code in vdbesort.c */
-+typedef struct VdbeSorter VdbeSorter;
-+
-+/* Opaque type used by the explainer */
-+typedef struct Explain Explain;
-+
-+/* Elements of the linked list at Vdbe.pAuxData */
-+typedef struct AuxData AuxData;
-+
-+/*
-+** A cursor is a pointer into a single BTree within a database file.
-+** The cursor can seek to a BTree entry with a particular key, or
-+** loop over all entries of the Btree.  You can also insert new BTree
-+** entries or retrieve the key or data from the entry that the cursor
-+** is currently pointing to.
+ /*
+-** The charMap() macro maps alphabetic characters into their
++** The charMap() macro maps alphabetic characters (only) into their
+ ** lower-case ASCII equivalent.  On ASCII machines, this is just
+ ** an upper-to-lower case map.  On EBCDIC machines we also need
+-** to adjust the encoding.  Only alphabetic characters and underscores
+-** need to be translated.
++** to adjust the encoding.  The mapping is only valid for alphabetics
++** which are the only characters for which this feature is used. 
 +**
-+** Cursors can also point to virtual tables, sorters, or "pseudo-tables".
-+** A pseudo-table is a single-row table implemented by registers.
-+** 
-+** Every cursor that the virtual machine has open is represented by an
-+** instance of the following structure.
-+*/
-+struct VdbeCursor {
-+  BtCursor *pCursor;    /* The cursor structure of the backend */
-+  Btree *pBt;           /* Separate file holding temporary table */
-+  KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
-+  int seekResult;       /* Result of previous sqlite3BtreeMoveto() */
-+  int pseudoTableReg;   /* Register holding pseudotable content. */
-+  i16 nField;           /* Number of fields in the header */
-+  u16 nHdrParsed;       /* Number of header fields parsed so far */
-+#ifdef SQLITE_DEBUG
-+  u8 seekOp;            /* Most recent seek operation on this cursor */
-+#endif
-+  i8 iDb;               /* Index of cursor database in db->aDb[] (or -1) */
-+  u8 nullRow;           /* True if pointing to a row with no data */
-+  u8 deferredMoveto;    /* A call to sqlite3BtreeMoveto() is needed */
-+  Bool isEphemeral:1;   /* True for an ephemeral table */
-+  Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
-+  Bool isTable:1;       /* True if a table requiring integer keys */
-+  Bool isOrdered:1;     /* True if the underlying table is BTREE_UNORDERED */
-+  Pgno pgnoRoot;        /* Root page of the open btree cursor */
-+  sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
-+  i64 seqCount;         /* Sequence counter */
-+  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
-+  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
-+
-+  /* Cached information about the header for the data record that the
-+  ** cursor is currently pointing to.  Only valid if cacheStatus matches
-+  ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
-+  ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
-+  ** the cache is out of date.
-+  **
-+  ** aRow might point to (ephemeral) data for the current row, or it might
-+  ** be NULL.
-+  */
-+  u32 cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
-+  u32 payloadSize;      /* Total number of bytes in the record */
-+  u32 szRow;            /* Byte available in aRow */
-+  u32 iHdrOffset;       /* Offset to next unparsed byte of the header */
-+  const u8 *aRow;       /* Data for the current row, if all on one page */
-+  u32 *aOffset;         /* Pointer to aType[nField] */
-+  u32 aType[1];         /* Type values for all entries in the record */
-+  /* 2*nField extra array elements allocated for aType[], beyond the one
-+  ** static element declared in the structure.  nField total array slots for
-+  ** aType[] and nField+1 array slots for aOffset[] */
++** Used by keywordhash.h
+ */
+ #ifdef SQLITE_ASCII
+ # define charMap(X) sqlite3UpperToLower[(unsigned char)X]
+@@ -126931,7 +143731,7 @@
+ ** returned.  If the input is not a keyword, TK_ID is returned.
+ **
+ ** The implementation of this routine was generated by a program,
+-** mkkeywordhash.h, located in the tool subdirectory of the distribution.
++** mkkeywordhash.c, located in the tool subdirectory of the distribution.
+ ** The output of the mkkeywordhash.c program is written into a file
+ ** named keywordhash.h and then included into this source file by
+ ** the #include below.
+@@ -126952,133 +143752,152 @@
+ ** on platforms with limited memory.
+ */
+ /* Hash score: 182 */
+-static int keywordCode(const char *z, int n){
+-  /* zText[] encodes 834 bytes of keywords in 554 bytes */
+-  /*   REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT       */
+-  /*   ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE         */
+-  /*   XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY         */
+-  /*   UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERECURSIVE         */
+-  /*   BETWEENOTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATEDETACH     */
+-  /*   IMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHEN     */
+-  /*   WHERENAMEAFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT         */
+-  /*   CONFLICTCROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAIL        */
+-  /*   FROMFULLGLOBYIFISNULLORDERESTRICTRIGHTROLLBACKROWUNIONUSING        */
+-  /*   VACUUMVIEWINITIALLY                                                */
+-  static const char zText[553] = {
+-    'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
+-    'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
+-    'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
+-    'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F',
+-    'E','R','R','A','B','L','E','L','S','E','X','C','E','P','T','R','A','N',
+-    'S','A','C','T','I','O','N','A','T','U','R','A','L','T','E','R','A','I',
+-    'S','E','X','C','L','U','S','I','V','E','X','I','S','T','S','A','V','E',
+-    'P','O','I','N','T','E','R','S','E','C','T','R','I','G','G','E','R','E',
+-    'F','E','R','E','N','C','E','S','C','O','N','S','T','R','A','I','N','T',
+-    'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q',
+-    'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S',
+-    'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A',
+-    'T','E','B','E','G','I','N','N','E','R','E','C','U','R','S','I','V','E',
+-    'B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C','A',
+-    'S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L','A',
+-    'T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A',
+-    'T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E','J',
+-    'O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A','L',
+-    'Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U','E',
+-    'S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W','H',
+-    'E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C','E',
+-    'A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R','E',
+-    'M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M','M',
+-    'I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U','R',
+-    'R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M','A',
+-    'R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','D',
+-    'R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L','O',
+-    'B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T',
+-    'R','I','C','T','R','I','G','H','T','R','O','L','L','B','A','C','K','R',
+-    'O','W','U','N','I','O','N','U','S','I','N','G','V','A','C','U','U','M',
+-    'V','I','E','W','I','N','I','T','I','A','L','L','Y',
+-  };
+-  static const unsigned char aHash[127] = {
+-      76, 105, 117,  74,   0,  45,   0,   0,  82,   0,  77,   0,   0,
+-      42,  12,  78,  15,   0, 116,  85,  54, 112,   0,  19,   0,   0,
+-     121,   0, 119, 115,   0,  22,  93,   0,   9,   0,   0,  70,  71,
+-       0,  69,   6,   0,  48,  90, 102,   0, 118, 101,   0,   0,  44,
+-       0, 103,  24,   0,  17,   0, 122,  53,  23,   0,   5, 110,  25,
+-      96,   0,   0, 124, 106,  60, 123,  57,  28,  55,   0,  91,   0,
+-     100,  26,   0,  99,   0,   0,   0,  95,  92,  97,  88, 109,  14,
+-      39, 108,   0,  81,   0,  18,  89, 111,  32,   0, 120,  80, 113,
+-      62,  46,  84,   0,   0,  94,  40,  59, 114,   0,  36,   0,   0,
+-      29,   0,  86,  63,  64,   0,  20,  61,   0,  56,
+-  };
+-  static const unsigned char aNext[124] = {
+-       0,   0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,
+-       0,   2,   0,   0,   0,   0,   0,   0,  13,   0,   0,   0,   0,
+-       0,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+-       0,   0,   0,   0,  33,   0,  21,   0,   0,   0,   0,   0,  50,
+-       0,  43,   3,  47,   0,   0,   0,   0,  30,   0,  58,   0,  38,
+-       0,   0,   0,   1,  66,   0,   0,  67,   0,  41,   0,   0,   0,
+-       0,   0,   0,  49,  65,   0,   0,   0,   0,  31,  52,  16,  34,
+-      10,   0,   0,   0,   0,   0,   0,   0,  11,  72,  79,   0,   8,
+-       0, 104,  98,   0, 107,   0,  87,   0,  75,  51,   0,  27,  37,
+-      73,  83,   0,  35,  68,   0,   0,
+-  };
+-  static const unsigned char aLen[124] = {
+-       7,   7,   5,   4,   6,   4,   5,   3,   6,   7,   3,   6,   6,
+-       7,   7,   3,   8,   2,   6,   5,   4,   4,   3,  10,   4,   6,
+-      11,   6,   2,   7,   5,   5,   9,   6,   9,   9,   7,  10,  10,
+-       4,   6,   2,   3,   9,   4,   2,   6,   5,   7,   4,   5,   7,
+-       6,   6,   5,   6,   5,   5,   9,   7,   7,   3,   2,   4,   4,
+-       7,   3,   6,   4,   7,   6,  12,   6,   9,   4,   6,   5,   4,
+-       7,   6,   5,   6,   7,   5,   4,   5,   6,   5,   7,   3,   7,
+-      13,   2,   2,   4,   6,   6,   8,   5,  17,  12,   7,   8,   8,
+-       2,   4,   4,   4,   4,   4,   2,   2,   6,   5,   8,   5,   8,
+-       3,   5,   5,   6,   4,   9,   3,
+-  };
+-  static const unsigned short int aOffset[124] = {
+-       0,   2,   2,   8,   9,  14,  16,  20,  23,  25,  25,  29,  33,
+-      36,  41,  46,  48,  53,  54,  59,  62,  65,  67,  69,  78,  81,
+-      86,  91,  95,  96, 101, 105, 109, 117, 122, 128, 136, 142, 152,
+-     159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 184, 188, 192,
+-     199, 204, 209, 212, 218, 221, 225, 234, 240, 240, 240, 243, 246,
+-     250, 251, 255, 261, 265, 272, 278, 290, 296, 305, 307, 313, 318,
+-     320, 327, 332, 337, 343, 349, 354, 358, 361, 367, 371, 378, 380,
+-     387, 389, 391, 400, 404, 410, 416, 424, 429, 429, 445, 452, 459,
+-     460, 467, 471, 475, 479, 483, 486, 488, 490, 496, 500, 508, 513,
+-     521, 524, 529, 534, 540, 544, 549,
+-  };
+-  static const unsigned char aCode[124] = {
+-    TK_REINDEX,    TK_INDEXED,    TK_INDEX,      TK_DESC,       TK_ESCAPE,     
+-    TK_EACH,       TK_CHECK,      TK_KEY,        TK_BEFORE,     TK_FOREIGN,    
+-    TK_FOR,        TK_IGNORE,     TK_LIKE_KW,    TK_EXPLAIN,    TK_INSTEAD,    
+-    TK_ADD,        TK_DATABASE,   TK_AS,         TK_SELECT,     TK_TABLE,      
+-    TK_JOIN_KW,    TK_THEN,       TK_END,        TK_DEFERRABLE, TK_ELSE,       
+-    TK_EXCEPT,     TK_TRANSACTION,TK_ACTION,     TK_ON,         TK_JOIN_KW,    
+-    TK_ALTER,      TK_RAISE,      TK_EXCLUSIVE,  TK_EXISTS,     TK_SAVEPOINT,  
+-    TK_INTERSECT,  TK_TRIGGER,    TK_REFERENCES, TK_CONSTRAINT, TK_INTO,       
+-    TK_OFFSET,     TK_OF,         TK_SET,        TK_TEMP,       TK_TEMP,       
+-    TK_OR,         TK_UNIQUE,     TK_QUERY,      TK_WITHOUT,    TK_WITH,       
+-    TK_JOIN_KW,    TK_RELEASE,    TK_ATTACH,     TK_HAVING,     TK_GROUP,      
+-    TK_UPDATE,     TK_BEGIN,      TK_JOIN_KW,    TK_RECURSIVE,  TK_BETWEEN,    
+-    TK_NOTNULL,    TK_NOT,        TK_NO,         TK_NULL,       TK_LIKE_KW,    
+-    TK_CASCADE,    TK_ASC,        TK_DELETE,     TK_CASE,       TK_COLLATE,    
+-    TK_CREATE,     TK_CTIME_KW,   TK_DETACH,     TK_IMMEDIATE,  TK_JOIN,       
+-    TK_INSERT,     TK_MATCH,      TK_PLAN,       TK_ANALYZE,    TK_PRAGMA,     
+-    TK_ABORT,      TK_VALUES,     TK_VIRTUAL,    TK_LIMIT,      TK_WHEN,       
+-    TK_WHERE,      TK_RENAME,     TK_AFTER,      TK_REPLACE,    TK_AND,        
+-    TK_DEFAULT,    TK_AUTOINCR,   TK_TO,         TK_IN,         TK_CAST,       
+-    TK_COLUMNKW,   TK_COMMIT,     TK_CONFLICT,   TK_JOIN_KW,    TK_CTIME_KW,   
+-    TK_CTIME_KW,   TK_PRIMARY,    TK_DEFERRED,   TK_DISTINCT,   TK_IS,         
+-    TK_DROP,       TK_FAIL,       TK_FROM,       TK_JOIN_KW,    TK_LIKE_KW,    
+-    TK_BY,         TK_IF,         TK_ISNULL,     TK_ORDER,      TK_RESTRICT,   
+-    TK_JOIN_KW,    TK_ROLLBACK,   TK_ROW,        TK_UNION,      TK_USING,      
+-    TK_VACUUM,     TK_VIEW,       TK_INITIALLY,  TK_ALL,        
+-  };
+-  int h, i;
+-  if( n<2 ) return TK_ID;
+-  h = ((charMap(z[0])*4) ^
+-      (charMap(z[n-1])*3) ^
+-      n) % 127;
+-  for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
+-    if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){
++/* zKWText[] encodes 834 bytes of keyword text in 554 bytes */
++/*   REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT       */
++/*   ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE         */
++/*   XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY         */
++/*   UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERECURSIVE         */
++/*   BETWEENOTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATEDETACH     */
++/*   IMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHEN     */
++/*   WHERENAMEAFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT         */
++/*   CONFLICTCROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAIL        */
++/*   FROMFULLGLOBYIFISNULLORDERESTRICTRIGHTROLLBACKROWUNIONUSING        */
++/*   VACUUMVIEWINITIALLY                                                */
++static const char zKWText[553] = {
++  'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
++  'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
++  'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
++  'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F',
++  'E','R','R','A','B','L','E','L','S','E','X','C','E','P','T','R','A','N',
++  'S','A','C','T','I','O','N','A','T','U','R','A','L','T','E','R','A','I',
++  'S','E','X','C','L','U','S','I','V','E','X','I','S','T','S','A','V','E',
++  'P','O','I','N','T','E','R','S','E','C','T','R','I','G','G','E','R','E',
++  'F','E','R','E','N','C','E','S','C','O','N','S','T','R','A','I','N','T',
++  'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q',
++  'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S',
++  'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A',
++  'T','E','B','E','G','I','N','N','E','R','E','C','U','R','S','I','V','E',
++  'B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C','A',
++  'S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L','A',
++  'T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A',
++  'T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E','J',
++  'O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A','L',
++  'Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U','E',
++  'S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W','H',
++  'E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C','E',
++  'A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R','E',
++  'M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M','M',
++  'I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U','R',
++  'R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M','A',
++  'R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','D',
++  'R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L','O',
++  'B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T',
++  'R','I','C','T','R','I','G','H','T','R','O','L','L','B','A','C','K','R',
++  'O','W','U','N','I','O','N','U','S','I','N','G','V','A','C','U','U','M',
++  'V','I','E','W','I','N','I','T','I','A','L','L','Y',
 +};
-+typedef struct VdbeCursor VdbeCursor;
-+
-+/*
-+** When a sub-program is executed (OP_Program), a structure of this type
-+** is allocated to store the current value of the program counter, as
-+** well as the current memory cell array and various other frame specific
-+** values stored in the Vdbe struct. When the sub-program is finished, 
-+** these values are copied back to the Vdbe from the VdbeFrame structure,
-+** restoring the state of the VM to as it was before the sub-program
-+** began executing.
-+**
-+** The memory for a VdbeFrame object is allocated and managed by a memory
-+** cell in the parent (calling) frame. When the memory cell is deleted or
-+** overwritten, the VdbeFrame object is not freed immediately. Instead, it
-+** is linked into the Vdbe.pDelFrame list. The contents of the Vdbe.pDelFrame
-+** list is deleted when the VM is reset in VdbeHalt(). The reason for doing
-+** this instead of deleting the VdbeFrame immediately is to avoid recursive
-+** calls to sqlite3VdbeMemRelease() when the memory cells belonging to the
-+** child frame are released.
-+**
-+** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is
-+** set to NULL if the currently executing frame is the main program.
-+*/
-+typedef struct VdbeFrame VdbeFrame;
-+struct VdbeFrame {
-+  Vdbe *v;                /* VM this frame belongs to */
-+  VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
-+  Op *aOp;                /* Program instructions for parent frame */
-+  i64 *anExec;            /* Event counters from parent frame */
-+  Mem *aMem;              /* Array of memory cells for parent frame */
-+  u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
-+  VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
-+  void *token;            /* Copy of SubProgram.token */
-+  i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
-+  int nCursor;            /* Number of entries in apCsr */
-+  int pc;                 /* Program Counter in parent (calling) frame */
-+  int nOp;                /* Size of aOp array */
-+  int nMem;               /* Number of entries in aMem */
-+  int nOnceFlag;          /* Number of entries in aOnceFlag */
-+  int nChildMem;          /* Number of memory cells for child frame */
-+  int nChildCsr;          /* Number of cursors for child frame */
-+  int nChange;            /* Statement changes (Vdbe.nChange)     */
-+  int nDbChange;          /* Value of db->nChange */
++/* aKWHash[i] is the hash value for the i-th keyword */
++static const unsigned char aKWHash[127] = {
++    76, 105, 117,  74,   0,  45,   0,   0,  82,   0,  77,   0,   0,
++    42,  12,  78,  15,   0, 116,  85,  54, 112,   0,  19,   0,   0,
++   121,   0, 119, 115,   0,  22,  93,   0,   9,   0,   0,  70,  71,
++     0,  69,   6,   0,  48,  90, 102,   0, 118, 101,   0,   0,  44,
++     0, 103,  24,   0,  17,   0, 122,  53,  23,   0,   5, 110,  25,
++    96,   0,   0, 124, 106,  60, 123,  57,  28,  55,   0,  91,   0,
++   100,  26,   0,  99,   0,   0,   0,  95,  92,  97,  88, 109,  14,
++    39, 108,   0,  81,   0,  18,  89, 111,  32,   0, 120,  80, 113,
++    62,  46,  84,   0,   0,  94,  40,  59, 114,   0,  36,   0,   0,
++    29,   0,  86,  63,  64,   0,  20,  61,   0,  56,
 +};
++/* aKWNext[] forms the hash collision chain.  If aKWHash[i]==0
++** then the i-th keyword has no more hash collisions.  Otherwise,
++** the next keyword with the same hash is aKWHash[i]-1. */
++static const unsigned char aKWNext[124] = {
++     0,   0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,
++     0,   2,   0,   0,   0,   0,   0,   0,  13,   0,   0,   0,   0,
++     0,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
++     0,   0,   0,   0,  33,   0,  21,   0,   0,   0,   0,   0,  50,
++     0,  43,   3,  47,   0,   0,   0,   0,  30,   0,  58,   0,  38,
++     0,   0,   0,   1,  66,   0,   0,  67,   0,  41,   0,   0,   0,
++     0,   0,   0,  49,  65,   0,   0,   0,   0,  31,  52,  16,  34,
++    10,   0,   0,   0,   0,   0,   0,   0,  11,  72,  79,   0,   8,
++     0, 104,  98,   0, 107,   0,  87,   0,  75,  51,   0,  27,  37,
++    73,  83,   0,  35,  68,   0,   0,
++};
++/* aKWLen[i] is the length (in bytes) of the i-th keyword */
++static const unsigned char aKWLen[124] = {
++     7,   7,   5,   4,   6,   4,   5,   3,   6,   7,   3,   6,   6,
++     7,   7,   3,   8,   2,   6,   5,   4,   4,   3,  10,   4,   6,
++    11,   6,   2,   7,   5,   5,   9,   6,   9,   9,   7,  10,  10,
++     4,   6,   2,   3,   9,   4,   2,   6,   5,   7,   4,   5,   7,
++     6,   6,   5,   6,   5,   5,   9,   7,   7,   3,   2,   4,   4,
++     7,   3,   6,   4,   7,   6,  12,   6,   9,   4,   6,   5,   4,
++     7,   6,   5,   6,   7,   5,   4,   5,   6,   5,   7,   3,   7,
++    13,   2,   2,   4,   6,   6,   8,   5,  17,  12,   7,   8,   8,
++     2,   4,   4,   4,   4,   4,   2,   2,   6,   5,   8,   5,   8,
++     3,   5,   5,   6,   4,   9,   3,
++};
++/* aKWOffset[i] is the index into zKWText[] of the start of
++** the text for the i-th keyword. */
++static const unsigned short int aKWOffset[124] = {
++     0,   2,   2,   8,   9,  14,  16,  20,  23,  25,  25,  29,  33,
++    36,  41,  46,  48,  53,  54,  59,  62,  65,  67,  69,  78,  81,
++    86,  91,  95,  96, 101, 105, 109, 117, 122, 128, 136, 142, 152,
++   159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 184, 188, 192,
++   199, 204, 209, 212, 218, 221, 225, 234, 240, 240, 240, 243, 246,
++   250, 251, 255, 261, 265, 272, 278, 290, 296, 305, 307, 313, 318,
++   320, 327, 332, 337, 343, 349, 354, 358, 361, 367, 371, 378, 380,
++   387, 389, 391, 400, 404, 410, 416, 424, 429, 429, 445, 452, 459,
++   460, 467, 471, 475, 479, 483, 486, 488, 490, 496, 500, 508, 513,
++   521, 524, 529, 534, 540, 544, 549,
++};
++/* aKWCode[i] is the parser symbol code for the i-th keyword */
++static const unsigned char aKWCode[124] = {
++  TK_REINDEX,    TK_INDEXED,    TK_INDEX,      TK_DESC,       TK_ESCAPE,     
++  TK_EACH,       TK_CHECK,      TK_KEY,        TK_BEFORE,     TK_FOREIGN,    
++  TK_FOR,        TK_IGNORE,     TK_LIKE_KW,    TK_EXPLAIN,    TK_INSTEAD,    
++  TK_ADD,        TK_DATABASE,   TK_AS,         TK_SELECT,     TK_TABLE,      
++  TK_JOIN_KW,    TK_THEN,       TK_END,        TK_DEFERRABLE, TK_ELSE,       
++  TK_EXCEPT,     TK_TRANSACTION,TK_ACTION,     TK_ON,         TK_JOIN_KW,    
++  TK_ALTER,      TK_RAISE,      TK_EXCLUSIVE,  TK_EXISTS,     TK_SAVEPOINT,  
++  TK_INTERSECT,  TK_TRIGGER,    TK_REFERENCES, TK_CONSTRAINT, TK_INTO,       
++  TK_OFFSET,     TK_OF,         TK_SET,        TK_TEMP,       TK_TEMP,       
++  TK_OR,         TK_UNIQUE,     TK_QUERY,      TK_WITHOUT,    TK_WITH,       
++  TK_JOIN_KW,    TK_RELEASE,    TK_ATTACH,     TK_HAVING,     TK_GROUP,      
++  TK_UPDATE,     TK_BEGIN,      TK_JOIN_KW,    TK_RECURSIVE,  TK_BETWEEN,    
++  TK_NOTNULL,    TK_NOT,        TK_NO,         TK_NULL,       TK_LIKE_KW,    
++  TK_CASCADE,    TK_ASC,        TK_DELETE,     TK_CASE,       TK_COLLATE,    
++  TK_CREATE,     TK_CTIME_KW,   TK_DETACH,     TK_IMMEDIATE,  TK_JOIN,       
++  TK_INSERT,     TK_MATCH,      TK_PLAN,       TK_ANALYZE,    TK_PRAGMA,     
++  TK_ABORT,      TK_VALUES,     TK_VIRTUAL,    TK_LIMIT,      TK_WHEN,       
++  TK_WHERE,      TK_RENAME,     TK_AFTER,      TK_REPLACE,    TK_AND,        
++  TK_DEFAULT,    TK_AUTOINCR,   TK_TO,         TK_IN,         TK_CAST,       
++  TK_COLUMNKW,   TK_COMMIT,     TK_CONFLICT,   TK_JOIN_KW,    TK_CTIME_KW,   
++  TK_CTIME_KW,   TK_PRIMARY,    TK_DEFERRED,   TK_DISTINCT,   TK_IS,         
++  TK_DROP,       TK_FAIL,       TK_FROM,       TK_JOIN_KW,    TK_LIKE_KW,    
++  TK_BY,         TK_IF,         TK_ISNULL,     TK_ORDER,      TK_RESTRICT,   
++  TK_JOIN_KW,    TK_ROLLBACK,   TK_ROW,        TK_UNION,      TK_USING,      
++  TK_VACUUM,     TK_VIEW,       TK_INITIALLY,  TK_ALL,        
++};
++/* Check to see if z[0..n-1] is a keyword. If it is, write the
++** parser symbol code for that keyword into *pType.  Always
++** return the integer n (the length of the token). */
++static int keywordCode(const char *z, int n, int *pType){
++  int i, j;
++  const char *zKW;
++  if( n>=2 ){
++    i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) % 127;
++    for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){
++      if( aKWLen[i]!=n ) continue;
++      j = 0;
++      zKW = &zKWText[aKWOffset[i]];
++#ifdef SQLITE_ASCII
++      while( j<n && (z[j]&~0x20)==zKW[j] ){ j++; }
++#endif
++#ifdef SQLITE_EBCDIC
++      while( j<n && toupper(z[j])==zKW[j] ){ j++; }
++#endif
++      if( j<n ) continue;
+       testcase( i==0 ); /* REINDEX */
+       testcase( i==1 ); /* INDEXED */
+       testcase( i==2 ); /* INDEX */
+@@ -127203,13 +144022,16 @@
+       testcase( i==121 ); /* VIEW */
+       testcase( i==122 ); /* INITIALLY */
+       testcase( i==123 ); /* ALL */
+-      return aCode[i];
++      *pType = aKWCode[i];
++      break;
+     }
+   }
+-  return TK_ID;
++  return n;
+ }
+ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
+-  return keywordCode((char*)z, n);
++  int id = TK_ID;
++  keywordCode((char*)z, n, &id);
++  return id;
+ }
+ #define SQLITE_N_KEYWORD 124
+ 
+@@ -127254,17 +144076,23 @@
+ };
+ #define IdChar(C)  (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
+ #endif
 +
-+#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
-+
-+/*
-+** A value for VdbeCursor.cacheValid that means the cache is always invalid.
-+*/
-+#define CACHE_STALE 0
-+
-+/*
-+** Internally, the vdbe manipulates nearly all SQL values as Mem
-+** structures. Each Mem struct may cache multiple representations (string,
-+** integer etc.) of the same value.
-+*/
-+struct Mem {
-+  union MemValue {
-+    double r;           /* Real value used when MEM_Real is set in flags */
-+    i64 i;              /* Integer value used when MEM_Int is set in flags */
-+    int nZero;          /* Used when bit MEM_Zero is set in flags */
-+    FuncDef *pDef;      /* Used only when flags==MEM_Agg */
-+    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
-+    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
-+  } u;
-+  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
-+  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
-+  int n;              /* Number of characters in string value, excluding '\0' */
-+  char *z;            /* String or BLOB value */
-+  /* ShallowCopy only needs to copy the information above */
-+  char *zMalloc;      /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
-+  int szMalloc;       /* Size of the zMalloc allocation */
-+  u32 uTemp;          /* Transient storage for serial_type in OP_MakeRecord */
-+  sqlite3 *db;        /* The associated database connection */
-+  void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
-+#ifdef SQLITE_DEBUG
-+  Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
-+  void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
++/* Make the IdChar function accessible from ctime.c */
++#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+ SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); }
 +#endif
-+};
+ 
+ 
+ /*
+-** Return the length of the token that begins at z[0]. 
++** Return the length (in bytes) of the token that begins at z[0]. 
+ ** Store the token type in *tokenType before returning.
+ */
+ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
+   int i, c;
+-  switch( *z ){
+-    case ' ': case '\t': case '\n': case '\f': case '\r': {
++  switch( aiClass[*z] ){  /* Switch on the character-class of the first byte
++                          ** of the token. See the comment on the CC_ defines
++                          ** above. */
++    case CC_SPACE: {
+       testcase( z[0]==' ' );
+       testcase( z[0]=='\t' );
+       testcase( z[0]=='\n' );
+@@ -127274,7 +144102,7 @@
+       *tokenType = TK_SPACE;
+       return i;
+     }
+-    case '-': {
++    case CC_MINUS: {
+       if( z[1]=='-' ){
+         for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
+         *tokenType = TK_SPACE;   /* IMP: R-22934-25134 */
+@@ -127283,27 +144111,27 @@
+       *tokenType = TK_MINUS;
+       return 1;
+     }
+-    case '(': {
++    case CC_LP: {
+       *tokenType = TK_LP;
+       return 1;
+     }
+-    case ')': {
++    case CC_RP: {
+       *tokenType = TK_RP;
+       return 1;
+     }
+-    case ';': {
++    case CC_SEMI: {
+       *tokenType = TK_SEMI;
+       return 1;
+     }
+-    case '+': {
++    case CC_PLUS: {
+       *tokenType = TK_PLUS;
+       return 1;
+     }
+-    case '*': {
++    case CC_STAR: {
+       *tokenType = TK_STAR;
+       return 1;
+     }
+-    case '/': {
++    case CC_SLASH: {
+       if( z[1]!='*' || z[2]==0 ){
+         *tokenType = TK_SLASH;
+         return 1;
+@@ -127313,15 +144141,15 @@
+       *tokenType = TK_SPACE;   /* IMP: R-22934-25134 */
+       return i;
+     }
+-    case '%': {
++    case CC_PERCENT: {
+       *tokenType = TK_REM;
+       return 1;
+     }
+-    case '=': {
++    case CC_EQ: {
+       *tokenType = TK_EQ;
+       return 1 + (z[1]=='=');
+     }
+-    case '<': {
++    case CC_LT: {
+       if( (c=z[1])=='=' ){
+         *tokenType = TK_LE;
+         return 2;
+@@ -127336,7 +144164,7 @@
+         return 1;
+       }
+     }
+-    case '>': {
++    case CC_GT: {
+       if( (c=z[1])=='=' ){
+         *tokenType = TK_GE;
+         return 2;
+@@ -127348,16 +144176,16 @@
+         return 1;
+       }
+     }
+-    case '!': {
++    case CC_BANG: {
+       if( z[1]!='=' ){
+         *tokenType = TK_ILLEGAL;
+-        return 2;
++        return 1;
+       }else{
+         *tokenType = TK_NE;
+         return 2;
+       }
+     }
+-    case '|': {
++    case CC_PIPE: {
+       if( z[1]!='|' ){
+         *tokenType = TK_BITOR;
+         return 1;
+@@ -127366,21 +144194,19 @@
+         return 2;
+       }
+     }
+-    case ',': {
++    case CC_COMMA: {
+       *tokenType = TK_COMMA;
+       return 1;
+     }
+-    case '&': {
++    case CC_AND: {
+       *tokenType = TK_BITAND;
+       return 1;
+     }
+-    case '~': {
++    case CC_TILDA: {
+       *tokenType = TK_BITNOT;
+       return 1;
+     }
+-    case '`':
+-    case '\'':
+-    case '"': {
++    case CC_QUOTE: {
+       int delim = z[0];
+       testcase( delim=='`' );
+       testcase( delim=='\'' );
+@@ -127405,7 +144231,7 @@
+         return i;
+       }
+     }
+-    case '.': {
++    case CC_DOT: {
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+       if( !sqlite3Isdigit(z[1]) )
+ #endif
+@@ -127416,8 +144242,7 @@
+       /* If the next character is a digit, this is a floating point
+       ** number that begins with ".".  Fall thru into the next case */
+     }
+-    case '0': case '1': case '2': case '3': case '4':
+-    case '5': case '6': case '7': case '8': case '9': {
++    case CC_DIGIT: {
+       testcase( z[0]=='0' );  testcase( z[0]=='1' );  testcase( z[0]=='2' );
+       testcase( z[0]=='3' );  testcase( z[0]=='4' );  testcase( z[0]=='5' );
+       testcase( z[0]=='6' );  testcase( z[0]=='7' );  testcase( z[0]=='8' );
+@@ -127452,22 +144277,18 @@
+       }
+       return i;
+     }
+-    case '[': {
++    case CC_QUOTE2: {
+       for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){}
+       *tokenType = c==']' ? TK_ID : TK_ILLEGAL;
+       return i;
+     }
+-    case '?': {
++    case CC_VARNUM: {
+       *tokenType = TK_VARIABLE;
+       for(i=1; sqlite3Isdigit(z[i]); i++){}
+       return i;
+     }
+-#ifndef SQLITE_OMIT_TCL_VARIABLE
+-    case '$':
+-#endif
+-    case '@':  /* For compatibility with MS SQL Server */
+-    case '#':
+-    case ':': {
++    case CC_DOLLAR:
++    case CC_VARALPHA: {
+       int n = 0;
+       testcase( z[0]=='$' );  testcase( z[0]=='@' );
+       testcase( z[0]==':' );  testcase( z[0]=='#' );
+@@ -127496,8 +144317,20 @@
+       if( n==0 ) *tokenType = TK_ILLEGAL;
+       return i;
+     }
++    case CC_KYWD: {
++      for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
++      if( IdChar(z[i]) ){
++        /* This token started out using characters that can appear in keywords,
++        ** but z[i] is a character not allowed within keywords, so this must
++        ** be an identifier instead */
++        i++;
++        break;
++      }
++      *tokenType = TK_ID;
++      return keywordCode((char*)z, i, tokenType);
++    }
++    case CC_X: {
+ #ifndef SQLITE_OMIT_BLOB_LITERAL
+-    case 'x': case 'X': {
+       testcase( z[0]=='x' ); testcase( z[0]=='X' );
+       if( z[1]=='\'' ){
+         *tokenType = TK_BLOB;
+@@ -127509,20 +144342,22 @@
+         if( z[i] ) i++;
+         return i;
+       }
+-      /* Otherwise fall through to the next case */
+-    }
+ #endif
++      /* If it is not a BLOB literal, then it must be an ID, since no
++      ** SQL keywords start with the letter 'x'.  Fall through */
++    }
++    case CC_ID: {
++      i = 1;
++      break;
++    }
+     default: {
+-      if( !IdChar(*z) ){
+-        break;
+-      }
+-      for(i=1; IdChar(z[i]); i++){}
+-      *tokenType = keywordCode((char*)z, i);
+-      return i;
++      *tokenType = TK_ILLEGAL;
++      return 1;
+     }
+   }
+-  *tokenType = TK_ILLEGAL;
+-  return 1;
++  while( IdChar(z[i]) ){ i++; }
++  *tokenType = TK_ID;
++  return i;
+ }
+ 
+ /*
+@@ -127534,13 +144369,15 @@
+ */
+ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
+   int nErr = 0;                   /* Number of errors encountered */
+-  int i;                          /* Loop counter */
+   void *pEngine;                  /* The LEMON-generated LALR(1) parser */
++  int n = 0;                      /* Length of the next token token */
+   int tokenType;                  /* type of the next token */
+   int lastTokenParsed = -1;       /* type of the previous token */
+-  u8 enableLookaside;             /* Saved value of db->lookaside.bEnabled */
+   sqlite3 *db = pParse->db;       /* The database connection */
+   int mxSqlLen;                   /* Max length of an SQL string */
++#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
++  yyParser sEngine;    /* Space to hold the Lemon-generated Parser object */
++#endif
+ 
+   assert( zSql!=0 );
+   mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
+@@ -127549,82 +144386,81 @@
+   }
+   pParse->rc = SQLITE_OK;
+   pParse->zTail = zSql;
+-  i = 0;
+   assert( pzErrMsg!=0 );
++  /* sqlite3ParserTrace(stdout, "parser: "); */
++#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
++  pEngine = &sEngine;
++  sqlite3ParserInit(pEngine);
++#else
+   pEngine = sqlite3ParserAlloc(sqlite3Malloc);
+   if( pEngine==0 ){
+-    db->mallocFailed = 1;
+-    return SQLITE_NOMEM;
++    sqlite3OomFault(db);
++    return SQLITE_NOMEM_BKPT;
+   }
++#endif
+   assert( pParse->pNewTable==0 );
+   assert( pParse->pNewTrigger==0 );
+   assert( pParse->nVar==0 );
+-  assert( pParse->nzVar==0 );
+-  assert( pParse->azVar==0 );
+-  enableLookaside = db->lookaside.bEnabled;
+-  if( db->lookaside.pStart ) db->lookaside.bEnabled = 1;
+-  while( !db->mallocFailed && zSql[i]!=0 ){
+-    assert( i>=0 );
+-    pParse->sLastToken.z = &zSql[i];
+-    pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType);
+-    i += pParse->sLastToken.n;
+-    if( i>mxSqlLen ){
+-      pParse->rc = SQLITE_TOOBIG;
+-      break;
+-    }
+-    switch( tokenType ){
+-      case TK_SPACE: {
+-        if( db->u1.isInterrupted ){
+-          sqlite3ErrorMsg(pParse, "interrupt");
+-          pParse->rc = SQLITE_INTERRUPT;
+-          goto abort_parse;
+-        }
++  assert( pParse->pVList==0 );
++  while( 1 ){
++    if( zSql[0]!=0 ){
++      n = sqlite3GetToken((u8*)zSql, &tokenType);
++      mxSqlLen -= n;
++      if( mxSqlLen<0 ){
++        pParse->rc = SQLITE_TOOBIG;
+         break;
+       }
+-      case TK_ILLEGAL: {
+-        sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
+-                        &pParse->sLastToken);
+-        goto abort_parse;
++    }else{
++      /* Upon reaching the end of input, call the parser two more times
++      ** with tokens TK_SEMI and 0, in that order. */
++      if( lastTokenParsed==TK_SEMI ){
++        tokenType = 0;
++      }else if( lastTokenParsed==0 ){
++        break;
++      }else{
++        tokenType = TK_SEMI;
+       }
+-      case TK_SEMI: {
+-        pParse->zTail = &zSql[i];
+-        /* Fall thru into the default case */
++      zSql -= n;
++    }
++    if( tokenType>=TK_SPACE ){
++      assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
++      if( db->u1.isInterrupted ){
++        pParse->rc = SQLITE_INTERRUPT;
++        break;
+       }
+-      default: {
+-        sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
+-        lastTokenParsed = tokenType;
+-        if( pParse->rc!=SQLITE_OK ){
+-          goto abort_parse;
+-        }
++      if( tokenType==TK_ILLEGAL ){
++        sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
+         break;
+       }
++      zSql += n;
++    }else{
++      pParse->sLastToken.z = zSql;
++      pParse->sLastToken.n = n;
++      sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
++      lastTokenParsed = tokenType;
++      zSql += n;
++      if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
+     }
+   }
+-abort_parse:
+   assert( nErr==0 );
+-  if( zSql[i]==0 && pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
+-    if( lastTokenParsed!=TK_SEMI ){
+-      sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
+-      pParse->zTail = &zSql[i];
+-    }
+-    if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
+-      sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
+-    }
+-  }
++  pParse->zTail = zSql;
+ #ifdef YYTRACKMAXSTACKDEPTH
+   sqlite3_mutex_enter(sqlite3MallocMutex());
+-  sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
++  sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
+       sqlite3ParserStackPeak(pEngine)
+   );
+   sqlite3_mutex_leave(sqlite3MallocMutex());
+ #endif /* YYDEBUG */
++#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
++  sqlite3ParserFinalize(pEngine);
++#else
+   sqlite3ParserFree(pEngine, sqlite3_free);
+-  db->lookaside.bEnabled = enableLookaside;
++#endif
+   if( db->mallocFailed ){
+-    pParse->rc = SQLITE_NOMEM;
++    pParse->rc = SQLITE_NOMEM_BKPT;
+   }
+   if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
+-    sqlite3SetString(&pParse->zErrMsg, db, "%s", sqlite3ErrStr(pParse->rc));
++    pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
+   }
+   assert( pzErrMsg!=0 );
+   if( pParse->zErrMsg ){
+@@ -127656,14 +144492,13 @@
+     sqlite3DeleteTable(db, pParse->pNewTable);
+   }
+ 
+-  if( pParse->bFreeWith ) sqlite3WithDelete(db, pParse->pWith);
++  if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree);
+   sqlite3DeleteTrigger(db, pParse->pNewTrigger);
+-  for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]);
+-  sqlite3DbFree(db, pParse->azVar);
++  sqlite3DbFree(db, pParse->pVList);
+   while( pParse->pAinc ){
+     AutoincInfo *p = pParse->pAinc;
+     pParse->pAinc = p->pNext;
+-    sqlite3DbFree(db, p);
++    sqlite3DbFreeNN(db, p);
+   }
+   while( pParse->pZombieTab ){
+     Table *p = pParse->pZombieTab;
+@@ -127694,6 +144529,7 @@
+ ** separating it out, the code will be automatically omitted from
+ ** static links that do not use it.
+ */
++/* #include "sqliteInt.h" */
+ #ifndef SQLITE_OMIT_COMPLETE
+ 
+ /*
+@@ -127778,7 +144614,7 @@
+ ** to recognize the end of a trigger can be omitted.  All we have to do
+ ** is look for a semicolon that is not part of an string or comment.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *zSql){
++SQLITE_API int sqlite3_complete(const char *zSql){
+   u8 state = 0;   /* Current state, using numbers defined in header comment */
+   u8 token;       /* Value of the next token */
+ 
+@@ -127943,7 +144779,7 @@
+ ** above, except that the parameter is required to be UTF-16 encoded, not
+ ** UTF-8.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *zSql){
++SQLITE_API int sqlite3_complete16(const void *zSql){
+   sqlite3_value *pVal;
+   char const *zSql8;
+   int rc;
+@@ -127958,10 +144794,10 @@
+   if( zSql8 ){
+     rc = sqlite3_complete(zSql8);
+   }else{
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+   }
+   sqlite3ValueFree(pVal);
+-  return sqlite3ApiExit(0, rc);
++  return rc & 0xff;
+ }
+ #endif /* SQLITE_OMIT_UTF16 */
+ #endif /* SQLITE_OMIT_COMPLETE */
+@@ -127984,6 +144820,7 @@
+ ** other files are for internal use by SQLite and should not be
+ ** accessed by users of the library.
+ */
++/* #include "sqliteInt.h" */
+ 
+ #ifdef SQLITE_ENABLE_FTS3
+ /************** Include fts3.h in the middle of main.c ***********************/
+@@ -128003,6 +144840,7 @@
+ ** This header file is used by programs that want to link against the
+ ** FTS3 library.  All it does is declare the sqlite3Fts3Init() interface.
+ */
++/* #include "sqlite3.h" */
+ 
+ #if 0
+ extern "C" {
+@@ -128035,6 +144873,7 @@
+ ** This header file is used by programs that want to link against the
+ ** RTREE library.  All it does is declare the sqlite3RtreeInit() interface.
+ */
++/* #include "sqlite3.h" */
+ 
+ #if 0
+ extern "C" {
+@@ -128067,6 +144906,7 @@
+ ** This header file is used by programs that want to link against the
+ ** ICU extension.  All it does is declare the sqlite3IcuInit() interface.
+ */
++/* #include "sqlite3.h" */
+ 
+ #if 0
+ extern "C" {
+@@ -128082,6 +144922,15 @@
+ /************** End of sqliteicu.h *******************************************/
+ /************** Continuing where we left off in main.c ***********************/
+ #endif
++#ifdef SQLITE_ENABLE_JSON1
++SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*);
++#endif
++#ifdef SQLITE_ENABLE_STMTVTAB
++SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*);
++#endif
++#ifdef SQLITE_ENABLE_FTS5
++SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*);
++#endif
+ 
+ #ifndef SQLITE_AMALGAMATION
+ /* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
+@@ -128093,24 +144942,24 @@
+ /* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns
+ ** a pointer to the to the sqlite3_version[] string constant. 
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void){ return sqlite3_version; }
++SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; }
+ 
+ /* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a
+ ** pointer to a string constant whose value is the same as the
+ ** SQLITE_SOURCE_ID C preprocessor macro. 
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
++SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
+ 
+ /* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function
+ ** returns an integer equal to SQLITE_VERSION_NUMBER.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
++SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
+ 
+ /* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns
+ ** zero if and only if SQLite was compiled with mutexing code omitted due to
+ ** the SQLITE_THREADSAFE compile-time option being set to 0.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
++SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
+ 
+ /*
+ ** When compiling the test fixture or with debugging enabled (on Win32),
+@@ -128183,7 +145032,7 @@
+ **    *  Recursive calls to this routine from thread X return immediately
+ **       without blocking.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){
++SQLITE_API int sqlite3_initialize(void){
+   MUTEX_LOGIC( sqlite3_mutex *pMaster; )       /* The main static mutex */
+   int rc;                                      /* Result code */
+ #ifdef SQLITE_EXTRA_INIT
+@@ -128238,7 +145087,7 @@
+       sqlite3GlobalConfig.pInitMutex =
+            sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
+       if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){
+-        rc = SQLITE_NOMEM;
++        rc = SQLITE_NOMEM_BKPT;
+       }
+     }
+   }
+@@ -128269,10 +145118,15 @@
+   */
+   sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
+   if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
+-    FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
+     sqlite3GlobalConfig.inProgress = 1;
+-    memset(pHash, 0, sizeof(sqlite3GlobalFunctions));
+-    sqlite3RegisterGlobalFunctions();
++#ifdef SQLITE_ENABLE_SQLLOG
++    {
++      extern void sqlite3_init_sqllog(void);
++      sqlite3_init_sqllog();
++    }
++#endif
++    memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions));
++    sqlite3RegisterBuiltinFunctions();
+     if( sqlite3GlobalConfig.isPCacheInit==0 ){
+       rc = sqlite3PcacheInitialize();
+     }
+@@ -128344,7 +145198,7 @@
+ ** on when SQLite is already shut down.  If SQLite is already shut down
+ ** when this routine is invoked, then this routine is a harmless no-op.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void){
++SQLITE_API int sqlite3_shutdown(void){
+ #ifdef SQLITE_OMIT_WSD
+   int rc = sqlite3_wsd_init(4096, 24);
+   if( rc!=SQLITE_OK ){
+@@ -128398,7 +145252,7 @@
+ ** threadsafe.  Failure to heed these warnings can lead to unpredictable
+ ** behavior.
+ */
+-SQLITE_API int SQLITE_CDECL sqlite3_config(int op, ...){
++SQLITE_API int sqlite3_config(int op, ...){
+   va_list ap;
+   int rc = SQLITE_OK;
+ 
+@@ -128490,9 +145344,10 @@
+       break;
+     }
+     case SQLITE_CONFIG_PAGECACHE: {
+-      /* EVIDENCE-OF: R-31408-40510 There are three arguments to
+-      ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory, the size
+-      ** of each page buffer (sz), and the number of pages (N). */
++      /* EVIDENCE-OF: R-18761-36601 There are three arguments to
++      ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory (pMem),
++      ** the size of each page cache line (sz), and the number of cache lines
++      ** (N). */
+       sqlite3GlobalConfig.pPage = va_arg(ap, void*);
+       sqlite3GlobalConfig.szPage = va_arg(ap, int);
+       sqlite3GlobalConfig.nPage = va_arg(ap, int);
+@@ -128678,6 +145533,11 @@
+       break;
+     }
+ 
++    case SQLITE_CONFIG_STMTJRNL_SPILL: {
++      sqlite3GlobalConfig.nStmtSpill = va_arg(ap, int);
++      break;
++    }
 +
-+/* One or more of the following flags are set to indicate the validOK
-+** representations of the value stored in the Mem struct.
-+**
-+** If the MEM_Null flag is set, then the value is an SQL NULL value.
-+** No other flags may be set in this case.
-+**
-+** If the MEM_Str flag is set then Mem.z points at a string representation.
-+** Usually this is encoded in the same unicode encoding as the main
-+** database (see below for exceptions). If the MEM_Term flag is also
-+** set, then the string is nul terminated. The MEM_Int and MEM_Real 
-+** flags may coexist with the MEM_Str flag.
+     default: {
+       rc = SQLITE_ERROR;
+       break;
+@@ -128699,6 +145559,7 @@
+ ** the lookaside memory.
+ */
+ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
++#ifndef SQLITE_OMIT_LOOKASIDE
+   void *pStart;
+   if( db->lookaside.nOut ){
+     return SQLITE_BUSY;
+@@ -128741,21 +145602,22 @@
+       p = (LookasideSlot*)&((u8*)p)[sz];
+     }
+     db->lookaside.pEnd = p;
+-    db->lookaside.bEnabled = 1;
++    db->lookaside.bDisable = 0;
+     db->lookaside.bMalloced = pBuf==0 ?1:0;
+   }else{
+     db->lookaside.pStart = db;
+     db->lookaside.pEnd = db;
+-    db->lookaside.bEnabled = 0;
++    db->lookaside.bDisable = 1;
+     db->lookaside.bMalloced = 0;
+   }
++#endif /* SQLITE_OMIT_LOOKASIDE */
+   return SQLITE_OK;
+ }
+ 
+ /*
+ ** Return the mutex associated with a database connection.
+ */
+-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3 *db){
++SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(db) ){
+     (void)SQLITE_MISUSE_BKPT;
+@@ -128769,7 +145631,7 @@
+ ** Free up as much memory as we can from the given database
+ ** connection.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3 *db){
++SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
+   int i;
+ 
+ #ifdef SQLITE_ENABLE_API_ARMOR
+@@ -128790,13 +145652,50 @@
+ }
+ 
+ /*
++** Flush any dirty pages in the pager-cache for any attached database
++** to disk.
 +*/
-+#define MEM_Null      0x0001   /* Value is NULL */
-+#define MEM_Str       0x0002   /* Value is a string */
-+#define MEM_Int       0x0004   /* Value is an integer */
-+#define MEM_Real      0x0008   /* Value is a real number */
-+#define MEM_Blob      0x0010   /* Value is a BLOB */
-+#define MEM_AffMask   0x001f   /* Mask of affinity bits */
-+#define MEM_RowSet    0x0020   /* Value is a RowSet object */
-+#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
-+#define MEM_Undefined 0x0080   /* Value is undefined */
-+#define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
-+#define MEM_TypeMask  0x01ff   /* Mask of type bits */
-+
++SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){
++  int i;
++  int rc = SQLITE_OK;
++  int bSeenBusy = 0;
 +
-+/* Whenever Mem contains a valid string or blob representation, one of
-+** the following flags must be set to determine the memory management
-+** policy for Mem.z.  The MEM_Term flag tells us whether or not the
-+** string is \000 or \u0000 terminated
-+*/
-+#define MEM_Term      0x0200   /* String rep is nul terminated */
-+#define MEM_Dyn       0x0400   /* Need to call Mem.xDel() on Mem.z */
-+#define MEM_Static    0x0800   /* Mem.z points to a static string */
-+#define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
-+#define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
-+#define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
-+#ifdef SQLITE_OMIT_INCRBLOB
-+  #undef MEM_Zero
-+  #define MEM_Zero 0x0000
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
 +#endif
++  sqlite3_mutex_enter(db->mutex);
++  sqlite3BtreeEnterAll(db);
++  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
++    Btree *pBt = db->aDb[i].pBt;
++    if( pBt && sqlite3BtreeIsInTrans(pBt) ){
++      Pager *pPager = sqlite3BtreePager(pBt);
++      rc = sqlite3PagerFlush(pPager);
++      if( rc==SQLITE_BUSY ){
++        bSeenBusy = 1;
++        rc = SQLITE_OK;
++      }
++    }
++  }
++  sqlite3BtreeLeaveAll(db);
++  sqlite3_mutex_leave(db->mutex);
++  return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc);
++}
 +
 +/*
-+** Clear any existing type flags from a Mem and replace them with f
-+*/
-+#define MemSetTypeFlag(p, f) \
-+   ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
-+
-+/*
-+** Return true if a memory cell is not marked as invalid.  This macro
-+** is for use inside assert() statements only.
+ ** Configuration settings for an individual database connection
+ */
+-SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3 *db, int op, ...){
++SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
+   va_list ap;
+   int rc;
+   va_start(ap, op);
+   switch( op ){
++    case SQLITE_DBCONFIG_MAINDBNAME: {
++      /* IMP: R-06824-28531 */
++      /* IMP: R-36257-52125 */
++      db->aDb[0].zDbSName = va_arg(ap,char*);
++      rc = SQLITE_OK;
++      break;
++    }
+     case SQLITE_DBCONFIG_LOOKASIDE: {
+       void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
+       int sz = va_arg(ap, int);       /* IMP: R-47871-25994 */
+@@ -128809,8 +145708,12 @@
+         int op;      /* The opcode */
+         u32 mask;    /* Mask of the bit in sqlite3.flags to set/clear */
+       } aFlagOp[] = {
+-        { SQLITE_DBCONFIG_ENABLE_FKEY,    SQLITE_ForeignKeys    },
+-        { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger  },
++        { SQLITE_DBCONFIG_ENABLE_FKEY,           SQLITE_ForeignKeys    },
++        { SQLITE_DBCONFIG_ENABLE_TRIGGER,        SQLITE_EnableTrigger  },
++        { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer  },
++        { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension  },
++        { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE,      SQLITE_NoCkptOnClose  },
++        { SQLITE_DBCONFIG_ENABLE_QPSG,           SQLITE_EnableQPSG     },
+       };
+       unsigned int i;
+       rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
+@@ -128867,6 +145770,7 @@
+   /* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
+   ** strings byte by byte using the memcmp() function from the standard C
+   ** library. */
++  assert( pKey1 && pKey2 );
+   rc = memcmp(pKey1, pKey2, n);
+   if( rc==0 ){
+     if( padFlag
+@@ -128911,7 +145815,7 @@
+ /*
+ ** Return the ROWID of the most recent insert
+ */
+-SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3 *db){
++SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(db) ){
+     (void)SQLITE_MISUSE_BKPT;
+@@ -128922,9 +145826,24 @@
+ }
+ 
+ /*
++** Set the value returned by the sqlite3_last_insert_rowid() API function.
 +*/
-+#ifdef SQLITE_DEBUG
-+#define memIsValid(M)  ((M)->flags & MEM_Undefined)==0
++SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !sqlite3SafetyCheckOk(db) ){
++    (void)SQLITE_MISUSE_BKPT;
++    return;
++  }
 +#endif
++  sqlite3_mutex_enter(db->mutex);
++  db->lastRowid = iRowid;
++  sqlite3_mutex_leave(db->mutex);
++}
 +
 +/*
-+** Each auxiliary data pointer stored by a user defined function 
-+** implementation calling sqlite3_set_auxdata() is stored in an instance
-+** of this structure. All such structures associated with a single VM
-+** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
-+** when the VM is halted (if not before).
-+*/
-+struct AuxData {
-+  int iOp;                        /* Instruction number of OP_Function opcode */
-+  int iArg;                       /* Index of function argument. */
-+  void *pAux;                     /* Aux data pointer */
-+  void (*xDelete)(void *);        /* Destructor for the aux data */
-+  AuxData *pNext;                 /* Next element in list */
-+};
-+
-+/*
-+** The "context" argument for an installable function.  A pointer to an
-+** instance of this structure is the first argument to the routines used
-+** implement the SQL functions.
-+**
-+** There is a typedef for this structure in sqlite.h.  So all routines,
-+** even the public interface to SQLite, can use a pointer to this structure.
-+** But this file is the only place where the internal details of this
-+** structure are known.
-+**
-+** This structure is defined inside of vdbeInt.h because it uses substructures
-+** (Mem) which are only defined there.
-+*/
-+struct sqlite3_context {
-+  Mem *pOut;            /* The return value is stored here */
-+  FuncDef *pFunc;       /* Pointer to function information */
-+  Mem *pMem;            /* Memory cell used to store aggregate context */
-+  Vdbe *pVdbe;          /* The VM that owns this context */
-+  int iOp;              /* Instruction number of OP_Function */
-+  int isError;          /* Error code returned by the function. */
-+  u8 skipFlag;          /* Skip accumulator loading if true */
-+  u8 fErrorOrAux;       /* isError!=0 or pVdbe->pAuxData modified */
-+};
-+
-+/*
-+** An Explain object accumulates indented output which is helpful
-+** in describing recursive data structures.
-+*/
-+struct Explain {
-+  Vdbe *pVdbe;       /* Attach the explanation to this Vdbe */
-+  StrAccum str;      /* The string being accumulated */
-+  int nIndent;       /* Number of elements in aIndent */
-+  u16 aIndent[100];  /* Levels of indentation */
-+  char zBase[100];   /* Initial space */
-+};
-+
-+/* A bitfield type for use inside of structures.  Always follow with :N where
-+** N is the number of bits.
-+*/
-+typedef unsigned bft;  /* Bit Field Type */
-+
-+typedef struct ScanStatus ScanStatus;
-+struct ScanStatus {
-+  int addrExplain;                /* OP_Explain for loop */
-+  int addrLoop;                   /* Address of "loops" counter */
-+  int addrVisit;                  /* Address of "rows visited" counter */
-+  int iSelectID;                  /* The "Select-ID" for this loop */
-+  LogEst nEst;                    /* Estimated output rows per loop */
-+  char *zName;                    /* Name of table or index */
-+};
+ ** Return the number of changes in the most recent call to sqlite3_exec().
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3 *db){
++SQLITE_API int sqlite3_changes(sqlite3 *db){
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(db) ){
+     (void)SQLITE_MISUSE_BKPT;
+@@ -128937,7 +145856,7 @@
+ /*
+ ** Return the number of changes since the database handle was opened.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3 *db){
++SQLITE_API int sqlite3_total_changes(sqlite3 *db){
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(db) ){
+     (void)SQLITE_MISUSE_BKPT;
+@@ -128970,7 +145889,7 @@
+ ** with SQLITE_ANY as the encoding.
+ */
+ static void functionDestroy(sqlite3 *db, FuncDef *p){
+-  FuncDestructor *pDestructor = p->pDestructor;
++  FuncDestructor *pDestructor = p->u.pDestructor;
+   if( pDestructor ){
+     pDestructor->nRef--;
+     if( pDestructor->nRef==0 ){
+@@ -128987,17 +145906,23 @@
+ static void disconnectAllVtab(sqlite3 *db){
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+   int i;
++  HashElem *p;
+   sqlite3BtreeEnterAll(db);
+   for(i=0; i<db->nDb; i++){
+     Schema *pSchema = db->aDb[i].pSchema;
+     if( db->aDb[i].pSchema ){
+-      HashElem *p;
+       for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
+         Table *pTab = (Table *)sqliteHashData(p);
+         if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
+       }
+     }
+   }
++  for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){
++    Module *pMod = (Module *)sqliteHashData(p);
++    if( pMod->pEpoTab ){
++      sqlite3VtabDisconnect(db, pMod->pEpoTab);
++    }
++  }
+   sqlite3VtabUnlockList(db);
+   sqlite3BtreeLeaveAll(db);
+ #else
+@@ -129033,6 +145958,9 @@
+     return SQLITE_MISUSE_BKPT;
+   }
+   sqlite3_mutex_enter(db->mutex);
++  if( db->mTrace & SQLITE_TRACE_CLOSE ){
++    db->xTrace(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0);
++  }
+ 
+   /* Force xDisconnect calls on all virtual tables */
+   disconnectAllVtab(db);
+@@ -129079,8 +146007,8 @@
+ ** unclosed resources, and arranges for deallocation when the last
+ ** prepare statement or sqlite3_backup closes.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
+-SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
++SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
++SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
+ 
+ 
+ /*
+@@ -129146,18 +146074,17 @@
+   */
+   sqlite3ConnectionClosed(db);
+ 
+-  for(j=0; j<ArraySize(db->aFunc.a); j++){
+-    FuncDef *pNext, *pHash, *p;
+-    for(p=db->aFunc.a[j]; p; p=pHash){
+-      pHash = p->pHash;
+-      while( p ){
+-        functionDestroy(db, p);
+-        pNext = p->pNext;
+-        sqlite3DbFree(db, p);
+-        p = pNext;
+-      }
+-    }
++  for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
++    FuncDef *pNext, *p;
++    p = sqliteHashData(i);
++    do{
++      functionDestroy(db, p);
++      pNext = p->pNext;
++      sqlite3DbFree(db, p);
++      p = pNext;
++    }while( p );
+   }
++  sqlite3HashClear(&db->aFunc);
+   for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
+     CollSeq *pColl = (CollSeq *)sqliteHashData(i);
+     /* Invoke any destructors registered for collation sequence user data. */
+@@ -129175,6 +146102,7 @@
+     if( pMod->xDestroy ){
+       pMod->xDestroy(pMod->pAux);
+     }
++    sqlite3VtabEponymousTableClear(db, pMod);
+     sqlite3DbFree(db, pMod);
+   }
+   sqlite3HashClear(&db->aModule);
+@@ -129375,10 +146303,10 @@
+ SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){
+   static const char* const aMsg[] = {
+     /* SQLITE_OK          */ "not an error",
+-    /* SQLITE_ERROR       */ "SQL logic error or missing database",
++    /* SQLITE_ERROR       */ "SQL logic error",
+     /* SQLITE_INTERNAL    */ 0,
+     /* SQLITE_PERM        */ "access permission denied",
+-    /* SQLITE_ABORT       */ "callback requested query abort",
++    /* SQLITE_ABORT       */ "query aborted",
+     /* SQLITE_BUSY        */ "database is locked",
+     /* SQLITE_LOCKED      */ "database table is locked",
+     /* SQLITE_NOMEM       */ "out of memory",
+@@ -129390,17 +146318,21 @@
+     /* SQLITE_FULL        */ "database or disk is full",
+     /* SQLITE_CANTOPEN    */ "unable to open database file",
+     /* SQLITE_PROTOCOL    */ "locking protocol",
+-    /* SQLITE_EMPTY       */ "table contains no data",
++    /* SQLITE_EMPTY       */ 0,
+     /* SQLITE_SCHEMA      */ "database schema has changed",
+     /* SQLITE_TOOBIG      */ "string or blob too big",
+     /* SQLITE_CONSTRAINT  */ "constraint failed",
+     /* SQLITE_MISMATCH    */ "datatype mismatch",
+-    /* SQLITE_MISUSE      */ "library routine called out of sequence",
++    /* SQLITE_MISUSE      */ "bad parameter or other API misuse",
++#ifdef SQLITE_DISABLE_LFS
+     /* SQLITE_NOLFS       */ "large file support is disabled",
++#else
++    /* SQLITE_NOLFS       */ 0,
++#endif
+     /* SQLITE_AUTH        */ "authorization denied",
+-    /* SQLITE_FORMAT      */ "auxiliary database format error",
+-    /* SQLITE_RANGE       */ "bind or column index out of range",
+-    /* SQLITE_NOTADB      */ "file is encrypted or is not a database",
++    /* SQLITE_FORMAT      */ 0,
++    /* SQLITE_RANGE       */ "column index out of range",
++    /* SQLITE_NOTADB      */ "file is not a database",
+   };
+   const char *zErr = "unknown error";
+   switch( rc ){
+@@ -129487,7 +146419,7 @@
+ ** This routine sets the busy callback for an Sqlite database to the
+ ** given callback function with the given argument.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(
++SQLITE_API int sqlite3_busy_handler(
+   sqlite3 *db,
+   int (*xBusy)(void*,int),
+   void *pArg
+@@ -129510,7 +146442,7 @@
+ ** given callback function with the given argument. The progress callback will
+ ** be invoked every nOps opcodes.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(
++SQLITE_API void sqlite3_progress_handler(
+   sqlite3 *db, 
+   int nOps,
+   int (*xProgress)(void*), 
+@@ -129541,7 +146473,7 @@
+ ** This routine installs a default busy handler that waits for the
+ ** specified number of milliseconds before returning 0.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3 *db, int ms){
++SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+ #endif
+@@ -129557,9 +146489,9 @@
+ /*
+ ** Cause any pending operation to stop at its earliest opportunity.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3 *db){
++SQLITE_API void sqlite3_interrupt(sqlite3 *db){
+ #ifdef SQLITE_ENABLE_API_ARMOR
+-  if( !sqlite3SafetyCheckOk(db) ){
++  if( !sqlite3SafetyCheckOk(db) && (db==0 || db->magic!=SQLITE_MAGIC_ZOMBIE) ){
+     (void)SQLITE_MISUSE_BKPT;
+     return;
+   }
+@@ -129580,7 +146512,7 @@
+   int nArg,
+   int enc,
+   void *pUserData,
+-  void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
++  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
+   void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+   void (*xFinal)(sqlite3_context*),
+   FuncDestructor *pDestructor
+@@ -129591,9 +146523,9 @@
+ 
+   assert( sqlite3_mutex_held(db->mutex) );
+   if( zFunctionName==0 ||
+-      (xFunc && (xFinal || xStep)) || 
+-      (!xFunc && (xFinal && !xStep)) ||
+-      (!xFunc && (!xFinal && xStep)) ||
++      (xSFunc && (xFinal || xStep)) || 
++      (!xSFunc && (xFinal && !xStep)) ||
++      (!xSFunc && (!xFinal && xStep)) ||
+       (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
+       (255<(nName = sqlite3Strlen30( zFunctionName))) ){
+     return SQLITE_MISUSE_BKPT;
+@@ -129616,10 +146548,10 @@
+   }else if( enc==SQLITE_ANY ){
+     int rc;
+     rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags,
+-         pUserData, xFunc, xStep, xFinal, pDestructor);
++         pUserData, xSFunc, xStep, xFinal, pDestructor);
+     if( rc==SQLITE_OK ){
+       rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags,
+-          pUserData, xFunc, xStep, xFinal, pDestructor);
++          pUserData, xSFunc, xStep, xFinal, pDestructor);
+     }
+     if( rc!=SQLITE_OK ){
+       return rc;
+@@ -129635,7 +146567,7 @@
+   ** is being overridden/deleted but there are no active VMs, allow the
+   ** operation to continue but invalidate all precompiled statements.
+   */
+-  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
++  p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0);
+   if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
+     if( db->nVdbeActive ){
+       sqlite3ErrorWithMsg(db, SQLITE_BUSY, 
+@@ -129647,10 +146579,10 @@
+     }
+   }
+ 
+-  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1);
++  p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1);
+   assert(p || db->mallocFailed);
+   if( !p ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+ 
+   /* If an older version of the function with a configured destructor is
+@@ -129660,11 +146592,10 @@
+   if( pDestructor ){
+     pDestructor->nRef++;
+   }
+-  p->pDestructor = pDestructor;
++  p->u.pDestructor = pDestructor;
+   p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
+   testcase( p->funcFlags & SQLITE_DETERMINISTIC );
+-  p->xFunc = xFunc;
+-  p->xStep = xStep;
++  p->xSFunc = xSFunc ? xSFunc : xStep;
+   p->xFinalize = xFinal;
+   p->pUserData = pUserData;
+   p->nArg = (u16)nArg;
+@@ -129674,27 +146605,27 @@
+ /*
+ ** Create new user functions.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
++SQLITE_API int sqlite3_create_function(
+   sqlite3 *db,
+   const char *zFunc,
+   int nArg,
+   int enc,
+   void *p,
+-  void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
++  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
+   void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+   void (*xFinal)(sqlite3_context*)
+ ){
+-  return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xFunc, xStep,
++  return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xSFunc, xStep,
+                                     xFinal, 0);
+ }
+ 
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
++SQLITE_API int sqlite3_create_function_v2(
+   sqlite3 *db,
+   const char *zFunc,
+   int nArg,
+   int enc,
+   void *p,
+-  void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
++  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
+   void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+   void (*xFinal)(sqlite3_context*),
+   void (*xDestroy)(void *)
+@@ -129717,7 +146648,7 @@
+     pArg->xDestroy = xDestroy;
+     pArg->pUserData = p;
+   }
+-  rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xFunc, xStep, xFinal, pArg);
++  rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, pArg);
+   if( pArg && pArg->nRef==0 ){
+     assert( rc!=SQLITE_OK );
+     xDestroy(p);
+@@ -129731,13 +146662,13 @@
+ }
+ 
+ #ifndef SQLITE_OMIT_UTF16
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
++SQLITE_API int sqlite3_create_function16(
+   sqlite3 *db,
+   const void *zFunctionName,
+   int nArg,
+   int eTextRep,
+   void *p,
+-  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
++  void (*xSFunc)(sqlite3_context*,int,sqlite3_value**),
+   void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+   void (*xFinal)(sqlite3_context*)
+ ){
+@@ -129750,7 +146681,7 @@
+   sqlite3_mutex_enter(db->mutex);
+   assert( !db->mallocFailed );
+   zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
+-  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal,0);
++  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0);
+   sqlite3DbFree(db, zFunc8);
+   rc = sqlite3ApiExit(db, rc);
+   sqlite3_mutex_leave(db->mutex);
+@@ -129771,12 +146702,11 @@
+ ** A global function must exist in order for name resolution to work
+ ** properly.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(
++SQLITE_API int sqlite3_overload_function(
+   sqlite3 *db,
+   const char *zName,
+   int nArg
+ ){
+-  int nName = sqlite3Strlen30(zName);
+   int rc = SQLITE_OK;
+ 
+ #ifdef SQLITE_ENABLE_API_ARMOR
+@@ -129785,7 +146715,7 @@
+   }
+ #endif
+   sqlite3_mutex_enter(db->mutex);
+-  if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
++  if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){
+     rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
+                            0, sqlite3InvalidFunction, 0, 0, 0);
+   }
+@@ -129803,7 +146733,8 @@
+ ** trace is a pointer to a function that is invoked at the start of each
+ ** SQL statement.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
++#ifndef SQLITE_OMIT_DEPRECATED
++SQLITE_API void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){
+   void *pOld;
+ 
+ #ifdef SQLITE_ENABLE_API_ARMOR
+@@ -129814,11 +146745,38 @@
+ #endif
+   sqlite3_mutex_enter(db->mutex);
+   pOld = db->pTraceArg;
+-  db->xTrace = xTrace;
++  db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0;
++  db->xTrace = (int(*)(u32,void*,void*,void*))xTrace;
+   db->pTraceArg = pArg;
+   sqlite3_mutex_leave(db->mutex);
+   return pOld;
+ }
++#endif /* SQLITE_OMIT_DEPRECATED */
 +
-+/*
-+** An instance of the virtual machine.  This structure contains the complete
-+** state of the virtual machine.
-+**
-+** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
-+** is really a pointer to an instance of this structure.
++/* Register a trace callback using the version-2 interface.
 +*/
-+struct Vdbe {
-+  sqlite3 *db;            /* The database connection that owns this statement */
-+  Op *aOp;                /* Space to hold the virtual machine's program */
-+  Mem *aMem;              /* The memory locations */
-+  Mem **apArg;            /* Arguments to currently executing user function */
-+  Mem *aColName;          /* Column names to return */
-+  Mem *pResultSet;        /* Pointer to an array of results */
-+  Parse *pParse;          /* Parsing context used to create this Vdbe */
-+  int nMem;               /* Number of memory locations currently allocated */
-+  int nOp;                /* Number of instructions in the program */
-+  int nCursor;            /* Number of slots in apCsr[] */
-+  u32 magic;              /* Magic number for sanity checking */
-+  char *zErrMsg;          /* Error message written here */
-+  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
-+  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
-+  Mem *aVar;              /* Values for the OP_Variable opcode. */
-+  char **azVar;           /* Name of variables */
-+  ynVar nVar;             /* Number of entries in aVar[] */
-+  ynVar nzVar;            /* Number of entries in azVar[] */
-+  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
-+  int pc;                 /* The program counter */
-+  int rc;                 /* Value to return */
-+#ifdef SQLITE_DEBUG
-+  int rcApp;              /* errcode set by sqlite3_result_error_code() */
-+#endif
-+  u16 nResColumn;         /* Number of columns in one row of the result set */
-+  u8 errorAction;         /* Recovery action to do in case of an error */
-+  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
-+  bft explain:2;          /* True if EXPLAIN present on SQL command */
-+  bft changeCntOn:1;      /* True to update the change-counter */
-+  bft expired:1;          /* True if the VM needs to be recompiled */
-+  bft runOnlyOnce:1;      /* Automatically expire on reset */
-+  bft usesStmtJournal:1;  /* True if uses a statement journal */
-+  bft readOnly:1;         /* True for statements that do not write */
-+  bft bIsReader:1;        /* True for statements that read */
-+  bft isPrepareV2:1;      /* True if prepared with prepare_v2() */
-+  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
-+  int nChange;            /* Number of db changes made since last reset */
-+  yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
-+  yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
-+  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
-+  u32 aCounter[5];        /* Counters used by sqlite3_stmt_status() */
-+#ifndef SQLITE_OMIT_TRACE
-+  i64 startTime;          /* Time when query started - used for profiling */
-+#endif
-+  i64 iCurrentTime;       /* Value of julianday('now') for this statement */
-+  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
-+  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
-+  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
-+  char *zSql;             /* Text of the SQL statement that generated this */
-+  void *pFree;            /* Free this when deleting the vdbe */
-+  VdbeFrame *pFrame;      /* Parent frame */
-+  VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
-+  int nFrame;             /* Number of frames in pFrame list */
-+  u32 expmask;            /* Binding to these vars invalidates VM */
-+  SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
-+  int nOnceFlag;          /* Size of array aOnceFlag[] */
-+  u8 *aOnceFlag;          /* Flags for OP_Once */
-+  AuxData *pAuxData;      /* Linked list of auxdata allocations */
-+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
-+  i64 *anExec;            /* Number of times each op has been executed */
-+  int nScan;              /* Entries in aScan[] */
-+  ScanStatus *aScan;      /* Scan definitions for sqlite3_stmt_scanstatus() */
++SQLITE_API int sqlite3_trace_v2(
++  sqlite3 *db,                               /* Trace this connection */
++  unsigned mTrace,                           /* Mask of events to be traced */
++  int(*xTrace)(unsigned,void*,void*,void*),  /* Callback to invoke */
++  void *pArg                                 /* Context */
++){
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !sqlite3SafetyCheckOk(db) ){
++    return SQLITE_MISUSE_BKPT;
++  }
 +#endif
-+};
++  sqlite3_mutex_enter(db->mutex);
++  if( mTrace==0 ) xTrace = 0;
++  if( xTrace==0 ) mTrace = 0;
++  db->mTrace = mTrace;
++  db->xTrace = xTrace;
++  db->pTraceArg = pArg;
++  sqlite3_mutex_leave(db->mutex);
++  return SQLITE_OK;
++}
 +
++#ifndef SQLITE_OMIT_DEPRECATED
+ /*
+ ** Register a profile function.  The pArg from the previously registered 
+ ** profile function is returned.  
+@@ -129827,7 +146785,7 @@
+ ** profile is a pointer to a function that is invoked at the conclusion of
+ ** each SQL statement that is run.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_profile(
++SQLITE_API void *sqlite3_profile(
+   sqlite3 *db,
+   void (*xProfile)(void*,const char*,sqlite_uint64),
+   void *pArg
+@@ -129847,6 +146805,7 @@
+   sqlite3_mutex_leave(db->mutex);
+   return pOld;
+ }
++#endif /* SQLITE_OMIT_DEPRECATED */
+ #endif /* SQLITE_OMIT_TRACE */
+ 
+ /*
+@@ -129854,7 +146813,7 @@
+ ** If the invoked function returns non-zero, then the commit becomes a
+ ** rollback.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(
++SQLITE_API void *sqlite3_commit_hook(
+   sqlite3 *db,              /* Attach the hook to this database */
+   int (*xCallback)(void*),  /* Function to invoke on each commit */
+   void *pArg                /* Argument to the function */
+@@ -129879,7 +146838,7 @@
+ ** Register a callback to be invoked each time a row is updated,
+ ** inserted or deleted using this database connection.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
++SQLITE_API void *sqlite3_update_hook(
+   sqlite3 *db,              /* Attach the hook to this database */
+   void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
+   void *pArg                /* Argument to the function */
+@@ -129904,7 +146863,7 @@
+ ** Register a callback to be invoked each time a transaction is rolled
+ ** back by this database connection.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(
++SQLITE_API void *sqlite3_rollback_hook(
+   sqlite3 *db,              /* Attach the hook to this database */
+   void (*xCallback)(void*), /* Callback function */
+   void *pArg                /* Argument to the function */
+@@ -129925,6 +146884,27 @@
+   return pRet;
+ }
+ 
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
 +/*
-+** The following are allowed values for Vdbe.magic
++** Register a callback to be invoked each time a row is updated,
++** inserted or deleted using this database connection.
 +*/
-+#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
-+#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
-+#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
-+#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */
++SQLITE_API void *sqlite3_preupdate_hook(
++  sqlite3 *db,              /* Attach the hook to this database */
++  void(*xCallback)(         /* Callback function */
++    void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64),
++  void *pArg                /* First callback argument */
++){
++  void *pRet;
++  sqlite3_mutex_enter(db->mutex);
++  pRet = db->pPreUpdateArg;
++  db->xPreUpdateCallback = xCallback;
++  db->pPreUpdateArg = pArg;
++  sqlite3_mutex_leave(db->mutex);
++  return pRet;
++}
++#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
 +
-+/*
-+** Function prototypes
-+*/
-+SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
-+void sqliteVdbePopStack(Vdbe*,int);
-+SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
-+SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
-+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
-+SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
-+#endif
-+SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
-+SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
-+SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
-+SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
-+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
-+
-+int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
-+SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
-+SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
-+SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
-+SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
-+SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
-+SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
-+SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
-+SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*);
-+SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
-+SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*);
-+SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*);
-+SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
-+SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64);
-+#ifdef SQLITE_OMIT_FLOATING_POINT
-+# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64
-+#else
-+SQLITE_PRIVATE   void sqlite3VdbeMemSetDouble(Mem*, double);
-+#endif
-+SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
-+SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
-+SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
-+SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*);
-+SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
-+SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
-+SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
-+SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
-+SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
-+SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
-+SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
-+SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
-+SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8);
-+SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
-+SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
-+#define VdbeMemDynamic(X)  \
-+  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
-+SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
-+SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
-+SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
-+SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
-+SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
-+SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
-+SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
-+SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
-+
-+SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *);
-+SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *);
-+SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
-+SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
-+SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
-+SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
-+SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
-+SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
+ #ifndef SQLITE_OMIT_WAL
+ /*
+ ** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
+@@ -129958,7 +146938,7 @@
+ ** using sqlite3_wal_hook() disables the automatic checkpoint mechanism
+ ** configured by this function.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
++SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
+ #ifdef SQLITE_OMIT_WAL
+   UNUSED_PARAMETER(db);
+   UNUSED_PARAMETER(nFrame);
+@@ -129979,7 +146959,7 @@
+ ** Register a callback to be invoked each time a transaction is written
+ ** into the write-ahead-log by this database connection.
+ */
+-SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
++SQLITE_API void *sqlite3_wal_hook(
+   sqlite3 *db,                    /* Attach the hook to this db handle */
+   int(*xCallback)(void *, sqlite3*, const char*, int),
+   void *pArg                      /* First argument passed to xCallback() */
+@@ -130006,7 +146986,7 @@
+ /*
+ ** Checkpoint database zDb.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
++SQLITE_API int sqlite3_wal_checkpoint_v2(
+   sqlite3 *db,                    /* Database handle */
+   const char *zDb,                /* Name of attached database (or NULL) */
+   int eMode,                      /* SQLITE_CHECKPOINT_* value */
+@@ -130050,6 +147030,13 @@
+     sqlite3Error(db, rc);
+   }
+   rc = sqlite3ApiExit(db, rc);
 +
-+#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
-+SQLITE_PRIVATE   void sqlite3VdbeEnter(Vdbe*);
-+SQLITE_PRIVATE   void sqlite3VdbeLeave(Vdbe*);
++  /* If there are no active statements, clear the interrupt flag at this
++  ** point.  */
++  if( db->nVdbeActive==0 ){
++    db->u1.isInterrupted = 0;
++  }
++
+   sqlite3_mutex_leave(db->mutex);
+   return rc;
+ #endif
+@@ -130061,7 +147048,7 @@
+ ** to contains a zero-length string, all attached databases are 
+ ** checkpointed.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
++SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
+   /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to
+   ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */
+   return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0);
+@@ -130139,9 +147126,11 @@
+   return ( db->temp_store!=1 );
+ #endif
+ #if SQLITE_TEMP_STORE==3
++  UNUSED_PARAMETER(db);
+   return 1;
+ #endif
+ #if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3
++  UNUSED_PARAMETER(db);
+   return 0;
+ #endif
+ }
+@@ -130150,17 +147139,17 @@
+ ** Return UTF-8 encoded English language explanation of the most recent
+ ** error.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3 *db){
++SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
+   const char *z;
+   if( !db ){
+-    return sqlite3ErrStr(SQLITE_NOMEM);
++    return sqlite3ErrStr(SQLITE_NOMEM_BKPT);
+   }
+   if( !sqlite3SafetyCheckSickOrOk(db) ){
+     return sqlite3ErrStr(SQLITE_MISUSE_BKPT);
+   }
+   sqlite3_mutex_enter(db->mutex);
+   if( db->mallocFailed ){
+-    z = sqlite3ErrStr(SQLITE_NOMEM);
++    z = sqlite3ErrStr(SQLITE_NOMEM_BKPT);
+   }else{
+     testcase( db->pErr==0 );
+     z = (char*)sqlite3_value_text(db->pErr);
+@@ -130178,17 +147167,14 @@
+ ** Return UTF-16 encoded English language explanation of the most recent
+ ** error.
+ */
+-SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3 *db){
++SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
+   static const u16 outOfMem[] = {
+     'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0
+   };
+   static const u16 misuse[] = {
+-    'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ', 
+-    'r', 'o', 'u', 't', 'i', 'n', 'e', ' ', 
+-    'c', 'a', 'l', 'l', 'e', 'd', ' ', 
+-    'o', 'u', 't', ' ', 
+-    'o', 'f', ' ', 
+-    's', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 0
++    'b', 'a', 'd', ' ', 'p', 'a', 'r', 'a', 'm', 'e', 't', 'e', 'r', ' ',
++    'o', 'r', ' ', 'o', 't', 'h', 'e', 'r', ' ', 'A', 'P', 'I', ' ',
++    'm', 'i', 's', 'u', 's', 'e', 0
+   };
+ 
+   const void *z;
+@@ -130212,7 +147198,7 @@
+     ** be cleared before returning. Do this directly, instead of via
+     ** sqlite3ApiExit(), to avoid setting the database handle error message.
+     */
+-    db->mallocFailed = 0;
++    sqlite3OomClear(db);
+   }
+   sqlite3_mutex_leave(db->mutex);
+   return z;
+@@ -130223,31 +147209,34 @@
+ ** Return the most recent error code generated by an SQLite routine. If NULL is
+ ** passed to this function, we assume a malloc() failed during sqlite3_open().
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db){
++SQLITE_API int sqlite3_errcode(sqlite3 *db){
+   if( db && !sqlite3SafetyCheckSickOrOk(db) ){
+     return SQLITE_MISUSE_BKPT;
+   }
+   if( !db || db->mallocFailed ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   return db->errCode & db->errMask;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db){
++SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){
+   if( db && !sqlite3SafetyCheckSickOrOk(db) ){
+     return SQLITE_MISUSE_BKPT;
+   }
+   if( !db || db->mallocFailed ){
+-    return SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }
+   return db->errCode;
+ }
++SQLITE_API int sqlite3_system_errno(sqlite3 *db){
++  return db ? db->iSysErrno : 0;
++}  
+ 
+ /*
+ ** 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 *SQLITE_STDCALL sqlite3_errstr(int rc){
++SQLITE_API const char *sqlite3_errstr(int rc){
+   return sqlite3ErrStr(rc);
+ }
+ 
+@@ -130317,7 +147306,7 @@
+   }
+ 
+   pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
+-  if( pColl==0 ) return SQLITE_NOMEM;
++  if( pColl==0 ) return SQLITE_NOMEM_BKPT;
+   pColl->xCmp = xCompare;
+   pColl->pUser = pCtx;
+   pColl->xDel = xDel;
+@@ -130365,8 +147354,8 @@
+ #if SQLITE_MAX_VDBE_OP<40
+ # error SQLITE_MAX_VDBE_OP must be at least 40
+ #endif
+-#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
+-# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
++#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127
++# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127
+ #endif
+ #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125
+ # error SQLITE_MAX_ATTACHED must be between 0 and 125
+@@ -130395,7 +147384,7 @@
+ ** It merely prevents new constructs that exceed the limit
+ ** from forming.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
++SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
+   int oldLimit;
+ 
+ #ifdef SQLITE_ENABLE_API_ARMOR
+@@ -130496,7 +147485,7 @@
+ 
+     for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
+     zFile = sqlite3_malloc64(nByte);
+-    if( !zFile ) return SQLITE_NOMEM;
++    if( !zFile ) return SQLITE_NOMEM_BKPT;
+ 
+     iIn = 5;
+ #ifdef SQLITE_ALLOW_URI_AUTHORITY
+@@ -130547,6 +147536,7 @@
+ 
+         assert( octet>=0 && octet<256 );
+         if( octet==0 ){
++#ifndef SQLITE_ENABLE_URI_00_ERROR
+           /* This branch is taken when "%00" appears within the URI. In this
+           ** case we ignore all text in the remainder of the path, name or
+           ** value currently being parsed. So ignore the current character
+@@ -130559,6 +147549,12 @@
+             iIn++;
+           }
+           continue;
 +#else
-+# define sqlite3VdbeEnter(X)
-+# define sqlite3VdbeLeave(X)
++          /* If ENABLE_URI_00_ERROR is defined, "%00" in a URI is an error. */
++          *pzErrMsg = sqlite3_mprintf("unexpected %%00 in uri");
++          rc = SQLITE_ERROR;
++          goto parse_uri_out;
 +#endif
-+
-+#ifdef SQLITE_DEBUG
-+SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*);
-+SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem*);
+         }
+         c = octet;
+       }else if( eState==1 && (c=='&' || c=='=') ){
+@@ -130662,8 +147658,10 @@
+ 
+   }else{
+     zFile = sqlite3_malloc64(nUri+2);
+-    if( !zFile ) return SQLITE_NOMEM;
+-    memcpy(zFile, zUri, nUri);
++    if( !zFile ) return SQLITE_NOMEM_BKPT;
++    if( nUri ){
++      memcpy(zFile, zUri, nUri);
++    }
+     zFile[nUri] = '\0';
+     zFile[nUri+1] = '\0';
+     flags &= ~SQLITE_OPEN_URI;
+@@ -130711,26 +147709,6 @@
+   if( rc ) return rc;
+ #endif
+ 
+-  /* Only allow sensible combinations of bits in the flags argument.  
+-  ** Throw an error if any non-sense combination is used.  If we
+-  ** do not block illegal combinations here, it could trigger
+-  ** assert() statements in deeper layers.  Sensible combinations
+-  ** are:
+-  **
+-  **  1:  SQLITE_OPEN_READONLY
+-  **  2:  SQLITE_OPEN_READWRITE
+-  **  6:  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
+-  */
+-  assert( SQLITE_OPEN_READONLY  == 0x01 );
+-  assert( SQLITE_OPEN_READWRITE == 0x02 );
+-  assert( SQLITE_OPEN_CREATE    == 0x04 );
+-  testcase( (1<<(flags&7))==0x02 ); /* READONLY */
+-  testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
+-  testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
+-  if( ((1<<(flags&7)) & 0x46)==0 ){
+-    return SQLITE_MISUSE_BKPT;  /* IMP: R-65497-44594 */
+-  }
+-
+   if( sqlite3GlobalConfig.bCoreMutex==0 ){
+     isThreadsafe = 0;
+   }else if( flags & SQLITE_OPEN_NOMUTEX ){
+@@ -130816,6 +147794,15 @@
+ #if defined(SQLITE_REVERSE_UNORDERED_SELECTS)
+                  | SQLITE_ReverseOrder
+ #endif
++#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
++                 | SQLITE_CellSizeCk
 +#endif
-+
-+#ifndef SQLITE_OMIT_FOREIGN_KEY
-+SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int);
-+#else
-+# define sqlite3VdbeCheckFk(p,i) 0
++#if defined(SQLITE_ENABLE_FTS3_TOKENIZER)
++                 | SQLITE_Fts3Tokenizer
 +#endif
-+
-+SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8);
-+#ifdef SQLITE_DEBUG
-+SQLITE_PRIVATE   void sqlite3VdbePrintSql(Vdbe*);
-+SQLITE_PRIVATE   void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
++#if defined(SQLITE_ENABLE_QPSG)
++                 | SQLITE_EnableQPSG
 +#endif
-+SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem);
-+
-+#ifndef SQLITE_OMIT_INCRBLOB
-+SQLITE_PRIVATE   int sqlite3VdbeMemExpandBlob(Mem *);
-+  #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)
-+#else
-+  #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK
-+  #define ExpandBlob(P) SQLITE_OK
+       ;
+   sqlite3HashInit(&db->aCollSeq);
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+@@ -130829,9 +147816,9 @@
+   ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating
+   ** functions:
+   */
+-  createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0);
+-  createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0);
+-  createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0);
++  createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0);
++  createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
++  createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
+   createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
+   createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
+   if( db->mallocFailed ){
+@@ -130840,14 +147827,35 @@
+   /* EVIDENCE-OF: R-08308-17224 The default collating function for all
+   ** strings is BINARY. 
+   */
+-  db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
++  db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0);
+   assert( db->pDfltColl!=0 );
+ 
+-  /* Parse the filename/URI argument. */
++  /* Parse the filename/URI argument
++  **
++  ** Only allow sensible combinations of bits in the flags argument.  
++  ** Throw an error if any non-sense combination is used.  If we
++  ** do not block illegal combinations here, it could trigger
++  ** assert() statements in deeper layers.  Sensible combinations
++  ** are:
++  **
++  **  1:  SQLITE_OPEN_READONLY
++  **  2:  SQLITE_OPEN_READWRITE
++  **  6:  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
++  */
+   db->openFlags = flags;
+-  rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
++  assert( SQLITE_OPEN_READONLY  == 0x01 );
++  assert( SQLITE_OPEN_READWRITE == 0x02 );
++  assert( SQLITE_OPEN_CREATE    == 0x04 );
++  testcase( (1<<(flags&7))==0x02 ); /* READONLY */
++  testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
++  testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
++  if( ((1<<(flags&7)) & 0x46)==0 ){
++    rc = SQLITE_MISUSE_BKPT;  /* IMP: R-65497-44594 */
++  }else{
++    rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
++  }
+   if( rc!=SQLITE_OK ){
+-    if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
++    if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
+     sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
+     sqlite3_free(zErrMsg);
+     goto opendb_out;
+@@ -130858,7 +147866,7 @@
+                         flags | SQLITE_OPEN_MAIN_DB);
+   if( rc!=SQLITE_OK ){
+     if( rc==SQLITE_IOERR_NOMEM ){
+-      rc = SQLITE_NOMEM;
++      rc = SQLITE_NOMEM_BKPT;
+     }
+     sqlite3Error(db, rc);
+     goto opendb_out;
+@@ -130869,13 +147877,13 @@
+   sqlite3BtreeLeave(db->aDb[0].pBt);
+   db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
+ 
+-  /* The default safety_level for the main database is 'full'; for the temp
+-  ** database it is 'NONE'. This matches the pager layer defaults.  
++  /* The default safety_level for the main database is FULL; for the temp
++  ** database it is OFF. This matches the pager layer defaults.  
+   */
+-  db->aDb[0].zName = "main";
+-  db->aDb[0].safety_level = 3;
+-  db->aDb[1].zName = "temp";
+-  db->aDb[1].safety_level = 1;
++  db->aDb[0].zDbSName = "main";
++  db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
++  db->aDb[1].zDbSName = "temp";
++  db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF;
+ 
+   db->magic = SQLITE_MAGIC_OPEN;
+   if( db->mallocFailed ){
+@@ -130887,12 +147895,21 @@
+   ** is accessed.
+   */
+   sqlite3Error(db, SQLITE_OK);
+-  sqlite3RegisterBuiltinFunctions(db);
++  sqlite3RegisterPerConnectionBuiltinFunctions(db);
++  rc = sqlite3_errcode(db);
++
++#ifdef SQLITE_ENABLE_FTS5
++  /* Register any built-in FTS5 module before loading the automatic
++  ** extensions. This allows automatic extensions to register FTS5 
++  ** tokenizers and auxiliary functions.  */
++  if( !db->mallocFailed && rc==SQLITE_OK ){
++    rc = sqlite3Fts5Init(db);
++  }
 +#endif
-+
-+#endif /* !defined(_VDBEINT_H_) */
-+
-+/************** End of vdbeInt.h *********************************************/
-+/************** Continuing where we left off in status.c *********************/
-+
-+/*
-+** Variables in which to record status information.
-+*/
-+typedef struct sqlite3StatType sqlite3StatType;
-+static SQLITE_WSD struct sqlite3StatType {
-+#if SQLITE_PTRSIZE>4
-+  sqlite3_int64 nowValue[10];         /* Current value */
-+  sqlite3_int64 mxValue[10];          /* Maximum value */
-+#else
-+  u32 nowValue[10];                   /* Current value */
-+  u32 mxValue[10];                    /* Maximum value */
-+#endif
-+} sqlite3Stat = { {0,}, {0,} };
-+
-+/*
-+** Elements of sqlite3Stat[] are protected by either the memory allocator
-+** mutex, or by the pcache1 mutex.  The following array determines which.
-+*/
-+static const char statMutex[] = {
-+  0,  /* SQLITE_STATUS_MEMORY_USED */
-+  1,  /* SQLITE_STATUS_PAGECACHE_USED */
-+  1,  /* SQLITE_STATUS_PAGECACHE_OVERFLOW */
-+  0,  /* SQLITE_STATUS_SCRATCH_USED */
-+  0,  /* SQLITE_STATUS_SCRATCH_OVERFLOW */
-+  0,  /* SQLITE_STATUS_MALLOC_SIZE */
-+  0,  /* SQLITE_STATUS_PARSER_STACK */
-+  1,  /* SQLITE_STATUS_PAGECACHE_SIZE */
-+  0,  /* SQLITE_STATUS_SCRATCH_SIZE */
-+  0,  /* SQLITE_STATUS_MALLOC_COUNT */
-+};
-+
-+
-+/* The "wsdStat" macro will resolve to the status information
-+** state vector.  If writable static data is unsupported on the target,
-+** we have to locate the state vector at run-time.  In the more common
-+** case where writable static data is supported, wsdStat can refer directly
-+** to the "sqlite3Stat" state vector declared above.
-+*/
-+#ifdef SQLITE_OMIT_WSD
-+# define wsdStatInit  sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat)
-+# define wsdStat x[0]
-+#else
-+# define wsdStatInit
-+# define wsdStat sqlite3Stat
+ 
+   /* Load automatic extensions - extensions that have been registered
+   ** using the sqlite3_automatic_extension() API.
+   */
+-  rc = sqlite3_errcode(db);
+   if( rc==SQLITE_OK ){
+     sqlite3AutoLoadExtensions(db);
+     rc = sqlite3_errcode(db);
+@@ -130915,7 +147932,7 @@
+   }
+ #endif
+ 
+-#ifdef SQLITE_ENABLE_FTS3
++#ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */
+   if( !db->mallocFailed && rc==SQLITE_OK ){
+     rc = sqlite3Fts3Init(db);
+   }
+@@ -130935,8 +147952,19 @@
+ 
+ #ifdef SQLITE_ENABLE_DBSTAT_VTAB
+   if( !db->mallocFailed && rc==SQLITE_OK){
+-    int sqlite3_dbstat_register(sqlite3*);
+-    rc = sqlite3_dbstat_register(db);
++    rc = sqlite3DbstatRegister(db);
++  }
 +#endif
 +
-+/*
-+** Return the current value of a status parameter.  The caller must
-+** be holding the appropriate mutex.
-+*/
-+SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int op){
-+  wsdStatInit;
-+  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
-+  assert( op>=0 && op<ArraySize(statMutex) );
-+  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
-+                                           : sqlite3MallocMutex()) );
-+  return wsdStat.nowValue[op];
-+}
++#ifdef SQLITE_ENABLE_JSON1
++  if( !db->mallocFailed && rc==SQLITE_OK){
++    rc = sqlite3Json1Init(db);
++  }
++#endif
 +
-+/*
-+** Add N to the value of a status record.  The caller must hold the
-+** appropriate mutex.  (Locking is checked by assert()).
-+**
-+** The StatusUp() routine can accept positive or negative values for N.
-+** The value of N is added to the current status value and the high-water
-+** mark is adjusted if necessary.
-+**
-+** The StatusDown() routine lowers the current value by N.  The highwater
-+** mark is unchanged.  N must be non-negative for StatusDown().
-+*/
-+SQLITE_PRIVATE void sqlite3StatusUp(int op, int N){
-+  wsdStatInit;
-+  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
-+  assert( op>=0 && op<ArraySize(statMutex) );
-+  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
-+                                           : sqlite3MallocMutex()) );
-+  wsdStat.nowValue[op] += N;
-+  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
-+    wsdStat.mxValue[op] = wsdStat.nowValue[op];
++#ifdef SQLITE_ENABLE_STMTVTAB
++  if( !db->mallocFailed && rc==SQLITE_OK){
++    rc = sqlite3StmtVtabInit(db);
+   }
+ #endif
+ 
+@@ -130959,7 +147987,6 @@
+   sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT);
+ 
+ opendb_out:
+-  sqlite3_free(zOpen);
+   if( db ){
+     assert( db->mutex!=0 || isThreadsafe==0
+            || sqlite3GlobalConfig.bFullMutex==0 );
+@@ -130981,20 +148008,38 @@
+     sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
+   }
+ #endif
+-  return sqlite3ApiExit(0, rc);
++#if defined(SQLITE_HAS_CODEC)
++  if( rc==SQLITE_OK ){
++    const char *zKey;
++    if( (zKey = sqlite3_uri_parameter(zOpen, "hexkey"))!=0 && zKey[0] ){
++      u8 iByte;
++      int i;
++      char zDecoded[40];
++      for(i=0, iByte=0; i<sizeof(zDecoded)*2 && sqlite3Isxdigit(zKey[i]); i++){
++        iByte = (iByte<<4) + sqlite3HexToInt(zKey[i]);
++        if( (i&1)!=0 ) zDecoded[i/2] = iByte;
++      }
++      sqlite3_key_v2(db, 0, zDecoded, i/2);
++    }else if( (zKey = sqlite3_uri_parameter(zOpen, "key"))!=0 ){
++      sqlite3_key_v2(db, 0, zKey, sqlite3Strlen30(zKey));
++    }
 +  }
++#endif
++  sqlite3_free(zOpen);
++  return rc & 0xff;
+ }
+ 
+ /*
+ ** Open a new database handle.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_open(
++SQLITE_API int sqlite3_open(
+   const char *zFilename, 
+   sqlite3 **ppDb 
+ ){
+   return openDatabase(zFilename, ppDb,
+                       SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
++SQLITE_API int sqlite3_open_v2(
+   const char *filename,   /* Database filename (UTF-8) */
+   sqlite3 **ppDb,         /* OUT: SQLite db handle */
+   int flags,              /* Flags */
+@@ -131007,7 +148052,7 @@
+ /*
+ ** Open a new database handle.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_open16(
++SQLITE_API int sqlite3_open16(
+   const void *zFilename, 
+   sqlite3 **ppDb
+ ){
+@@ -131035,18 +148080,18 @@
+       SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE;
+     }
+   }else{
+-    rc = SQLITE_NOMEM;
++    rc = SQLITE_NOMEM_BKPT;
+   }
+   sqlite3ValueFree(pVal);
+ 
+-  return sqlite3ApiExit(0, rc);
++  return rc & 0xff;
+ }
+ #endif /* SQLITE_OMIT_UTF16 */
+ 
+ /*
+ ** Register a new collation sequence with the database handle db.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
++SQLITE_API int sqlite3_create_collation(
+   sqlite3* db, 
+   const char *zName, 
+   int enc, 
+@@ -131059,7 +148104,7 @@
+ /*
+ ** Register a new collation sequence with the database handle db.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
++SQLITE_API int sqlite3_create_collation_v2(
+   sqlite3* db, 
+   const char *zName, 
+   int enc, 
+@@ -131084,7 +148129,7 @@
+ /*
+ ** Register a new collation sequence with the database handle db.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
++SQLITE_API int sqlite3_create_collation16(
+   sqlite3* db, 
+   const void *zName,
+   int enc, 
+@@ -131114,7 +148159,7 @@
+ ** Register a collation sequence factory callback with the database handle
+ ** db. Replace any previously installed collation sequence factory.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
++SQLITE_API int sqlite3_collation_needed(
+   sqlite3 *db, 
+   void *pCollNeededArg, 
+   void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
+@@ -131135,7 +148180,7 @@
+ ** Register a collation sequence factory callback with the database handle
+ ** db. Replace any previously installed collation sequence factory.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
++SQLITE_API int sqlite3_collation_needed16(
+   sqlite3 *db, 
+   void *pCollNeededArg, 
+   void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
+@@ -131157,7 +148202,7 @@
+ ** This function is now an anachronism. It used to be used to recover from a
+ ** malloc() failure, but SQLite now does this automatically.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_global_recover(void){
++SQLITE_API int sqlite3_global_recover(void){
+   return SQLITE_OK;
+ }
+ #endif
+@@ -131168,7 +148213,7 @@
+ ** by default.  Autocommit is disabled by a BEGIN statement and reenabled
+ ** by the next COMMIT or ROLLBACK.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3 *db){
++SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(db) ){
+     (void)SQLITE_MISUSE_BKPT;
+@@ -131180,7 +148225,7 @@
+ 
+ /*
+ ** The following routines are substitutes for constants SQLITE_CORRUPT,
+-** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
++** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_NOMEM and possibly other error
+ ** constants.  They serve two purposes:
+ **
+ **   1.  Serve as a convenient place to set a breakpoint in a debugger
+@@ -131189,28 +148234,39 @@
+ **   2.  Invoke sqlite3_log() to provide the source code location where
+ **       a low-level error is first detected.
+ */
++static int reportError(int iErr, int lineno, const char *zType){
++  sqlite3_log(iErr, "%s at line %d of [%.10s]",
++              zType, lineno, 20+sqlite3_sourceid());
++  return iErr;
 +}
-+SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){
-+  wsdStatInit;
-+  assert( N>=0 );
-+  assert( op>=0 && op<ArraySize(statMutex) );
-+  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
-+                                           : sqlite3MallocMutex()) );
-+  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
-+  wsdStat.nowValue[op] -= N;
+ SQLITE_PRIVATE int sqlite3CorruptError(int lineno){
+   testcase( sqlite3GlobalConfig.xLog!=0 );
+-  sqlite3_log(SQLITE_CORRUPT,
+-              "database corruption at line %d of [%.10s]",
+-              lineno, 20+sqlite3_sourceid());
+-  return SQLITE_CORRUPT;
++  return reportError(SQLITE_CORRUPT, lineno, "database corruption");
+ }
+ SQLITE_PRIVATE int sqlite3MisuseError(int lineno){
+   testcase( sqlite3GlobalConfig.xLog!=0 );
+-  sqlite3_log(SQLITE_MISUSE, 
+-              "misuse at line %d of [%.10s]",
+-              lineno, 20+sqlite3_sourceid());
+-  return SQLITE_MISUSE;
++  return reportError(SQLITE_MISUSE, lineno, "misuse");
+ }
+ SQLITE_PRIVATE int sqlite3CantopenError(int lineno){
+   testcase( sqlite3GlobalConfig.xLog!=0 );
+-  sqlite3_log(SQLITE_CANTOPEN, 
+-              "cannot open file at line %d of [%.10s]",
+-              lineno, 20+sqlite3_sourceid());
+-  return SQLITE_CANTOPEN;
++  return reportError(SQLITE_CANTOPEN, lineno, "cannot open file");
+ }
+-
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE int sqlite3CorruptPgnoError(int lineno, Pgno pgno){
++  char zMsg[100];
++  sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno);
++  testcase( sqlite3GlobalConfig.xLog!=0 );
++  return reportError(SQLITE_CORRUPT, lineno, zMsg);
 +}
-+
-+/*
-+** Set the value of a status to X.  The highwater mark is adjusted if
-+** necessary.  The caller must hold the appropriate mutex.
-+*/
-+SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
-+  wsdStatInit;
-+  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
-+  assert( op>=0 && op<ArraySize(statMutex) );
-+  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
-+                                           : sqlite3MallocMutex()) );
-+  wsdStat.nowValue[op] = X;
-+  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
-+    wsdStat.mxValue[op] = wsdStat.nowValue[op];
-+  }
++SQLITE_PRIVATE int sqlite3NomemError(int lineno){
++  testcase( sqlite3GlobalConfig.xLog!=0 );
++  return reportError(SQLITE_NOMEM, lineno, "OOM");
 +}
-+
++SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){
++  testcase( sqlite3GlobalConfig.xLog!=0 );
++  return reportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
++}
++#endif
+ 
+ #ifndef SQLITE_OMIT_DEPRECATED
+ /*
+@@ -131220,7 +148276,7 @@
+ ** SQLite no longer uses thread-specific data so this routine is now a
+ ** no-op.  It is retained for historical compatibility.
+ */
+-SQLITE_API void SQLITE_STDCALL sqlite3_thread_cleanup(void){
++SQLITE_API void sqlite3_thread_cleanup(void){
+ }
+ #endif
+ 
+@@ -131228,7 +148284,7 @@
+ ** Return meta information about a specific column of a database table.
+ ** See comment in sqlite3.h (sqlite.h.in) for details.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
++SQLITE_API int sqlite3_table_column_metadata(
+   sqlite3 *db,                /* Connection handle */
+   const char *zDbName,        /* Database name or NULL */
+   const char *zTableName,     /* Table name */
+@@ -131304,7 +148360,7 @@
+   **        explicitly declared column. Copy meta information from *pCol.
+   */ 
+   if( pCol ){
+-    zDataType = pCol->zType;
++    zDataType = sqlite3ColumnType(pCol,0);
+     zCollSeq = pCol->zColl;
+     notnull = pCol->notNull!=0;
+     primarykey  = (pCol->colFlags & COLFLAG_PRIMKEY)!=0;
+@@ -131314,7 +148370,7 @@
+     primarykey = 1;
+   }
+   if( !zCollSeq ){
+-    zCollSeq = "BINARY";
++    zCollSeq = sqlite3StrBINARY;
+   }
+ 
+ error_out:
+@@ -131346,7 +148402,7 @@
+ /*
+ ** Sleep for a little while.  Return the amount of time slept.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int ms){
++SQLITE_API int sqlite3_sleep(int ms){
+   sqlite3_vfs *pVfs;
+   int rc;
+   pVfs = sqlite3_vfs_find(0);
+@@ -131362,7 +148418,7 @@
+ /*
+ ** Enable or disable the extended result codes.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3 *db, int onoff){
++SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+ #endif
+@@ -131375,7 +148431,7 @@
+ /*
+ ** Invoke the xFileControl method on a particular database.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
++SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
+   int rc = SQLITE_ERROR;
+   Btree *pBtree;
+ 
+@@ -131395,6 +148451,12 @@
+     if( op==SQLITE_FCNTL_FILE_POINTER ){
+       *(sqlite3_file**)pArg = fd;
+       rc = SQLITE_OK;
++    }else if( op==SQLITE_FCNTL_VFS_POINTER ){
++      *(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager);
++      rc = SQLITE_OK;
++    }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){
++      *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager);
++      rc = SQLITE_OK;
+     }else if( fd->pMethods ){
+       rc = sqlite3OsFileControl(fd, op, pArg);
+     }else{
+@@ -131409,9 +148471,11 @@
+ /*
+ ** Interface to the testing logic.
+ */
+-SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){
++SQLITE_API int sqlite3_test_control(int op, ...){
+   int rc = 0;
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
++#ifdef SQLITE_UNTESTABLE
++  UNUSED_PARAMETER(op);
++#else
+   va_list ap;
+   va_start(ap, op);
+   switch( op ){
+@@ -131533,7 +148597,7 @@
+     */
+     case SQLITE_TESTCTRL_ASSERT: {
+       volatile int x = 0;
+-      assert( (x = va_arg(ap,int))!=0 );
++      assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 );
+       rc = x;
+       break;
+     }
+@@ -131675,6 +148739,15 @@
+       break;
+     }
+ 
++    /* Set the threshold at which OP_Once counters reset back to zero.
++    ** By default this is 0x7ffffffe (over 2 billion), but that value is
++    ** too big to test in a reasonable amount of time, so this control is
++    ** provided to set a small and easily reachable reset value.
++    */
++    case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: {
++      sqlite3GlobalConfig.iOnceResetThreshold = va_arg(ap, int);
++      break;
++    }
+ 
+     /*   sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr);
+     **
+@@ -131737,7 +148810,7 @@
+     }
+   }
+   va_end(ap);
+-#endif /* SQLITE_OMIT_BUILTIN_TEST */
++#endif /* SQLITE_UNTESTABLE */
+   return rc;
+ }
+ 
+@@ -131752,7 +148825,7 @@
+ ** parameter if it exists.  If the parameter does not exist, this routine
+ ** returns a NULL pointer.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam){
++SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
+   if( zFilename==0 || zParam==0 ) return 0;
+   zFilename += sqlite3Strlen30(zFilename) + 1;
+   while( zFilename[0] ){
+@@ -131767,7 +148840,7 @@
+ /*
+ ** Return a boolean value for a query parameter.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
++SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
+   const char *z = sqlite3_uri_parameter(zFilename, zParam);
+   bDflt = bDflt!=0;
+   return z ? sqlite3GetBoolean(z, bDflt) : bDflt;
+@@ -131776,7 +148849,7 @@
+ /*
+ ** Return a 64-bit integer value for a query parameter.
+ */
+-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(
++SQLITE_API sqlite3_int64 sqlite3_uri_int64(
+   const char *zFilename,    /* Filename as passed to xOpen */
+   const char *zParam,       /* URI parameter sought */
+   sqlite3_int64 bDflt       /* return if parameter is missing */
+@@ -131793,22 +148866,15 @@
+ ** Return the Btree pointer identified by zDbName.  Return NULL if not found.
+ */
+ SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
+-  int i;
+-  for(i=0; i<db->nDb; i++){
+-    if( db->aDb[i].pBt
+-     && (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zName)==0)
+-    ){
+-      return db->aDb[i].pBt;
+-    }
+-  }
+-  return 0;
++  int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0;
++  return iDb<0 ? 0 : db->aDb[iDb].pBt;
+ }
+ 
+ /*
+ ** Return the filename of the database associated with a database
+ ** connection.
+ */
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName){
++SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
+   Btree *pBt;
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(db) ){
+@@ -131824,7 +148890,7 @@
+ ** Return 1 if database is read-only or 0 if read/write.  Return -1 if
+ ** no such database exists.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
++SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
+   Btree *pBt;
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(db) ){
+@@ -131836,6 +148902,173 @@
+   return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
+ }
+ 
++#ifdef SQLITE_ENABLE_SNAPSHOT
 +/*
-+** Query status information.
++** Obtain a snapshot handle for the snapshot of database zDb currently 
++** being read by handle db.
 +*/
-+SQLITE_API int SQLITE_STDCALL sqlite3_status64(
-+  int op,
-+  sqlite3_int64 *pCurrent,
-+  sqlite3_int64 *pHighwater,
-+  int resetFlag
++SQLITE_API int sqlite3_snapshot_get(
++  sqlite3 *db, 
++  const char *zDb,
++  sqlite3_snapshot **ppSnapshot
 +){
-+  sqlite3_mutex *pMutex;
-+  wsdStatInit;
-+  if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
-+    return SQLITE_MISUSE_BKPT;
-+  }
++  int rc = SQLITE_ERROR;
++#ifndef SQLITE_OMIT_WAL
++
 +#ifdef SQLITE_ENABLE_API_ARMOR
-+  if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
-+#endif
-+  pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex();
-+  sqlite3_mutex_enter(pMutex);
-+  *pCurrent = wsdStat.nowValue[op];
-+  *pHighwater = wsdStat.mxValue[op];
-+  if( resetFlag ){
-+    wsdStat.mxValue[op] = wsdStat.nowValue[op];
++  if( !sqlite3SafetyCheckOk(db) ){
++    return SQLITE_MISUSE_BKPT;
 +  }
-+  sqlite3_mutex_leave(pMutex);
-+  (void)pMutex;  /* Prevent warning when SQLITE_THREADSAFE=0 */
-+  return SQLITE_OK;
-+}
-+SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
-+  sqlite3_int64 iCur, iHwtr;
-+  int rc;
-+#ifdef SQLITE_ENABLE_API_ARMOR
-+  if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
 +#endif
-+  rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag);
-+  if( rc==0 ){
-+    *pCurrent = (int)iCur;
-+    *pHighwater = (int)iHwtr;
++  sqlite3_mutex_enter(db->mutex);
++
++  if( db->autoCommit==0 ){
++    int iDb = sqlite3FindDbName(db, zDb);
++    if( iDb==0 || iDb>1 ){
++      Btree *pBt = db->aDb[iDb].pBt;
++      if( 0==sqlite3BtreeIsInTrans(pBt) ){
++        rc = sqlite3BtreeBeginTrans(pBt, 0);
++        if( rc==SQLITE_OK ){
++          rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
++        }
++      }
++    }
 +  }
++
++  sqlite3_mutex_leave(db->mutex);
++#endif   /* SQLITE_OMIT_WAL */
 +  return rc;
 +}
 +
 +/*
-+** Query status information for a single database connection
++** Open a read-transaction on the snapshot idendified by pSnapshot.
 +*/
-+SQLITE_API int SQLITE_STDCALL sqlite3_db_status(
-+  sqlite3 *db,          /* The database connection whose status is desired */
-+  int op,               /* Status verb */
-+  int *pCurrent,        /* Write current value here */
-+  int *pHighwater,      /* Write high-water mark here */
-+  int resetFlag         /* Reset high-water mark if true */
++SQLITE_API int sqlite3_snapshot_open(
++  sqlite3 *db, 
++  const char *zDb, 
++  sqlite3_snapshot *pSnapshot
 +){
-+  int rc = SQLITE_OK;   /* Return code */
++  int rc = SQLITE_ERROR;
++#ifndef SQLITE_OMIT_WAL
++
 +#ifdef SQLITE_ENABLE_API_ARMOR
-+  if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){
++  if( !sqlite3SafetyCheckOk(db) ){
 +    return SQLITE_MISUSE_BKPT;
 +  }
 +#endif
 +  sqlite3_mutex_enter(db->mutex);
-+  switch( op ){
-+    case SQLITE_DBSTATUS_LOOKASIDE_USED: {
-+      *pCurrent = db->lookaside.nOut;
-+      *pHighwater = db->lookaside.mxOut;
-+      if( resetFlag ){
-+        db->lookaside.mxOut = db->lookaside.nOut;
-+      }
-+      break;
-+    }
-+
-+    case SQLITE_DBSTATUS_LOOKASIDE_HIT:
-+    case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE:
-+    case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: {
-+      testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT );
-+      testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE );
-+      testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL );
-+      assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 );
-+      assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 );
-+      *pCurrent = 0;
-+      *pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT];
-+      if( resetFlag ){
-+        db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0;
-+      }
-+      break;
-+    }
-+
-+    /* 
-+    ** Return an approximation for the amount of memory currently used
-+    ** by all pagers associated with the given database connection.  The
-+    ** highwater mark is meaningless and is returned as zero.
-+    */
-+    case SQLITE_DBSTATUS_CACHE_USED: {
-+      int totalUsed = 0;
-+      int i;
-+      sqlite3BtreeEnterAll(db);
-+      for(i=0; i<db->nDb; i++){
-+        Btree *pBt = db->aDb[i].pBt;
-+        if( pBt ){
-+          Pager *pPager = sqlite3BtreePager(pBt);
-+          totalUsed += sqlite3PagerMemUsed(pPager);
-+        }
-+      }
-+      sqlite3BtreeLeaveAll(db);
-+      *pCurrent = totalUsed;
-+      *pHighwater = 0;
-+      break;
-+    }
-+
-+    /*
-+    ** *pCurrent gets an accurate estimate of the amount of memory used
-+    ** to store the schema for all databases (main, temp, and any ATTACHed
-+    ** databases.  *pHighwater is set to zero.
-+    */
-+    case SQLITE_DBSTATUS_SCHEMA_USED: {
-+      int i;                      /* Used to iterate through schemas */
-+      int nByte = 0;              /* Used to accumulate return value */
-+
-+      sqlite3BtreeEnterAll(db);
-+      db->pnBytesFreed = &nByte;
-+      for(i=0; i<db->nDb; i++){
-+        Schema *pSchema = db->aDb[i].pSchema;
-+        if( ALWAYS(pSchema!=0) ){
-+          HashElem *p;
-+
-+          nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * (
-+              pSchema->tblHash.count 
-+            + pSchema->trigHash.count
-+            + pSchema->idxHash.count
-+            + pSchema->fkeyHash.count
-+          );
-+          nByte += sqlite3MallocSize(pSchema->tblHash.ht);
-+          nByte += sqlite3MallocSize(pSchema->trigHash.ht);
-+          nByte += sqlite3MallocSize(pSchema->idxHash.ht);
-+          nByte += sqlite3MallocSize(pSchema->fkeyHash.ht);
-+
-+          for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
-+            sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
-+          }
-+          for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
-+            sqlite3DeleteTable(db, (Table *)sqliteHashData(p));
-+          }
++  if( db->autoCommit==0 ){
++    int iDb;
++    iDb = sqlite3FindDbName(db, zDb);
++    if( iDb==0 || iDb>1 ){
++      Btree *pBt = db->aDb[iDb].pBt;
++      if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
++        rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot);
++        if( rc==SQLITE_OK ){
++          rc = sqlite3BtreeBeginTrans(pBt, 0);
++          sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0);
 +        }
 +      }
-+      db->pnBytesFreed = 0;
-+      sqlite3BtreeLeaveAll(db);
-+
-+      *pHighwater = 0;
-+      *pCurrent = nByte;
-+      break;
 +    }
++  }
 +
-+    /*
-+    ** *pCurrent gets an accurate estimate of the amount of memory used
-+    ** to store all prepared statements.
-+    ** *pHighwater is set to zero.
-+    */
-+    case SQLITE_DBSTATUS_STMT_USED: {
-+      struct Vdbe *pVdbe;         /* Used to iterate through VMs */
-+      int nByte = 0;              /* Used to accumulate return value */
-+
-+      db->pnBytesFreed = &nByte;
-+      for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
-+        sqlite3VdbeClearObject(db, pVdbe);
-+        sqlite3DbFree(db, pVdbe);
-+      }
-+      db->pnBytesFreed = 0;
-+
-+      *pHighwater = 0;  /* IMP: R-64479-57858 */
-+      *pCurrent = nByte;
++  sqlite3_mutex_leave(db->mutex);
++#endif   /* SQLITE_OMIT_WAL */
++  return rc;
++}
 +
-+      break;
-+    }
++/*
++** Recover as many snapshots as possible from the wal file associated with
++** schema zDb of database db.
++*/
++SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){
++  int rc = SQLITE_ERROR;
++  int iDb;
++#ifndef SQLITE_OMIT_WAL
 +
-+    /*
-+    ** Set *pCurrent to the total cache hits or misses encountered by all
-+    ** pagers the database handle is connected to. *pHighwater is always set 
-+    ** to zero.
-+    */
-+    case SQLITE_DBSTATUS_CACHE_HIT:
-+    case SQLITE_DBSTATUS_CACHE_MISS:
-+    case SQLITE_DBSTATUS_CACHE_WRITE:{
-+      int i;
-+      int nRet = 0;
-+      assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
-+      assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 );
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !sqlite3SafetyCheckOk(db) ){
++    return SQLITE_MISUSE_BKPT;
++  }
++#endif
 +
-+      for(i=0; i<db->nDb; i++){
-+        if( db->aDb[i].pBt ){
-+          Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
-+          sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
-+        }
++  sqlite3_mutex_enter(db->mutex);
++  iDb = sqlite3FindDbName(db, zDb);
++  if( iDb==0 || iDb>1 ){
++    Btree *pBt = db->aDb[iDb].pBt;
++    if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
++      rc = sqlite3BtreeBeginTrans(pBt, 0);
++      if( rc==SQLITE_OK ){
++        rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt));
++        sqlite3BtreeCommit(pBt);
 +      }
-+      *pHighwater = 0; /* IMP: R-42420-56072 */
-+                       /* IMP: R-54100-20147 */
-+                       /* IMP: R-29431-39229 */
-+      *pCurrent = nRet;
-+      break;
-+    }
-+
-+    /* Set *pCurrent to non-zero if there are unresolved deferred foreign
-+    ** key constraints.  Set *pCurrent to zero if all foreign key constraints
-+    ** have been satisfied.  The *pHighwater is always set to zero.
-+    */
-+    case SQLITE_DBSTATUS_DEFERRED_FKS: {
-+      *pHighwater = 0;  /* IMP: R-11967-56545 */
-+      *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
-+      break;
-+    }
-+
-+    default: {
-+      rc = SQLITE_ERROR;
 +    }
 +  }
 +  sqlite3_mutex_leave(db->mutex);
++#endif   /* SQLITE_OMIT_WAL */
 +  return rc;
 +}
 +
-+/************** End of status.c **********************************************/
-+/************** Begin file date.c ********************************************/
 +/*
-+** 2003 October 31
-+**
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
-+**
-+**    May you do good and not evil.
-+**    May you find forgiveness for yourself and forgive others.
-+**    May you share freely, never taking more than you give.
-+**
-+*************************************************************************
-+** This file contains the C functions that implement date and time
-+** functions for SQLite.  
-+**
-+** There is only one exported symbol in this file - the function
-+** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
-+** All other code has file scope.
-+**
-+** SQLite processes all times and dates as julian day numbers.  The
-+** dates and times are stored as the number of days since noon
-+** in Greenwich on November 24, 4714 B.C. according to the Gregorian
-+** calendar system. 
-+**
-+** 1970-01-01 00:00:00 is JD 2440587.5
-+** 2000-01-01 00:00:00 is JD 2451544.5
-+**
-+** This implementation requires years to be expressed as a 4-digit number
-+** which means that only dates between 0000-01-01 and 9999-12-31 can
-+** be represented, even though julian day numbers allow a much wider
-+** range of dates.
-+**
-+** The Gregorian calendar system is used for all dates and times,
-+** even those that predate the Gregorian calendar.  Historians usually
-+** use the julian calendar for dates prior to 1582-10-15 and for some
-+** dates afterwards, depending on locale.  Beware of this difference.
-+**
-+** The conversion algorithms are implemented based on descriptions
-+** in the following text:
-+**
-+**      Jean Meeus
-+**      Astronomical Algorithms, 2nd Edition, 1998
-+**      ISBM 0-943396-61-1
-+**      Willmann-Bell, Inc
-+**      Richmond, Virginia (USA)
++** Free a snapshot handle obtained from sqlite3_snapshot_get().
 +*/
-+/* #include <stdlib.h> */
-+/* #include <assert.h> */
-+#include <time.h>
-+
-+#ifndef SQLITE_OMIT_DATETIME_FUNCS
-+
++SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){
++  sqlite3_free(pSnapshot);
++}
++#endif /* SQLITE_ENABLE_SNAPSHOT */
 +
++#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
 +/*
-+** A structure for holding a single date and time.
++** Given the name of a compile-time option, return true if that option
++** was used and false if not.
++**
++** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
++** is not required for a match.
 +*/
-+typedef struct DateTime DateTime;
-+struct DateTime {
-+  sqlite3_int64 iJD; /* The julian day number times 86400000 */
-+  int Y, M, D;       /* Year, month, and day */
-+  int h, m;          /* Hour and minutes */
-+  int tz;            /* Timezone offset in minutes */
-+  double s;          /* Seconds */
-+  char validYMD;     /* True (1) if Y,M,D are valid */
-+  char validHMS;     /* True (1) if h,m,s are valid */
-+  char validJD;      /* True (1) if iJD is valid */
-+  char validTZ;      /* True (1) if tz is valid */
-+};
++SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
++  int i, n;
++  int nOpt;
++  const char **azCompileOpt;
++ 
++#if SQLITE_ENABLE_API_ARMOR
++  if( zOptName==0 ){
++    (void)SQLITE_MISUSE_BKPT;
++    return 0;
++  }
++#endif
 +
++  azCompileOpt = sqlite3CompileOptions(&nOpt);
 +
-+/*
-+** Convert zDate into one or more integers.  Additional arguments
-+** come in groups of 5 as follows:
-+**
-+**       N       number of digits in the integer
-+**       min     minimum allowed value of the integer
-+**       max     maximum allowed value of the integer
-+**       nextC   first character after the integer
-+**       pVal    where to write the integers value.
-+**
-+** Conversions continue until one with nextC==0 is encountered.
-+** The function returns the number of successful conversions.
-+*/
-+static int getDigits(const char *zDate, ...){
-+  va_list ap;
-+  int val;
-+  int N;
-+  int min;
-+  int max;
-+  int nextC;
-+  int *pVal;
-+  int cnt = 0;
-+  va_start(ap, zDate);
-+  do{
-+    N = va_arg(ap, int);
-+    min = va_arg(ap, int);
-+    max = va_arg(ap, int);
-+    nextC = va_arg(ap, int);
-+    pVal = va_arg(ap, int*);
-+    val = 0;
-+    while( N-- ){
-+      if( !sqlite3Isdigit(*zDate) ){
-+        goto end_getDigits;
-+      }
-+      val = val*10 + *zDate - '0';
-+      zDate++;
-+    }
-+    if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
-+      goto end_getDigits;
-+    }
-+    *pVal = val;
-+    zDate++;
-+    cnt++;
-+  }while( nextC );
-+end_getDigits:
-+  va_end(ap);
-+  return cnt;
++  if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
++  n = sqlite3Strlen30(zOptName);
++
++  /* Since nOpt is normally in single digits, a linear search is 
++  ** adequate. No need for a binary search. */
++  for(i=0; i<nOpt; i++){
++    if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
++     && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
++    ){
++      return 1;
++    }
++  }
++  return 0;
 +}
 +
 +/*
-+** Parse a timezone extension on the end of a date-time.
-+** The extension is of the form:
-+**
-+**        (+/-)HH:MM
-+**
-+** Or the "zulu" notation:
-+**
-+**        Z
-+**
-+** If the parse is successful, write the number of minutes
-+** of change in p->tz and return 0.  If a parser error occurs,
-+** return non-zero.
-+**
-+** A missing specifier is not considered an error.
++** Return the N-th compile-time option string.  If N is out of range,
++** return a NULL pointer.
 +*/
-+static int parseTimezone(const char *zDate, DateTime *p){
-+  int sgn = 0;
-+  int nHr, nMn;
-+  int c;
-+  while( sqlite3Isspace(*zDate) ){ zDate++; }
-+  p->tz = 0;
-+  c = *zDate;
-+  if( c=='-' ){
-+    sgn = -1;
-+  }else if( c=='+' ){
-+    sgn = +1;
-+  }else if( c=='Z' || c=='z' ){
-+    zDate++;
-+    goto zulu_time;
-+  }else{
-+    return c!=0;
-+  }
-+  zDate++;
-+  if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
-+    return 1;
++SQLITE_API const char *sqlite3_compileoption_get(int N){
++  int nOpt;
++  const char **azCompileOpt;
++  azCompileOpt = sqlite3CompileOptions(&nOpt);
++  if( N>=0 && N<nOpt ){
++    return azCompileOpt[N];
 +  }
-+  zDate += 5;
-+  p->tz = sgn*(nMn + nHr*60);
-+zulu_time:
-+  while( sqlite3Isspace(*zDate) ){ zDate++; }
-+  return *zDate!=0;
++  return 0;
 +}
++#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
++
+ /************** End of main.c ************************************************/
+ /************** Begin file notify.c ******************************************/
+ /*
+@@ -131853,6 +149086,8 @@
+ ** This file contains the implementation of the sqlite3_unlock_notify()
+ ** API method and its associated functionality.
+ */
++/* #include "sqliteInt.h" */
++/* #include "btreeInt.h" */
+ 
+ /* Omit this entire file if SQLITE_ENABLE_UNLOCK_NOTIFY is not defined. */
+ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
+@@ -131983,7 +149218,7 @@
+ ** on the same "db".  If xNotify==0 then any prior callbacks are immediately
+ ** cancelled.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
++SQLITE_API int sqlite3_unlock_notify(
+   sqlite3 *db,
+   void (*xNotify)(void **, int),
+   void *pArg
+@@ -132483,6 +149718,12 @@
+ # define NDEBUG 1
+ #endif
+ 
++/* FTS3/FTS4 require virtual tables */
++#ifdef SQLITE_OMIT_VIRTUALTABLE
++# undef SQLITE_ENABLE_FTS3
++# undef SQLITE_ENABLE_FTS4
++#endif
++
+ /*
+ ** FTS4 is really an extension for FTS3.  It is enabled using the
+ ** SQLITE_ENABLE_FTS3 macro.  But to avoid confusion we also all
+@@ -132496,9 +149737,11 @@
+ 
+ /* If not building as part of the core, include sqlite3ext.h. */
+ #ifndef SQLITE_CORE
++/* # include "sqlite3ext.h"  */
+ SQLITE_EXTENSION_INIT3
+ #endif
+ 
++/* #include "sqlite3.h" */
+ /************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/
+ /************** Begin file fts3_tokenizer.h **********************************/
+ /*
+@@ -132527,6 +149770,7 @@
+ ** If tokenizers are to be allowed to call sqlite3_*() functions, then
+ ** we will need a way to register the API consistently.
+ */
++/* #include "sqlite3.h" */
+ 
+ /*
+ ** Structures used by the tokenizer interface. When a new tokenizer
+@@ -132940,6 +150184,8 @@
+ typedef struct Fts3SegReader Fts3SegReader;
+ typedef struct Fts3MultiSegReader Fts3MultiSegReader;
+ 
++typedef struct MatchinfoBuffer MatchinfoBuffer;
 +
+ /*
+ ** A connection to a fulltext index is an instance of the following
+ ** structure. The xCreate and xConnect methods create an instance
+@@ -132965,6 +150211,7 @@
+   ** statements is run and reset within a single virtual table API call. 
+   */
+   sqlite3_stmt *aStmt[40];
++  sqlite3_stmt *pSeekStmt;        /* Cache for fts3CursorSeekStmt() */
+ 
+   char *zReadExprlist;
+   char *zWriteExprlist;
+@@ -133005,6 +150252,7 @@
+   int nPendingData;               /* Current bytes of pending data */
+   sqlite_int64 iPrevDocid;        /* Docid of most recently inserted document */
+   int iPrevLangid;                /* Langid of recently inserted document */
++  int bPrevDelete;                /* True if last operation was a delete */
+ 
+ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
+   /* State variables used for validating that the transaction control
+@@ -133033,6 +150281,7 @@
+   i16 eSearch;                    /* Search strategy (see below) */
+   u8 isEof;                       /* True if at End Of Results */
+   u8 isRequireSeek;               /* True if must seek pStmt to %_content row */
++  u8 bSeekStmt;                   /* True if pStmt is a seek */
+   sqlite3_stmt *pStmt;            /* Prepared statement in use by the cursor */
+   Fts3Expr *pExpr;                /* Parsed MATCH query string */
+   int iLangid;                    /* Language being queried for */
+@@ -133049,9 +150298,7 @@
+   i64 iMinDocid;                  /* Minimum docid to return */
+   i64 iMaxDocid;                  /* Maximum docid to return */
+   int isMatchinfoNeeded;          /* True when aMatchinfo[] needs filling in */
+-  u32 *aMatchinfo;                /* Information about most recent match */
+-  int nMatchinfo;                 /* Number of elements in aMatchinfo[] */
+-  char *zMatchinfo;               /* Matchinfo specification */
++  MatchinfoBuffer *pMIBuffer;     /* Buffer for matchinfo data */
+ };
+ 
+ #define FTS3_EVAL_FILTER    0
+@@ -133171,7 +150418,9 @@
+   u8 bStart;                 /* True if iDocid is valid */
+   u8 bDeferred;              /* True if this expression is entirely deferred */
+ 
+-  u32 *aMI;
++  /* The following are used by the fts3_snippet.c module. */
++  int iPhrase;               /* Index of this phrase in matchinfo() results */
++  u32 *aMI;                  /* See above */
+ };
+ 
+ /*
+@@ -133292,6 +150541,7 @@
+ SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
+ SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
+ SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
++SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc);
+ 
+ /* fts3_tokenizer.c */
+ SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
+@@ -133307,6 +150557,7 @@
+   const char *, const char *, int, int
+ );
+ SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
++SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p);
+ 
+ /* fts3_expr.c */
+ SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
+@@ -133363,7 +150614,9 @@
+ /* #include <string.h> */
+ /* #include <stdarg.h> */
+ 
++/* #include "fts3.h" */
+ #ifndef SQLITE_CORE 
++/* # include "sqlite3ext.h" */
+   SQLITE_EXTENSION_INIT1
+ #endif
+ 
+@@ -133408,8 +150661,9 @@
+ ** Return the number of bytes read, or 0 on error.
+ ** The value is stored in *v.
+ */
+-SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){
+-  const char *pStart = p;
++SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){
++  const unsigned char *p = (const unsigned char*)pBuf;
++  const unsigned char *pStart = p;
+   u32 a;
+   u64 b;
+   int shift;
+@@ -133430,8 +150684,8 @@
+ }
+ 
+ /*
+-** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to a
+-** 32-bit integer before it is returned.
++** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to 
++** a non-negative 32-bit integer before it is returned.
+ */
+ SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){
+   u32 a;
+@@ -133447,7 +150701,9 @@
+   GETVARINT_STEP(a, p, 14, 0x3FFF,   0x200000, *pi, 3);
+   GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4);
+   a = (a & 0x0FFFFFFF );
+-  *pi = (int)(a | ((u32)(*p & 0x0F) << 28));
++  *pi = (int)(a | ((u32)(*p & 0x07) << 28));
++  assert( 0==(a & 0x80000000) );
++  assert( *pi>=0 );
+   return 5;
+ }
+ 
+@@ -133551,6 +150807,7 @@
+   assert( p->pSegments==0 );
+ 
+   /* Free any prepared statements held */
++  sqlite3_finalize(p->pSeekStmt);
+   for(i=0; i<SizeofArray(p->aStmt); i++){
+     sqlite3_finalize(p->aStmt[i]);
+   }
+@@ -134276,65 +151533,66 @@
+             break;
+           }
+         }
+-        if( iOpt==SizeofArray(aFts4Opt) ){
+-          sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
+-          rc = SQLITE_ERROR;
+-        }else{
+-          switch( iOpt ){
+-            case 0:               /* MATCHINFO */
+-              if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
+-                sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
+-                rc = SQLITE_ERROR;
+-              }
+-              bNoDocsize = 1;
+-              break;
++        switch( iOpt ){
++          case 0:               /* MATCHINFO */
++            if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
++              sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
++              rc = SQLITE_ERROR;
++            }
++            bNoDocsize = 1;
++            break;
+ 
+-            case 1:               /* PREFIX */
+-              sqlite3_free(zPrefix);
+-              zPrefix = zVal;
+-              zVal = 0;
+-              break;
++          case 1:               /* PREFIX */
++            sqlite3_free(zPrefix);
++            zPrefix = zVal;
++            zVal = 0;
++            break;
+ 
+-            case 2:               /* COMPRESS */
+-              sqlite3_free(zCompress);
+-              zCompress = zVal;
+-              zVal = 0;
+-              break;
++          case 2:               /* COMPRESS */
++            sqlite3_free(zCompress);
++            zCompress = zVal;
++            zVal = 0;
++            break;
+ 
+-            case 3:               /* UNCOMPRESS */
+-              sqlite3_free(zUncompress);
+-              zUncompress = zVal;
+-              zVal = 0;
+-              break;
++          case 3:               /* UNCOMPRESS */
++            sqlite3_free(zUncompress);
++            zUncompress = zVal;
++            zVal = 0;
++            break;
+ 
+-            case 4:               /* ORDER */
+-              if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) 
+-               && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4)) 
+-              ){
+-                sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
+-                rc = SQLITE_ERROR;
+-              }
+-              bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
+-              break;
++          case 4:               /* ORDER */
++            if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) 
++             && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4)) 
++            ){
++              sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
++              rc = SQLITE_ERROR;
++            }
++            bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
++            break;
+ 
+-            case 5:              /* CONTENT */
+-              sqlite3_free(zContent);
+-              zContent = zVal;
+-              zVal = 0;
+-              break;
++          case 5:              /* CONTENT */
++            sqlite3_free(zContent);
++            zContent = zVal;
++            zVal = 0;
++            break;
+ 
+-            case 6:              /* LANGUAGEID */
+-              assert( iOpt==6 );
+-              sqlite3_free(zLanguageid);
+-              zLanguageid = zVal;
+-              zVal = 0;
+-              break;
++          case 6:              /* LANGUAGEID */
++            assert( iOpt==6 );
++            sqlite3_free(zLanguageid);
++            zLanguageid = zVal;
++            zVal = 0;
++            break;
+ 
+-            case 7:              /* NOTINDEXED */
+-              azNotindexed[nNotindexed++] = zVal;
+-              zVal = 0;
+-              break;
+-          }
++          case 7:              /* NOTINDEXED */
++            azNotindexed[nNotindexed++] = zVal;
++            zVal = 0;
++            break;
++
++          default:
++            assert( iOpt==SizeofArray(aFts4Opt) );
++            sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
++            rc = SQLITE_ERROR;
++            break;
+         }
+         sqlite3_free(zVal);
+       }
+@@ -134422,9 +151680,9 @@
+   p->pTokenizer = pTokenizer;
+   p->nMaxPendingData = FTS3_MAX_PENDING_DATA;
+   p->bHasDocsize = (isFts4 && bNoDocsize==0);
+-  p->bHasStat = isFts4;
+-  p->bFts4 = isFts4;
+-  p->bDescIdx = bDescIdx;
++  p->bHasStat = (u8)isFts4;
++  p->bFts4 = (u8)isFts4;
++  p->bDescIdx = (u8)bDescIdx;
+   p->nAutoincrmerge = 0xff;   /* 0xff means setting unknown */
+   p->zContentTbl = zContent;
+   p->zLanguageid = zLanguageid;
+@@ -134455,7 +151713,9 @@
+     char *z; 
+     int n = 0;
+     z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n);
+-    memcpy(zCsr, z, n);
++    if( n>0 ){
++      memcpy(zCsr, z, n);
++    }
+     zCsr[n] = '\0';
+     sqlite3Fts3Dequote(zCsr);
+     p->azColumn[iCol] = zCsr;
+@@ -134576,6 +151836,19 @@
+ #endif
+ }
+ 
 +/*
-+** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
-+** The HH, MM, and SS must each be exactly 2 digits.  The
-+** fractional seconds FFFF can be one or more digits.
-+**
-+** Return 1 if there is a parsing error and 0 on success.
++** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
++** extension is currently being used by a version of SQLite too old to
++** support index-info flags. In that case this function is a no-op.
 +*/
-+static int parseHhMmSs(const char *zDate, DateTime *p){
-+  int h, m, s;
-+  double ms = 0.0;
-+  if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
-+    return 1;
-+  }
-+  zDate += 5;
-+  if( *zDate==':' ){
-+    zDate++;
-+    if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
-+      return 1;
-+    }
-+    zDate += 2;
-+    if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){
-+      double rScale = 1.0;
-+      zDate++;
-+      while( sqlite3Isdigit(*zDate) ){
-+        ms = ms*10.0 + *zDate - '0';
-+        rScale *= 10.0;
-+        zDate++;
-+      }
-+      ms /= rScale;
-+    }
-+  }else{
-+    s = 0;
++static void fts3SetUniqueFlag(sqlite3_index_info *pIdxInfo){
++#if SQLITE_VERSION_NUMBER>=3008012
++  if( sqlite3_libversion_number()>=3008012 ){
++    pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
 +  }
-+  p->validJD = 0;
-+  p->validHMS = 1;
-+  p->h = h;
-+  p->m = m;
-+  p->s = s + ms;
-+  if( parseTimezone(zDate, p) ) return 1;
-+  p->validTZ = (p->tz!=0)?1:0;
-+  return 0;
++#endif
 +}
 +
-+/*
-+** Convert from YYYY-MM-DD HH:MM:SS to julian day.  We always assume
-+** that the YYYY-MM-DD is according to the Gregorian calendar.
+ /* 
+ ** Implementation of the xBestIndex method for FTS3 tables. There
+ ** are three possible strategies, in order of preference:
+@@ -134666,6 +151939,9 @@
+     }
+   }
+ 
++  /* If using a docid=? or rowid=? strategy, set the UNIQUE flag. */
++  if( pInfo->idxNum==FTS3_DOCID_SEARCH ) fts3SetUniqueFlag(pInfo);
++
+   iIdx = 1;
+   if( iCons>=0 ){
+     pInfo->aConstraintUsage[iCons].argvIndex = iIdx++;
+@@ -134724,17 +152000,46 @@
+ }
+ 
+ /*
++** Finalize the statement handle at pCsr->pStmt.
 +**
-+** Reference:  Meeus page 61
++** Or, if that statement handle is one created by fts3CursorSeekStmt(),
++** and the Fts3Table.pSeekStmt slot is currently NULL, save the statement
++** pointer there instead of finalizing it.
 +*/
-+static void computeJD(DateTime *p){
-+  int Y, M, D, A, B, X1, X2;
-+
-+  if( p->validJD ) return;
-+  if( p->validYMD ){
-+    Y = p->Y;
-+    M = p->M;
-+    D = p->D;
-+  }else{
-+    Y = 2000;  /* If no YMD specified, assume 2000-Jan-01 */
-+    M = 1;
-+    D = 1;
-+  }
-+  if( M<=2 ){
-+    Y--;
-+    M += 12;
-+  }
-+  A = Y/100;
-+  B = 2 - A + (A/4);
-+  X1 = 36525*(Y+4716)/100;
-+  X2 = 306001*(M+1)/10000;
-+  p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
-+  p->validJD = 1;
-+  if( p->validHMS ){
-+    p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000);
-+    if( p->validTZ ){
-+      p->iJD -= p->tz*60000;
-+      p->validYMD = 0;
-+      p->validHMS = 0;
-+      p->validTZ = 0;
++static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){
++  if( pCsr->bSeekStmt ){
++    Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
++    if( p->pSeekStmt==0 ){
++      p->pSeekStmt = pCsr->pStmt;
++      sqlite3_reset(pCsr->pStmt);
++      pCsr->pStmt = 0;
 +    }
++    pCsr->bSeekStmt = 0;
 +  }
++  sqlite3_finalize(pCsr->pStmt);
 +}
 +
 +/*
-+** Parse dates of the form
-+**
-+**     YYYY-MM-DD HH:MM:SS.FFF
-+**     YYYY-MM-DD HH:MM:SS
-+**     YYYY-MM-DD HH:MM
-+**     YYYY-MM-DD
-+**
-+** Write the result into the DateTime structure and return 0
-+** on success and 1 if the input string is not a well-formed
-+** date.
++** Free all resources currently held by the cursor passed as the only
++** argument.
 +*/
-+static int parseYyyyMmDd(const char *zDate, DateTime *p){
-+  int Y, M, D, neg;
++static void fts3ClearCursor(Fts3Cursor *pCsr){
++  fts3CursorFinalizeStmt(pCsr);
++  sqlite3Fts3FreeDeferredTokens(pCsr);
++  sqlite3_free(pCsr->aDoclist);
++  sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
++  sqlite3Fts3ExprFree(pCsr->pExpr);
++  memset(&(&pCsr->base)[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
++}
 +
-+  if( zDate[0]=='-' ){
-+    zDate++;
-+    neg = 1;
-+  }else{
-+    neg = 0;
-+  }
-+  if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
-+    return 1;
++/*
+ ** Close the cursor.  For additional information see the documentation
+ ** on the xClose method of the virtual table interface.
+ */
+ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
+   Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
+   assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
+-  sqlite3_finalize(pCsr->pStmt);
+-  sqlite3Fts3ExprFree(pCsr->pExpr);
+-  sqlite3Fts3FreeDeferredTokens(pCsr);
+-  sqlite3_free(pCsr->aDoclist);
+-  sqlite3_free(pCsr->aMatchinfo);
++  fts3ClearCursor(pCsr);
+   assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
+   sqlite3_free(pCsr);
+   return SQLITE_OK;
+@@ -134748,20 +152053,23 @@
+ **
+ ** (or the equivalent for a content=xxx table) and set pCsr->pStmt to
+ ** it. If an error occurs, return an SQLite error code.
+-**
+-** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK.
+ */
+-static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
++static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
+   int rc = SQLITE_OK;
+   if( pCsr->pStmt==0 ){
+     Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
+     char *zSql;
+-    zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
+-    if( !zSql ) return SQLITE_NOMEM;
+-    rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
+-    sqlite3_free(zSql);
++    if( p->pSeekStmt ){
++      pCsr->pStmt = p->pSeekStmt;
++      p->pSeekStmt = 0;
++    }else{
++      zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
++      if( !zSql ) return SQLITE_NOMEM;
++      rc = sqlite3_prepare_v3(p->db, zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0);
++      sqlite3_free(zSql);
++    }
++    if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1;
+   }
+-  *ppStmt = pCsr->pStmt;
+   return rc;
+ }
+ 
+@@ -134773,9 +152081,7 @@
+ static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
+   int rc = SQLITE_OK;
+   if( pCsr->isRequireSeek ){
+-    sqlite3_stmt *pStmt = 0;
+-
+-    rc = fts3CursorSeekStmt(pCsr, &pStmt);
++    rc = fts3CursorSeekStmt(pCsr);
+     if( rc==SQLITE_OK ){
+       sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
+       pCsr->isRequireSeek = 0;
+@@ -134864,7 +152170,8 @@
+     isFirstTerm = 0;
+     zCsr += fts3GetVarint32(zCsr, &nSuffix);
+     
+-    if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
++    assert( nPrefix>=0 && nSuffix>=0 );
++    if( &zCsr[nSuffix]>zEnd ){
+       rc = FTS_CORRUPT_VTAB;
+       goto finish_scan;
+     }
+@@ -135674,7 +152981,7 @@
+     fts3ColumnlistCopy(0, &p);
+   }
+ 
+-  while( p<pEnd && *p==0x01 ){
++  while( p<pEnd ){
+     sqlite3_int64 iCol;
+     p++;
+     p += sqlite3Fts3GetVarint(p, &iCol);
+@@ -136233,11 +153540,7 @@
+   assert( iIdx==nVal );
+ 
+   /* In case the cursor has been used before, clear it now. */
+-  sqlite3_finalize(pCsr->pStmt);
+-  sqlite3_free(pCsr->aDoclist);
+-  sqlite3_free(pCsr->aMatchinfo);
+-  sqlite3Fts3ExprFree(pCsr->pExpr);
+-  memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
++  fts3ClearCursor(pCsr);
+ 
+   /* Set the lower and upper bounds on docids to return */
+   pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
+@@ -136295,13 +153598,13 @@
+       );
+     }
+     if( zSql ){
+-      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
++      rc = sqlite3_prepare_v3(p->db,zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0);
+       sqlite3_free(zSql);
+     }else{
+       rc = SQLITE_NOMEM;
+     }
+   }else if( eSearch==FTS3_DOCID_SEARCH ){
+-    rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
++    rc = fts3CursorSeekStmt(pCsr);
+     if( rc==SQLITE_OK ){
+       rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons);
+     }
+@@ -136316,7 +153619,12 @@
+ ** routine to find out if it has reached the end of a result set.
+ */
+ static int fts3EofMethod(sqlite3_vtab_cursor *pCursor){
+-  return ((Fts3Cursor *)pCursor)->isEof;
++  Fts3Cursor *pCsr = (Fts3Cursor*)pCursor;
++  if( pCsr->isEof ){
++    fts3ClearCursor(pCsr);
++    pCsr->isEof = 1;
 +  }
-+  zDate += 10;
-+  while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; }
-+  if( parseHhMmSs(zDate, p)==0 ){
-+    /* We got the time */
-+  }else if( *zDate==0 ){
-+    p->validHMS = 0;
++  return pCsr->isEof;
+ }
+ 
+ /* 
+@@ -136354,33 +153662,37 @@
+   /* The column value supplied by SQLite must be in range. */
+   assert( iCol>=0 && iCol<=p->nColumn+2 );
+ 
+-  if( iCol==p->nColumn+1 ){
+-    /* This call is a request for the "docid" column. Since "docid" is an 
+-    ** alias for "rowid", use the xRowid() method to obtain the value.
+-    */
+-    sqlite3_result_int64(pCtx, pCsr->iPrevId);
+-  }else if( iCol==p->nColumn ){
+-    /* The extra column whose name is the same as the table.
+-    ** Return a blob which is a pointer to the cursor.  */
+-    sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT);
+-  }else if( iCol==p->nColumn+2 && pCsr->pExpr ){
+-    sqlite3_result_int64(pCtx, pCsr->iLangid);
+-  }else{
+-    /* The requested column is either a user column (one that contains 
+-    ** indexed data), or the language-id column.  */
+-    rc = fts3CursorSeek(0, pCsr);
+-
+-    if( rc==SQLITE_OK ){
+-      if( iCol==p->nColumn+2 ){
+-        int iLangid = 0;
+-        if( p->zLanguageid ){
+-          iLangid = sqlite3_column_int(pCsr->pStmt, p->nColumn+1);
+-        }
+-        sqlite3_result_int(pCtx, iLangid);
+-      }else if( sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){
++  switch( iCol-p->nColumn ){
++    case 0:
++      /* The special 'table-name' column */
++      sqlite3_result_pointer(pCtx, pCsr, "fts3cursor", 0);
++      break;
++
++    case 1:
++      /* The docid column */
++      sqlite3_result_int64(pCtx, pCsr->iPrevId);
++      break;
++
++    case 2:
++      if( pCsr->pExpr ){
++        sqlite3_result_int64(pCtx, pCsr->iLangid);
++        break;
++      }else if( p->zLanguageid==0 ){
++        sqlite3_result_int(pCtx, 0);
++        break;
++      }else{
++        iCol = p->nColumn;
++        /* fall-through */
++      }
++
++    default:
++      /* A user column. Or, if this is a full-table scan, possibly the
++      ** language-id column. Seek the cursor. */
++      rc = fts3CursorSeek(0, pCsr);
++      if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)-1>iCol ){
+         sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
+       }
+-    }
++      break;
+   }
+ 
+   assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
+@@ -136429,8 +153741,10 @@
+   const u32 nMinMerge = 64;       /* Minimum amount of incr-merge work to do */
+ 
+   Fts3Table *p = (Fts3Table*)pVtab;
+-  int rc = sqlite3Fts3PendingTermsFlush(p);
++  int rc;
++  i64 iLastRowid = sqlite3_last_insert_rowid(p->db);
+ 
++  rc = sqlite3Fts3PendingTermsFlush(p);
+   if( rc==SQLITE_OK 
+    && p->nLeafAdd>(nMinMerge/16) 
+    && p->nAutoincrmerge && p->nAutoincrmerge!=0xff
+@@ -136445,6 +153759,7 @@
+     if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge);
+   }
+   sqlite3Fts3SegmentsClose(p);
++  sqlite3_set_last_insert_rowid(p->db, iLastRowid);
+   return rc;
+ }
+ 
+@@ -136457,17 +153772,11 @@
+ static int fts3SetHasStat(Fts3Table *p){
+   int rc = SQLITE_OK;
+   if( p->bHasStat==2 ){
+-    const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'";
+-    char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName);
+-    if( zSql ){
+-      sqlite3_stmt *pStmt = 0;
+-      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+-      if( rc==SQLITE_OK ){
+-        int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW);
+-        rc = sqlite3_finalize(pStmt);
+-        if( rc==SQLITE_OK ) p->bHasStat = bHasStat;
+-      }
+-      sqlite3_free(zSql);
++    char *zTbl = sqlite3_mprintf("%s_stat", p->zName);
++    if( zTbl ){
++      int res = sqlite3_table_column_metadata(p->db, p->zDb, zTbl, 0,0,0,0,0,0);
++      sqlite3_free(zTbl);
++      p->bHasStat = (res==SQLITE_OK);
+     }else{
+       rc = SQLITE_NOMEM;
+     }
+@@ -136574,18 +153883,17 @@
+   sqlite3_value *pVal,            /* argv[0] passed to function */
+   Fts3Cursor **ppCsr              /* OUT: Store cursor handle here */
+ ){
+-  Fts3Cursor *pRet;
+-  if( sqlite3_value_type(pVal)!=SQLITE_BLOB 
+-   || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *)
+-  ){
++  int rc;
++  *ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal, "fts3cursor");
++  if( (*ppCsr)!=0 ){
++    rc = SQLITE_OK;
 +  }else{
-+    return 1;
-+  }
-+  p->validJD = 0;
-+  p->validYMD = 1;
-+  p->Y = neg ? -Y : Y;
-+  p->M = M;
-+  p->D = D;
-+  if( p->validTZ ){
-+    computeJD(p);
-+  }
-+  return 0;
-+}
+     char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc);
+     sqlite3_result_error(pContext, zErr, -1);
+     sqlite3_free(zErr);
+-    return SQLITE_ERROR;
++    rc = SQLITE_ERROR;
+   }
+-  memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *));
+-  *ppCsr = pRet;
+-  return SQLITE_OK;
++  return rc;
+ }
+ 
+ /*
+@@ -136972,7 +154280,7 @@
+ #endif
+ 
+   /* Create the virtual table wrapper around the hash-table and overload 
+-  ** the two scalar functions. If this is successful, register the
++  ** the four scalar functions. If this is successful, register the
+   ** module with sqlite.
+   */
+   if( SQLITE_OK==rc 
+@@ -137290,7 +154598,6 @@
+   int bIncrOk = (bOptOk 
+    && pCsr->bDesc==pTab->bDescIdx 
+    && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0
+-   && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0
+ #ifdef SQLITE_TEST
+    && pTab->bNoIncrDoclist==0
+ #endif
+@@ -137410,6 +154717,7 @@
+     p += sqlite3Fts3GetVarint(p, piDocid);
+   }else{
+     fts3PoslistCopy(0, &p);
++    while( p<&aDoclist[nDoclist] && *p==0 ) p++; 
+     if( p>=&aDoclist[nDoclist] ){
+       *pbEof = 1;
+     }else{
+@@ -137555,7 +154863,7 @@
+   ** one incremental token. In which case the bIncr flag is set. */
+   assert( p->bIncr==1 );
+ 
+-  if( p->nToken==1 && p->bIncr ){
++  if( p->nToken==1 ){
+     rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, 
+         &pDL->iDocid, &pDL->pList, &pDL->nList
+     );
+@@ -137788,6 +155096,7 @@
+ ** the number of overflow pages consumed by a record B bytes in size.
+ */
+ static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
++  int rc = SQLITE_OK;
+   if( pCsr->nRowAvg==0 ){
+     /* The average document size, which is required to calculate the cost
+     ** of each doclist, has not yet been determined. Read the required 
+@@ -137800,7 +155109,6 @@
+     ** data stored in all rows of each column of the table, from left
+     ** to right.
+     */
+-    int rc;
+     Fts3Table *p = (Fts3Table*)pCsr->base.pVtab;
+     sqlite3_stmt *pStmt;
+     sqlite3_int64 nDoc = 0;
+@@ -137827,11 +155135,10 @@
+     pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz);
+     assert( pCsr->nRowAvg>0 ); 
+     rc = sqlite3_reset(pStmt);
+-    if( rc!=SQLITE_OK ) return rc;
+   }
+ 
+   *pnPage = pCsr->nRowAvg;
+-  return SQLITE_OK;
++  return rc;
+ }
+ 
+ /*
+@@ -138133,7 +155440,7 @@
+ **   2. NEAR is treated as AND. If the expression is "x NEAR y", it is 
+ **      advanced to point to the next row that matches "x AND y".
+ ** 
+-** See fts3EvalTestDeferredAndNear() for details on testing if a row is
++** See sqlite3Fts3EvalTestDeferred() for details on testing if a row is
+ ** really a match, taking into account deferred tokens and NEAR operators.
+ */
+ static void fts3EvalNextRow(
+@@ -138181,7 +155488,8 @@
+           pExpr->iDocid = pLeft->iDocid;
+           pExpr->bEof = (pLeft->bEof || pRight->bEof);
+           if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){
+-            if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){
++            assert( pRight->eType==FTSQUERY_PHRASE );
++            if( pRight->pPhrase->doclist.aAll ){
+               Fts3Doclist *pDl = &pRight->pPhrase->doclist;
+               while( *pRc==SQLITE_OK && pRight->bEof==0 ){
+                 memset(pDl->pList, 0, pDl->nList);
+@@ -138210,7 +155518,7 @@
+ 
+         if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
+           fts3EvalNextRow(pCsr, pLeft, pRc);
+-        }else if( pLeft->bEof || (pRight->bEof==0 && iCmp>0) ){
++        }else if( pLeft->bEof || iCmp>0 ){
+           fts3EvalNextRow(pCsr, pRight, pRc);
+         }else{
+           fts3EvalNextRow(pCsr, pLeft, pRc);
+@@ -138302,7 +155610,6 @@
+   */
+   if( *pRc==SQLITE_OK 
+    && pExpr->eType==FTSQUERY_NEAR 
+-   && pExpr->bEof==0
+    && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR)
+   ){
+     Fts3Expr *p; 
+@@ -138311,49 +155618,46 @@
+ 
+     /* Allocate temporary working space. */
+     for(p=pExpr; p->pLeft; p=p->pLeft){
++      assert( p->pRight->pPhrase->doclist.nList>0 );
+       nTmp += p->pRight->pPhrase->doclist.nList;
+     }
+     nTmp += p->pPhrase->doclist.nList;
+-    if( nTmp==0 ){
++    aTmp = sqlite3_malloc(nTmp*2);
++    if( !aTmp ){
++      *pRc = SQLITE_NOMEM;
+       res = 0;
+     }else{
+-      aTmp = sqlite3_malloc(nTmp*2);
+-      if( !aTmp ){
+-        *pRc = SQLITE_NOMEM;
+-        res = 0;
+-      }else{
+-        char *aPoslist = p->pPhrase->doclist.pList;
+-        int nToken = p->pPhrase->nToken;
++      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;
+ }
+ 
+ /*
+-** This function is a helper function for fts3EvalTestDeferredAndNear().
++** This function is a helper function for sqlite3Fts3EvalTestDeferred().
+ ** Assuming no error occurs or has occurred, It returns non-zero if the
+ ** expression passed as the second argument matches the row that pCsr 
+ ** currently points to, or zero if it does not.
+@@ -138474,7 +155778,7 @@
+ ** Or, if no error occurs and it seems the current row does match the FTS
+ ** query, return 0.
+ */
+-static int fts3EvalTestDeferredAndNear(Fts3Cursor *pCsr, int *pRc){
++SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc){
+   int rc = *pRc;
+   int bMiss = 0;
+   if( rc==SQLITE_OK ){
+@@ -138521,7 +155825,7 @@
+       pCsr->isRequireSeek = 1;
+       pCsr->isMatchinfoNeeded = 1;
+       pCsr->iPrevId = pExpr->iDocid;
+-    }while( pCsr->isEof==0 && fts3EvalTestDeferredAndNear(pCsr, &rc) );
++    }while( pCsr->isEof==0 && sqlite3Fts3EvalTestDeferred(pCsr, &rc) );
+   }
+ 
+   /* Check if the cursor is past the end of the docid range specified
+@@ -138682,7 +155986,7 @@
+         pCsr->iPrevId = pRoot->iDocid;
+       }while( pCsr->isEof==0 
+            && pRoot->eType==FTSQUERY_NEAR 
+-           && fts3EvalTestDeferredAndNear(pCsr, &rc) 
++           && sqlite3Fts3EvalTestDeferred(pCsr, &rc) 
+       );
+ 
+       if( rc==SQLITE_OK && pCsr->isEof==0 ){
+@@ -138707,7 +156011,6 @@
+         fts3EvalNextRow(pCsr, pRoot, &rc);
+         assert( pRoot->bEof==0 );
+       }while( pRoot->iDocid!=iDocid && rc==SQLITE_OK );
+-      fts3EvalTestDeferredAndNear(pCsr, &rc);
+     }
+   }
+   return rc;
+@@ -138817,10 +156120,10 @@
+     int rc = SQLITE_OK;
+     int bDescDoclist = pTab->bDescIdx;      /* For DOCID_CMP macro */
+     int bOr = 0;
+-    u8 bEof = 0;
+     u8 bTreeEof = 0;
+     Fts3Expr *p;                  /* Used to iterate from pExpr to root */
+     Fts3Expr *pNear;              /* Most senior NEAR ancestor (or pExpr) */
++    int bMatch;
+ 
+     /* Check if this phrase descends from an OR expression node. If not, 
+     ** return NULL. Otherwise, the entry that corresponds to docid 
+@@ -138854,31 +156157,47 @@
+     }
+     if( rc!=SQLITE_OK ) return rc;
+ 
+-    pIter = pPhrase->pOrPoslist;
+-    iDocid = pPhrase->iOrDocid;
+-    if( pCsr->bDesc==bDescDoclist ){
+-      bEof = !pPhrase->doclist.nAll ||
+-                 (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
+-      while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
+-        sqlite3Fts3DoclistNext(
+-            bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, 
+-            &pIter, &iDocid, &bEof
+-        );
+-      }
+-    }else{
+-      bEof = !pPhrase->doclist.nAll || (pIter && pIter<=pPhrase->doclist.aAll);
+-      while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
+-        int dummy;
+-        sqlite3Fts3DoclistPrev(
+-            bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, 
+-            &pIter, &iDocid, &dummy, &bEof
+-        );
++    bMatch = 1;
++    for(p=pNear; p; p=p->pLeft){
++      u8 bEof = 0;
++      Fts3Expr *pTest = p;
++      Fts3Phrase *pPh;
++      assert( pTest->eType==FTSQUERY_NEAR || pTest->eType==FTSQUERY_PHRASE );
++      if( pTest->eType==FTSQUERY_NEAR ) pTest = pTest->pRight;
++      assert( pTest->eType==FTSQUERY_PHRASE );
++      pPh = pTest->pPhrase;
++
++      pIter = pPh->pOrPoslist;
++      iDocid = pPh->iOrDocid;
++      if( pCsr->bDesc==bDescDoclist ){
++        bEof = !pPh->doclist.nAll ||
++          (pIter >= (pPh->doclist.aAll + pPh->doclist.nAll));
++        while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
++          sqlite3Fts3DoclistNext(
++              bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, 
++              &pIter, &iDocid, &bEof
++          );
++        }
++      }else{
++        bEof = !pPh->doclist.nAll || (pIter && pIter<=pPh->doclist.aAll);
++        while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
++          int dummy;
++          sqlite3Fts3DoclistPrev(
++              bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, 
++              &pIter, &iDocid, &dummy, &bEof
++              );
++        }
+       }
++      pPh->pOrPoslist = pIter;
++      pPh->iOrDocid = iDocid;
++      if( bEof || iDocid!=pCsr->iPrevId ) bMatch = 0;
+     }
+-    pPhrase->pOrPoslist = pIter;
+-    pPhrase->iOrDocid = iDocid;
+ 
+-    if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0;
++    if( bMatch ){
++      pIter = pPhrase->pOrPoslist;
++    }else{
++      pIter = 0;
++    }
+   }
+   if( pIter==0 ) return SQLITE_OK;
+ 
+@@ -138939,7 +156258,7 @@
+ #ifdef _WIN32
+ __declspec(dllexport)
+ #endif
+-SQLITE_API int SQLITE_STDCALL sqlite3_fts3_init(
++SQLITE_API int sqlite3_fts3_init(
+   sqlite3 *db, 
+   char **pzErrMsg,
+   const sqlite3_api_routines *pApi
+@@ -138966,6 +156285,7 @@
+ ******************************************************************************
+ **
+ */
++/* #include "fts3Int.h" */
+ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
+ 
+ /* #include <string.h> */
+@@ -139522,6 +156842,7 @@
+ ** syntax is relatively simple, the whole tokenizer/parser system is
+ ** hand-coded. 
+ */
++/* #include "fts3Int.h" */
+ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
+ 
+ /*
+@@ -140299,125 +157620,151 @@
+     rc = SQLITE_ERROR;
+   }
+ 
+-  if( rc==SQLITE_OK && (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
+-    Fts3Expr **apLeaf;
+-    apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth);
+-    if( 0==apLeaf ){
+-      rc = SQLITE_NOMEM;
+-    }else{
+-      memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth);
+-    }
+-
+-    if( rc==SQLITE_OK ){
+-      int i;
+-      Fts3Expr *p;
+-
+-      /* Set $p to point to the left-most leaf in the tree of eType nodes. */
+-      for(p=pRoot; p->eType==eType; p=p->pLeft){
+-        assert( p->pParent==0 || p->pParent->pLeft==p );
+-        assert( p->pLeft && p->pRight );
++  if( rc==SQLITE_OK ){
++    if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
++      Fts3Expr **apLeaf;
++      apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth);
++      if( 0==apLeaf ){
++        rc = SQLITE_NOMEM;
++      }else{
++        memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth);
+       }
+ 
+-      /* This loop runs once for each leaf in the tree of eType nodes. */
+-      while( 1 ){
+-        int iLvl;
+-        Fts3Expr *pParent = p->pParent;     /* Current parent of p */
++      if( rc==SQLITE_OK ){
++        int i;
++        Fts3Expr *p;
+ 
+-        assert( pParent==0 || pParent->pLeft==p );
+-        p->pParent = 0;
+-        if( pParent ){
+-          pParent->pLeft = 0;
+-        }else{
+-          pRoot = 0;
++        /* Set $p to point to the left-most leaf in the tree of eType nodes. */
++        for(p=pRoot; p->eType==eType; p=p->pLeft){
++          assert( p->pParent==0 || p->pParent->pLeft==p );
++          assert( p->pLeft && p->pRight );
+         }
+-        rc = fts3ExprBalance(&p, nMaxDepth-1);
+-        if( rc!=SQLITE_OK ) break;
+ 
+-        for(iLvl=0; p && iLvl<nMaxDepth; iLvl++){
+-          if( apLeaf[iLvl]==0 ){
+-            apLeaf[iLvl] = p;
+-            p = 0;
++        /* This loop runs once for each leaf in the tree of eType nodes. */
++        while( 1 ){
++          int iLvl;
++          Fts3Expr *pParent = p->pParent;     /* Current parent of p */
++
++          assert( pParent==0 || pParent->pLeft==p );
++          p->pParent = 0;
++          if( pParent ){
++            pParent->pLeft = 0;
+           }else{
+-            assert( pFree );
+-            pFree->pLeft = apLeaf[iLvl];
+-            pFree->pRight = p;
+-            pFree->pLeft->pParent = pFree;
+-            pFree->pRight->pParent = pFree;
+-
+-            p = pFree;
+-            pFree = pFree->pParent;
+-            p->pParent = 0;
+-            apLeaf[iLvl] = 0;
++            pRoot = 0;
+           }
+-        }
+-        if( p ){
+-          sqlite3Fts3ExprFree(p);
+-          rc = SQLITE_TOOBIG;
+-          break;
+-        }
+-
+-        /* If that was the last leaf node, break out of the loop */
+-        if( pParent==0 ) break;
+-
+-        /* Set $p to point to the next leaf in the tree of eType nodes */
+-        for(p=pParent->pRight; p->eType==eType; p=p->pLeft);
+-
+-        /* Remove pParent from the original tree. */
+-        assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent );
+-        pParent->pRight->pParent = pParent->pParent;
+-        if( pParent->pParent ){
+-          pParent->pParent->pLeft = pParent->pRight;
+-        }else{
+-          assert( pParent==pRoot );
+-          pRoot = pParent->pRight;
+-        }
+-
+-        /* Link pParent into the free node list. It will be used as an
+-        ** internal node of the new tree.  */
+-        pParent->pParent = pFree;
+-        pFree = pParent;
+-      }
++          rc = fts3ExprBalance(&p, nMaxDepth-1);
++          if( rc!=SQLITE_OK ) break;
+ 
+-      if( rc==SQLITE_OK ){
+-        p = 0;
+-        for(i=0; i<nMaxDepth; i++){
+-          if( apLeaf[i] ){
+-            if( p==0 ){
+-              p = apLeaf[i];
+-              p->pParent = 0;
++          for(iLvl=0; p && iLvl<nMaxDepth; iLvl++){
++            if( apLeaf[iLvl]==0 ){
++              apLeaf[iLvl] = p;
++              p = 0;
+             }else{
+-              assert( pFree!=0 );
++              assert( pFree );
++              pFree->pLeft = apLeaf[iLvl];
+               pFree->pRight = p;
+-              pFree->pLeft = apLeaf[i];
+               pFree->pLeft->pParent = pFree;
+               pFree->pRight->pParent = pFree;
+ 
+               p = pFree;
+               pFree = pFree->pParent;
+               p->pParent = 0;
++              apLeaf[iLvl] = 0;
+             }
+           }
++          if( p ){
++            sqlite3Fts3ExprFree(p);
++            rc = SQLITE_TOOBIG;
++            break;
++          }
 +
-+/*
-+** Set the time to the current time reported by the VFS.
-+**
-+** Return the number of errors.
-+*/
-+static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
-+  p->iJD = sqlite3StmtCurrentTime(context);
-+  if( p->iJD>0 ){
-+    p->validJD = 1;
-+    return 0;
-+  }else{
-+    return 1;
-+  }
-+}
++          /* If that was the last leaf node, break out of the loop */
++          if( pParent==0 ) break;
 +
-+/*
-+** Attempt to parse the given string into a julian day number.  Return
-+** the number of errors.
-+**
-+** The following are acceptable forms for the input string:
-+**
-+**      YYYY-MM-DD HH:MM:SS.FFF  +/-HH:MM
-+**      DDDD.DD 
-+**      now
-+**
-+** In the first form, the +/-HH:MM is always optional.  The fractional
-+** seconds extension (the ".FFF") is optional.  The seconds portion
-+** (":SS.FFF") is option.  The year and date can be omitted as long
-+** as there is a time string.  The time string can be omitted as long
-+** as there is a year and date.
-+*/
-+static int parseDateOrTime(
-+  sqlite3_context *context, 
-+  const char *zDate, 
-+  DateTime *p
-+){
-+  double r;
-+  if( parseYyyyMmDd(zDate,p)==0 ){
-+    return 0;
-+  }else if( parseHhMmSs(zDate, p)==0 ){
-+    return 0;
-+  }else if( sqlite3StrICmp(zDate,"now")==0){
-+    return setDateTimeToCurrent(context, p);
-+  }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
-+    p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
-+    p->validJD = 1;
-+    return 0;
-+  }
-+  return 1;
-+}
++          /* Set $p to point to the next leaf in the tree of eType nodes */
++          for(p=pParent->pRight; p->eType==eType; p=p->pLeft);
 +
-+/*
-+** Compute the Year, Month, and Day from the julian day number.
-+*/
-+static void computeYMD(DateTime *p){
-+  int Z, A, B, C, D, E, X1;
-+  if( p->validYMD ) return;
-+  if( !p->validJD ){
-+    p->Y = 2000;
-+    p->M = 1;
-+    p->D = 1;
-+  }else{
-+    Z = (int)((p->iJD + 43200000)/86400000);
-+    A = (int)((Z - 1867216.25)/36524.25);
-+    A = Z + 1 + A - (A/4);
-+    B = A + 1524;
-+    C = (int)((B - 122.1)/365.25);
-+    D = (36525*C)/100;
-+    E = (int)((B-D)/30.6001);
-+    X1 = (int)(30.6001*E);
-+    p->D = B - D - X1;
-+    p->M = E<14 ? E-1 : E-13;
-+    p->Y = p->M>2 ? C - 4716 : C - 4715;
-+  }
-+  p->validYMD = 1;
-+}
++          /* Remove pParent from the original tree. */
++          assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent );
++          pParent->pRight->pParent = pParent->pParent;
++          if( pParent->pParent ){
++            pParent->pParent->pLeft = pParent->pRight;
++          }else{
++            assert( pParent==pRoot );
++            pRoot = pParent->pRight;
++          }
 +
-+/*
-+** Compute the Hour, Minute, and Seconds from the julian day number.
-+*/
-+static void computeHMS(DateTime *p){
-+  int s;
-+  if( p->validHMS ) return;
-+  computeJD(p);
-+  s = (int)((p->iJD + 43200000) % 86400000);
-+  p->s = s/1000.0;
-+  s = (int)p->s;
-+  p->s -= s;
-+  p->h = s/3600;
-+  s -= p->h*3600;
-+  p->m = s/60;
-+  p->s += s - p->m*60;
-+  p->validHMS = 1;
-+}
++          /* Link pParent into the free node list. It will be used as an
++          ** internal node of the new tree.  */
++          pParent->pParent = pFree;
++          pFree = pParent;
+         }
+-        pRoot = p;
+-      }else{
+-        /* An error occurred. Delete the contents of the apLeaf[] array 
+-        ** and pFree list. Everything else is cleaned up by the call to
+-        ** sqlite3Fts3ExprFree(pRoot) below.  */
+-        Fts3Expr *pDel;
+-        for(i=0; i<nMaxDepth; i++){
+-          sqlite3Fts3ExprFree(apLeaf[i]);
+-        }
+-        while( (pDel=pFree)!=0 ){
+-          pFree = pDel->pParent;
+-          sqlite3_free(pDel);
 +
-+/*
-+** Compute both YMD and HMS
-+*/
-+static void computeYMD_HMS(DateTime *p){
-+  computeYMD(p);
-+  computeHMS(p);
-+}
++        if( rc==SQLITE_OK ){
++          p = 0;
++          for(i=0; i<nMaxDepth; i++){
++            if( apLeaf[i] ){
++              if( p==0 ){
++                p = apLeaf[i];
++                p->pParent = 0;
++              }else{
++                assert( pFree!=0 );
++                pFree->pRight = p;
++                pFree->pLeft = apLeaf[i];
++                pFree->pLeft->pParent = pFree;
++                pFree->pRight->pParent = pFree;
++
++                p = pFree;
++                pFree = pFree->pParent;
++                p->pParent = 0;
++              }
++            }
++          }
++          pRoot = p;
++        }else{
++          /* An error occurred. Delete the contents of the apLeaf[] array 
++          ** and pFree list. Everything else is cleaned up by the call to
++          ** sqlite3Fts3ExprFree(pRoot) below.  */
++          Fts3Expr *pDel;
++          for(i=0; i<nMaxDepth; i++){
++            sqlite3Fts3ExprFree(apLeaf[i]);
++          }
++          while( (pDel=pFree)!=0 ){
++            pFree = pDel->pParent;
++            sqlite3_free(pDel);
++          }
+         }
 +
-+/*
-+** Clear the YMD and HMS and the TZ
-+*/
-+static void clearYMD_HMS_TZ(DateTime *p){
-+  p->validYMD = 0;
-+  p->validHMS = 0;
-+  p->validTZ = 0;
-+}
++        assert( pFree==0 );
++        sqlite3_free( apLeaf );
++      }
++    }else if( eType==FTSQUERY_NOT ){
++      Fts3Expr *pLeft = pRoot->pLeft;
++      Fts3Expr *pRight = pRoot->pRight;
 +
-+/*
-+** On recent Windows platforms, the localtime_s() function is available
-+** as part of the "Secure CRT". It is essentially equivalent to 
-+** localtime_r() available under most POSIX platforms, except that the 
-+** order of the parameters is reversed.
-+**
-+** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx.
-+**
-+** If the user has not indicated to use localtime_r() or localtime_s()
-+** already, check for an MSVC build environment that provides 
-+** localtime_s().
-+*/
-+#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \
-+    && defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
-+#undef  HAVE_LOCALTIME_S
-+#define HAVE_LOCALTIME_S 1
-+#endif
++      pRoot->pLeft = 0;
++      pRoot->pRight = 0;
++      pLeft->pParent = 0;
++      pRight->pParent = 0;
 +
-+#ifndef SQLITE_OMIT_LOCALTIME
-+/*
-+** The following routine implements the rough equivalent of localtime_r()
-+** using whatever operating-system specific localtime facility that
-+** is available.  This routine returns 0 on success and
-+** non-zero on any kind of error.
-+**
-+** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
-+** routine will always fail.
-+**
-+** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
-+** library function localtime_r() is used to assist in the calculation of
-+** local time.
++      rc = fts3ExprBalance(&pLeft, nMaxDepth-1);
++      if( rc==SQLITE_OK ){
++        rc = fts3ExprBalance(&pRight, nMaxDepth-1);
+       }
+ 
+-      assert( pFree==0 );
+-      sqlite3_free( apLeaf );
++      if( rc!=SQLITE_OK ){
++        sqlite3Fts3ExprFree(pRight);
++        sqlite3Fts3ExprFree(pLeft);
++      }else{
++        assert( pLeft && pRight );
++        pRoot->pLeft = pLeft;
++        pLeft->pParent = pRoot;
++        pRoot->pRight = pRight;
++        pRight->pParent = pRoot;
++      }
+     }
+   }
+-
++  
+   if( rc!=SQLITE_OK ){
+     sqlite3Fts3ExprFree(pRoot);
+     pRoot = 0;
+@@ -140815,12 +158162,14 @@
+ **     * The FTS3 module is being built into the core of
+ **       SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
+ */
++/* #include "fts3Int.h" */
+ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
+ 
+ /* #include <assert.h> */
+ /* #include <stdlib.h> */
+ /* #include <string.h> */
+ 
++/* #include "fts3_hash.h" */
+ 
+ /*
+ ** Malloc and Free functions
+@@ -141198,6 +158547,7 @@
+ **     * The FTS3 module is being built into the core of
+ **       SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
+ */
++/* #include "fts3Int.h" */
+ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
+ 
+ /* #include <assert.h> */
+@@ -141205,6 +158555,7 @@
+ /* #include <stdio.h> */
+ /* #include <string.h> */
+ 
++/* #include "fts3_tokenizer.h" */
+ 
+ /*
+ ** Class derived from sqlite3_tokenizer
+@@ -141862,12 +159213,25 @@
+ **     * The FTS3 module is being built into the core of
+ **       SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
+ */
++/* #include "fts3Int.h" */
+ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
+ 
+ /* #include <assert.h> */
+ /* #include <string.h> */
+ 
+ /*
++** Return true if the two-argument version of fts3_tokenizer()
++** has been activated via a prior call to sqlite3_db_config(db,
++** SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0);
 +*/
-+static int osLocaltime(time_t *t, struct tm *pTm){
-+  int rc;
-+#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S
-+  struct tm *pX;
-+#if SQLITE_THREADSAFE>0
-+  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-+#endif
-+  sqlite3_mutex_enter(mutex);
-+  pX = localtime(t);
-+#ifndef SQLITE_OMIT_BUILTIN_TEST
-+  if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
-+#endif
-+  if( pX ) *pTm = *pX;
-+  sqlite3_mutex_leave(mutex);
-+  rc = pX==0;
-+#else
-+#ifndef SQLITE_OMIT_BUILTIN_TEST
-+  if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
-+#endif
-+#if HAVE_LOCALTIME_R
-+  rc = localtime_r(t, pTm)==0;
-+#else
-+  rc = localtime_s(pTm, t);
-+#endif /* HAVE_LOCALTIME_R */
-+#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */
-+  return rc;
++static int fts3TokenizerEnabled(sqlite3_context *context){
++  sqlite3 *db = sqlite3_context_db_handle(context);
++  int isEnabled = 0;
++  sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,-1,&isEnabled);
++  return isEnabled;
 +}
-+#endif /* SQLITE_OMIT_LOCALTIME */
 +
-+
-+#ifndef SQLITE_OMIT_LOCALTIME
 +/*
-+** Compute the difference (in milliseconds) between localtime and UTC
-+** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
-+** return this value and set *pRc to SQLITE_OK. 
-+**
-+** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
-+** is undefined in this case.
-+*/
-+static sqlite3_int64 localtimeOffset(
-+  DateTime *p,                    /* Date at which to calculate offset */
-+  sqlite3_context *pCtx,          /* Write error here if one occurs */
-+  int *pRc                        /* OUT: Error code. SQLITE_OK or ERROR */
-+){
-+  DateTime x, y;
-+  time_t t;
-+  struct tm sLocal;
-+
-+  /* Initialize the contents of sLocal to avoid a compiler warning. */
-+  memset(&sLocal, 0, sizeof(sLocal));
-+
-+  x = *p;
-+  computeYMD_HMS(&x);
-+  if( x.Y<1971 || x.Y>=2038 ){
-+    /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
-+    ** works for years between 1970 and 2037. For dates outside this range,
-+    ** SQLite attempts to map the year into an equivalent year within this
-+    ** range, do the calculation, then map the year back.
-+    */
-+    x.Y = 2000;
-+    x.M = 1;
-+    x.D = 1;
-+    x.h = 0;
-+    x.m = 0;
-+    x.s = 0.0;
-+  } else {
-+    int s = (int)(x.s + 0.5);
-+    x.s = s;
-+  }
-+  x.tz = 0;
-+  x.validJD = 0;
-+  computeJD(&x);
-+  t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
-+  if( osLocaltime(&t, &sLocal) ){
-+    sqlite3_result_error(pCtx, "local time unavailable", -1);
-+    *pRc = SQLITE_ERROR;
-+    return 0;
-+  }
-+  y.Y = sLocal.tm_year + 1900;
-+  y.M = sLocal.tm_mon + 1;
-+  y.D = sLocal.tm_mday;
-+  y.h = sLocal.tm_hour;
-+  y.m = sLocal.tm_min;
-+  y.s = sLocal.tm_sec;
-+  y.validYMD = 1;
-+  y.validHMS = 1;
-+  y.validJD = 0;
-+  y.validTZ = 0;
-+  computeJD(&y);
-+  *pRc = SQLITE_OK;
-+  return y.iJD - x.iJD;
-+}
-+#endif /* SQLITE_OMIT_LOCALTIME */
-+
-+/*
-+** Process a modifier to a date-time stamp.  The modifiers are
-+** as follows:
-+**
-+**     NNN days
-+**     NNN hours
-+**     NNN minutes
-+**     NNN.NNNN seconds
-+**     NNN months
-+**     NNN years
-+**     start of month
-+**     start of year
-+**     start of week
-+**     start of day
-+**     weekday N
-+**     unixepoch
-+**     localtime
-+**     utc
-+**
-+** Return 0 on success and 1 if there is any kind of error. If the error
-+** is in a system call (i.e. localtime()), then an error message is written
-+** to context pCtx. If the error is an unrecognized modifier, no error is
-+** written to pCtx.
-+*/
-+static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
-+  int rc = 1;
-+  int n;
-+  double r;
-+  char *z, zBuf[30];
-+  z = zBuf;
-+  for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){
-+    z[n] = (char)sqlite3UpperToLower[(u8)zMod[n]];
-+  }
-+  z[n] = 0;
-+  switch( z[0] ){
-+#ifndef SQLITE_OMIT_LOCALTIME
-+    case 'l': {
-+      /*    localtime
-+      **
-+      ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
-+      ** show local time.
-+      */
-+      if( strcmp(z, "localtime")==0 ){
-+        computeJD(p);
-+        p->iJD += localtimeOffset(p, pCtx, &rc);
-+        clearYMD_HMS_TZ(p);
-+      }
-+      break;
-+    }
-+#endif
-+    case 'u': {
-+      /*
-+      **    unixepoch
-+      **
-+      ** Treat the current value of p->iJD as the number of
-+      ** seconds since 1970.  Convert to a real julian day number.
-+      */
-+      if( strcmp(z, "unixepoch")==0 && p->validJD ){
-+        p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000;
-+        clearYMD_HMS_TZ(p);
-+        rc = 0;
+ ** Implementation of the SQL scalar function for accessing the underlying 
+ ** hash table. This function may be called as follows:
+ **
+@@ -141887,7 +159251,7 @@
+ ** is a blob containing the pointer stored as the hash data corresponding
+ ** to string <key-name> (after the hash-table is updated, if applicable).
+ */
+-static void scalarFunc(
++static void fts3TokenizerFunc(
+   sqlite3_context *context,
+   int argc,
+   sqlite3_value **argv
+@@ -141905,16 +159269,20 @@
+   nName = sqlite3_value_bytes(argv[0])+1;
+ 
+   if( argc==2 ){
+-    void *pOld;
+-    int n = sqlite3_value_bytes(argv[1]);
+-    if( zName==0 || n!=sizeof(pPtr) ){
+-      sqlite3_result_error(context, "argument type mismatch", -1);
+-      return;
+-    }
+-    pPtr = *(void **)sqlite3_value_blob(argv[1]);
+-    pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr);
+-    if( pOld==pPtr ){
+-      sqlite3_result_error(context, "out of memory", -1);
++    if( fts3TokenizerEnabled(context) ){
++      void *pOld;
++      int n = sqlite3_value_bytes(argv[1]);
++      if( zName==0 || n!=sizeof(pPtr) ){
++        sqlite3_result_error(context, "argument type mismatch", -1);
++        return;
 +      }
-+#ifndef SQLITE_OMIT_LOCALTIME
-+      else if( strcmp(z, "utc")==0 ){
-+        sqlite3_int64 c1;
-+        computeJD(p);
-+        c1 = localtimeOffset(p, pCtx, &rc);
-+        if( rc==SQLITE_OK ){
-+          p->iJD -= c1;
-+          clearYMD_HMS_TZ(p);
-+          p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
-+        }
++      pPtr = *(void **)sqlite3_value_blob(argv[1]);
++      pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr);
++      if( pOld==pPtr ){
++        sqlite3_result_error(context, "out of memory", -1);
 +      }
++    }else{
++      sqlite3_result_error(context, "fts3tokenize disabled", -1);
+       return;
+     }
+   }else{
+@@ -141928,7 +159296,6 @@
+       return;
+     }
+   }
+-
+   sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
+ }
+ 
+@@ -142047,7 +159414,11 @@
+ 
+ #ifdef SQLITE_TEST
+ 
+-#include <tcl.h>
++#if defined(INCLUDE_SQLITE_TCL_H)
++#  include "sqlite_tcl.h"
++#else
++#  include "tcl.h"
 +#endif
-+      break;
-+    }
-+    case 'w': {
-+      /*
-+      **    weekday N
-+      **
-+      ** Move the date to the same time on the next occurrence of
-+      ** weekday N where 0==Sunday, 1==Monday, and so forth.  If the
-+      ** date is already on the appropriate weekday, this is a no-op.
-+      */
-+      if( strncmp(z, "weekday ", 8)==0
-+               && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
-+               && (n=(int)r)==r && n>=0 && r<7 ){
-+        sqlite3_int64 Z;
-+        computeYMD_HMS(p);
-+        p->validTZ = 0;
-+        p->validJD = 0;
-+        computeJD(p);
-+        Z = ((p->iJD + 129600000)/86400000) % 7;
-+        if( Z>n ) Z -= 7;
-+        p->iJD += (n - Z)*86400000;
-+        clearYMD_HMS_TZ(p);
-+        rc = 0;
-+      }
-+      break;
-+    }
-+    case 's': {
-+      /*
-+      **    start of TTTTT
-+      **
-+      ** Move the date backwards to the beginning of the current day,
-+      ** or month or year.
-+      */
-+      if( strncmp(z, "start of ", 9)!=0 ) break;
-+      z += 9;
-+      computeYMD(p);
-+      p->validHMS = 1;
-+      p->h = p->m = 0;
-+      p->s = 0.0;
-+      p->validTZ = 0;
-+      p->validJD = 0;
-+      if( strcmp(z,"month")==0 ){
-+        p->D = 1;
-+        rc = 0;
-+      }else if( strcmp(z,"year")==0 ){
-+        computeYMD(p);
-+        p->M = 1;
-+        p->D = 1;
-+        rc = 0;
-+      }else if( strcmp(z,"day")==0 ){
-+        rc = 0;
-+      }
-+      break;
-+    }
-+    case '+':
-+    case '-':
-+    case '0':
-+    case '1':
-+    case '2':
-+    case '3':
-+    case '4':
-+    case '5':
-+    case '6':
-+    case '7':
-+    case '8':
-+    case '9': {
-+      double rRounder;
-+      for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
-+      if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
-+        rc = 1;
-+        break;
-+      }
-+      if( z[n]==':' ){
-+        /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
-+        ** specified number of hours, minutes, seconds, and fractional seconds
-+        ** to the time.  The ".FFF" may be omitted.  The ":SS.FFF" may be
-+        ** omitted.
-+        */
-+        const char *z2 = z;
-+        DateTime tx;
-+        sqlite3_int64 day;
-+        if( !sqlite3Isdigit(*z2) ) z2++;
-+        memset(&tx, 0, sizeof(tx));
-+        if( parseHhMmSs(z2, &tx) ) break;
-+        computeJD(&tx);
-+        tx.iJD -= 43200000;
-+        day = tx.iJD/86400000;
-+        tx.iJD -= day*86400000;
-+        if( z[0]=='-' ) tx.iJD = -tx.iJD;
-+        computeJD(p);
-+        clearYMD_HMS_TZ(p);
-+        p->iJD += tx.iJD;
-+        rc = 0;
-+        break;
-+      }
-+      z += n;
-+      while( sqlite3Isspace(*z) ) z++;
-+      n = sqlite3Strlen30(z);
-+      if( n>10 || n<3 ) break;
-+      if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
-+      computeJD(p);
-+      rc = 0;
-+      rRounder = r<0 ? -0.5 : +0.5;
-+      if( n==3 && strcmp(z,"day")==0 ){
-+        p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder);
-+      }else if( n==4 && strcmp(z,"hour")==0 ){
-+        p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder);
-+      }else if( n==6 && strcmp(z,"minute")==0 ){
-+        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder);
-+      }else if( n==6 && strcmp(z,"second")==0 ){
-+        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder);
-+      }else if( n==5 && strcmp(z,"month")==0 ){
-+        int x, y;
-+        computeYMD_HMS(p);
-+        p->M += (int)r;
-+        x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
-+        p->Y += x;
-+        p->M -= x*12;
-+        p->validJD = 0;
-+        computeJD(p);
-+        y = (int)r;
-+        if( y!=r ){
-+          p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder);
-+        }
-+      }else if( n==4 && strcmp(z,"year")==0 ){
-+        int y = (int)r;
-+        computeYMD_HMS(p);
-+        p->Y += y;
-+        p->validJD = 0;
-+        computeJD(p);
-+        if( y!=r ){
-+          p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder);
-+        }
-+      }else{
-+        rc = 1;
-+      }
-+      clearYMD_HMS_TZ(p);
-+      break;
-+    }
-+    default: {
-+      break;
-+    }
-+  }
-+  return rc;
-+}
+ /* #include <string.h> */
+ 
+ /*
+@@ -142188,6 +159559,7 @@
+   return sqlite3_finalize(pStmt);
+ }
+ 
 +
-+/*
-+** Process time function arguments.  argv[0] is a date-time stamp.
-+** argv[1] and following are modifiers.  Parse them all and write
-+** the resulting time into the DateTime structure p.  Return 0
-+** on success and 1 if there are any errors.
-+**
-+** If there are zero parameters (if even argv[0] is undefined)
-+** then assume a default value of "now" for argv[0].
-+*/
-+static int isDate(
-+  sqlite3_context *context, 
-+  int argc, 
-+  sqlite3_value **argv, 
-+  DateTime *p
-+){
-+  int i;
-+  const unsigned char *z;
-+  int eType;
-+  memset(p, 0, sizeof(*p));
-+  if( argc==0 ){
-+    return setDateTimeToCurrent(context, p);
+ static
+ int queryTokenizer(
+   sqlite3 *db, 
+@@ -142258,11 +159630,13 @@
+   assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") );
+ 
+   /* Test the storage function */
+-  rc = registerTokenizer(db, "nosuchtokenizer", p1);
+-  assert( rc==SQLITE_OK );
+-  rc = queryTokenizer(db, "nosuchtokenizer", &p2);
+-  assert( rc==SQLITE_OK );
+-  assert( p2==p1 );
++  if( fts3TokenizerEnabled(context) ){
++    rc = registerTokenizer(db, "nosuchtokenizer", p1);
++    assert( rc==SQLITE_OK );
++    rc = queryTokenizer(db, "nosuchtokenizer", &p2);
++    assert( rc==SQLITE_OK );
++    assert( p2==p1 );
 +  }
-+  if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
-+                   || eType==SQLITE_INTEGER ){
-+    p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
-+    p->validJD = 1;
-+  }else{
-+    z = sqlite3_value_text(argv[0]);
-+    if( !z || parseDateOrTime(context, (char*)z, p) ){
-+      return 1;
+ 
+   sqlite3_result_text(context, "ok", -1, SQLITE_STATIC);
+ }
+@@ -142278,7 +159652,7 @@
+ **    sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
+ **
+ ** This function adds a scalar function (see header comment above
+-** scalarFunc() in this file for details) and, if ENABLE_TABLE is
++** fts3TokenizerFunc() in this file for details) and, if ENABLE_TABLE is
+ ** defined at compilation time, a temporary virtual table (see header 
+ ** comment above struct HashTableVtab) to the database schema. Both 
+ ** provide read/write access to the contents of *pHash.
+@@ -142307,10 +159681,10 @@
+ #endif
+ 
+   if( SQLITE_OK==rc ){
+-    rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0);
++    rc = sqlite3_create_function(db, zName, 1, any, p, fts3TokenizerFunc, 0, 0);
+   }
+   if( SQLITE_OK==rc ){
+-    rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0);
++    rc = sqlite3_create_function(db, zName, 2, any, p, fts3TokenizerFunc, 0, 0);
+   }
+ #ifdef SQLITE_TEST
+   if( SQLITE_OK==rc ){
+@@ -142357,6 +159731,7 @@
+ **     * The FTS3 module is being built into the core of
+ **       SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
+ */
++/* #include "fts3Int.h" */
+ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
+ 
+ /* #include <assert.h> */
+@@ -142364,6 +159739,7 @@
+ /* #include <stdio.h> */
+ /* #include <string.h> */
+ 
++/* #include "fts3_tokenizer.h" */
+ 
+ typedef struct simple_tokenizer {
+   sqlite3_tokenizer base;
+@@ -142608,6 +159984,7 @@
+ **   pos:     Token offset of token within input.
+ **
+ */
++/* #include "fts3Int.h" */
+ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
+ 
+ /* #include <string.h> */
+@@ -143043,6 +160420,7 @@
+ ** code in fts3.c.
+ */
+ 
++/* #include "fts3Int.h" */
+ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
+ 
+ /* #include <string.h> */
+@@ -143358,7 +160736,8 @@
+ ** of the oldest level in the db that contains at least ? segments. Or,
+ ** if no level in the FTS index contains more than ? segments, the statement
+ ** returns zero rows.  */
+-/* 28 */ "SELECT level FROM %Q.'%q_segdir' GROUP BY level HAVING count(*)>=?"
++/* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' "
++         "  GROUP BY level HAVING cnt>=?"
+          "  ORDER BY (level %% 1024) ASC LIMIT 1",
+ 
+ /* Estimate the upper limit on the number of leaf nodes in a new segment
+@@ -143431,7 +160810,8 @@
+     if( !zSql ){
+       rc = SQLITE_NOMEM;
+     }else{
+-      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, NULL);
++      rc = sqlite3_prepare_v3(p->db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
++                              &pStmt, NULL);
+       sqlite3_free(zSql);
+       assert( rc==SQLITE_OK || pStmt==0 );
+       p->aStmt[eStmt] = pStmt;
+@@ -143885,10 +161265,12 @@
+ */
+ static int fts3PendingTermsDocid(
+   Fts3Table *p,                   /* Full-text table handle */
++  int bDelete,                    /* True if this op is a delete */
+   int iLangid,                    /* Language id of row being written */
+   sqlite_int64 iDocid             /* Docid of row being written */
+ ){
+   assert( iLangid>=0 );
++  assert( bDelete==1 || bDelete==0 );
+ 
+   /* TODO(shess) Explore whether partially flushing the buffer on
+   ** forced-flush would provide better performance.  I suspect that if
+@@ -143896,7 +161278,8 @@
+   ** buffer was half empty, that would let the less frequent terms
+   ** generate longer doclists.
+   */
+-  if( iDocid<=p->iPrevDocid 
++  if( iDocid<p->iPrevDocid 
++   || (iDocid==p->iPrevDocid && p->bPrevDelete==0)
+    || p->iPrevLangid!=iLangid
+    || p->nPendingData>p->nMaxPendingData 
+   ){
+@@ -143905,6 +161288,7 @@
+   }
+   p->iPrevDocid = iDocid;
+   p->iPrevLangid = iLangid;
++  p->bPrevDelete = bDelete;
+   return SQLITE_OK;
+ }
+ 
+@@ -144094,7 +161478,8 @@
+     if( SQLITE_ROW==sqlite3_step(pSelect) ){
+       int i;
+       int iLangid = langidFromSelect(p, pSelect);
+-      rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0));
++      i64 iDocid = sqlite3_column_int64(pSelect, 0);
++      rc = fts3PendingTermsDocid(p, 1, iLangid, iDocid);
+       for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){
+         int iCol = i-1;
+         if( p->abNotindexed[iCol]==0 ){
+@@ -144342,14 +161727,19 @@
+ 
+     if( fts3SegReaderIsPending(pReader) ){
+       Fts3HashElem *pElem = *(pReader->ppNextElem);
+-      if( pElem==0 ){
+-        pReader->aNode = 0;
+-      }else{
++      sqlite3_free(pReader->aNode);
++      pReader->aNode = 0;
++      if( pElem ){
++        char *aCopy;
+         PendingList *pList = (PendingList *)fts3HashData(pElem);
++        int nCopy = pList->nData+1;
+         pReader->zTerm = (char *)fts3HashKey(pElem);
+         pReader->nTerm = fts3HashKeysize(pElem);
+-        pReader->nNode = pReader->nDoclist = pList->nData + 1;
+-        pReader->aNode = pReader->aDoclist = pList->aData;
++        aCopy = (char*)sqlite3_malloc(nCopy);
++        if( !aCopy ) return SQLITE_NOMEM;
++        memcpy(aCopy, pList->aData, nCopy);
++        pReader->nNode = pReader->nDoclist = nCopy;
++        pReader->aNode = pReader->aDoclist = aCopy;
+         pReader->ppNextElem++;
+         assert( pReader->aNode );
+       }
+@@ -144589,12 +161979,14 @@
+ ** second argument.
+ */
+ SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
+-  if( pReader && !fts3SegReaderIsPending(pReader) ){
+-    sqlite3_free(pReader->zTerm);
++  if( pReader ){
++    if( !fts3SegReaderIsPending(pReader) ){
++      sqlite3_free(pReader->zTerm);
 +    }
-+  }
-+  for(i=1; i<argc; i++){
-+    z = sqlite3_value_text(argv[i]);
-+    if( z==0 || parseModifier(context, (char*)z, p) ) return 1;
-+  }
-+  return 0;
-+}
-+
-+
+     if( !fts3SegReaderIsRootOnly(pReader) ){
+       sqlite3_free(pReader->aNode);
+-      sqlite3_blob_close(pReader->pBlob);
+     }
++    sqlite3_blob_close(pReader->pBlob);
+   }
+   sqlite3_free(pReader);
+ }
+@@ -146207,7 +163599,7 @@
+     ** 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 ){
++    if( csr.nSegment==1 && 0==fts3SegReaderIsPending(csr.apSegment[0]) ){
+       rc = SQLITE_DONE;
+       goto finished;
+     }
+@@ -146537,7 +163929,7 @@
+     while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
+       int iCol;
+       int iLangid = langidFromSelect(p, pStmt);
+-      rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0));
++      rc = fts3PendingTermsDocid(p, 0, iLangid, sqlite3_column_int64(pStmt, 0));
+       memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1));
+       for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
+         if( p->abNotindexed[iCol]==0 ){
+@@ -147849,10 +165241,11 @@
+     ** set nSeg to -1.
+     */
+     rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0);
+-    sqlite3_bind_int(pFindLevel, 1, nMin);
++    sqlite3_bind_int(pFindLevel, 1, MAX(2, nMin));
+     if( sqlite3_step(pFindLevel)==SQLITE_ROW ){
+       iAbsLevel = sqlite3_column_int64(pFindLevel, 0);
+-      nSeg = nMin;
++      nSeg = sqlite3_column_int(pFindLevel, 1);
++      assert( nSeg>=2 );
+     }else{
+       nSeg = -1;
+     }
+@@ -147967,11 +165360,14 @@
+ ** Convert the text beginning at *pz into an integer and return
+ ** its value.  Advance *pz to point to the first character past
+ ** the integer.
++**
++** This function used for parameters to merge= and incrmerge=
++** commands. 
+ */
+ static int fts3Getint(const char **pz){
+   const char *z = *pz;
+   int i = 0;
+-  while( (*z)>='0' && (*z)<='9' ) i = 10*i + *(z++) - '0';
++  while( (*z)>='0' && (*z)<='9' && i<214748363 ) i = 10*i + *(z++) - '0';
+   *pz = z;
+   return i;
+ }
+@@ -148642,7 +166038,7 @@
+       }
+     }
+     if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
+-      rc = fts3PendingTermsDocid(p, iLangid, *pRowid);
++      rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
+     }
+     if( rc==SQLITE_OK ){
+       assert( p->iPrevDocid==*pRowid );
+@@ -148703,6 +166099,7 @@
+ ******************************************************************************
+ */
+ 
++/* #include "fts3Int.h" */
+ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
+ 
+ /* #include <string.h> */
+@@ -148719,6 +166116,7 @@
+ #define FTS3_MATCHINFO_LCS       's'        /* nCol values */
+ #define FTS3_MATCHINFO_HITS      'x'        /* 3*nCol*nPhrase values */
+ #define FTS3_MATCHINFO_LHITS     'y'        /* nCol*nPhrase values */
++#define FTS3_MATCHINFO_LHITS_BM  'b'        /* nCol*nPhrase values */
+ 
+ /*
+ ** The default value for the second argument to matchinfo(). 
+@@ -148780,9 +166178,22 @@
+   int nCol;                       /* Number of columns in table */
+   int nPhrase;                    /* Number of matchable phrases in query */
+   sqlite3_int64 nDoc;             /* Number of docs in database */
++  char flag;
+   u32 *aMatchinfo;                /* Pre-allocated buffer */
+ };
+ 
 +/*
-+** The following routines implement the various date and time functions
-+** of SQLite.
++** An instance of this structure is used to manage a pair of buffers, each
++** (nElem * sizeof(u32)) bytes in size. See the MatchinfoBuffer code below
++** for details.
++*/
++struct MatchinfoBuffer {
++  u8 aRef[3];
++  int nElem;
++  int bGlobal;                    /* Set if global data is loaded */
++  char *zMatchinfo;
++  u32 aMatchinfo[1];
++};
+ 
+ 
+ /*
+@@ -148798,6 +166209,97 @@
+ };
+ 
+ 
++/*************************************************************************
++** Start of MatchinfoBuffer code.
 +*/
 +
 +/*
-+**    julianday( TIMESTRING, MOD, MOD, ...)
-+**
-+** Return the julian day number of the date specified in the arguments
++** Allocate a two-slot MatchinfoBuffer object.
 +*/
-+static void juliandayFunc(
-+  sqlite3_context *context,
-+  int argc,
-+  sqlite3_value **argv
-+){
-+  DateTime x;
-+  if( isDate(context, argc, argv, &x)==0 ){
-+    computeJD(&x);
-+    sqlite3_result_double(context, x.iJD/86400000.0);
++static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){
++  MatchinfoBuffer *pRet;
++  int nByte = sizeof(u32) * (2*nElem + 1) + sizeof(MatchinfoBuffer);
++  int nStr = (int)strlen(zMatchinfo);
++
++  pRet = sqlite3_malloc(nByte + nStr+1);
++  if( pRet ){
++    memset(pRet, 0, nByte);
++    pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
++    pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1);
++    pRet->nElem = nElem;
++    pRet->zMatchinfo = ((char*)pRet) + nByte;
++    memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1);
++    pRet->aRef[0] = 1;
 +  }
-+}
 +
-+/*
-+**    datetime( TIMESTRING, MOD, MOD, ...)
-+**
-+** Return YYYY-MM-DD HH:MM:SS
-+*/
-+static void datetimeFunc(
-+  sqlite3_context *context,
-+  int argc,
-+  sqlite3_value **argv
-+){
-+  DateTime x;
-+  if( isDate(context, argc, argv, &x)==0 ){
-+    char zBuf[100];
-+    computeYMD_HMS(&x);
-+    sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d",
-+                     x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
-+    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
-+  }
++  return pRet;
 +}
 +
-+/*
-+**    time( TIMESTRING, MOD, MOD, ...)
-+**
-+** Return HH:MM:SS
-+*/
-+static void timeFunc(
-+  sqlite3_context *context,
-+  int argc,
-+  sqlite3_value **argv
-+){
-+  DateTime x;
-+  if( isDate(context, argc, argv, &x)==0 ){
-+    char zBuf[100];
-+    computeHMS(&x);
-+    sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
-+    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
++static void fts3MIBufferFree(void *p){
++  MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]);
++
++  assert( (u32*)p==&pBuf->aMatchinfo[1] 
++       || (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2] 
++  );
++  if( (u32*)p==&pBuf->aMatchinfo[1] ){
++    pBuf->aRef[1] = 0;
++  }else{
++    pBuf->aRef[2] = 0;
 +  }
-+}
 +
-+/*
-+**    date( TIMESTRING, MOD, MOD, ...)
-+**
-+** Return YYYY-MM-DD
-+*/
-+static void dateFunc(
-+  sqlite3_context *context,
-+  int argc,
-+  sqlite3_value **argv
-+){
-+  DateTime x;
-+  if( isDate(context, argc, argv, &x)==0 ){
-+    char zBuf[100];
-+    computeYMD(&x);
-+    sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
-+    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
++  if( pBuf->aRef[0]==0 && pBuf->aRef[1]==0 && pBuf->aRef[2]==0 ){
++    sqlite3_free(pBuf);
 +  }
 +}
 +
-+/*
-+**    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
-+**
-+** Return a string described by FORMAT.  Conversions as follows:
-+**
-+**   %d  day of month
-+**   %f  ** fractional seconds  SS.SSS
-+**   %H  hour 00-24
-+**   %j  day of year 000-366
-+**   %J  ** julian day number
-+**   %m  month 01-12
-+**   %M  minute 00-59
-+**   %s  seconds since 1970-01-01
-+**   %S  seconds 00-59
-+**   %w  day of week 0-6  sunday==0
-+**   %W  week of year 00-53
-+**   %Y  year 0000-9999
-+**   %%  %
-+*/
-+static void strftimeFunc(
-+  sqlite3_context *context,
-+  int argc,
-+  sqlite3_value **argv
-+){
-+  DateTime x;
-+  u64 n;
-+  size_t i,j;
-+  char *z;
-+  sqlite3 *db;
-+  const char *zFmt;
-+  char zBuf[100];
-+  if( argc==0 ) return;
-+  zFmt = (const char*)sqlite3_value_text(argv[0]);
-+  if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
-+  db = sqlite3_context_db_handle(context);
-+  for(i=0, n=1; zFmt[i]; i++, n++){
-+    if( zFmt[i]=='%' ){
-+      switch( zFmt[i+1] ){
-+        case 'd':
-+        case 'H':
-+        case 'm':
-+        case 'M':
-+        case 'S':
-+        case 'W':
-+          n++;
-+          /* fall thru */
-+        case 'w':
-+        case '%':
-+          break;
-+        case 'f':
-+          n += 8;
-+          break;
-+        case 'j':
-+          n += 3;
-+          break;
-+        case 'Y':
-+          n += 8;
-+          break;
-+        case 's':
-+        case 'J':
-+          n += 50;
-+          break;
-+        default:
-+          return;  /* ERROR.  return a NULL */
-+      }
-+      i++;
-+    }
++static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
++  void (*xRet)(void*) = 0;
++  u32 *aOut = 0;
++
++  if( p->aRef[1]==0 ){
++    p->aRef[1] = 1;
++    aOut = &p->aMatchinfo[1];
++    xRet = fts3MIBufferFree;
 +  }
-+  testcase( n==sizeof(zBuf)-1 );
-+  testcase( n==sizeof(zBuf) );
-+  testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
-+  testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] );
-+  if( n<sizeof(zBuf) ){
-+    z = zBuf;
-+  }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){
-+    sqlite3_result_error_toobig(context);
-+    return;
++  else if( p->aRef[2]==0 ){
++    p->aRef[2] = 1;
++    aOut = &p->aMatchinfo[p->nElem+2];
++    xRet = fts3MIBufferFree;
 +  }else{
-+    z = sqlite3DbMallocRaw(db, (int)n);
-+    if( z==0 ){
-+      sqlite3_result_error_nomem(context);
-+      return;
-+    }
-+  }
-+  computeJD(&x);
-+  computeYMD_HMS(&x);
-+  for(i=j=0; zFmt[i]; i++){
-+    if( zFmt[i]!='%' ){
-+      z[j++] = zFmt[i];
-+    }else{
-+      i++;
-+      switch( zFmt[i] ){
-+        case 'd':  sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break;
-+        case 'f': {
-+          double s = x.s;
-+          if( s>59.999 ) s = 59.999;
-+          sqlite3_snprintf(7, &z[j],"%06.3f", s);
-+          j += sqlite3Strlen30(&z[j]);
-+          break;
-+        }
-+        case 'H':  sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break;
-+        case 'W': /* Fall thru */
-+        case 'j': {
-+          int nDay;             /* Number of days since 1st day of year */
-+          DateTime y = x;
-+          y.validJD = 0;
-+          y.M = 1;
-+          y.D = 1;
-+          computeJD(&y);
-+          nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
-+          if( zFmt[i]=='W' ){
-+            int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
-+            wd = (int)(((x.iJD+43200000)/86400000)%7);
-+            sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7);
-+            j += 2;
-+          }else{
-+            sqlite3_snprintf(4, &z[j],"%03d",nDay+1);
-+            j += 3;
-+          }
-+          break;
-+        }
-+        case 'J': {
-+          sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0);
-+          j+=sqlite3Strlen30(&z[j]);
-+          break;
-+        }
-+        case 'm':  sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break;
-+        case 'M':  sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break;
-+        case 's': {
-+          sqlite3_snprintf(30,&z[j],"%lld",
-+                           (i64)(x.iJD/1000 - 21086676*(i64)10000));
-+          j += sqlite3Strlen30(&z[j]);
-+          break;
-+        }
-+        case 'S':  sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break;
-+        case 'w': {
-+          z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
-+          break;
-+        }
-+        case 'Y': {
-+          sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]);
-+          break;
-+        }
-+        default:   z[j++] = '%'; break;
-+      }
++    aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32));
++    if( aOut ){
++      xRet = sqlite3_free;
++      if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
 +    }
 +  }
-+  z[j] = 0;
-+  sqlite3_result_text(context, z, -1,
-+                      z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
++
++  *paOut = aOut;
++  return xRet;
 +}
 +
-+/*
-+** current_time()
-+**
-+** This function returns the same value as time('now').
-+*/
-+static void ctimeFunc(
-+  sqlite3_context *context,
-+  int NotUsed,
-+  sqlite3_value **NotUsed2
-+){
-+  UNUSED_PARAMETER2(NotUsed, NotUsed2);
-+  timeFunc(context, 0, 0);
++static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){
++  p->bGlobal = 1;
++  memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32));
 +}
 +
 +/*
-+** current_date()
-+**
-+** This function returns the same value as date('now').
++** Free a MatchinfoBuffer object allocated using fts3MIBufferNew()
 +*/
-+static void cdateFunc(
-+  sqlite3_context *context,
-+  int NotUsed,
-+  sqlite3_value **NotUsed2
-+){
-+  UNUSED_PARAMETER2(NotUsed, NotUsed2);
-+  dateFunc(context, 0, 0);
++SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){
++  if( p ){
++    assert( p->aRef[0]==1 );
++    p->aRef[0] = 0;
++    if( p->aRef[0]==0 && p->aRef[1]==0 && p->aRef[2]==0 ){
++      sqlite3_free(p);
++    }
++  }
 +}
 +
-+/*
-+** current_timestamp()
-+**
-+** This function returns the same value as datetime('now').
++/* 
++** End of MatchinfoBuffer code.
++*************************************************************************/
++
++
+ /*
+ ** This function is used to help iterate through a position-list. A position
+ ** list is a list of unique integers, sorted from smallest to largest. Each
+@@ -148834,7 +166336,7 @@
+   void *pCtx                      /* Second argument to pass to callback */
+ ){
+   int rc;                         /* Return code */
+-  int eType = pExpr->eType;       /* Type of expression node pExpr */
++  int eType = pExpr->eType;     /* Type of expression node pExpr */
+ 
+   if( eType!=FTSQUERY_PHRASE ){
+     assert( pExpr->pLeft && pExpr->pRight );
+@@ -148868,6 +166370,7 @@
+   return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx);
+ }
+ 
++
+ /*
+ ** This is an fts3ExprIterate() callback used while loading the doclists
+ ** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
+@@ -148912,8 +166415,7 @@
+ 
+ static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
+   (*(int *)ctx)++;
+-  UNUSED_PARAMETER(pExpr);
+-  UNUSED_PARAMETER(iPhrase);
++  pExpr->iPhrase = iPhrase;
+   return SQLITE_OK;
+ }
+ static int fts3ExprPhraseCount(Fts3Expr *pExpr){
+@@ -149134,7 +166636,7 @@
+   sIter.nSnippet = nSnippet;
+   sIter.nPhrase = nList;
+   sIter.iCurrent = -1;
+-  rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
++  rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter);
+   if( rc==SQLITE_OK ){
+ 
+     /* Set the *pmSeen output variable. */
+@@ -149436,6 +166938,60 @@
+ }
+ 
+ /*
++** This function gathers 'y' or 'b' data for a single phrase.
 +*/
-+static void ctimestampFunc(
-+  sqlite3_context *context,
-+  int NotUsed,
-+  sqlite3_value **NotUsed2
++static void fts3ExprLHits(
++  Fts3Expr *pExpr,                /* Phrase expression node */
++  MatchInfo *p                    /* Matchinfo context */
 +){
-+  UNUSED_PARAMETER2(NotUsed, NotUsed2);
-+  datetimeFunc(context, 0, 0);
++  Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
++  int iStart;
++  Fts3Phrase *pPhrase = pExpr->pPhrase;
++  char *pIter = pPhrase->doclist.pList;
++  int iCol = 0;
++
++  assert( p->flag==FTS3_MATCHINFO_LHITS_BM || p->flag==FTS3_MATCHINFO_LHITS );
++  if( p->flag==FTS3_MATCHINFO_LHITS ){
++    iStart = pExpr->iPhrase * p->nCol;
++  }else{
++    iStart = pExpr->iPhrase * ((p->nCol + 31) / 32);
++  }
++
++  while( 1 ){
++    int nHit = fts3ColumnlistCount(&pIter);
++    if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
++      if( p->flag==FTS3_MATCHINFO_LHITS ){
++        p->aMatchinfo[iStart + iCol] = (u32)nHit;
++      }else if( nHit ){
++        p->aMatchinfo[iStart + (iCol+1)/32] |= (1 << (iCol&0x1F));
++      }
++    }
++    assert( *pIter==0x00 || *pIter==0x01 );
++    if( *pIter!=0x01 ) break;
++    pIter++;
++    pIter += fts3GetVarint32(pIter, &iCol);
++  }
 +}
-+#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */
 +
-+#ifdef SQLITE_OMIT_DATETIME_FUNCS
 +/*
-+** If the library is compiled to omit the full-scale date and time
-+** handling (to get a smaller binary), the following minimal version
-+** of the functions current_time(), current_date() and current_timestamp()
-+** are included instead. This is to support column declarations that
-+** include "DEFAULT CURRENT_TIME" etc.
-+**
-+** This function uses the C-library functions time(), gmtime()
-+** and strftime(). The format string to pass to strftime() is supplied
-+** as the user-data for the function.
++** Gather the results for matchinfo directives 'y' and 'b'.
 +*/
-+static void currentTimeFunc(
-+  sqlite3_context *context,
-+  int argc,
-+  sqlite3_value **argv
++static void fts3ExprLHitGather(
++  Fts3Expr *pExpr,
++  MatchInfo *p
 +){
-+  time_t t;
-+  char *zFormat = (char *)sqlite3_user_data(context);
-+  sqlite3 *db;
-+  sqlite3_int64 iT;
-+  struct tm *pTm;
-+  struct tm sNow;
-+  char zBuf[20];
-+
-+  UNUSED_PARAMETER(argc);
-+  UNUSED_PARAMETER(argv);
-+
-+  iT = sqlite3StmtCurrentTime(context);
-+  if( iT<=0 ) return;
-+  t = iT/1000 - 10000*(sqlite3_int64)21086676;
-+#if HAVE_GMTIME_R
-+  pTm = gmtime_r(&t, &sNow);
-+#else
-+  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-+  pTm = gmtime(&t);
-+  if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
-+  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-+#endif
-+  if( pTm ){
-+    strftime(zBuf, 20, zFormat, &sNow);
-+    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
++  assert( (pExpr->pLeft==0)==(pExpr->pRight==0) );
++  if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
++    if( pExpr->pLeft ){
++      fts3ExprLHitGather(pExpr->pLeft, p);
++      fts3ExprLHitGather(pExpr->pRight, p);
++    }else{
++      fts3ExprLHits(pExpr, p);
++    }
 +  }
 +}
-+#endif
 +
 +/*
-+** This function registered all of the above C functions as SQL
-+** functions.  This should be the only routine in this file with
-+** external linkage.
-+*/
-+SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
-+  static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
-+#ifndef SQLITE_OMIT_DATETIME_FUNCS
-+    FUNCTION(julianday,        -1, 0, 0, juliandayFunc ),
-+    FUNCTION(date,             -1, 0, 0, dateFunc      ),
-+    FUNCTION(time,             -1, 0, 0, timeFunc      ),
-+    FUNCTION(datetime,         -1, 0, 0, datetimeFunc  ),
-+    FUNCTION(strftime,         -1, 0, 0, strftimeFunc  ),
-+    FUNCTION(current_time,      0, 0, 0, ctimeFunc     ),
-+    FUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
-+    FUNCTION(current_date,      0, 0, 0, cdateFunc     ),
-+#else
-+    STR_FUNCTION(current_time,      0, "%H:%M:%S",          0, currentTimeFunc),
-+    STR_FUNCTION(current_date,      0, "%Y-%m-%d",          0, currentTimeFunc),
-+    STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
-+#endif
-+  };
-+  int i;
-+  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
-+  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs);
+ ** fts3ExprIterate() callback used to collect the "global" matchinfo stats
+ ** for a single query. 
+ **
+@@ -149501,51 +167057,6 @@
+   return rc;
+ }
+ 
+-/*
+-** fts3ExprIterate() callback used to gather information for the matchinfo
+-** directive 'y'.
+-*/
+-static int fts3ExprLHitsCb(
+-  Fts3Expr *pExpr,                /* Phrase expression node */
+-  int iPhrase,                    /* Phrase number */
+-  void *pCtx                      /* Pointer to MatchInfo structure */
+-){
+-  MatchInfo *p = (MatchInfo *)pCtx;
+-  Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
+-  int rc = SQLITE_OK;
+-  int iStart = iPhrase * p->nCol;
+-  Fts3Expr *pEof;                 /* Ancestor node already at EOF */
+-  
+-  /* This must be a phrase */
+-  assert( pExpr->pPhrase );
+-
+-  /* Initialize all output integers to zero. */
+-  memset(&p->aMatchinfo[iStart], 0, sizeof(u32) * p->nCol);
+-
+-  /* Check if this or any parent node is at EOF. If so, then all output
+-  ** values are zero.  */
+-  for(pEof=pExpr; pEof && pEof->bEof==0; pEof=pEof->pParent);
+-
+-  if( pEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
+-    Fts3Phrase *pPhrase = pExpr->pPhrase;
+-    char *pIter = pPhrase->doclist.pList;
+-    int iCol = 0;
+-
+-    while( 1 ){
+-      int nHit = fts3ColumnlistCount(&pIter);
+-      if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
+-        p->aMatchinfo[iStart + iCol] = (u32)nHit;
+-      }
+-      assert( *pIter==0x00 || *pIter==0x01 );
+-      if( *pIter!=0x01 ) break;
+-      pIter++;
+-      pIter += fts3GetVarint32(pIter, &iCol);
+-    }
+-  }
+-
+-  return rc;
+-}
+-
+ static int fts3MatchinfoCheck(
+   Fts3Table *pTab, 
+   char cArg,
+@@ -149559,6 +167070,7 @@
+    || (cArg==FTS3_MATCHINFO_LCS)
+    || (cArg==FTS3_MATCHINFO_HITS)
+    || (cArg==FTS3_MATCHINFO_LHITS)
++   || (cArg==FTS3_MATCHINFO_LHITS_BM)
+   ){
+     return SQLITE_OK;
+   }
+@@ -149586,6 +167098,10 @@
+       nVal = pInfo->nCol * pInfo->nPhrase;
+       break;
+ 
++    case FTS3_MATCHINFO_LHITS_BM:
++      nVal = pInfo->nPhrase * ((pInfo->nCol + 31) / 32);
++      break;
 +
-+  for(i=0; i<ArraySize(aDateTimeFuncs); i++){
-+    sqlite3FuncDefInsert(pHash, &aFunc[i]);
+     default:
+       assert( cArg==FTS3_MATCHINFO_HITS );
+       nVal = pInfo->nCol * pInfo->nPhrase * 3;
+@@ -149780,7 +167296,7 @@
+   sqlite3_stmt *pSelect = 0;
+ 
+   for(i=0; rc==SQLITE_OK && zArg[i]; i++){
+-
++    pInfo->flag = zArg[i];
+     switch( zArg[i] ){
+       case FTS3_MATCHINFO_NPHRASE:
+         if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase;
+@@ -149840,9 +167356,13 @@
+         }
+         break;
+ 
+-      case FTS3_MATCHINFO_LHITS:
+-        (void)fts3ExprIterate(pCsr->pExpr, fts3ExprLHitsCb, (void*)pInfo);
++      case FTS3_MATCHINFO_LHITS_BM:
++      case FTS3_MATCHINFO_LHITS: {
++        int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
++        memset(pInfo->aMatchinfo, 0, nZero);
++        fts3ExprLHitGather(pCsr->pExpr, pInfo);
+         break;
++      }
+ 
+       default: {
+         Fts3Expr *pExpr;
+@@ -149856,6 +167376,7 @@
+             if( rc!=SQLITE_OK ) break;
+           }
+           rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo);
++          sqlite3Fts3EvalTestDeferred(pCsr, &rc);
+           if( rc!=SQLITE_OK ) break;
+         }
+         (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo);
+@@ -149875,7 +167396,8 @@
+ ** Populate pCsr->aMatchinfo[] with data for the current row. The 
+ ** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32).
+ */
+-static int fts3GetMatchinfo(
++static void fts3GetMatchinfo(
++  sqlite3_context *pCtx,        /* Return results here */
+   Fts3Cursor *pCsr,               /* FTS3 Cursor object */
+   const char *zArg                /* Second argument to matchinfo() function */
+ ){
+@@ -149884,6 +167406,9 @@
+   int rc = SQLITE_OK;
+   int bGlobal = 0;                /* Collect 'global' stats as well as local */
+ 
++  u32 *aOut = 0;
++  void (*xDestroyOut)(void*) = 0;
++
+   memset(&sInfo, 0, sizeof(MatchInfo));
+   sInfo.pCursor = pCsr;
+   sInfo.nCol = pTab->nColumn;
+@@ -149891,21 +167416,18 @@
+   /* If there is cached matchinfo() data, but the format string for the 
+   ** cache does not match the format string for this request, discard 
+   ** the cached data. */
+-  if( pCsr->zMatchinfo && strcmp(pCsr->zMatchinfo, zArg) ){
+-    assert( pCsr->aMatchinfo );
+-    sqlite3_free(pCsr->aMatchinfo);
+-    pCsr->zMatchinfo = 0;
+-    pCsr->aMatchinfo = 0;
++  if( pCsr->pMIBuffer && strcmp(pCsr->pMIBuffer->zMatchinfo, zArg) ){
++    sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
++    pCsr->pMIBuffer = 0;
+   }
+ 
+-  /* If Fts3Cursor.aMatchinfo[] is NULL, then this is the first time the
++  /* If Fts3Cursor.pMIBuffer is NULL, then this is the first time the
+   ** matchinfo function has been called for this query. In this case 
+   ** allocate the array used to accumulate the matchinfo data and
+   ** initialize those elements that are constant for every row.
+   */
+-  if( pCsr->aMatchinfo==0 ){
++  if( pCsr->pMIBuffer==0 ){
+     int nMatchinfo = 0;           /* Number of u32 elements in match-info */
+-    int nArg;                     /* Bytes in zArg */
+     int i;                        /* Used to iterate through zArg */
+ 
+     /* Determine the number of phrases in the query */
+@@ -149914,30 +167436,46 @@
+ 
+     /* Determine the number of integers in the buffer returned by this call. */
+     for(i=0; zArg[i]; i++){
++      char *zErr = 0;
++      if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){
++        sqlite3_result_error(pCtx, zErr, -1);
++        sqlite3_free(zErr);
++        return;
++      }
+       nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]);
+     }
+ 
+     /* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */
+-    nArg = (int)strlen(zArg);
+-    pCsr->aMatchinfo = (u32 *)sqlite3_malloc(sizeof(u32)*nMatchinfo + nArg + 1);
+-    if( !pCsr->aMatchinfo ) return SQLITE_NOMEM;
+-
+-    pCsr->zMatchinfo = (char *)&pCsr->aMatchinfo[nMatchinfo];
+-    pCsr->nMatchinfo = nMatchinfo;
+-    memcpy(pCsr->zMatchinfo, zArg, nArg+1);
+-    memset(pCsr->aMatchinfo, 0, sizeof(u32)*nMatchinfo);
++    pCsr->pMIBuffer = fts3MIBufferNew(nMatchinfo, zArg);
++    if( !pCsr->pMIBuffer ) rc = SQLITE_NOMEM;
++
+     pCsr->isMatchinfoNeeded = 1;
+     bGlobal = 1;
+   }
+ 
+-  sInfo.aMatchinfo = pCsr->aMatchinfo;
+-  sInfo.nPhrase = pCsr->nPhrase;
+-  if( pCsr->isMatchinfoNeeded ){
++  if( rc==SQLITE_OK ){
++    xDestroyOut = fts3MIBufferAlloc(pCsr->pMIBuffer, &aOut);
++    if( xDestroyOut==0 ){
++      rc = SQLITE_NOMEM;
++    }
 +  }
-+}
 +
-+/************** End of date.c ************************************************/
-+/************** Begin file os.c **********************************************/
-+/*
-+** 2005 November 29
-+**
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
-+**
-+**    May you do good and not evil.
-+**    May you find forgiveness for yourself and forgive others.
-+**    May you share freely, never taking more than you give.
-+**
-+******************************************************************************
-+**
-+** This file contains OS interface code that is common to all
-+** architectures.
++  if( rc==SQLITE_OK ){
++    sInfo.aMatchinfo = aOut;
++    sInfo.nPhrase = pCsr->nPhrase;
+     rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg);
+-    pCsr->isMatchinfoNeeded = 0;
++    if( bGlobal ){
++      fts3MIBufferSetGlobal(pCsr->pMIBuffer);
++    }
+   }
+ 
+-  return rc;
++  if( rc!=SQLITE_OK ){
++    sqlite3_result_error_code(pCtx, rc);
++    if( xDestroyOut ) xDestroyOut(aOut);
++  }else{
++    int n = pCsr->pMIBuffer->nElem * sizeof(u32);
++    sqlite3_result_blob(pCtx, aOut, n, xDestroyOut);
++  }
+ }
+ 
+ /*
+@@ -150143,7 +167681,7 @@
+     */
+     sCtx.iCol = iCol;
+     sCtx.iTerm = 0;
+-    (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void *)&sCtx);
++    (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
+ 
+     /* Retreive the text stored in column iCol. If an SQL NULL is stored 
+     ** in column iCol, jump immediately to the next iteration of the loop.
+@@ -150235,19 +167773,9 @@
+   const char *zArg                /* Second arg to matchinfo() function */
+ ){
+   Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
+-  int rc;
+-  int i;
+   const char *zFormat;
+ 
+   if( zArg ){
+-    for(i=0; zArg[i]; i++){
+-      char *zErr = 0;
+-      if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){
+-        sqlite3_result_error(pContext, zErr, -1);
+-        sqlite3_free(zErr);
+-        return;
+-      }
+-    }
+     zFormat = zArg;
+   }else{
+     zFormat = FTS3_MATCHINFO_DEFAULT;
+@@ -150256,17 +167784,10 @@
+   if( !pCsr->pExpr ){
+     sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC);
+     return;
+-  }
+-
+-  /* Retrieve matchinfo() data. */
+-  rc = fts3GetMatchinfo(pCsr, zFormat);
+-  sqlite3Fts3SegmentsClose(pTab);
+-
+-  if( rc!=SQLITE_OK ){
+-    sqlite3_result_error_code(pContext, rc);
+   }else{
+-    int n = pCsr->nMatchinfo * sizeof(u32);
+-    sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT);
++    /* Retrieve matchinfo() data. */
++    fts3GetMatchinfo(pContext, pCsr, zFormat);
++    sqlite3Fts3SegmentsClose(pTab);
+   }
+ }
+ 
+@@ -150291,6 +167812,7 @@
+ 
+ #ifndef SQLITE_DISABLE_FTS3_UNICODE
+ 
++/* #include "fts3Int.h" */
+ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
+ 
+ /* #include <assert.h> */
+@@ -150298,6 +167820,7 @@
+ /* #include <stdio.h> */
+ /* #include <string.h> */
+ 
++/* #include "fts3_tokenizer.h" */
+ 
+ /*
+ ** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied
+@@ -150410,16 +167933,16 @@
+ ){
+   const unsigned char *z = (const unsigned char *)zIn;
+   const unsigned char *zTerm = &z[nIn];
+-  int iCode;
++  unsigned int iCode;
+   int nEntry = 0;
+ 
+   assert( bAlnum==0 || bAlnum==1 );
+ 
+   while( z<zTerm ){
+     READ_UTF8(z, zTerm, iCode);
+-    assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
+-    if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum 
+-     && sqlite3FtsUnicodeIsdiacritic(iCode)==0 
++    assert( (sqlite3FtsUnicodeIsalnum((int)iCode) & 0xFFFFFFFE)==0 );
++    if( sqlite3FtsUnicodeIsalnum((int)iCode)!=bAlnum 
++     && sqlite3FtsUnicodeIsdiacritic((int)iCode)==0 
+     ){
+       nEntry++;
+     }
+@@ -150436,13 +167959,13 @@
+     z = (const unsigned char *)zIn;
+     while( z<zTerm ){
+       READ_UTF8(z, zTerm, iCode);
+-      if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum 
+-       && sqlite3FtsUnicodeIsdiacritic(iCode)==0
++      if( sqlite3FtsUnicodeIsalnum((int)iCode)!=bAlnum 
++       && sqlite3FtsUnicodeIsdiacritic((int)iCode)==0
+       ){
+         int i, j;
+-        for(i=0; i<nNew && aNew[i]<iCode; i++);
++        for(i=0; i<nNew && aNew[i]<(int)iCode; i++);
+         for(j=nNew; j>i; j--) aNew[j] = aNew[j-1];
+-        aNew[i] = iCode;
++        aNew[i] = (int)iCode;
+         nNew++;
+       }
+     }
+@@ -150592,7 +168115,7 @@
+ ){
+   unicode_cursor *pCsr = (unicode_cursor *)pC;
+   unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer);
+-  int iCode = 0;
++  unsigned int iCode = 0;
+   char *zOut;
+   const unsigned char *z = &pCsr->aInput[pCsr->iOff];
+   const unsigned char *zStart = z;
+@@ -150604,7 +168127,7 @@
+   ** the input.  */
+   while( z<zTerm ){
+     READ_UTF8(z, zTerm, iCode);
+-    if( unicodeIsAlnum(p, iCode) ) break;
++    if( unicodeIsAlnum(p, (int)iCode) ) break;
+     zStart = z;
+   }
+   if( zStart>=zTerm ) return SQLITE_DONE;
+@@ -150624,7 +168147,7 @@
+ 
+     /* Write the folded case of the last character read to the output */
+     zEnd = z;
+-    iOut = sqlite3FtsUnicodeFold(iCode, p->bRemoveDiacritic);
++    iOut = sqlite3FtsUnicodeFold((int)iCode, p->bRemoveDiacritic);
+     if( iOut ){
+       WRITE_UTF8(zOut, iOut);
+     }
+@@ -150632,8 +168155,8 @@
+     /* If the cursor is not at EOF, read the next character */
+     if( z>=zTerm ) break;
+     READ_UTF8(z, zTerm, iCode);
+-  }while( unicodeIsAlnum(p, iCode) 
+-       || sqlite3FtsUnicodeIsdiacritic(iCode)
++  }while( unicodeIsAlnum(p, (int)iCode) 
++       || sqlite3FtsUnicodeIsdiacritic((int)iCode)
+   );
+ 
+   /* Set the output variables and return. */
+@@ -150797,9 +168320,9 @@
+     0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
+   };
+ 
+-  if( c<128 ){
+-    return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
+-  }else if( c<(1<<22) ){
++  if( (unsigned int)c<128 ){
++    return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 );
++  }else if( (unsigned int)c<(1<<22) ){
+     unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
+     int iRes = 0;
+     int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
+@@ -150992,16 +168515,17 @@
+ 
+   int ret = c;
+ 
+-  assert( c>=0 );
+   assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
+ 
+   if( c<128 ){
+     if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
+   }else if( c<65536 ){
++    const struct TableEntry *p;
+     int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
+     int iLo = 0;
+     int iRes = -1;
+ 
++    assert( c>aEntry[0].iCode );
+     while( iHi>=iLo ){
+       int iTest = (iHi + iLo) / 2;
+       int cmp = (c - aEntry[iTest].iCode);
+@@ -151012,14 +168536,12 @@
+         iHi = iTest-1;
+       }
+     }
+-    assert( iRes<0 || c>=aEntry[iRes].iCode );
+ 
+-    if( iRes>=0 ){
+-      const struct TableEntry *p = &aEntry[iRes];
+-      if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
+-        ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
+-        assert( ret>0 );
+-      }
++    assert( iRes>=0 && c>=aEntry[iRes].iCode );
++    p = &aEntry[iRes];
++    if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
++      ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
++      assert( ret>0 );
+     }
+ 
+     if( bRemoveDiacritic ) ret = remove_diacritic(ret);
+@@ -151093,8 +168615,10 @@
+ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE)
+ 
+ #ifndef SQLITE_CORE
++/*   #include "sqlite3ext.h" */
+   SQLITE_EXTENSION_INIT1
+ #else
++/*   #include "sqlite3.h" */
+ #endif
+ 
+ /* #include <string.h> */
+@@ -151104,6 +168628,7 @@
+ #ifndef SQLITE_AMALGAMATION
+ #include "sqlite3rtree.h"
+ typedef sqlite3_int64 i64;
++typedef sqlite3_uint64 u64;
+ typedef unsigned char u8;
+ typedef unsigned short u16;
+ typedef unsigned int u32;
+@@ -151152,13 +168677,16 @@
+   sqlite3 *db;                /* Host database connection */
+   int iNodeSize;              /* Size in bytes of each node in the node table */
+   u8 nDim;                    /* Number of dimensions */
++  u8 nDim2;                   /* Twice the number of dimensions */
+   u8 eCoordType;              /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
+   u8 nBytesPerCell;           /* Bytes consumed per cell */
++  u8 inWrTrans;               /* True if inside write transaction */
+   int iDepth;                 /* Current depth of the r-tree structure */
+   char *zDb;                  /* Name of database containing r-tree table */
+   char *zName;                /* Name of r-tree table */ 
+-  int nBusy;                  /* Current number of users of this structure */
++  u32 nBusy;                  /* Current number of users of this structure */
+   i64 nRowEst;                /* Estimated number of rows in this table */
++  u32 nCursor;                /* Number of open cursors */
+ 
+   /* List of nodes removed during a CondenseTree operation. List is
+   ** linked together via the pointer normally used for hash chains -
+@@ -151168,8 +168696,10 @@
+   RtreeNode *pDeleted;
+   int iReinsertHeight;        /* Height of sub-trees Reinsert() has run on */
+ 
++  /* Blob I/O on xxx_node */
++  sqlite3_blob *pNodeBlob;
++
+   /* Statements to read/write/delete a record from xxx_node */
+-  sqlite3_stmt *pReadNode;
+   sqlite3_stmt *pWriteNode;
+   sqlite3_stmt *pDeleteNode;
+ 
+@@ -151369,14 +168899,6 @@
+   void *pContext;
+ };
+ 
+-
+-/*
+-** Value for the first field of every RtreeMatchArg object. The MATCH
+-** operator tests that the first field of a blob operand matches this
+-** value to avoid operating on invalid blobs (which could cause a segfault).
+-*/
+-#define RTREE_GEOMETRY_MAGIC 0x891245AB
+-
+ /*
+ ** An instance of this structure (in the form of a BLOB) is returned by
+ ** the SQL functions that sqlite3_rtree_geometry_callback() and
+@@ -151384,9 +168906,10 @@
+ ** operand to the MATCH operator of an R-Tree.
+ */
+ struct RtreeMatchArg {
+-  u32 magic;                  /* Always RTREE_GEOMETRY_MAGIC */
++  u32 iSize;                  /* Size of this object */
+   RtreeGeomCallback cb;       /* Info about the callback functions */
+   int nParam;                 /* Number of parameters to the SQL function */
++  sqlite3_value **apSqlParam; /* Original SQL parameter values */
+   RtreeDValue aParam[1];      /* Values for parameters to the SQL function */
+ };
+ 
+@@ -151397,6 +168920,58 @@
+ # define MIN(x,y) ((x) > (y) ? (y) : (x))
+ #endif
+ 
++/* What version of GCC is being used.  0 means GCC is not being used .
++** Note that the GCC_VERSION macro will also be set correctly when using
++** clang, since clang works hard to be gcc compatible.  So the gcc
++** optimizations will also work when compiling with clang.
++*/
++#ifndef GCC_VERSION
++#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
++# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
++#else
++# define GCC_VERSION 0
++#endif
++#endif
++
++/* The testcase() macro should already be defined in the amalgamation.  If
++** it is not, make it a no-op.
 +*/
-+#define _SQLITE_OS_C_ 1
-+#undef _SQLITE_OS_C_
++#ifndef SQLITE_AMALGAMATION
++# define testcase(X)
++#endif
 +
 +/*
-+** The default SQLite sqlite3_vfs implementations do not allocate
-+** memory (actually, os_unix.c allocates a small amount of memory
-+** from within OsOpen()), but some third-party implementations may.
-+** So we test the effects of a malloc() failing and the sqlite3OsXXX()
-+** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
-+**
-+** The following functions are instrumented for malloc() failure 
-+** testing:
-+**
-+**     sqlite3OsRead()
-+**     sqlite3OsWrite()
-+**     sqlite3OsSync()
-+**     sqlite3OsFileSize()
-+**     sqlite3OsLock()
-+**     sqlite3OsCheckReservedLock()
-+**     sqlite3OsFileControl()
-+**     sqlite3OsShmMap()
-+**     sqlite3OsOpen()
-+**     sqlite3OsDelete()
-+**     sqlite3OsAccess()
-+**     sqlite3OsFullPathname()
++** Macros to determine whether the machine is big or little endian,
++** and whether or not that determination is run-time or compile-time.
 +**
++** For best performance, an attempt is made to guess at the byte-order
++** using C-preprocessor macros.  If that is unsuccessful, or if
++** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
++** at run-time.
 +*/
-+#if defined(SQLITE_TEST)
-+SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1;
-+  #define DO_OS_MALLOC_TEST(x)                                       \
-+  if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) {  \
-+    void *pTstAlloc = sqlite3Malloc(10);                             \
-+    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
-+    sqlite3_free(pTstAlloc);                                         \
-+  }
++#ifndef SQLITE_BYTEORDER
++#if defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
++    defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)  ||    \
++    defined(_M_AMD64) || defined(_M_ARM)     || defined(__x86)   ||    \
++    defined(__arm__)
++# define SQLITE_BYTEORDER    1234
++#elif defined(sparc)    || defined(__ppc__)
++# define SQLITE_BYTEORDER    4321
 +#else
-+  #define DO_OS_MALLOC_TEST(x)
++# define SQLITE_BYTEORDER    0     /* 0 means "unknown at compile-time" */
++#endif
 +#endif
 +
-+/*
-+** The following routines are convenience wrappers around methods
-+** of the sqlite3_file object.  This is mostly just syntactic sugar. All
-+** of this would be completely automatic if SQLite were coded using
-+** C++ instead of plain old C.
-+*/
-+SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file *pId){
-+  int rc = SQLITE_OK;
-+  if( pId->pMethods ){
-+    rc = pId->pMethods->xClose(pId);
-+    pId->pMethods = 0;
-+  }
-+  return rc;
-+}
-+SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
-+  DO_OS_MALLOC_TEST(id);
-+  return id->pMethods->xRead(id, pBuf, amt, offset);
-+}
-+SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
-+  DO_OS_MALLOC_TEST(id);
-+  return id->pMethods->xWrite(id, pBuf, amt, offset);
-+}
-+SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){
-+  return id->pMethods->xTruncate(id, size);
-+}
-+SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){
-+  DO_OS_MALLOC_TEST(id);
-+  return id->pMethods->xSync(id, flags);
-+}
-+SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
-+  DO_OS_MALLOC_TEST(id);
-+  return id->pMethods->xFileSize(id, pSize);
-+}
-+SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){
-+  DO_OS_MALLOC_TEST(id);
-+  return id->pMethods->xLock(id, lockType);
-+}
-+SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){
-+  return id->pMethods->xUnlock(id, lockType);
-+}
-+SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
-+  DO_OS_MALLOC_TEST(id);
-+  return id->pMethods->xCheckReservedLock(id, pResOut);
-+}
 +
-+/*
-+** Use sqlite3OsFileControl() when we are doing something that might fail
-+** and we need to know about the failures.  Use sqlite3OsFileControlHint()
-+** when simply tossing information over the wall to the VFS and we do not
-+** really care if the VFS receives and understands the information since it
-+** is only a hint and can be safely ignored.  The sqlite3OsFileControlHint()
-+** routine has no return value since the return value would be meaningless.
-+*/
-+SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
-+#ifdef SQLITE_TEST
-+  if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
-+    /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
-+    ** is using a regular VFS, it is called after the corresponding 
-+    ** transaction has been committed. Injecting a fault at this point 
-+    ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
-+    ** but the transaction is committed anyway.
-+    **
-+    ** The core must call OsFileControl() though, not OsFileControlHint(),
-+    ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
-+    ** means the commit really has failed and an error should be returned
-+    ** to the user.  */
-+    DO_OS_MALLOC_TEST(id);
-+  }
++/* What version of MSVC is being used.  0 means MSVC is not being used */
++#ifndef MSVC_VERSION
++#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
++# define MSVC_VERSION _MSC_VER
++#else
++# define MSVC_VERSION 0
++#endif
 +#endif
-+  return id->pMethods->xFileControl(id, op, pArg);
-+}
-+SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
-+  (void)id->pMethods->xFileControl(id, op, pArg);
-+}
-+
-+SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){
-+  int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
-+  return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
-+}
-+SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
-+  return id->pMethods->xDeviceCharacteristics(id);
-+}
-+SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
-+  return id->pMethods->xShmLock(id, offset, n, flags);
-+}
-+SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){
-+  id->pMethods->xShmBarrier(id);
-+}
-+SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
-+  return id->pMethods->xShmUnmap(id, deleteFlag);
-+}
-+SQLITE_PRIVATE int sqlite3OsShmMap(
-+  sqlite3_file *id,               /* Database file handle */
-+  int iPage,
-+  int pgsz,
-+  int bExtend,                    /* True to extend file if necessary */
-+  void volatile **pp              /* OUT: Pointer to mapping */
-+){
-+  DO_OS_MALLOC_TEST(id);
-+  return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
-+}
 +
-+#if SQLITE_MAX_MMAP_SIZE>0
-+/* The real implementation of xFetch and xUnfetch */
-+SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
-+  DO_OS_MALLOC_TEST(id);
-+  return id->pMethods->xFetch(id, iOff, iAmt, pp);
+ /*
+ ** Functions to deserialize a 16 bit integer, 32 bit real number and
+ ** 64 bit integer. The deserialized value is returned.
+@@ -151405,24 +168980,47 @@
+   return (p[0]<<8) + p[1];
+ }
+ static void readCoord(u8 *p, RtreeCoord *pCoord){
++  assert( ((((char*)p) - (char*)0)&3)==0 );  /* p is always 4-byte aligned */
++#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
++  pCoord->u = _byteswap_ulong(*(u32*)p);
++#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
++  pCoord->u = __builtin_bswap32(*(u32*)p);
++#elif SQLITE_BYTEORDER==4321
++  pCoord->u = *(u32*)p;
++#else
+   pCoord->u = (
+     (((u32)p[0]) << 24) + 
+     (((u32)p[1]) << 16) + 
+     (((u32)p[2]) <<  8) + 
+     (((u32)p[3]) <<  0)
+   );
++#endif
  }
- SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
-   return id->pMethods->xUnfetch(id, iOff, p);
-@@ -20088,7 +23720,7 @@
+ static i64 readInt64(u8 *p){
+-  return (
+-    (((i64)p[0]) << 56) + 
+-    (((i64)p[1]) << 48) + 
+-    (((i64)p[2]) << 40) + 
+-    (((i64)p[3]) << 32) + 
+-    (((i64)p[4]) << 24) + 
+-    (((i64)p[5]) << 16) + 
+-    (((i64)p[6]) <<  8) + 
+-    (((i64)p[7]) <<  0)
++#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
++  u64 x;
++  memcpy(&x, p, 8);
++  return (i64)_byteswap_uint64(x);
++#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
++  u64 x;
++  memcpy(&x, p, 8);
++  return (i64)__builtin_bswap64(x);
++#elif SQLITE_BYTEORDER==4321
++  i64 x;
++  memcpy(&x, p, 8);
++  return x;
++#else
++  return (i64)(
++    (((u64)p[0]) << 56) + 
++    (((u64)p[1]) << 48) + 
++    (((u64)p[2]) << 40) + 
++    (((u64)p[3]) << 32) + 
++    (((u64)p[4]) << 24) + 
++    (((u64)p[5]) << 16) + 
++    (((u64)p[6]) <<  8) + 
++    (((u64)p[7]) <<  0)
+   );
++#endif
+ }
+ 
  /*
- ** Include the primary Windows SDK header file.
+@@ -151430,23 +169028,43 @@
+ ** 64 bit integer. The value returned is the number of bytes written
+ ** to the argument buffer (always 2, 4 and 8 respectively).
  */
--#include "windows.h"
-+/* #include "windows.h" */
+-static int writeInt16(u8 *p, int i){
++static void writeInt16(u8 *p, int i){
+   p[0] = (i>> 8)&0xFF;
+   p[1] = (i>> 0)&0xFF;
+-  return 2;
+ }
+ static int writeCoord(u8 *p, RtreeCoord *pCoord){
+   u32 i;
++  assert( ((((char*)p) - (char*)0)&3)==0 );  /* p is always 4-byte aligned */
+   assert( sizeof(RtreeCoord)==4 );
+   assert( sizeof(u32)==4 );
++#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
++  i = __builtin_bswap32(pCoord->u);
++  memcpy(p, &i, 4);
++#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
++  i = _byteswap_ulong(pCoord->u);
++  memcpy(p, &i, 4);
++#elif SQLITE_BYTEORDER==4321
++  i = pCoord->u;
++  memcpy(p, &i, 4);
++#else
+   i = pCoord->u;
+   p[0] = (i>>24)&0xFF;
+   p[1] = (i>>16)&0xFF;
+   p[2] = (i>> 8)&0xFF;
+   p[3] = (i>> 0)&0xFF;
++#endif
+   return 4;
+ }
+ static int writeInt64(u8 *p, i64 i){
++#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
++  i = (i64)__builtin_bswap64((u64)i);
++  memcpy(p, &i, 8);
++#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
++  i = (i64)_byteswap_uint64((u64)i);
++  memcpy(p, &i, 8);
++#elif SQLITE_BYTEORDER==4321
++  memcpy(p, &i, 8);
++#else
+   p[0] = (i>>56)&0xFF;
+   p[1] = (i>>48)&0xFF;
+   p[2] = (i>>40)&0xFF;
+@@ -151455,6 +169073,7 @@
+   p[5] = (i>>16)&0xFF;
+   p[6] = (i>> 8)&0xFF;
+   p[7] = (i>> 0)&0xFF;
++#endif
+   return 8;
+ }
  
- #ifdef __CYGWIN__
- # include <sys/cygwin.h>
-@@ -25328,7 +28960,7 @@
- #include <sys/time.h>
- #include <errno.h>
- #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
--# include <sys/mman.h>
-+/* # include <sys/mman.h> */
- #endif
+@@ -151538,6 +169157,17 @@
+ }
  
- #if SQLITE_ENABLE_LOCKING_STYLE
-@@ -33657,6275 +37289,5194 @@
- #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-   { "AreFileApisANSI",         (SYSCALL)AreFileApisANSI,         0 },
- #else
--  { "AreFileApisANSI",         (SYSCALL)0,                       0 },
--#endif
--
--#ifndef osAreFileApisANSI
--#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent)
--#endif
--
--#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
--  { "CharLowerW",              (SYSCALL)CharLowerW,              0 },
--#else
--  { "CharLowerW",              (SYSCALL)0,                       0 },
--#endif
--
--#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent)
--
--#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
--  { "CharUpperW",              (SYSCALL)CharUpperW,              0 },
--#else
--  { "CharUpperW",              (SYSCALL)0,                       0 },
--#endif
--
--#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent)
--
--  { "CloseHandle",             (SYSCALL)CloseHandle,             0 },
--
--#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent)
--
--#if defined(SQLITE_WIN32_HAS_ANSI)
--  { "CreateFileA",             (SYSCALL)CreateFileA,             0 },
--#else
--  { "CreateFileA",             (SYSCALL)0,                       0 },
--#endif
--
--#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
--        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
--
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
--  { "CreateFileW",             (SYSCALL)CreateFileW,             0 },
--#else
--  { "CreateFileW",             (SYSCALL)0,                       0 },
--#endif
--
--#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
--        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
--
--#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
--        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
--  { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
--#else
--  { "CreateFileMappingA",      (SYSCALL)0,                       0 },
--#endif
--
--#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
--        DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
--
--#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
--        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
--  { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
--#else
--  { "CreateFileMappingW",      (SYSCALL)0,                       0 },
--#endif
--
--#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
--        DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
--
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
--  { "CreateMutexW",            (SYSCALL)CreateMutexW,            0 },
--#else
--  { "CreateMutexW",            (SYSCALL)0,                       0 },
--#endif
--
--#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
--        LPCWSTR))aSyscall[8].pCurrent)
--
--#if defined(SQLITE_WIN32_HAS_ANSI)
--  { "DeleteFileA",             (SYSCALL)DeleteFileA,             0 },
--#else
--  { "DeleteFileA",             (SYSCALL)0,                       0 },
--#endif
--
--#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent)
--
--#if defined(SQLITE_WIN32_HAS_WIDE)
--  { "DeleteFileW",             (SYSCALL)DeleteFileW,             0 },
--#else
--  { "DeleteFileW",             (SYSCALL)0,                       0 },
--#endif
--
--#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent)
--
--#if SQLITE_OS_WINCE
--  { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
--#else
--  { "FileTimeToLocalFileTime", (SYSCALL)0,                       0 },
--#endif
--
--#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
--        LPFILETIME))aSyscall[11].pCurrent)
--
--#if SQLITE_OS_WINCE
--  { "FileTimeToSystemTime",    (SYSCALL)FileTimeToSystemTime,    0 },
--#else
--  { "FileTimeToSystemTime",    (SYSCALL)0,                       0 },
--#endif
--
--#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
--        LPSYSTEMTIME))aSyscall[12].pCurrent)
--
--  { "FlushFileBuffers",        (SYSCALL)FlushFileBuffers,        0 },
--
--#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent)
--
--#if defined(SQLITE_WIN32_HAS_ANSI)
--  { "FormatMessageA",          (SYSCALL)FormatMessageA,          0 },
--#else
--  { "FormatMessageA",          (SYSCALL)0,                       0 },
--#endif
--
--#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
--        DWORD,va_list*))aSyscall[14].pCurrent)
--
--#if defined(SQLITE_WIN32_HAS_WIDE)
--  { "FormatMessageW",          (SYSCALL)FormatMessageW,          0 },
--#else
--  { "FormatMessageW",          (SYSCALL)0,                       0 },
--#endif
--
--#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
--        DWORD,va_list*))aSyscall[15].pCurrent)
--
--#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
--  { "FreeLibrary",             (SYSCALL)FreeLibrary,             0 },
--#else
--  { "FreeLibrary",             (SYSCALL)0,                       0 },
--#endif
--
--#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
--
--  { "GetCurrentProcessId",     (SYSCALL)GetCurrentProcessId,     0 },
--
--#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent)
--
--#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
--  { "GetDiskFreeSpaceA",       (SYSCALL)GetDiskFreeSpaceA,       0 },
--#else
--  { "GetDiskFreeSpaceA",       (SYSCALL)0,                       0 },
--#endif
--
--#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
--        LPDWORD))aSyscall[18].pCurrent)
--
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
--  { "GetDiskFreeSpaceW",       (SYSCALL)GetDiskFreeSpaceW,       0 },
--#else
--  { "GetDiskFreeSpaceW",       (SYSCALL)0,                       0 },
--#endif
--
--#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
--        LPDWORD))aSyscall[19].pCurrent)
--
--#if defined(SQLITE_WIN32_HAS_ANSI)
--  { "GetFileAttributesA",      (SYSCALL)GetFileAttributesA,      0 },
--#else
--  { "GetFileAttributesA",      (SYSCALL)0,                       0 },
--#endif
--
--#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
--
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
--  { "GetFileAttributesW",      (SYSCALL)GetFileAttributesW,      0 },
--#else
--  { "GetFileAttributesW",      (SYSCALL)0,                       0 },
--#endif
--
--#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
--
--#if defined(SQLITE_WIN32_HAS_WIDE)
--  { "GetFileAttributesExW",    (SYSCALL)GetFileAttributesExW,    0 },
--#else
--  { "GetFileAttributesExW",    (SYSCALL)0,                       0 },
--#endif
--
--#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
--        LPVOID))aSyscall[22].pCurrent)
--
--#if !SQLITE_OS_WINRT
--  { "GetFileSize",             (SYSCALL)GetFileSize,             0 },
--#else
--  { "GetFileSize",             (SYSCALL)0,                       0 },
--#endif
--
--#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent)
--
--#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
--  { "GetFullPathNameA",        (SYSCALL)GetFullPathNameA,        0 },
--#else
--  { "GetFullPathNameA",        (SYSCALL)0,                       0 },
--#endif
--
--#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
--        LPSTR*))aSyscall[24].pCurrent)
--
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
--  { "GetFullPathNameW",        (SYSCALL)GetFullPathNameW,        0 },
--#else
--  { "GetFullPathNameW",        (SYSCALL)0,                       0 },
--#endif
--
--#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
--        LPWSTR*))aSyscall[25].pCurrent)
--
--  { "GetLastError",            (SYSCALL)GetLastError,            0 },
--
--#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
--
--#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
--#if SQLITE_OS_WINCE
--  /* The GetProcAddressA() routine is only available on Windows CE. */
--  { "GetProcAddressA",         (SYSCALL)GetProcAddressA,         0 },
--#else
--  /* All other Windows platforms expect GetProcAddress() to take
--  ** an ANSI string regardless of the _UNICODE setting */
--  { "GetProcAddressA",         (SYSCALL)GetProcAddress,          0 },
--#endif
--#else
--  { "GetProcAddressA",         (SYSCALL)0,                       0 },
--#endif
--
--#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
--        LPCSTR))aSyscall[27].pCurrent)
--
--#if !SQLITE_OS_WINRT
--  { "GetSystemInfo",           (SYSCALL)GetSystemInfo,           0 },
--#else
--  { "GetSystemInfo",           (SYSCALL)0,                       0 },
--#endif
--
--#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent)
--
--  { "GetSystemTime",           (SYSCALL)GetSystemTime,           0 },
--
--#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent)
--
--#if !SQLITE_OS_WINCE
--  { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
--#else
--  { "GetSystemTimeAsFileTime", (SYSCALL)0,                       0 },
--#endif
--
--#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
--        LPFILETIME))aSyscall[30].pCurrent)
--
--#if defined(SQLITE_WIN32_HAS_ANSI)
--  { "GetTempPathA",            (SYSCALL)GetTempPathA,            0 },
--#else
--  { "GetTempPathA",            (SYSCALL)0,                       0 },
--#endif
--
--#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent)
--
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
--  { "GetTempPathW",            (SYSCALL)GetTempPathW,            0 },
--#else
--  { "GetTempPathW",            (SYSCALL)0,                       0 },
--#endif
--
--#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent)
--
--#if !SQLITE_OS_WINRT
--  { "GetTickCount",            (SYSCALL)GetTickCount,            0 },
--#else
--  { "GetTickCount",            (SYSCALL)0,                       0 },
--#endif
--
--#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
--
--#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \
--        SQLITE_WIN32_GETVERSIONEX
--  { "GetVersionExA",           (SYSCALL)GetVersionExA,           0 },
--#else
--  { "GetVersionExA",           (SYSCALL)0,                       0 },
--#endif
--
--#define osGetVersionExA ((BOOL(WINAPI*)( \
--        LPOSVERSIONINFOA))aSyscall[34].pCurrent)
--
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
--        defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
--  { "GetVersionExW",           (SYSCALL)GetVersionExW,           0 },
--#else
--  { "GetVersionExW",           (SYSCALL)0,                       0 },
--#endif
--
--#define osGetVersionExW ((BOOL(WINAPI*)( \
--        LPOSVERSIONINFOW))aSyscall[35].pCurrent)
--
--  { "HeapAlloc",               (SYSCALL)HeapAlloc,               0 },
--
--#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
--        SIZE_T))aSyscall[36].pCurrent)
--
--#if !SQLITE_OS_WINRT
--  { "HeapCreate",              (SYSCALL)HeapCreate,              0 },
--#else
--  { "HeapCreate",              (SYSCALL)0,                       0 },
--#endif
--
--#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
--        SIZE_T))aSyscall[37].pCurrent)
--
--#if !SQLITE_OS_WINRT
--  { "HeapDestroy",             (SYSCALL)HeapDestroy,             0 },
--#else
--  { "HeapDestroy",             (SYSCALL)0,                       0 },
--#endif
--
--#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent)
--
--  { "HeapFree",                (SYSCALL)HeapFree,                0 },
--
--#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent)
--
--  { "HeapReAlloc",             (SYSCALL)HeapReAlloc,             0 },
--
--#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
--        SIZE_T))aSyscall[40].pCurrent)
--
--  { "HeapSize",                (SYSCALL)HeapSize,                0 },
--
--#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
--        LPCVOID))aSyscall[41].pCurrent)
--
--#if !SQLITE_OS_WINRT
--  { "HeapValidate",            (SYSCALL)HeapValidate,            0 },
--#else
--  { "HeapValidate",            (SYSCALL)0,                       0 },
--#endif
--
--#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
--        LPCVOID))aSyscall[42].pCurrent)
--
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
--  { "HeapCompact",             (SYSCALL)HeapCompact,             0 },
--#else
--  { "HeapCompact",             (SYSCALL)0,                       0 },
--#endif
--
--#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent)
--
--#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
--  { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
--#else
--  { "LoadLibraryA",            (SYSCALL)0,                       0 },
--#endif
--
--#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent)
+ /*
++** Clear the Rtree.pNodeBlob object
++*/
++static void nodeBlobReset(Rtree *pRtree){
++  if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){
++    sqlite3_blob *pBlob = pRtree->pNodeBlob;
++    pRtree->pNodeBlob = 0;
++    sqlite3_blob_close(pBlob);
++  }
++}
++
++/*
+ ** Obtain a reference to an r-tree node.
+ */
+ static int nodeAcquire(
+@@ -151546,9 +169176,8 @@
+   RtreeNode *pParent,        /* Either the parent node or NULL */
+   RtreeNode **ppNode         /* OUT: Acquired node */
+ ){
+-  int rc;
+-  int rc2 = SQLITE_OK;
+-  RtreeNode *pNode;
++  int rc = SQLITE_OK;
++  RtreeNode *pNode = 0;
+ 
+   /* Check if the requested node is already in the hash table. If so,
+   ** increase its reference count and return it.
+@@ -151564,28 +169193,45 @@
+     return SQLITE_OK;
+   }
+ 
+-  sqlite3_bind_int64(pRtree->pReadNode, 1, iNode);
+-  rc = sqlite3_step(pRtree->pReadNode);
+-  if( rc==SQLITE_ROW ){
+-    const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0);
+-    if( pRtree->iNodeSize==sqlite3_column_bytes(pRtree->pReadNode, 0) ){
+-      pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
+-      if( !pNode ){
+-        rc2 = SQLITE_NOMEM;
+-      }else{
+-        pNode->pParent = pParent;
+-        pNode->zData = (u8 *)&pNode[1];
+-        pNode->nRef = 1;
+-        pNode->iNode = iNode;
+-        pNode->isDirty = 0;
+-        pNode->pNext = 0;
+-        memcpy(pNode->zData, zBlob, pRtree->iNodeSize);
+-        nodeReference(pParent);
+-      }
++  if( pRtree->pNodeBlob ){
++    sqlite3_blob *pBlob = pRtree->pNodeBlob;
++    pRtree->pNodeBlob = 0;
++    rc = sqlite3_blob_reopen(pBlob, iNode);
++    pRtree->pNodeBlob = pBlob;
++    if( rc ){
++      nodeBlobReset(pRtree);
++      if( rc==SQLITE_NOMEM ) return SQLITE_NOMEM;
++    }
++  }
++  if( pRtree->pNodeBlob==0 ){
++    char *zTab = sqlite3_mprintf("%s_node", pRtree->zName);
++    if( zTab==0 ) return SQLITE_NOMEM;
++    rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, zTab, "data", iNode, 0,
++                           &pRtree->pNodeBlob);
++    sqlite3_free(zTab);
++  }
++  if( rc ){
++    nodeBlobReset(pRtree);
++    *ppNode = 0;
++    /* If unable to open an sqlite3_blob on the desired row, that can only
++    ** be because the shadow tables hold erroneous data. */
++    if( rc==SQLITE_ERROR ) rc = SQLITE_CORRUPT_VTAB;
++  }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){
++    pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
++    if( !pNode ){
++      rc = SQLITE_NOMEM;
++    }else{
++      pNode->pParent = pParent;
++      pNode->zData = (u8 *)&pNode[1];
++      pNode->nRef = 1;
++      pNode->iNode = iNode;
++      pNode->isDirty = 0;
++      pNode->pNext = 0;
++      rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData,
++                             pRtree->iNodeSize, 0);
++      nodeReference(pParent);
+     }
+   }
+-  rc = sqlite3_reset(pRtree->pReadNode);
+-  if( rc==SQLITE_OK ) rc = rc2;
+ 
+   /* If the root node was just loaded, set pRtree->iDepth to the height
+   ** of the r-tree structure. A height of zero means all data is stored on
+@@ -151637,7 +169283,7 @@
+   int ii;
+   u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell];
+   p += writeInt64(p, pCell->iRowid);
+-  for(ii=0; ii<(pRtree->nDim*2); ii++){
++  for(ii=0; ii<pRtree->nDim2; ii++){
+     p += writeCoord(p, &pCell->aCoord[ii]);
+   }
+   pNode->isDirty = 1;
+@@ -151771,13 +169417,16 @@
+ ){
+   u8 *pData;
+   RtreeCoord *pCoord;
+-  int ii;
++  int ii = 0;
+   pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell);
+   pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell);
+   pCoord = pCell->aCoord;
+-  for(ii=0; ii<pRtree->nDim*2; ii++){
+-    readCoord(&pData[ii*4], &pCoord[ii]);
+-  }
++  do{
++    readCoord(pData, &pCoord[ii]);
++    readCoord(pData+4, &pCoord[ii+1]);
++    pData += 8;
++    ii += 2;
++  }while( ii<pRtree->nDim2 );
+ }
+ 
+ 
+@@ -151828,7 +169477,9 @@
+ static void rtreeRelease(Rtree *pRtree){
+   pRtree->nBusy--;
+   if( pRtree->nBusy==0 ){
+-    sqlite3_finalize(pRtree->pReadNode);
++    pRtree->inWrTrans = 0;
++    pRtree->nCursor = 0;
++    nodeBlobReset(pRtree);
+     sqlite3_finalize(pRtree->pWriteNode);
+     sqlite3_finalize(pRtree->pDeleteNode);
+     sqlite3_finalize(pRtree->pReadRowid);
+@@ -151866,6 +169517,7 @@
+   if( !zCreate ){
+     rc = SQLITE_NOMEM;
+   }else{
++    nodeBlobReset(pRtree);
+     rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0);
+     sqlite3_free(zCreate);
+   }
+@@ -151881,6 +169533,7 @@
+ */
+ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
+   int rc = SQLITE_NOMEM;
++  Rtree *pRtree = (Rtree *)pVTab;
+   RtreeCursor *pCsr;
+ 
+   pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor));
+@@ -151888,6 +169541,7 @@
+     memset(pCsr, 0, sizeof(RtreeCursor));
+     pCsr->base.pVtab = pVTab;
+     rc = SQLITE_OK;
++    pRtree->nCursor++;
+   }
+   *ppCursor = (sqlite3_vtab_cursor *)pCsr;
+ 
+@@ -151920,10 +169574,13 @@
+   Rtree *pRtree = (Rtree *)(cur->pVtab);
+   int ii;
+   RtreeCursor *pCsr = (RtreeCursor *)cur;
++  assert( pRtree->nCursor>0 );
+   freeCursorConstraints(pCsr);
+   sqlite3_free(pCsr->aPoint);
+   for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
+   sqlite3_free(pCsr);
++  pRtree->nCursor--;
++  nodeBlobReset(pRtree);
+   return SQLITE_OK;
+ }
+ 
+@@ -151946,15 +169603,22 @@
+ ** false.  a[] is the four bytes of the on-disk record to be decoded.
+ ** Store the results in "r".
+ **
+-** There are three versions of this macro, one each for little-endian and
+-** big-endian processors and a third generic implementation.  The endian-
+-** specific implementations are much faster and are preferred if the
+-** processor endianness is known at compile-time.  The SQLITE_BYTEORDER
+-** macro is part of sqliteInt.h and hence the endian-specific
+-** implementation will only be used if this module is compiled as part
+-** of the amalgamation.
++** There are five versions of this macro.  The last one is generic.  The
++** other four are various architectures-specific optimizations.
+ */
+-#if defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==1234
++#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
++#define RTREE_DECODE_COORD(eInt, a, r) {                        \
++    RtreeCoord c;    /* Coordinate decoded */                   \
++    c.u = _byteswap_ulong(*(u32*)a);                            \
++    r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
++}
++#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
++#define RTREE_DECODE_COORD(eInt, a, r) {                        \
++    RtreeCoord c;    /* Coordinate decoded */                   \
++    c.u = __builtin_bswap32(*(u32*)a);                          \
++    r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
++}
++#elif SQLITE_BYTEORDER==1234
+ #define RTREE_DECODE_COORD(eInt, a, r) {                        \
+     RtreeCoord c;    /* Coordinate decoded */                   \
+     memcpy(&c.u,a,4);                                           \
+@@ -151962,7 +169626,7 @@
+           ((c.u&0xff)<<24)|((c.u&0xff00)<<8);                   \
+     r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
+ }
+-#elif defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==4321
++#elif SQLITE_BYTEORDER==4321
+ #define RTREE_DECODE_COORD(eInt, a, r) {                        \
+     RtreeCoord c;    /* Coordinate decoded */                   \
+     memcpy(&c.u,a,4);                                           \
+@@ -151989,10 +169653,10 @@
+   sqlite3_rtree_dbl *prScore,    /* OUT: score for the cell */
+   int *peWithin                  /* OUT: visibility of the cell */
+ ){
+-  int i;                                                /* Loop counter */
+   sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */
+   int nCoord = pInfo->nCoord;                           /* No. of coordinates */
+   int rc;                                             /* Callback return code */
++  RtreeCoord c;                                       /* Translator union */
+   sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2];   /* Decoded coordinates */
+ 
+   assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY );
+@@ -152002,13 +169666,41 @@
+     pInfo->iRowid = readInt64(pCellData);
+   }
+   pCellData += 8;
+-  for(i=0; i<nCoord; i++, pCellData += 4){
+-    RTREE_DECODE_COORD(eInt, pCellData, aCoord[i]);
++#ifndef SQLITE_RTREE_INT_ONLY
++  if( eInt==0 ){
++    switch( nCoord ){
++      case 10:  readCoord(pCellData+36, &c); aCoord[9] = c.f;
++                readCoord(pCellData+32, &c); aCoord[8] = c.f;
++      case 8:   readCoord(pCellData+28, &c); aCoord[7] = c.f;
++                readCoord(pCellData+24, &c); aCoord[6] = c.f;
++      case 6:   readCoord(pCellData+20, &c); aCoord[5] = c.f;
++                readCoord(pCellData+16, &c); aCoord[4] = c.f;
++      case 4:   readCoord(pCellData+12, &c); aCoord[3] = c.f;
++                readCoord(pCellData+8,  &c); aCoord[2] = c.f;
++      default:  readCoord(pCellData+4,  &c); aCoord[1] = c.f;
++                readCoord(pCellData,    &c); aCoord[0] = c.f;
++    }
++  }else
++#endif
++  {
++    switch( nCoord ){
++      case 10:  readCoord(pCellData+36, &c); aCoord[9] = c.i;
++                readCoord(pCellData+32, &c); aCoord[8] = c.i;
++      case 8:   readCoord(pCellData+28, &c); aCoord[7] = c.i;
++                readCoord(pCellData+24, &c); aCoord[6] = c.i;
++      case 6:   readCoord(pCellData+20, &c); aCoord[5] = c.i;
++                readCoord(pCellData+16, &c); aCoord[4] = c.i;
++      case 4:   readCoord(pCellData+12, &c); aCoord[3] = c.i;
++                readCoord(pCellData+8,  &c); aCoord[2] = c.i;
++      default:  readCoord(pCellData+4,  &c); aCoord[1] = c.i;
++                readCoord(pCellData,    &c); aCoord[0] = c.i;
++    }
+   }
+   if( pConstraint->op==RTREE_MATCH ){
++    int eWithin = 0;
+     rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo,
+-                              nCoord, aCoord, &i);
+-    if( i==0 ) *peWithin = NOT_WITHIN;
++                              nCoord, aCoord, &eWithin);
++    if( eWithin==0 ) *peWithin = NOT_WITHIN;
+     *prScore = RTREE_ZERO;
+   }else{
+     pInfo->aCoord = aCoord;
+@@ -152044,6 +169736,7 @@
+ 
+   assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
+       || p->op==RTREE_GT || p->op==RTREE_EQ );
++  assert( ((((char*)pCellData) - (char*)0)&3)==0 );  /* 4-byte aligned */
+   switch( p->op ){
+     case RTREE_LE:
+     case RTREE_LT:
+@@ -152084,6 +169777,7 @@
+   assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
+       || p->op==RTREE_GT || p->op==RTREE_EQ );
+   pCellData += 8 + p->iCoord*4;
++  assert( ((((char*)pCellData) - (char*)0)&3)==0 );  /* 4-byte aligned */
+   RTREE_DECODE_COORD(eInt, pCellData, xN);
+   switch( p->op ){
+     case RTREE_LE: if( xN <= p->u.rValue ) return;  break;
+@@ -152152,7 +169846,7 @@
+ }
+ 
+ /*
+-** Interchange to search points in a cursor.
++** Interchange two search points in a cursor.
+ */
+ static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){
+   RtreeSearchPoint t = p->aPoint[i];
+@@ -152400,7 +170094,7 @@
+       if( rScore<RTREE_ZERO ) rScore = RTREE_ZERO;
+       p = rtreeSearchPointNew(pCur, rScore, x.iLevel);
+       if( p==0 ) return SQLITE_NOMEM;
+-      p->eWithin = eWithin;
++      p->eWithin = (u8)eWithin;
+       p->id = x.id;
+       p->iCell = x.iCell;
+       RTREE_QUEUE_TRACE(pCur, "PUSH-S:");
+@@ -152459,7 +170153,6 @@
+   if( i==0 ){
+     sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell));
+   }else{
+-    if( rc ) return rc;
+     nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c);
+ #ifndef SQLITE_RTREE_INT_ONLY
+     if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
+@@ -152508,37 +170201,21 @@
+ ** operator.
+ */
+ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
+-  RtreeMatchArg *pBlob;              /* BLOB returned by geometry function */
++  RtreeMatchArg *pBlob, *pSrc;       /* BLOB returned by geometry function */
+   sqlite3_rtree_query_info *pInfo;   /* Callback information */
+-  int nBlob;                         /* Size of the geometry function blob */
+-  int nExpected;                     /* Expected size of the BLOB */
 -
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
--        !defined(SQLITE_OMIT_LOAD_EXTENSION)
--  { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
--#else
--  { "LoadLibraryW",            (SYSCALL)0,                       0 },
--#endif
+-  /* Check that value is actually a blob. */
+-  if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR;
 -
--#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent)
+-  /* Check that the blob is roughly the right size. */
+-  nBlob = sqlite3_value_bytes(pValue);
+-  if( nBlob<(int)sizeof(RtreeMatchArg) 
+-   || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0
+-  ){
+-    return SQLITE_ERROR;
+-  }
+ 
+-  pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob );
++  pSrc = sqlite3_value_pointer(pValue, "RtreeMatchArg");
++  if( pSrc==0 ) return SQLITE_ERROR;
++  pInfo = (sqlite3_rtree_query_info*)
++                sqlite3_malloc64( sizeof(*pInfo)+pSrc->iSize );
+   if( !pInfo ) return SQLITE_NOMEM;
+   memset(pInfo, 0, sizeof(*pInfo));
+   pBlob = (RtreeMatchArg*)&pInfo[1];
 -
--#if !SQLITE_OS_WINRT
--  { "LocalFree",               (SYSCALL)LocalFree,               0 },
--#else
--  { "LocalFree",               (SYSCALL)0,                       0 },
+-  memcpy(pBlob, sqlite3_value_blob(pValue), nBlob);
+-  nExpected = (int)(sizeof(RtreeMatchArg) +
+-                    (pBlob->nParam-1)*sizeof(RtreeDValue));
+-  if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){
+-    sqlite3_free(pInfo);
+-    return SQLITE_ERROR;
+-  }
++  memcpy(pBlob, pSrc, pSrc->iSize);
+   pInfo->pContext = pBlob->cb.pContext;
+   pInfo->nParam = pBlob->nParam;
+   pInfo->aParam = pBlob->aParam;
++  pInfo->apSqlParam = pBlob->apSqlParam;
+ 
+   if( pBlob->cb.xGeom ){
+     pCons->u.xGeom = pBlob->cb.xGeom;
+@@ -152577,7 +170254,7 @@
+   if( idxNum==1 ){
+     /* Special case - lookup by rowid. */
+     RtreeNode *pLeaf;        /* Leaf on which the required cell resides */
+-    RtreeSearchPoint *p;     /* Search point for the the leaf */
++    RtreeSearchPoint *p;     /* Search point for the leaf */
+     i64 iRowid = sqlite3_value_int64(argv[0]);
+     i64 iNode = 0;
+     rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
+@@ -152588,7 +170265,7 @@
+       p->id = iNode;
+       p->eWithin = PARTLY_WITHIN;
+       rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell);
+-      p->iCell = iCell;
++      p->iCell = (u8)iCell;
+       RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:");
+     }else{
+       pCsr->atEOF = 1;
+@@ -152621,7 +170298,7 @@
+             if( rc!=SQLITE_OK ){
+               break;
+             }
+-            p->pInfo->nCoord = pRtree->nDim*2;
++            p->pInfo->nCoord = pRtree->nDim2;
+             p->pInfo->anQueue = pCsr->anQueue;
+             p->pInfo->mxLevel = pRtree->iDepth + 1;
+           }else{
+@@ -152636,7 +170313,7 @@
+     }
+     if( rc==SQLITE_OK ){
+       RtreeSearchPoint *pNew;
+-      pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, pRtree->iDepth+1);
++      pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1));
+       if( pNew==0 ) return SQLITE_NOMEM;
+       pNew->id = 1;
+       pNew->iCell = 0;
+@@ -152655,19 +170332,6 @@
+ }
+ 
+ /*
+-** Set the pIdxInfo->estimatedRows variable to nRow. Unless this
+-** extension is currently being used by a version of SQLite too old to
+-** support estimatedRows. In that case this function is a no-op.
+-*/
+-static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
+-#if SQLITE_VERSION_NUMBER>=3008002
+-  if( sqlite3_libversion_number()>=3008002 ){
+-    pIdxInfo->estimatedRows = nRow;
+-  }
 -#endif
+-}
 -
--#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent)
--
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
--  { "LockFile",                (SYSCALL)LockFile,                0 },
--#else
--  { "LockFile",                (SYSCALL)0,                       0 },
-+  { "AreFileApisANSI",         (SYSCALL)0,                       0 },
- #endif
+-/*
+ ** Rtree virtual table module xBestIndex method. There are three
+ ** table scan strategies to choose from (in order from most to 
+ ** least desirable):
+@@ -152705,17 +170369,30 @@
+   Rtree *pRtree = (Rtree*)tab;
+   int rc = SQLITE_OK;
+   int ii;
++  int bMatch = 0;                 /* True if there exists a MATCH constraint */
+   i64 nRow;                       /* Estimated rows returned by this scan */
+ 
+   int iIdx = 0;
+   char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
+   memset(zIdxStr, 0, sizeof(zIdxStr));
+ 
++  /* Check if there exists a MATCH constraint - even an unusable one. If there
++  ** is, do not consider the lookup-by-rowid plan as using such a plan would
++  ** require the VDBE to evaluate the MATCH constraint, which is not currently
++  ** possible. */
++  for(ii=0; ii<pIdxInfo->nConstraint; ii++){
++    if( pIdxInfo->aConstraint[ii].op==SQLITE_INDEX_CONSTRAINT_MATCH ){
++      bMatch = 1;
++    }
++  }
++
+   assert( pIdxInfo->idxStr==0 );
+   for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
+     struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
  
--#ifndef osLockFile
--#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
--        DWORD))aSyscall[47].pCurrent)
-+#ifndef osAreFileApisANSI
-+#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent)
- #endif
+-    if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
++    if( bMatch==0 && p->usable 
++     && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ 
++    ){
+       /* We have an equality constraint on the rowid. Use strategy 1. */
+       int jj;
+       for(jj=0; jj<ii; jj++){
+@@ -152733,7 +170410,7 @@
+       ** a single row.
+       */ 
+       pIdxInfo->estimatedCost = 30.0;
+-      setEstimatedRows(pIdxInfo, 1);
++      pIdxInfo->estimatedRows = 1;
+       return SQLITE_OK;
+     }
+ 
+@@ -152751,7 +170428,7 @@
+           break;
+       }
+       zIdxStr[iIdx++] = op;
+-      zIdxStr[iIdx++] = p->iColumn - 1 + '0';
++      zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0');
+       pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
+       pIdxInfo->aConstraintUsage[ii].omit = 1;
+     }
+@@ -152763,9 +170440,9 @@
+     return SQLITE_NOMEM;
+   }
+ 
+-  nRow = pRtree->nRowEst / (iIdx + 1);
++  nRow = pRtree->nRowEst >> (iIdx/2);
+   pIdxInfo->estimatedCost = (double)6.0 * (double)nRow;
+-  setEstimatedRows(pIdxInfo, nRow);
++  pIdxInfo->estimatedRows = nRow;
+ 
+   return rc;
+ }
+@@ -152775,9 +170452,26 @@
+ */
+ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
+   RtreeDValue area = (RtreeDValue)1;
+-  int ii;
+-  for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+-    area = (area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])));
++  assert( pRtree->nDim>=1 && pRtree->nDim<=5 );
++#ifndef SQLITE_RTREE_INT_ONLY
++  if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
++    switch( pRtree->nDim ){
++      case 5:  area  = p->aCoord[9].f - p->aCoord[8].f;
++      case 4:  area *= p->aCoord[7].f - p->aCoord[6].f;
++      case 3:  area *= p->aCoord[5].f - p->aCoord[4].f;
++      case 2:  area *= p->aCoord[3].f - p->aCoord[2].f;
++      default: area *= p->aCoord[1].f - p->aCoord[0].f;
++    }
++  }else
++#endif
++  {
++    switch( pRtree->nDim ){
++      case 5:  area  = p->aCoord[9].i - p->aCoord[8].i;
++      case 4:  area *= p->aCoord[7].i - p->aCoord[6].i;
++      case 3:  area *= p->aCoord[5].i - p->aCoord[4].i;
++      case 2:  area *= p->aCoord[3].i - p->aCoord[2].i;
++      default: area *= p->aCoord[1].i - p->aCoord[0].i;
++    }
+   }
+   return area;
+ }
+@@ -152787,11 +170481,12 @@
+ ** of the objects size in each dimension.
+ */
+ static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){
+-  RtreeDValue margin = (RtreeDValue)0;
+-  int ii;
+-  for(ii=0; ii<(pRtree->nDim*2); ii+=2){
++  RtreeDValue margin = 0;
++  int ii = pRtree->nDim2 - 2;
++  do{
+     margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
+-  }
++    ii -= 2;
++  }while( ii>=0 );
+   return margin;
+ }
+ 
+@@ -152799,17 +170494,19 @@
+ ** Store the union of cells p1 and p2 in p1.
+ */
+ static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
+-  int ii;
++  int ii = 0;
+   if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
+-    for(ii=0; ii<(pRtree->nDim*2); ii+=2){
++    do{
+       p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f);
+       p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f);
+-    }
++      ii += 2;
++    }while( ii<pRtree->nDim2 );
+   }else{
+-    for(ii=0; ii<(pRtree->nDim*2); ii+=2){
++    do{
+       p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i);
+       p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i);
+-    }
++      ii += 2;
++    }while( ii<pRtree->nDim2 );
+   }
+ }
+ 
+@@ -152820,7 +170517,7 @@
+ static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
+   int ii;
+   int isInt = (pRtree->eCoordType==RTREE_COORD_INT32);
+-  for(ii=0; ii<(pRtree->nDim*2); ii+=2){
++  for(ii=0; ii<pRtree->nDim2; ii+=2){
+     RtreeCoord *a1 = &p1->aCoord[ii];
+     RtreeCoord *a2 = &p2->aCoord[ii];
+     if( (!isInt && (a2[0].f<a1[0].f || a2[1].f>a1[1].f)) 
+@@ -152855,7 +170552,7 @@
+   for(ii=0; ii<nCell; ii++){
+     int jj;
+     RtreeDValue o = (RtreeDValue)1;
+-    for(jj=0; jj<(pRtree->nDim*2); jj+=2){
++    for(jj=0; jj<pRtree->nDim2; jj+=2){
+       RtreeDValue x1, x2;
+       x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj]));
+       x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1]));
+@@ -153822,6 +171519,53 @@
+ }
+ #endif /* !defined(SQLITE_RTREE_INT_ONLY) */
+ 
++/*
++** A constraint has failed while inserting a row into an rtree table. 
++** Assuming no OOM error occurs, this function sets the error message 
++** (at pRtree->base.zErrMsg) to an appropriate value and returns
++** SQLITE_CONSTRAINT.
++**
++** Parameter iCol is the index of the leftmost column involved in the
++** constraint failure. If it is 0, then the constraint that failed is
++** the unique constraint on the id column. Otherwise, it is the rtree
++** (c1<=c2) constraint on columns iCol and iCol+1 that has failed.
++**
++** If an OOM occurs, SQLITE_NOMEM is returned instead of SQLITE_CONSTRAINT.
++*/
++static int rtreeConstraintError(Rtree *pRtree, int iCol){
++  sqlite3_stmt *pStmt = 0;
++  char *zSql; 
++  int rc;
++
++  assert( iCol==0 || iCol%2 );
++  zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", pRtree->zDb, pRtree->zName);
++  if( zSql ){
++    rc = sqlite3_prepare_v2(pRtree->db, zSql, -1, &pStmt, 0);
++  }else{
++    rc = SQLITE_NOMEM;
++  }
++  sqlite3_free(zSql);
++
++  if( rc==SQLITE_OK ){
++    if( iCol==0 ){
++      const char *zCol = sqlite3_column_name(pStmt, 0);
++      pRtree->base.zErrMsg = sqlite3_mprintf(
++          "UNIQUE constraint failed: %s.%s", pRtree->zName, zCol
++      );
++    }else{
++      const char *zCol1 = sqlite3_column_name(pStmt, iCol);
++      const char *zCol2 = sqlite3_column_name(pStmt, iCol+1);
++      pRtree->base.zErrMsg = sqlite3_mprintf(
++          "rtree constraint failed: %s.(%s<=%s)", pRtree->zName, zCol1, zCol2
++      );
++    }
++  }
++
++  sqlite3_finalize(pStmt);
++  return (rc==SQLITE_OK ? SQLITE_CONSTRAINT : rc);
++}
++
++
+ 
+ /*
+ ** The xUpdate method for rtree module virtual tables.
+@@ -153864,7 +171608,7 @@
+     ** This problem was discovered after years of use, so we silently ignore
+     ** these kinds of misdeclared tables to avoid breaking any legacy.
+     */
+-    assert( nData<=(pRtree->nDim*2 + 3) );
++    assert( nData<=(pRtree->nDim2 + 3) );
+ 
+ #ifndef SQLITE_RTREE_INT_ONLY
+     if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
+@@ -153872,7 +171616,7 @@
+         cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
+         cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
+         if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
+-          rc = SQLITE_CONSTRAINT;
++          rc = rtreeConstraintError(pRtree, ii+1);
+           goto constraint;
+         }
+       }
+@@ -153883,7 +171627,7 @@
+         cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
+         cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
+         if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
+-          rc = SQLITE_CONSTRAINT;
++          rc = rtreeConstraintError(pRtree, ii+1);
+           goto constraint;
+         }
+       }
+@@ -153904,7 +171648,7 @@
+           if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){
+             rc = rtreeDeleteRowid(pRtree, cell.iRowid);
+           }else{
+-            rc = SQLITE_CONSTRAINT;
++            rc = rtreeConstraintError(pRtree, 0);
+             goto constraint;
+           }
+         }
+@@ -153955,6 +171699,27 @@
+ }
+ 
+ /*
++** Called when a transaction starts.
++*/
++static int rtreeBeginTransaction(sqlite3_vtab *pVtab){
++  Rtree *pRtree = (Rtree *)pVtab;
++  assert( pRtree->inWrTrans==0 );
++  pRtree->inWrTrans++;
++  return SQLITE_OK;
++}
++
++/*
++** Called when a transaction completes (either by COMMIT or ROLLBACK).
++** The sqlite3_blob object should be released at this point.
++*/
++static int rtreeEndTransaction(sqlite3_vtab *pVtab){
++  Rtree *pRtree = (Rtree *)pVtab;
++  pRtree->inWrTrans = 0;
++  nodeBlobReset(pRtree);
++  return SQLITE_OK;
++}
++
++/*
+ ** The xRename method for rtree module virtual tables.
+ */
+ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
+@@ -153969,6 +171734,7 @@
+     , pRtree->zDb, pRtree->zName, zNewName
+   );
+   if( zSql ){
++    nodeBlobReset(pRtree);
+     rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
+     sqlite3_free(zSql);
+   }
+@@ -153976,6 +171742,30 @@
+ }
+ 
+ /*
++** The xSavepoint method.
++**
++** This module does not need to do anything to support savepoints. However,
++** it uses this hook to close any open blob handle. This is done because a 
++** DROP TABLE command - which fortunately always opens a savepoint - cannot 
++** succeed if there are any open blob handles. i.e. if the blob handle were
++** not closed here, the following would fail:
++**
++**   BEGIN;
++**     INSERT INTO rtree...
++**     DROP TABLE <tablename>;    -- Would fail with SQLITE_LOCKED
++**   COMMIT;
++*/
++static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){
++  Rtree *pRtree = (Rtree *)pVtab;
++  int iwt = pRtree->inWrTrans;
++  UNUSED_PARAMETER(iSavepoint);
++  pRtree->inWrTrans = 0;
++  nodeBlobReset(pRtree);
++  pRtree->inWrTrans = iwt;
++  return SQLITE_OK;
++}
++
++/*
+ ** This function populates the pRtree->nRowEst variable with an estimate
+ ** of the number of rows in the virtual table. If possible, this is based
+ ** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST.
+@@ -153987,6 +171777,13 @@
+   int rc;
+   i64 nRow = 0;
+ 
++  rc = sqlite3_table_column_metadata(
++      db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0
++  );
++  if( rc!=SQLITE_OK ){
++    pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
++    return rc==SQLITE_ERROR ? SQLITE_OK : rc;
++  }
+   zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
+   if( zSql==0 ){
+     rc = SQLITE_NOMEM;
+@@ -154013,7 +171810,7 @@
+ }
+ 
+ static sqlite3_module rtreeModule = {
+-  0,                          /* iVersion */
++  2,                          /* iVersion */
+   rtreeCreate,                /* xCreate - create a table */
+   rtreeConnect,               /* xConnect - connect to an existing table */
+   rtreeBestIndex,             /* xBestIndex - Determine search strategy */
+@@ -154027,15 +171824,15 @@
+   rtreeColumn,                /* xColumn - read data */
+   rtreeRowid,                 /* xRowid - read data */
+   rtreeUpdate,                /* xUpdate - write data */
+-  0,                          /* xBegin - begin transaction */
+-  0,                          /* xSync - sync transaction */
+-  0,                          /* xCommit - commit transaction */
+-  0,                          /* xRollback - rollback transaction */
++  rtreeBeginTransaction,      /* xBegin - begin transaction */
++  rtreeEndTransaction,        /* xSync - sync transaction */
++  rtreeEndTransaction,        /* xCommit - commit transaction */
++  rtreeEndTransaction,        /* xRollback - rollback transaction */
+   0,                          /* xFindFunction - function overloading */
+   rtreeRename,                /* xRename - rename the table */
+-  0,                          /* xSavepoint */
++  rtreeSavepoint,             /* xSavepoint */
+   0,                          /* xRelease */
+-  0                           /* xRollbackTo */
++  0,                          /* xRollbackTo */
+ };
+ 
+ static int rtreeSqlInit(
+@@ -154047,10 +171844,9 @@
+ ){
+   int rc = SQLITE_OK;
+ 
+-  #define N_STATEMENT 9
++  #define N_STATEMENT 8
+   static const char *azSql[N_STATEMENT] = {
+-    /* Read and write the xxx_node table */
+-    "SELECT data FROM '%q'.'%q_node' WHERE nodeno = :1",
++    /* Write the xxx_node table */
+     "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)",
+     "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1",
+ 
+@@ -154088,21 +171884,21 @@
+     }
+   }
+ 
+-  appStmt[0] = &pRtree->pReadNode;
+-  appStmt[1] = &pRtree->pWriteNode;
+-  appStmt[2] = &pRtree->pDeleteNode;
+-  appStmt[3] = &pRtree->pReadRowid;
+-  appStmt[4] = &pRtree->pWriteRowid;
+-  appStmt[5] = &pRtree->pDeleteRowid;
+-  appStmt[6] = &pRtree->pReadParent;
+-  appStmt[7] = &pRtree->pWriteParent;
+-  appStmt[8] = &pRtree->pDeleteParent;
++  appStmt[0] = &pRtree->pWriteNode;
++  appStmt[1] = &pRtree->pDeleteNode;
++  appStmt[2] = &pRtree->pReadRowid;
++  appStmt[3] = &pRtree->pWriteRowid;
++  appStmt[4] = &pRtree->pDeleteRowid;
++  appStmt[5] = &pRtree->pReadParent;
++  appStmt[6] = &pRtree->pWriteParent;
++  appStmt[7] = &pRtree->pDeleteParent;
+ 
+   rc = rtreeQueryStat1(db, pRtree);
+   for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
+     char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix);
+     if( zSql ){
+-      rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0); 
++      rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
++                              appStmt[i], 0); 
+     }else{
+       rc = SQLITE_NOMEM;
+     }
+@@ -154177,6 +171973,10 @@
+     rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize);
+     if( rc!=SQLITE_OK ){
+       *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++    }else if( pRtree->iNodeSize<(512-64) ){
++      rc = SQLITE_CORRUPT;
++      *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
++                               pRtree->zName);
+     }
+   }
+ 
+@@ -154234,9 +172034,10 @@
+   pRtree->base.pModule = &rtreeModule;
+   pRtree->zDb = (char *)&pRtree[1];
+   pRtree->zName = &pRtree->zDb[nDb+1];
+-  pRtree->nDim = (argc-4)/2;
+-  pRtree->nBytesPerCell = 8 + pRtree->nDim*4*2;
+-  pRtree->eCoordType = eCoordType;
++  pRtree->nDim = (u8)((argc-4)/2);
++  pRtree->nDim2 = pRtree->nDim*2;
++  pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
++  pRtree->eCoordType = (u8)eCoordType;
+   memcpy(pRtree->zDb, argv[1], nDb);
+   memcpy(pRtree->zName, argv[2], nName);
+ 
+@@ -154309,7 +172110,8 @@
+   UNUSED_PARAMETER(nArg);
+   memset(&node, 0, sizeof(RtreeNode));
+   memset(&tree, 0, sizeof(Rtree));
+-  tree.nDim = sqlite3_value_int(apArg[0]);
++  tree.nDim = (u8)sqlite3_value_int(apArg[0]);
++  tree.nDim2 = tree.nDim*2;
+   tree.nBytesPerCell = 8 + 8 * tree.nDim;
+   node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
+ 
+@@ -154322,7 +172124,7 @@
+     nodeGetCell(&tree, &node, ii, &cell);
+     sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid);
+     nCell = (int)strlen(zCell);
+-    for(jj=0; jj<tree.nDim*2; jj++){
++    for(jj=0; jj<tree.nDim2; jj++){
+ #ifndef SQLITE_RTREE_INT_ONLY
+       sqlite3_snprintf(512-nCell,&zCell[nCell], " %g",
+                        (double)cell.aCoord[jj].f);
+@@ -154409,6 +172211,18 @@
+ }
  
--#if !SQLITE_OS_WINCE
--  { "LockFileEx",              (SYSCALL)LockFileEx,              0 },
-+#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "CharLowerW",              (SYSCALL)CharLowerW,              0 },
+ /*
++** This routine frees the BLOB that is returned by geomCallback().
++*/
++static void rtreeMatchArgFree(void *pArg){
++  int i;
++  RtreeMatchArg *p = (RtreeMatchArg*)pArg;
++  for(i=0; i<p->nParam; i++){
++    sqlite3_value_free(p->apSqlParam[i]);
++  }
++  sqlite3_free(p);
++}
++
++/*
+ ** Each call to sqlite3_rtree_geometry_callback() or
+ ** sqlite3_rtree_query_callback() creates an ordinary SQLite
+ ** scalar function that is implemented by this routine.
+@@ -154426,31 +172240,41 @@
+   RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
+   RtreeMatchArg *pBlob;
+   int nBlob;
++  int memErr = 0;
+ 
+-  nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue);
++  nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue)
++           + nArg*sizeof(sqlite3_value*);
+   pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
+   if( !pBlob ){
+     sqlite3_result_error_nomem(ctx);
+   }else{
+     int i;
+-    pBlob->magic = RTREE_GEOMETRY_MAGIC;
++    pBlob->iSize = nBlob;
+     pBlob->cb = pGeomCtx[0];
++    pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg];
+     pBlob->nParam = nArg;
+     for(i=0; i<nArg; i++){
++      pBlob->apSqlParam[i] = sqlite3_value_dup(aArg[i]);
++      if( pBlob->apSqlParam[i]==0 ) memErr = 1;
+ #ifdef SQLITE_RTREE_INT_ONLY
+       pBlob->aParam[i] = sqlite3_value_int64(aArg[i]);
  #else
--  { "LockFileEx",              (SYSCALL)0,                       0 },
-+  { "CharLowerW",              (SYSCALL)0,                       0 },
+       pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
  #endif
+     }
+-    sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free);
++    if( memErr ){
++      sqlite3_result_error_nomem(ctx);
++      rtreeMatchArgFree(pBlob);
++    }else{
++      sqlite3_result_pointer(ctx, pBlob, "RtreeMatchArg", rtreeMatchArgFree);
++    }
+   }
+ }
  
--#ifndef osLockFileEx
--#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
--        LPOVERLAPPED))aSyscall[48].pCurrent)
--#endif
-+#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent)
- 
--#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \
--        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
--  { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
-+#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "CharUpperW",              (SYSCALL)CharUpperW,              0 },
+ /*
+ ** Register a new geometry function for use with the r-tree MATCH operator.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
++SQLITE_API int sqlite3_rtree_geometry_callback(
+   sqlite3 *db,                  /* Register SQL function on this connection */
+   const char *zGeom,            /* Name of the new SQL function */
+   int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */
+@@ -154474,7 +172298,7 @@
+ ** Register a new 2nd-generation geometry function for use with the
+ ** r-tree MATCH operator.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
++SQLITE_API int sqlite3_rtree_query_callback(
+   sqlite3 *db,                 /* Register SQL function on this connection */
+   const char *zQueryFunc,      /* Name of new SQL function */
+   int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */
+@@ -154499,7 +172323,7 @@
+ #ifdef _WIN32
+ __declspec(dllexport)
+ #endif
+-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_init(
++SQLITE_API int sqlite3_rtree_init(
+   sqlite3 *db,
+   char **pzErrMsg,
+   const sqlite3_api_routines *pApi
+@@ -154554,8 +172378,10 @@
+ /* #include <assert.h> */
+ 
+ #ifndef SQLITE_CORE
++/*   #include "sqlite3ext.h" */
+   SQLITE_EXTENSION_INIT1
  #else
--  { "MapViewOfFile",           (SYSCALL)0,                       0 },
-+  { "CharUpperW",              (SYSCALL)0,                       0 },
++/*   #include "sqlite3.h" */
  #endif
  
--#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
--        SIZE_T))aSyscall[49].pCurrent)
--
--  { "MultiByteToWideChar",     (SYSCALL)MultiByteToWideChar,     0 },
--
--#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
--        int))aSyscall[50].pCurrent)
--
--  { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
--
--#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
--        LARGE_INTEGER*))aSyscall[51].pCurrent)
--
--  { "ReadFile",                (SYSCALL)ReadFile,                0 },
+ /*
+@@ -154574,6 +172400,38 @@
+ }
+ 
+ /*
++** This lookup table is used to help decode the first byte of
++** a multi-byte UTF8 character. It is copied here from SQLite source
++** code file utf8.c.
++*/
++static const unsigned char icuUtf8Trans1[] = {
++  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
++  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
++  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
++  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
++  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++  0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
++};
++
++#define SQLITE_ICU_READ_UTF8(zIn, c)                       \
++  c = *(zIn++);                                            \
++  if( c>=0xc0 ){                                           \
++    c = icuUtf8Trans1[c-0xc0];                             \
++    while( (*zIn & 0xc0)==0x80 ){                          \
++      c = (c<<6) + (0x3f & *(zIn++));                      \
++    }                                                      \
++  }
++
++#define SQLITE_ICU_SKIP_UTF8(zIn)                          \
++  assert( *zIn );                                          \
++  if( *(zIn++)>=0xc0 ){                                    \
++    while( (*zIn & 0xc0)==0x80 ){zIn++;}                   \
++  }
++
++
++/*
+ ** Compare two UTF-8 strings for equality where the first string is
+ ** a "LIKE" expression. Return true (1) if they are the same and 
+ ** false (0) if they are different.
+@@ -154586,17 +172444,14 @@
+   static const int MATCH_ONE = (UChar32)'_';
+   static const int MATCH_ALL = (UChar32)'%';
+ 
+-  int iPattern = 0;       /* Current byte index in zPattern */
+-  int iString = 0;        /* Current byte index in zString */
 -
--#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
--        LPOVERLAPPED))aSyscall[52].pCurrent)
-+#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent)
+   int prevEscape = 0;     /* True if the previous character was uEsc */
  
--  { "SetEndOfFile",            (SYSCALL)SetEndOfFile,            0 },
-+  { "CloseHandle",             (SYSCALL)CloseHandle,             0 },
+-  while( zPattern[iPattern]!=0 ){
++  while( 1 ){
  
--#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent)
-+#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent)
+     /* Read (and consume) the next character from the input pattern. */
+     UChar32 uPattern;
+-    U8_NEXT_UNSAFE(zPattern, iPattern, uPattern);
+-    assert(uPattern!=0);
++    SQLITE_ICU_READ_UTF8(zPattern, uPattern);
++    if( uPattern==0 ) break;
+ 
+     /* There are now 4 possibilities:
+     **
+@@ -154613,28 +172468,28 @@
+       ** MATCH_ALL. For each MATCH_ONE, skip one character in the 
+       ** test string.
+       */
+-      while( (c=zPattern[iPattern]) == MATCH_ALL || c == MATCH_ONE ){
++      while( (c=*zPattern) == MATCH_ALL || c == MATCH_ONE ){
+         if( c==MATCH_ONE ){
+-          if( zString[iString]==0 ) return 0;
+-          U8_FWD_1_UNSAFE(zString, iString);
++          if( *zString==0 ) return 0;
++          SQLITE_ICU_SKIP_UTF8(zString);
+         }
+-        iPattern++;
++        zPattern++;
+       }
  
--#if !SQLITE_OS_WINRT
--  { "SetFilePointer",          (SYSCALL)SetFilePointer,          0 },
-+#if defined(SQLITE_WIN32_HAS_ANSI)
-+  { "CreateFileA",             (SYSCALL)CreateFileA,             0 },
- #else
--  { "SetFilePointer",          (SYSCALL)0,                       0 },
-+  { "CreateFileA",             (SYSCALL)0,                       0 },
- #endif
+-      if( zPattern[iPattern]==0 ) return 1;
++      if( *zPattern==0 ) return 1;
  
--#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
--        DWORD))aSyscall[54].pCurrent)
-+#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
-+        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
+-      while( zString[iString] ){
+-        if( icuLikeCompare(&zPattern[iPattern], &zString[iString], uEsc) ){
++      while( *zString ){
++        if( icuLikeCompare(zPattern, zString, uEsc) ){
+           return 1;
+         }
+-        U8_FWD_1_UNSAFE(zString, iString);
++        SQLITE_ICU_SKIP_UTF8(zString);
+       }
+       return 0;
+ 
+     }else if( !prevEscape && uPattern==MATCH_ONE ){
+       /* Case 2. */
+-      if( zString[iString]==0 ) return 0;
+-      U8_FWD_1_UNSAFE(zString, iString);
++      if( *zString==0 ) return 0;
++      SQLITE_ICU_SKIP_UTF8(zString);
+ 
+     }else if( !prevEscape && uPattern==uEsc){
+       /* Case 3. */
+@@ -154643,7 +172498,7 @@
+     }else{
+       /* Case 4. */
+       UChar32 uString;
+-      U8_NEXT_UNSAFE(zString, iString, uString);
++      SQLITE_ICU_READ_UTF8(zString, uString);
+       uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT);
+       uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT);
+       if( uString!=uPattern ){
+@@ -154653,7 +172508,7 @@
+     }
+   }
  
--#if !SQLITE_OS_WINRT
--  { "Sleep",                   (SYSCALL)Sleep,                   0 },
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "CreateFileW",             (SYSCALL)CreateFileW,             0 },
- #else
--  { "Sleep",                   (SYSCALL)0,                       0 },
-+  { "CreateFileW",             (SYSCALL)0,                       0 },
- #endif
+-  return zString[iString]==0;
++  return *zString==0;
+ }
  
--#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent)
+ /*
+@@ -154833,20 +172688,22 @@
+ ** of upper() or lower().
+ **
+ **     lower('I', 'en_us') -> 'i'
+-**     lower('I', 'tr_tr') -> 'ı' (small dotless i)
++**     lower('I', 'tr_tr') -> '\u131' (small dotless i)
+ **
+ ** http://www.icu-project.org/userguide/posix.html#case_mappings
+ */
+ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
+-  const UChar *zInput;
+-  UChar *zOutput;
+-  int nInput;
+-  int nOutput;
 -
--  { "SystemTimeToFileTime",    (SYSCALL)SystemTimeToFileTime,    0 },
+-  UErrorCode status = U_ZERO_ERROR;
++  const UChar *zInput;            /* Pointer to input string */
++  UChar *zOutput = 0;             /* Pointer to output buffer */
++  int nInput;                     /* Size of utf-16 input string in bytes */
++  int nOut;                       /* Size of output buffer in bytes */
++  int cnt;
++  int bToUpper;                   /* True for toupper(), false for tolower() */
++  UErrorCode status;
+   const char *zLocale = 0;
+ 
+   assert(nArg==1 || nArg==2);
++  bToUpper = (sqlite3_user_data(p)!=0);
+   if( nArg==2 ){
+     zLocale = (const char *)sqlite3_value_text(apArg[1]);
+   }
+@@ -154855,26 +172712,38 @@
+   if( !zInput ){
+     return;
+   }
+-  nInput = sqlite3_value_bytes16(apArg[0]);
 -
--#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
--        LPFILETIME))aSyscall[56].pCurrent)
-+#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
-+        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
+-  nOutput = nInput * 2 + 2;
+-  zOutput = sqlite3_malloc(nOutput);
+-  if( !zOutput ){
++  nOut = nInput = sqlite3_value_bytes16(apArg[0]);
++  if( nOut==0 ){
++    sqlite3_result_text16(p, "", 0, SQLITE_STATIC);
+     return;
+   }
  
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
--  { "UnlockFile",              (SYSCALL)UnlockFile,              0 },
-+#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
-+        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
-+  { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
- #else
--  { "UnlockFile",              (SYSCALL)0,                       0 },
-+  { "CreateFileMappingA",      (SYSCALL)0,                       0 },
- #endif
+-  if( sqlite3_user_data(p) ){
+-    u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
+-  }else{
+-    u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
+-  }
++  for(cnt=0; cnt<2; cnt++){
++    UChar *zNew = sqlite3_realloc(zOutput, nOut);
++    if( zNew==0 ){
++      sqlite3_free(zOutput);
++      sqlite3_result_error_nomem(p);
++      return;
++    }
++    zOutput = zNew;
++    status = U_ZERO_ERROR;
++    if( bToUpper ){
++      nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
++    }else{
++      nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
++    }
  
--#ifndef osUnlockFile
--#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
--        DWORD))aSyscall[57].pCurrent)
--#endif
-+#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
-+        DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
- 
--#if !SQLITE_OS_WINCE
--  { "UnlockFileEx",            (SYSCALL)UnlockFileEx,            0 },
-+#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
-+        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
-+  { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
- #else
--  { "UnlockFileEx",            (SYSCALL)0,                       0 },
-+  { "CreateFileMappingW",      (SYSCALL)0,                       0 },
- #endif
+-  if( !U_SUCCESS(status) ){
+-    icuFunctionError(p, "u_strToLower()/u_strToUpper", status);
++    if( U_SUCCESS(status) ){
++      sqlite3_result_text16(p, zOutput, nOut, xFree);
++    }else if( status==U_BUFFER_OVERFLOW_ERROR ){
++      assert( cnt==0 );
++      continue;
++    }else{
++      icuFunctionError(p, bToUpper ? "u_strToUpper" : "u_strToLower", status);
++    }
+     return;
+   }
+-
+-  sqlite3_result_text16(p, zOutput, -1, xFree);
++  assert( 0 );     /* Unreachable */
+ }
  
--#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
--        LPOVERLAPPED))aSyscall[58].pCurrent)
-+#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
-+        DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
+ /*
+@@ -154935,6 +172804,7 @@
+   int rc;                   /* Return code from sqlite3_create_collation_x() */
  
--#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
--  { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "CreateMutexW",            (SYSCALL)CreateMutexW,            0 },
- #else
--  { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
-+  { "CreateMutexW",            (SYSCALL)0,                       0 },
- #endif
+   assert(nArg==2);
++  (void)nArg; /* Unused parameter */
+   zLocale = (const char *)sqlite3_value_text(apArg[0]);
+   zName = (const char *)sqlite3_value_text(apArg[1]);
  
--#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)
+@@ -154962,38 +172832,36 @@
+ ** Register the ICU extension functions with database db.
+ */
+ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
+-  struct IcuScalar {
++  static const struct IcuScalar {
+     const char *zName;                        /* Function name */
+-    int nArg;                                 /* Number of arguments */
+-    int enc;                                  /* Optimal text encoding */
+-    void *pContext;                           /* sqlite3_user_data() context */
++    unsigned char nArg;                       /* Number of arguments */
++    unsigned short enc;                       /* Optimal text encoding */
++    unsigned char iContext;                   /* sqlite3_user_data() context */
+     void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+   } scalars[] = {
+-    {"regexp", 2, SQLITE_ANY,          0, icuRegexpFunc},
 -
--  { "WideCharToMultiByte",     (SYSCALL)WideCharToMultiByte,     0 },
+-    {"lower",  1, SQLITE_UTF16,        0, icuCaseFunc16},
+-    {"lower",  2, SQLITE_UTF16,        0, icuCaseFunc16},
+-    {"upper",  1, SQLITE_UTF16, (void*)1, icuCaseFunc16},
+-    {"upper",  2, SQLITE_UTF16, (void*)1, icuCaseFunc16},
 -
--#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
--        LPCSTR,LPBOOL))aSyscall[60].pCurrent)
+-    {"lower",  1, SQLITE_UTF8,         0, icuCaseFunc16},
+-    {"lower",  2, SQLITE_UTF8,         0, icuCaseFunc16},
+-    {"upper",  1, SQLITE_UTF8,  (void*)1, icuCaseFunc16},
+-    {"upper",  2, SQLITE_UTF8,  (void*)1, icuCaseFunc16},
 -
--  { "WriteFile",               (SYSCALL)WriteFile,               0 },
+-    {"like",   2, SQLITE_UTF8,         0, icuLikeFunc},
+-    {"like",   3, SQLITE_UTF8,         0, icuLikeFunc},
 -
--#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
--        LPOVERLAPPED))aSyscall[61].pCurrent)
-+#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
-+        LPCWSTR))aSyscall[8].pCurrent)
- 
--#if SQLITE_OS_WINRT
--  { "CreateEventExW",          (SYSCALL)CreateEventExW,          0 },
-+#if defined(SQLITE_WIN32_HAS_ANSI)
-+  { "DeleteFileA",             (SYSCALL)DeleteFileA,             0 },
- #else
--  { "CreateEventExW",          (SYSCALL)0,                       0 },
-+  { "DeleteFileA",             (SYSCALL)0,                       0 },
- #endif
- 
--#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
--        DWORD,DWORD))aSyscall[62].pCurrent)
-+#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent)
- 
--#if !SQLITE_OS_WINRT
--  { "WaitForSingleObject",     (SYSCALL)WaitForSingleObject,     0 },
-+#if defined(SQLITE_WIN32_HAS_WIDE)
-+  { "DeleteFileW",             (SYSCALL)DeleteFileW,             0 },
- #else
--  { "WaitForSingleObject",     (SYSCALL)0,                       0 },
-+  { "DeleteFileW",             (SYSCALL)0,                       0 },
- #endif
- 
--#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
--        DWORD))aSyscall[63].pCurrent)
-+#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent)
- 
--#if !SQLITE_OS_WINCE
--  { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
-+#if SQLITE_OS_WINCE
-+  { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
- #else
--  { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
-+  { "FileTimeToLocalFileTime", (SYSCALL)0,                       0 },
- #endif
+-    {"icu_load_collation",  2, SQLITE_UTF8, (void*)db, icuLoadCollation},
++    {"icu_load_collation",  2, SQLITE_UTF8,                1, icuLoadCollation},
++    {"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC,         0, icuRegexpFunc},
++    {"lower",  1, SQLITE_UTF16|SQLITE_DETERMINISTIC,       0, icuCaseFunc16},
++    {"lower",  2, SQLITE_UTF16|SQLITE_DETERMINISTIC,       0, icuCaseFunc16},
++    {"upper",  1, SQLITE_UTF16|SQLITE_DETERMINISTIC,       1, icuCaseFunc16},
++    {"upper",  2, SQLITE_UTF16|SQLITE_DETERMINISTIC,       1, icuCaseFunc16},
++    {"lower",  1, SQLITE_UTF8|SQLITE_DETERMINISTIC,        0, icuCaseFunc16},
++    {"lower",  2, SQLITE_UTF8|SQLITE_DETERMINISTIC,        0, icuCaseFunc16},
++    {"upper",  1, SQLITE_UTF8|SQLITE_DETERMINISTIC,        1, icuCaseFunc16},
++    {"upper",  2, SQLITE_UTF8|SQLITE_DETERMINISTIC,        1, icuCaseFunc16},
++    {"like",   2, SQLITE_UTF8|SQLITE_DETERMINISTIC,        0, icuLikeFunc},
++    {"like",   3, SQLITE_UTF8|SQLITE_DETERMINISTIC,        0, icuLikeFunc},
+   };
+-
+   int rc = SQLITE_OK;
+   int i;
  
--#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
--        BOOL))aSyscall[64].pCurrent)
-+#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
-+        LPFILETIME))aSyscall[11].pCurrent)
++  
+   for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){
+-    struct IcuScalar *p = &scalars[i];
++    const struct IcuScalar *p = &scalars[i];
+     rc = sqlite3_create_function(
+-        db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0
++        db, p->zName, p->nArg, p->enc, 
++        p->iContext ? (void*)db : (void*)0,
++        p->xFunc, 0, 0
+     );
+   }
  
--#if SQLITE_OS_WINRT
--  { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
-+#if SQLITE_OS_WINCE
-+  { "FileTimeToSystemTime",    (SYSCALL)FileTimeToSystemTime,    0 },
- #else
--  { "SetFilePointerEx",        (SYSCALL)0,                       0 },
-+  { "FileTimeToSystemTime",    (SYSCALL)0,                       0 },
+@@ -155004,7 +172872,7 @@
+ #ifdef _WIN32
+ __declspec(dllexport)
  #endif
+-SQLITE_API int SQLITE_STDCALL sqlite3_icu_init(
++SQLITE_API int sqlite3_icu_init(
+   sqlite3 *db, 
+   char **pzErrMsg,
+   const sqlite3_api_routines *pApi
+@@ -155031,11 +172899,13 @@
+ *************************************************************************
+ ** This file implements a tokenizer for fts3 based on the ICU library.
+ */
++/* #include "fts3Int.h" */
+ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
+ #ifdef SQLITE_ENABLE_ICU
+ 
+ /* #include <assert.h> */
+ /* #include <string.h> */
++/* #include "fts3_tokenizer.h" */
+ 
+ #include <unicode/ubrk.h>
+ /* #include <unicode/ucol.h> */
+@@ -155258,12 +173128,13 @@
+ ** The set of routines that implement the simple tokenizer
+ */
+ static const sqlite3_tokenizer_module icuTokenizerModule = {
+-  0,                           /* iVersion */
+-  icuCreate,                   /* xCreate  */
+-  icuDestroy,                  /* xCreate  */
+-  icuOpen,                     /* xOpen    */
+-  icuClose,                    /* xClose   */
+-  icuNext,                     /* xNext    */
++  0,                           /* iVersion    */
++  icuCreate,                   /* xCreate     */
++  icuDestroy,                  /* xCreate     */
++  icuOpen,                     /* xOpen       */
++  icuClose,                    /* xClose      */
++  icuNext,                     /* xNext       */
++  0,                           /* xLanguageid */
+ };
  
--#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
--        PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent)
-+#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
-+        LPSYSTEMTIME))aSyscall[12].pCurrent)
- 
--#if SQLITE_OS_WINRT
--  { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
--#else
--  { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
--#endif
-+  { "FlushFileBuffers",        (SYSCALL)FlushFileBuffers,        0 },
- 
--#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
--        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
-+#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent)
- 
--#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
--  { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
-+#if defined(SQLITE_WIN32_HAS_ANSI)
-+  { "FormatMessageA",          (SYSCALL)FormatMessageA,          0 },
- #else
--  { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
-+  { "FormatMessageA",          (SYSCALL)0,                       0 },
- #endif
+ /*
+@@ -155279,6 +173150,5397 @@
+ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
  
--#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
--        SIZE_T))aSyscall[67].pCurrent)
-+#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
-+        DWORD,va_list*))aSyscall[14].pCurrent)
+ /************** End of fts3_icu.c ********************************************/
++/************** Begin file sqlite3rbu.c **************************************/
++/*
++** 2014 August 30
++**
++** 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.
++**
++*************************************************************************
++**
++**
++** OVERVIEW 
++**
++**  The RBU extension requires that the RBU update be packaged as an
++**  SQLite database. The tables it expects to find are described in
++**  sqlite3rbu.h.  Essentially, for each table xyz in the target database
++**  that the user wishes to write to, a corresponding data_xyz table is
++**  created in the RBU database and populated with one row for each row to
++**  update, insert or delete from the target table.
++** 
++**  The update proceeds in three stages:
++** 
++**  1) The database is updated. The modified database pages are written
++**     to a *-oal file. A *-oal file is just like a *-wal file, except
++**     that it is named "<database>-oal" instead of "<database>-wal".
++**     Because regular SQLite clients do not look for file named
++**     "<database>-oal", they go on using the original database in
++**     rollback mode while the *-oal file is being generated.
++** 
++**     During this stage RBU does not update the database by writing
++**     directly to the target tables. Instead it creates "imposter"
++**     tables using the SQLITE_TESTCTRL_IMPOSTER interface that it uses
++**     to update each b-tree individually. All updates required by each
++**     b-tree are completed before moving on to the next, and all
++**     updates are done in sorted key order.
++** 
++**  2) The "<database>-oal" file is moved to the equivalent "<database>-wal"
++**     location using a call to rename(2). Before doing this the RBU
++**     module takes an EXCLUSIVE lock on the database file, ensuring
++**     that there are no other active readers.
++** 
++**     Once the EXCLUSIVE lock is released, any other database readers
++**     detect the new *-wal file and read the database in wal mode. At
++**     this point they see the new version of the database - including
++**     the updates made as part of the RBU update.
++** 
++**  3) The new *-wal file is checkpointed. This proceeds in the same way 
++**     as a regular database checkpoint, except that a single frame is
++**     checkpointed each time sqlite3rbu_step() is called. If the RBU
++**     handle is closed before the entire *-wal file is checkpointed,
++**     the checkpoint progress is saved in the RBU database and the
++**     checkpoint can be resumed by another RBU client at some point in
++**     the future.
++**
++** POTENTIAL PROBLEMS
++** 
++**  The rename() call might not be portable. And RBU is not currently
++**  syncing the directory after renaming the file.
++**
++**  When state is saved, any commit to the *-oal file and the commit to
++**  the RBU update database are not atomic. So if the power fails at the
++**  wrong moment they might get out of sync. As the main database will be
++**  committed before the RBU update database this will likely either just
++**  pass unnoticed, or result in SQLITE_CONSTRAINT errors (due to UNIQUE
++**  constraint violations).
++**
++**  If some client does modify the target database mid RBU update, or some
++**  other error occurs, the RBU extension will keep throwing errors. It's
++**  not really clear how to get out of this state. The system could just
++**  by delete the RBU update database and *-oal file and have the device
++**  download the update again and start over.
++**
++**  At present, for an UPDATE, both the new.* and old.* records are
++**  collected in the rbu_xyz table. And for both UPDATEs and DELETEs all
++**  fields are collected.  This means we're probably writing a lot more
++**  data to disk when saving the state of an ongoing update to the RBU
++**  update database than is strictly necessary.
++** 
++*/
++
++/* #include <assert.h> */
++/* #include <string.h> */
++/* #include <stdio.h> */
++
++/* #include "sqlite3.h" */
++
++#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU)
++/************** Include sqlite3rbu.h in the middle of sqlite3rbu.c ***********/
++/************** Begin file sqlite3rbu.h **************************************/
++/*
++** 2014 August 30
++**
++** 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 public interface for the RBU extension. 
++*/
++
++/*
++** SUMMARY
++**
++** Writing a transaction containing a large number of operations on 
++** b-tree indexes that are collectively larger than the available cache
++** memory can be very inefficient. 
++**
++** The problem is that in order to update a b-tree, the leaf page (at least)
++** containing the entry being inserted or deleted must be modified. If the
++** working set of leaves is larger than the available cache memory, then a 
++** single leaf that is modified more than once as part of the transaction 
++** may be loaded from or written to the persistent media multiple times.
++** Additionally, because the index updates are likely to be applied in
++** random order, access to pages within the database is also likely to be in 
++** random order, which is itself quite inefficient.
++**
++** One way to improve the situation is to sort the operations on each index
++** by index key before applying them to the b-tree. This leads to an IO
++** pattern that resembles a single linear scan through the index b-tree,
++** and all but guarantees each modified leaf page is loaded and stored 
++** exactly once. SQLite uses this trick to improve the performance of
++** CREATE INDEX commands. This extension allows it to be used to improve
++** the performance of large transactions on existing databases.
++**
++** Additionally, this extension allows the work involved in writing the 
++** large transaction to be broken down into sub-transactions performed 
++** sequentially by separate processes. This is useful if the system cannot 
++** guarantee that a single update process will run for long enough to apply 
++** the entire update, for example because the update is being applied on a 
++** mobile device that is frequently rebooted. Even after the writer process 
++** has committed one or more sub-transactions, other database clients continue
++** to read from the original database snapshot. In other words, partially 
++** applied transactions are not visible to other clients. 
++**
++** "RBU" stands for "Resumable Bulk Update". As in a large database update
++** transmitted via a wireless network to a mobile device. A transaction
++** applied using this extension is hence refered to as an "RBU update".
++**
++**
++** LIMITATIONS
++**
++** An "RBU update" transaction is subject to the following limitations:
++**
++**   * The transaction must consist of INSERT, UPDATE and DELETE operations
++**     only.
++**
++**   * INSERT statements may not use any default values.
++**
++**   * UPDATE and DELETE statements must identify their target rows by 
++**     non-NULL PRIMARY KEY values. Rows with NULL values stored in PRIMARY
++**     KEY fields may not be updated or deleted. If the table being written 
++**     has no PRIMARY KEY, affected rows must be identified by rowid.
++**
++**   * UPDATE statements may not modify PRIMARY KEY columns.
++**
++**   * No triggers will be fired.
++**
++**   * No foreign key violations are detected or reported.
++**
++**   * CHECK constraints are not enforced.
++**
++**   * No constraint handling mode except for "OR ROLLBACK" is supported.
++**
++**
++** PREPARATION
++**
++** An "RBU update" is stored as a separate SQLite database. A database
++** containing an RBU update is an "RBU database". For each table in the 
++** target database to be updated, the RBU database should contain a table
++** named "data_<target name>" containing the same set of columns as the
++** target table, and one more - "rbu_control". The data_% table should 
++** have no PRIMARY KEY or UNIQUE constraints, but each column should have
++** the same type as the corresponding column in the target database.
++** The "rbu_control" column should have no type at all. For example, if
++** the target database contains:
++**
++**   CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c UNIQUE);
++**
++** Then the RBU database should contain:
++**
++**   CREATE TABLE data_t1(a INTEGER, b TEXT, c, rbu_control);
++**
++** The order of the columns in the data_% table does not matter.
++**
++** Instead of a regular table, the RBU database may also contain virtual
++** tables or view named using the data_<target> naming scheme. 
++**
++** Instead of the plain data_<target> naming scheme, RBU database tables 
++** may also be named data<integer>_<target>, where <integer> is any sequence
++** of zero or more numeric characters (0-9). This can be significant because
++** tables within the RBU database are always processed in order sorted by 
++** name. By judicious selection of the <integer> portion of the names
++** of the RBU tables the user can therefore control the order in which they
++** are processed. This can be useful, for example, to ensure that "external
++** content" FTS4 tables are updated before their underlying content tables.
++**
++** If the target database table is a virtual table or a table that has no
++** PRIMARY KEY declaration, the data_% table must also contain a column 
++** named "rbu_rowid". This column is mapped to the tables implicit primary 
++** key column - "rowid". Virtual tables for which the "rowid" column does 
++** not function like a primary key value cannot be updated using RBU. For 
++** example, if the target db contains either of the following:
++**
++**   CREATE VIRTUAL TABLE x1 USING fts3(a, b);
++**   CREATE TABLE x1(a, b)
++**
++** then the RBU database should contain:
++**
++**   CREATE TABLE data_x1(a, b, rbu_rowid, rbu_control);
++**
++** All non-hidden columns (i.e. all columns matched by "SELECT *") of the
++** target table must be present in the input table. For virtual tables,
++** hidden columns are optional - they are updated by RBU if present in
++** the input table, or not otherwise. For example, to write to an fts4
++** table with a hidden languageid column such as:
++**
++**   CREATE VIRTUAL TABLE ft1 USING fts4(a, b, languageid='langid');
++**
++** Either of the following input table schemas may be used:
++**
++**   CREATE TABLE data_ft1(a, b, langid, rbu_rowid, rbu_control);
++**   CREATE TABLE data_ft1(a, b, rbu_rowid, rbu_control);
++**
++** For each row to INSERT into the target database as part of the RBU 
++** update, the corresponding data_% table should contain a single record
++** with the "rbu_control" column set to contain integer value 0. The
++** other columns should be set to the values that make up the new record 
++** to insert. 
++**
++** If the target database table has an INTEGER PRIMARY KEY, it is not 
++** possible to insert a NULL value into the IPK column. Attempting to 
++** do so results in an SQLITE_MISMATCH error.
++**
++** For each row to DELETE from the target database as part of the RBU 
++** update, the corresponding data_% table should contain a single record
++** with the "rbu_control" column set to contain integer value 1. The
++** real primary key values of the row to delete should be stored in the
++** corresponding columns of the data_% table. The values stored in the
++** other columns are not used.
++**
++** For each row to UPDATE from the target database as part of the RBU 
++** update, the corresponding data_% table should contain a single record
++** with the "rbu_control" column set to contain a value of type text.
++** The real primary key values identifying the row to update should be 
++** stored in the corresponding columns of the data_% table row, as should
++** the new values of all columns being update. The text value in the 
++** "rbu_control" column must contain the same number of characters as
++** there are columns in the target database table, and must consist entirely
++** of 'x' and '.' characters (or in some special cases 'd' - see below). For 
++** each column that is being updated, the corresponding character is set to
++** 'x'. For those that remain as they are, the corresponding character of the
++** rbu_control value should be set to '.'. For example, given the tables 
++** above, the update statement:
++**
++**   UPDATE t1 SET c = 'usa' WHERE a = 4;
++**
++** is represented by the data_t1 row created by:
++**
++**   INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..x');
++**
++** Instead of an 'x' character, characters of the rbu_control value specified
++** for UPDATEs may also be set to 'd'. In this case, instead of updating the
++** target table with the value stored in the corresponding data_% column, the
++** user-defined SQL function "rbu_delta()" is invoked and the result stored in
++** the target table column. rbu_delta() is invoked with two arguments - the
++** original value currently stored in the target table column and the 
++** value specified in the data_xxx table.
++**
++** For example, this row:
++**
++**   INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..d');
++**
++** is similar to an UPDATE statement such as: 
++**
++**   UPDATE t1 SET c = rbu_delta(c, 'usa') WHERE a = 4;
++**
++** Finally, if an 'f' character appears in place of a 'd' or 's' in an 
++** ota_control string, the contents of the data_xxx table column is assumed
++** to be a "fossil delta" - a patch to be applied to a blob value in the
++** format used by the fossil source-code management system. In this case
++** the existing value within the target database table must be of type BLOB. 
++** It is replaced by the result of applying the specified fossil delta to
++** itself.
++**
++** If the target database table is a virtual table or a table with no PRIMARY
++** KEY, the rbu_control value should not include a character corresponding 
++** to the rbu_rowid value. For example, this:
++**
++**   INSERT INTO data_ft1(a, b, rbu_rowid, rbu_control) 
++**       VALUES(NULL, 'usa', 12, '.x');
++**
++** causes a result similar to:
++**
++**   UPDATE ft1 SET b = 'usa' WHERE rowid = 12;
++**
++** The data_xxx tables themselves should have no PRIMARY KEY declarations.
++** However, RBU is more efficient if reading the rows in from each data_xxx
++** table in "rowid" order is roughly the same as reading them sorted by
++** the PRIMARY KEY of the corresponding target database table. In other 
++** words, rows should be sorted using the destination table PRIMARY KEY 
++** fields before they are inserted into the data_xxx tables.
++**
++** USAGE
++**
++** The API declared below allows an application to apply an RBU update 
++** stored on disk to an existing target database. Essentially, the 
++** application:
++**
++**     1) Opens an RBU handle using the sqlite3rbu_open() function.
++**
++**     2) Registers any required virtual table modules with the database
++**        handle returned by sqlite3rbu_db(). Also, if required, register
++**        the rbu_delta() implementation.
++**
++**     3) Calls the sqlite3rbu_step() function one or more times on
++**        the new handle. Each call to sqlite3rbu_step() performs a single
++**        b-tree operation, so thousands of calls may be required to apply 
++**        a complete update.
++**
++**     4) Calls sqlite3rbu_close() to close the RBU update handle. If
++**        sqlite3rbu_step() has been called enough times to completely
++**        apply the update to the target database, then the RBU database
++**        is marked as fully applied. Otherwise, the state of the RBU 
++**        update application is saved in the RBU database for later 
++**        resumption.
++**
++** See comments below for more detail on APIs.
++**
++** If an update is only partially applied to the target database by the
++** time sqlite3rbu_close() is called, various state information is saved 
++** within the RBU database. This allows subsequent processes to automatically
++** resume the RBU update from where it left off.
++**
++** To remove all RBU extension state information, returning an RBU database 
++** to its original contents, it is sufficient to drop all tables that begin
++** with the prefix "rbu_"
++**
++** DATABASE LOCKING
++**
++** An RBU update may not be applied to a database in WAL mode. Attempting
++** to do so is an error (SQLITE_ERROR).
++**
++** While an RBU handle is open, a SHARED lock may be held on the target
++** database file. This means it is possible for other clients to read the
++** database, but not to write it.
++**
++** If an RBU update is started and then suspended before it is completed,
++** then an external client writes to the database, then attempting to resume
++** the suspended RBU update is also an error (SQLITE_BUSY).
++*/
++
++#ifndef _SQLITE3RBU_H
++#define _SQLITE3RBU_H
++
++/* #include "sqlite3.h"              ** Required for error code definitions ** */
++
++#if 0
++extern "C" {
++#endif
++
++typedef struct sqlite3rbu sqlite3rbu;
++
++/*
++** Open an RBU handle.
++**
++** Argument zTarget is the path to the target database. Argument zRbu is
++** the path to the RBU database. Each call to this function must be matched
++** by a call to sqlite3rbu_close(). When opening the databases, RBU passes
++** the SQLITE_CONFIG_URI flag to sqlite3_open_v2(). So if either zTarget
++** or zRbu begin with "file:", it will be interpreted as an SQLite 
++** database URI, not a regular file name.
++**
++** If the zState argument is passed a NULL value, the RBU extension stores 
++** the current state of the update (how many rows have been updated, which 
++** indexes are yet to be updated etc.) within the RBU database itself. This
++** can be convenient, as it means that the RBU application does not need to
++** organize removing a separate state file after the update is concluded. 
++** Or, if zState is non-NULL, it must be a path to a database file in which 
++** the RBU extension can store the state of the update.
++**
++** When resuming an RBU update, the zState argument must be passed the same
++** value as when the RBU update was started.
++**
++** Once the RBU update is finished, the RBU extension does not 
++** automatically remove any zState database file, even if it created it.
++**
++** By default, RBU uses the default VFS to access the files on disk. To
++** use a VFS other than the default, an SQLite "file:" URI containing a
++** "vfs=..." option may be passed as the zTarget option.
++**
++** IMPORTANT NOTE FOR ZIPVFS USERS: The RBU extension works with all of
++** SQLite's built-in VFSs, including the multiplexor VFS. However it does
++** not work out of the box with zipvfs. Refer to the comment describing
++** the zipvfs_create_vfs() API below for details on using RBU with zipvfs.
++*/
++SQLITE_API sqlite3rbu *sqlite3rbu_open(
++  const char *zTarget, 
++  const char *zRbu,
++  const char *zState
++);
++
++/*
++** Open an RBU handle to perform an RBU vacuum on database file zTarget.
++** An RBU vacuum is similar to SQLite's built-in VACUUM command, except
++** that it can be suspended and resumed like an RBU update.
++**
++** The second argument to this function identifies a database in which 
++** to store the state of the RBU vacuum operation if it is suspended. The 
++** first time sqlite3rbu_vacuum() is called, to start an RBU vacuum
++** operation, the state database should either not exist or be empty
++** (contain no tables). If an RBU vacuum is suspended by calling 
++** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has
++** returned SQLITE_DONE, the vacuum state is stored in the state database. 
++** The vacuum can be resumed by calling this function to open a new RBU
++** handle specifying the same target and state databases.
++**
++** If the second argument passed to this function is NULL, then the
++** name of the state database is "<database>-vacuum", where <database>
++** is the name of the target database file. In this case, on UNIX, if the
++** state database is not already present in the file-system, it is created
++** with the same permissions as the target db is made.
++**
++** This function does not delete the state database after an RBU vacuum
++** is completed, even if it created it. However, if the call to
++** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents
++** of the state tables within the state database are zeroed. This way,
++** the next call to sqlite3rbu_vacuum() opens a handle that starts a 
++** new RBU vacuum operation.
++**
++** As with sqlite3rbu_open(), Zipvfs users should rever to the comment
++** describing the sqlite3rbu_create_vfs() API function below for 
++** a description of the complications associated with using RBU with 
++** zipvfs databases.
++*/
++SQLITE_API sqlite3rbu *sqlite3rbu_vacuum(
++  const char *zTarget, 
++  const char *zState
++);
++
++/*
++** Internally, each RBU connection uses a separate SQLite database 
++** connection to access the target and rbu update databases. This
++** API allows the application direct access to these database handles.
++**
++** The first argument passed to this function must be a valid, open, RBU
++** handle. The second argument should be passed zero to access the target
++** database handle, or non-zero to access the rbu update database handle.
++** Accessing the underlying database handles may be useful in the
++** following scenarios:
++**
++**   * If any target tables are virtual tables, it may be necessary to
++**     call sqlite3_create_module() on the target database handle to 
++**     register the required virtual table implementations.
++**
++**   * If the data_xxx tables in the RBU source database are virtual 
++**     tables, the application may need to call sqlite3_create_module() on
++**     the rbu update db handle to any required virtual table
++**     implementations.
++**
++**   * If the application uses the "rbu_delta()" feature described above,
++**     it must use sqlite3_create_function() or similar to register the
++**     rbu_delta() implementation with the target database handle.
++**
++** If an error has occurred, either while opening or stepping the RBU object,
++** this function may return NULL. The error code and message may be collected
++** when sqlite3rbu_close() is called.
++**
++** Database handles returned by this function remain valid until the next
++** call to any sqlite3rbu_xxx() function other than sqlite3rbu_db().
++*/
++SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu*, int bRbu);
++
++/*
++** Do some work towards applying the RBU update to the target db. 
++**
++** Return SQLITE_DONE if the update has been completely applied, or 
++** SQLITE_OK if no error occurs but there remains work to do to apply
++** the RBU update. If an error does occur, some other error code is 
++** returned. 
++**
++** Once a call to sqlite3rbu_step() has returned a value other than
++** SQLITE_OK, all subsequent calls on the same RBU handle are no-ops
++** that immediately return the same value.
++*/
++SQLITE_API int sqlite3rbu_step(sqlite3rbu *pRbu);
++
++/*
++** Force RBU to save its state to disk.
++**
++** If a power failure or application crash occurs during an update, following
++** system recovery RBU may resume the update from the point at which the state
++** was last saved. In other words, from the most recent successful call to 
++** sqlite3rbu_close() or this function.
++**
++** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
++*/
++SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu);
++
++/*
++** Close an RBU handle. 
++**
++** If the RBU update has been completely applied, mark the RBU database
++** as fully applied. Otherwise, assuming no error has occurred, save the
++** current state of the RBU update appliation to the RBU database.
++**
++** If an error has already occurred as part of an sqlite3rbu_step()
++** or sqlite3rbu_open() call, or if one occurs within this function, an
++** SQLite error code is returned. Additionally, if pzErrmsg is not NULL,
++** *pzErrmsg may be set to point to a buffer containing a utf-8 formatted
++** English language error message. It is the responsibility of the caller to
++** eventually free any such buffer using sqlite3_free().
++**
++** Otherwise, if no error occurs, this function returns SQLITE_OK if the
++** update has been partially applied, or SQLITE_DONE if it has been 
++** completely applied.
++*/
++SQLITE_API int sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg);
++
++/*
++** Return the total number of key-value operations (inserts, deletes or 
++** updates) that have been performed on the target database since the
++** current RBU update was started.
++*/
++SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu);
++
++/*
++** Obtain permyriadage (permyriadage is to 10000 as percentage is to 100) 
++** progress indications for the two stages of an RBU update. This API may
++** be useful for driving GUI progress indicators and similar.
++**
++** An RBU update is divided into two stages:
++**
++**   * Stage 1, in which changes are accumulated in an oal/wal file, and
++**   * Stage 2, in which the contents of the wal file are copied into the
++**     main database.
++**
++** The update is visible to non-RBU clients during stage 2. During stage 1
++** non-RBU reader clients may see the original database.
++**
++** If this API is called during stage 2 of the update, output variable 
++** (*pnOne) is set to 10000 to indicate that stage 1 has finished and (*pnTwo)
++** to a value between 0 and 10000 to indicate the permyriadage progress of
++** stage 2. A value of 5000 indicates that stage 2 is half finished, 
++** 9000 indicates that it is 90% finished, and so on.
++**
++** If this API is called during stage 1 of the update, output variable 
++** (*pnTwo) is set to 0 to indicate that stage 2 has not yet started. The
++** value to which (*pnOne) is set depends on whether or not the RBU 
++** database contains an "rbu_count" table. The rbu_count table, if it 
++** exists, must contain the same columns as the following:
++**
++**   CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
++**
++** There must be one row in the table for each source (data_xxx) table within
++** the RBU database. The 'tbl' column should contain the name of the source
++** table. The 'cnt' column should contain the number of rows within the
++** source table.
++**
++** If the rbu_count table is present and populated correctly and this
++** API is called during stage 1, the *pnOne output variable is set to the
++** permyriadage progress of the same stage. If the rbu_count table does
++** not exist, then (*pnOne) is set to -1 during stage 1. If the rbu_count
++** table exists but is not correctly populated, the value of the *pnOne
++** output variable during stage 1 is undefined.
++*/
++SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo);
++
++/*
++** Obtain an indication as to the current stage of an RBU update or vacuum.
++** This function always returns one of the SQLITE_RBU_STATE_XXX constants
++** defined in this file. Return values should be interpreted as follows:
++**
++** SQLITE_RBU_STATE_OAL:
++**   RBU is currently building a *-oal file. The next call to sqlite3rbu_step()
++**   may either add further data to the *-oal file, or compute data that will
++**   be added by a subsequent call.
++**
++** SQLITE_RBU_STATE_MOVE:
++**   RBU has finished building the *-oal file. The next call to sqlite3rbu_step()
++**   will move the *-oal file to the equivalent *-wal path. If the current
++**   operation is an RBU update, then the updated version of the database
++**   file will become visible to ordinary SQLite clients following the next
++**   call to sqlite3rbu_step().
++**
++** SQLITE_RBU_STATE_CHECKPOINT:
++**   RBU is currently performing an incremental checkpoint. The next call to
++**   sqlite3rbu_step() will copy a page of data from the *-wal file into
++**   the target database file.
++**
++** SQLITE_RBU_STATE_DONE:
++**   The RBU operation has finished. Any subsequent calls to sqlite3rbu_step()
++**   will immediately return SQLITE_DONE.
++**
++** SQLITE_RBU_STATE_ERROR:
++**   An error has occurred. Any subsequent calls to sqlite3rbu_step() will
++**   immediately return the SQLite error code associated with the error.
++*/
++#define SQLITE_RBU_STATE_OAL        1
++#define SQLITE_RBU_STATE_MOVE       2
++#define SQLITE_RBU_STATE_CHECKPOINT 3
++#define SQLITE_RBU_STATE_DONE       4
++#define SQLITE_RBU_STATE_ERROR      5
++
++SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu);
++
++/*
++** Create an RBU VFS named zName that accesses the underlying file-system
++** via existing VFS zParent. Or, if the zParent parameter is passed NULL, 
++** then the new RBU VFS uses the default system VFS to access the file-system.
++** The new object is registered as a non-default VFS with SQLite before 
++** returning.
++**
++** Part of the RBU implementation uses a custom VFS object. Usually, this
++** object is created and deleted automatically by RBU. 
++**
++** The exception is for applications that also use zipvfs. In this case,
++** the custom VFS must be explicitly created by the user before the RBU
++** handle is opened. The RBU VFS should be installed so that the zipvfs
++** VFS uses the RBU VFS, which in turn uses any other VFS layers in use 
++** (for example multiplexor) to access the file-system. For example,
++** to assemble an RBU enabled VFS stack that uses both zipvfs and 
++** multiplexor (error checking omitted):
++**
++**     // Create a VFS named "multiplex" (not the default).
++**     sqlite3_multiplex_initialize(0, 0);
++**
++**     // Create an rbu VFS named "rbu" that uses multiplexor. If the
++**     // second argument were replaced with NULL, the "rbu" VFS would
++**     // access the file-system via the system default VFS, bypassing the
++**     // multiplexor.
++**     sqlite3rbu_create_vfs("rbu", "multiplex");
++**
++**     // Create a zipvfs VFS named "zipvfs" that uses rbu.
++**     zipvfs_create_vfs_v3("zipvfs", "rbu", 0, xCompressorAlgorithmDetector);
++**
++**     // Make zipvfs the default VFS.
++**     sqlite3_vfs_register(sqlite3_vfs_find("zipvfs"), 1);
++**
++** Because the default VFS created above includes a RBU functionality, it
++** may be used by RBU clients. Attempting to use RBU with a zipvfs VFS stack
++** that does not include the RBU layer results in an error.
++**
++** The overhead of adding the "rbu" VFS to the system is negligible for 
++** non-RBU users. There is no harm in an application accessing the 
++** file-system via "rbu" all the time, even if it only uses RBU functionality 
++** occasionally.
++*/
++SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent);
++
++/*
++** Deregister and destroy an RBU vfs created by an earlier call to
++** sqlite3rbu_create_vfs().
++**
++** VFS objects are not reference counted. If a VFS object is destroyed
++** before all database handles that use it have been closed, the results
++** are undefined.
++*/
++SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName);
++
++#if 0
++}  /* end of the 'extern "C"' block */
++#endif
++
++#endif /* _SQLITE3RBU_H */
++
++/************** End of sqlite3rbu.h ******************************************/
++/************** Continuing where we left off in sqlite3rbu.c *****************/
++
++#if defined(_WIN32_WCE)
++/* #include "windows.h" */
++#endif
++
++/* Maximum number of prepared UPDATE statements held by this module */
++#define SQLITE_RBU_UPDATE_CACHESIZE 16
++
++/*
++** Swap two objects of type TYPE.
++*/
++#if !defined(SQLITE_AMALGAMATION)
++# define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
++#endif
++
++/*
++** The rbu_state table is used to save the state of a partially applied
++** update so that it can be resumed later. The table consists of integer
++** keys mapped to values as follows:
++**
++** RBU_STATE_STAGE:
++**   May be set to integer values 1, 2, 4 or 5. As follows:
++**       1: the *-rbu file is currently under construction.
++**       2: the *-rbu file has been constructed, but not yet moved 
++**          to the *-wal path.
++**       4: the checkpoint is underway.
++**       5: the rbu update has been checkpointed.
++**
++** RBU_STATE_TBL:
++**   Only valid if STAGE==1. The target database name of the table 
++**   currently being written.
++**
++** RBU_STATE_IDX:
++**   Only valid if STAGE==1. The target database name of the index 
++**   currently being written, or NULL if the main table is currently being
++**   updated.
++**
++** RBU_STATE_ROW:
++**   Only valid if STAGE==1. Number of rows already processed for the current
++**   table/index.
++**
++** RBU_STATE_PROGRESS:
++**   Trbul number of sqlite3rbu_step() calls made so far as part of this
++**   rbu update.
++**
++** RBU_STATE_CKPT:
++**   Valid if STAGE==4. The 64-bit checksum associated with the wal-index
++**   header created by recovering the *-wal file. This is used to detect
++**   cases when another client appends frames to the *-wal file in the
++**   middle of an incremental checkpoint (an incremental checkpoint cannot
++**   be continued if this happens).
++**
++** RBU_STATE_COOKIE:
++**   Valid if STAGE==1. The current change-counter cookie value in the 
++**   target db file.
++**
++** RBU_STATE_OALSZ:
++**   Valid if STAGE==1. The size in bytes of the *-oal file.
++*/
++#define RBU_STATE_STAGE        1
++#define RBU_STATE_TBL          2
++#define RBU_STATE_IDX          3
++#define RBU_STATE_ROW          4
++#define RBU_STATE_PROGRESS     5
++#define RBU_STATE_CKPT         6
++#define RBU_STATE_COOKIE       7
++#define RBU_STATE_OALSZ        8
++#define RBU_STATE_PHASEONESTEP 9
++
++#define RBU_STAGE_OAL         1
++#define RBU_STAGE_MOVE        2
++#define RBU_STAGE_CAPTURE     3
++#define RBU_STAGE_CKPT        4
++#define RBU_STAGE_DONE        5
++
++
++#define RBU_CREATE_STATE \
++  "CREATE TABLE IF NOT EXISTS %s.rbu_state(k INTEGER PRIMARY KEY, v)"
++
++typedef struct RbuFrame RbuFrame;
++typedef struct RbuObjIter RbuObjIter;
++typedef struct RbuState RbuState;
++typedef struct rbu_vfs rbu_vfs;
++typedef struct rbu_file rbu_file;
++typedef struct RbuUpdateStmt RbuUpdateStmt;
++
++#if !defined(SQLITE_AMALGAMATION)
++typedef unsigned int u32;
++typedef unsigned short u16;
++typedef unsigned char u8;
++typedef sqlite3_int64 i64;
++#endif
++
++/*
++** These values must match the values defined in wal.c for the equivalent
++** locks. These are not magic numbers as they are part of the SQLite file
++** format.
++*/
++#define WAL_LOCK_WRITE  0
++#define WAL_LOCK_CKPT   1
++#define WAL_LOCK_READ0  3
++
++#define SQLITE_FCNTL_RBUCNT    5149216
++
++/*
++** A structure to store values read from the rbu_state table in memory.
++*/
++struct RbuState {
++  int eStage;
++  char *zTbl;
++  char *zIdx;
++  i64 iWalCksum;
++  int nRow;
++  i64 nProgress;
++  u32 iCookie;
++  i64 iOalSz;
++  i64 nPhaseOneStep;
++};
++
++struct RbuUpdateStmt {
++  char *zMask;                    /* Copy of update mask used with pUpdate */
++  sqlite3_stmt *pUpdate;          /* Last update statement (or NULL) */
++  RbuUpdateStmt *pNext;
++};
++
++/*
++** An iterator of this type is used to iterate through all objects in
++** the target database that require updating. For each such table, the
++** iterator visits, in order:
++**
++**     * the table itself, 
++**     * each index of the table (zero or more points to visit), and
++**     * a special "cleanup table" state.
++**
++** abIndexed:
++**   If the table has no indexes on it, abIndexed is set to NULL. Otherwise,
++**   it points to an array of flags nTblCol elements in size. The flag is
++**   set for each column that is either a part of the PK or a part of an
++**   index. Or clear otherwise.
++**   
++*/
++struct RbuObjIter {
++  sqlite3_stmt *pTblIter;         /* Iterate through tables */
++  sqlite3_stmt *pIdxIter;         /* Index iterator */
++  int nTblCol;                    /* Size of azTblCol[] array */
++  char **azTblCol;                /* Array of unquoted target column names */
++  char **azTblType;               /* Array of target column types */
++  int *aiSrcOrder;                /* src table col -> target table col */
++  u8 *abTblPk;                    /* Array of flags, set on target PK columns */
++  u8 *abNotNull;                  /* Array of flags, set on NOT NULL columns */
++  u8 *abIndexed;                  /* Array of flags, set on indexed & PK cols */
++  int eType;                      /* Table type - an RBU_PK_XXX value */
++
++  /* Output variables. zTbl==0 implies EOF. */
++  int bCleanup;                   /* True in "cleanup" state */
++  const char *zTbl;               /* Name of target db table */
++  const char *zDataTbl;           /* Name of rbu db table (or null) */
++  const char *zIdx;               /* Name of target db index (or null) */
++  int iTnum;                      /* Root page of current object */
++  int iPkTnum;                    /* If eType==EXTERNAL, root of PK index */
++  int bUnique;                    /* Current index is unique */
++  int nIndex;                     /* Number of aux. indexes on table zTbl */
++
++  /* Statements created by rbuObjIterPrepareAll() */
++  int nCol;                       /* Number of columns in current object */
++  sqlite3_stmt *pSelect;          /* Source data */
++  sqlite3_stmt *pInsert;          /* Statement for INSERT operations */
++  sqlite3_stmt *pDelete;          /* Statement for DELETE ops */
++  sqlite3_stmt *pTmpInsert;       /* Insert into rbu_tmp_$zDataTbl */
++
++  /* Last UPDATE used (for PK b-tree updates only), or NULL. */
++  RbuUpdateStmt *pRbuUpdate;
++};
++
++/*
++** Values for RbuObjIter.eType
++**
++**     0: Table does not exist (error)
++**     1: Table has an implicit rowid.
++**     2: Table has an explicit IPK column.
++**     3: Table has an external PK index.
++**     4: Table is WITHOUT ROWID.
++**     5: Table is a virtual table.
++*/
++#define RBU_PK_NOTABLE        0
++#define RBU_PK_NONE           1
++#define RBU_PK_IPK            2
++#define RBU_PK_EXTERNAL       3
++#define RBU_PK_WITHOUT_ROWID  4
++#define RBU_PK_VTAB           5
++
++
++/*
++** Within the RBU_STAGE_OAL stage, each call to sqlite3rbu_step() performs
++** one of the following operations.
++*/
++#define RBU_INSERT     1          /* Insert on a main table b-tree */
++#define RBU_DELETE     2          /* Delete a row from a main table b-tree */
++#define RBU_REPLACE    3          /* Delete and then insert a row */
++#define RBU_IDX_DELETE 4          /* Delete a row from an aux. index b-tree */
++#define RBU_IDX_INSERT 5          /* Insert on an aux. index b-tree */
++
++#define RBU_UPDATE     6          /* Update a row in a main table b-tree */
++
++/*
++** A single step of an incremental checkpoint - frame iWalFrame of the wal
++** file should be copied to page iDbPage of the database file.
++*/
++struct RbuFrame {
++  u32 iDbPage;
++  u32 iWalFrame;
++};
++
++/*
++** RBU handle.
++**
++** nPhaseOneStep:
++**   If the RBU database contains an rbu_count table, this value is set to
++**   a running estimate of the number of b-tree operations required to 
++**   finish populating the *-oal file. This allows the sqlite3_bp_progress()
++**   API to calculate the permyriadage progress of populating the *-oal file
++**   using the formula:
++**
++**     permyriadage = (10000 * nProgress) / nPhaseOneStep
++**
++**   nPhaseOneStep is initialized to the sum of:
++**
++**     nRow * (nIndex + 1)
++**
++**   for all source tables in the RBU database, where nRow is the number
++**   of rows in the source table and nIndex the number of indexes on the
++**   corresponding target database table.
++**
++**   This estimate is accurate if the RBU update consists entirely of
++**   INSERT operations. However, it is inaccurate if:
++**
++**     * the RBU update contains any UPDATE operations. If the PK specified
++**       for an UPDATE operation does not exist in the target table, then
++**       no b-tree operations are required on index b-trees. Or if the 
++**       specified PK does exist, then (nIndex*2) such operations are
++**       required (one delete and one insert on each index b-tree).
++**
++**     * the RBU update contains any DELETE operations for which the specified
++**       PK does not exist. In this case no operations are required on index
++**       b-trees.
++**
++**     * the RBU update contains REPLACE operations. These are similar to
++**       UPDATE operations.
++**
++**   nPhaseOneStep is updated to account for the conditions above during the
++**   first pass of each source table. The updated nPhaseOneStep value is
++**   stored in the rbu_state table if the RBU update is suspended.
++*/
++struct sqlite3rbu {
++  int eStage;                     /* Value of RBU_STATE_STAGE field */
++  sqlite3 *dbMain;                /* target database handle */
++  sqlite3 *dbRbu;                 /* rbu database handle */
++  char *zTarget;                  /* Path to target db */
++  char *zRbu;                     /* Path to rbu db */
++  char *zState;                   /* Path to state db (or NULL if zRbu) */
++  char zStateDb[5];               /* Db name for state ("stat" or "main") */
++  int rc;                         /* Value returned by last rbu_step() call */
++  char *zErrmsg;                  /* Error message if rc!=SQLITE_OK */
++  int nStep;                      /* Rows processed for current object */
++  int nProgress;                  /* Rows processed for all objects */
++  RbuObjIter objiter;             /* Iterator for skipping through tbl/idx */
++  const char *zVfsName;           /* Name of automatically created rbu vfs */
++  rbu_file *pTargetFd;            /* File handle open on target db */
++  int nPagePerSector;             /* Pages per sector for pTargetFd */
++  i64 iOalSz;
++  i64 nPhaseOneStep;
++
++  /* The following state variables are used as part of the incremental
++  ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding
++  ** function rbuSetupCheckpoint() for details.  */
++  u32 iMaxFrame;                  /* Largest iWalFrame value in aFrame[] */
++  u32 mLock;
++  int nFrame;                     /* Entries in aFrame[] array */
++  int nFrameAlloc;                /* Allocated size of aFrame[] array */
++  RbuFrame *aFrame;
++  int pgsz;
++  u8 *aBuf;
++  i64 iWalCksum;
++
++  /* Used in RBU vacuum mode only */
++  int nRbu;                       /* Number of RBU VFS in the stack */
++  rbu_file *pRbuFd;               /* Fd for main db of dbRbu */
++};
++
++/*
++** An rbu VFS is implemented using an instance of this structure.
++*/
++struct rbu_vfs {
++  sqlite3_vfs base;               /* rbu VFS shim methods */
++  sqlite3_vfs *pRealVfs;          /* Underlying VFS */
++  sqlite3_mutex *mutex;           /* Mutex to protect pMain */
++  rbu_file *pMain;                /* Linked list of main db files */
++};
++
++/*
++** Each file opened by an rbu VFS is represented by an instance of
++** the following structure.
++*/
++struct rbu_file {
++  sqlite3_file base;              /* sqlite3_file methods */
++  sqlite3_file *pReal;            /* Underlying file handle */
++  rbu_vfs *pRbuVfs;               /* Pointer to the rbu_vfs object */
++  sqlite3rbu *pRbu;               /* Pointer to rbu object (rbu target only) */
++
++  int openFlags;                  /* Flags this file was opened with */
++  u32 iCookie;                    /* Cookie value for main db files */
++  u8 iWriteVer;                   /* "write-version" value for main db files */
++  u8 bNolock;                     /* True to fail EXCLUSIVE locks */
++
++  int nShm;                       /* Number of entries in apShm[] array */
++  char **apShm;                   /* Array of mmap'd *-shm regions */
++  char *zDel;                     /* Delete this when closing file */
++
++  const char *zWal;               /* Wal filename for this main db file */
++  rbu_file *pWalFd;               /* Wal file descriptor for this main db */
++  rbu_file *pMainNext;            /* Next MAIN_DB file */
++};
++
++/*
++** True for an RBU vacuum handle, or false otherwise.
++*/
++#define rbuIsVacuum(p) ((p)->zTarget==0)
++
++
++/*************************************************************************
++** The following three functions, found below:
++**
++**   rbuDeltaGetInt()
++**   rbuDeltaChecksum()
++**   rbuDeltaApply()
++**
++** are lifted from the fossil source code (http://fossil-scm.org). They
++** are used to implement the scalar SQL function rbu_fossil_delta().
++*/
++
++/*
++** Read bytes from *pz and convert them into a positive integer.  When
++** finished, leave *pz pointing to the first character past the end of
++** the integer.  The *pLen parameter holds the length of the string
++** in *pz and is decremented once for each character in the integer.
++*/
++static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){
++  static const signed char zValue[] = {
++    -1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1,
++    -1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1,
++    -1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1,
++     0,  1,  2,  3,  4,  5,  6,  7,    8,  9, -1, -1, -1, -1, -1, -1,
++    -1, 10, 11, 12, 13, 14, 15, 16,   17, 18, 19, 20, 21, 22, 23, 24,
++    25, 26, 27, 28, 29, 30, 31, 32,   33, 34, 35, -1, -1, -1, -1, 36,
++    -1, 37, 38, 39, 40, 41, 42, 43,   44, 45, 46, 47, 48, 49, 50, 51,
++    52, 53, 54, 55, 56, 57, 58, 59,   60, 61, 62, -1, -1, -1, 63, -1,
++  };
++  unsigned int v = 0;
++  int c;
++  unsigned char *z = (unsigned char*)*pz;
++  unsigned char *zStart = z;
++  while( (c = zValue[0x7f&*(z++)])>=0 ){
++     v = (v<<6) + c;
++  }
++  z--;
++  *pLen -= z - zStart;
++  *pz = (char*)z;
++  return v;
++}
++
++/*
++** Compute a 32-bit checksum on the N-byte buffer.  Return the result.
++*/
++static unsigned int rbuDeltaChecksum(const char *zIn, size_t N){
++  const unsigned char *z = (const unsigned char *)zIn;
++  unsigned sum0 = 0;
++  unsigned sum1 = 0;
++  unsigned sum2 = 0;
++  unsigned sum3 = 0;
++  while(N >= 16){
++    sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
++    sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
++    sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
++    sum3 += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
++    z += 16;
++    N -= 16;
++  }
++  while(N >= 4){
++    sum0 += z[0];
++    sum1 += z[1];
++    sum2 += z[2];
++    sum3 += z[3];
++    z += 4;
++    N -= 4;
++  }
++  sum3 += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
++  switch(N){
++    case 3:   sum3 += (z[2] << 8);
++    case 2:   sum3 += (z[1] << 16);
++    case 1:   sum3 += (z[0] << 24);
++    default:  ;
++  }
++  return sum3;
++}
++
++/*
++** Apply a delta.
++**
++** The output buffer should be big enough to hold the whole output
++** file and a NUL terminator at the end.  The delta_output_size()
++** routine will determine this size for you.
++**
++** The delta string should be null-terminated.  But the delta string
++** may contain embedded NUL characters (if the input and output are
++** binary files) so we also have to pass in the length of the delta in
++** the lenDelta parameter.
++**
++** This function returns the size of the output file in bytes (excluding
++** the final NUL terminator character).  Except, if the delta string is
++** malformed or intended for use with a source file other than zSrc,
++** then this routine returns -1.
++**
++** Refer to the delta_create() documentation above for a description
++** of the delta file format.
++*/
++static int rbuDeltaApply(
++  const char *zSrc,      /* The source or pattern file */
++  int lenSrc,            /* Length of the source file */
++  const char *zDelta,    /* Delta to apply to the pattern */
++  int lenDelta,          /* Length of the delta */
++  char *zOut             /* Write the output into this preallocated buffer */
++){
++  unsigned int limit;
++  unsigned int total = 0;
++#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST
++  char *zOrigOut = zOut;
++#endif
++
++  limit = rbuDeltaGetInt(&zDelta, &lenDelta);
++  if( *zDelta!='\n' ){
++    /* ERROR: size integer not terminated by "\n" */
++    return -1;
++  }
++  zDelta++; lenDelta--;
++  while( *zDelta && lenDelta>0 ){
++    unsigned int cnt, ofst;
++    cnt = rbuDeltaGetInt(&zDelta, &lenDelta);
++    switch( zDelta[0] ){
++      case '@': {
++        zDelta++; lenDelta--;
++        ofst = rbuDeltaGetInt(&zDelta, &lenDelta);
++        if( lenDelta>0 && zDelta[0]!=',' ){
++          /* ERROR: copy command not terminated by ',' */
++          return -1;
++        }
++        zDelta++; lenDelta--;
++        total += cnt;
++        if( total>limit ){
++          /* ERROR: copy exceeds output file size */
++          return -1;
++        }
++        if( (int)(ofst+cnt) > lenSrc ){
++          /* ERROR: copy extends past end of input */
++          return -1;
++        }
++        memcpy(zOut, &zSrc[ofst], cnt);
++        zOut += cnt;
++        break;
++      }
++      case ':': {
++        zDelta++; lenDelta--;
++        total += cnt;
++        if( total>limit ){
++          /* ERROR:  insert command gives an output larger than predicted */
++          return -1;
++        }
++        if( (int)cnt>lenDelta ){
++          /* ERROR: insert count exceeds size of delta */
++          return -1;
++        }
++        memcpy(zOut, zDelta, cnt);
++        zOut += cnt;
++        zDelta += cnt;
++        lenDelta -= cnt;
++        break;
++      }
++      case ';': {
++        zDelta++; lenDelta--;
++        zOut[0] = 0;
++#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST
++        if( cnt!=rbuDeltaChecksum(zOrigOut, total) ){
++          /* ERROR:  bad checksum */
++          return -1;
++        }
++#endif
++        if( total!=limit ){
++          /* ERROR: generated size does not match predicted size */
++          return -1;
++        }
++        return total;
++      }
++      default: {
++        /* ERROR: unknown delta operator */
++        return -1;
++      }
++    }
++  }
++  /* ERROR: unterminated delta */
++  return -1;
++}
++
++static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){
++  int size;
++  size = rbuDeltaGetInt(&zDelta, &lenDelta);
++  if( *zDelta!='\n' ){
++    /* ERROR: size integer not terminated by "\n" */
++    return -1;
++  }
++  return size;
++}
++
++/*
++** End of code taken from fossil.
++*************************************************************************/
++
++/*
++** Implementation of SQL scalar function rbu_fossil_delta().
++**
++** This function applies a fossil delta patch to a blob. Exactly two
++** arguments must be passed to this function. The first is the blob to
++** patch and the second the patch to apply. If no error occurs, this
++** function returns the patched blob.
++*/
++static void rbuFossilDeltaFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  const char *aDelta;
++  int nDelta;
++  const char *aOrig;
++  int nOrig;
++
++  int nOut;
++  int nOut2;
++  char *aOut;
++
++  assert( argc==2 );
++
++  nOrig = sqlite3_value_bytes(argv[0]);
++  aOrig = (const char*)sqlite3_value_blob(argv[0]);
++  nDelta = sqlite3_value_bytes(argv[1]);
++  aDelta = (const char*)sqlite3_value_blob(argv[1]);
++
++  /* Figure out the size of the output */
++  nOut = rbuDeltaOutputSize(aDelta, nDelta);
++  if( nOut<0 ){
++    sqlite3_result_error(context, "corrupt fossil delta", -1);
++    return;
++  }
++
++  aOut = sqlite3_malloc(nOut+1);
++  if( aOut==0 ){
++    sqlite3_result_error_nomem(context);
++  }else{
++    nOut2 = rbuDeltaApply(aOrig, nOrig, aDelta, nDelta, aOut);
++    if( nOut2!=nOut ){
++      sqlite3_result_error(context, "corrupt fossil delta", -1);
++    }else{
++      sqlite3_result_blob(context, aOut, nOut, sqlite3_free);
++    }
++  }
++}
++
++
++/*
++** Prepare the SQL statement in buffer zSql against database handle db.
++** If successful, set *ppStmt to point to the new statement and return
++** SQLITE_OK. 
++**
++** Otherwise, if an error does occur, set *ppStmt to NULL and return
++** an SQLite error code. Additionally, set output variable *pzErrmsg to
++** point to a buffer containing an error message. It is the responsibility
++** of the caller to (eventually) free this buffer using sqlite3_free().
++*/
++static int prepareAndCollectError(
++  sqlite3 *db, 
++  sqlite3_stmt **ppStmt,
++  char **pzErrmsg,
++  const char *zSql
++){
++  int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
++  if( rc!=SQLITE_OK ){
++    *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++    *ppStmt = 0;
++  }
++  return rc;
++}
++
++/*
++** Reset the SQL statement passed as the first argument. Return a copy
++** of the value returned by sqlite3_reset().
++**
++** If an error has occurred, then set *pzErrmsg to point to a buffer
++** containing an error message. It is the responsibility of the caller
++** to eventually free this buffer using sqlite3_free().
++*/
++static int resetAndCollectError(sqlite3_stmt *pStmt, char **pzErrmsg){
++  int rc = sqlite3_reset(pStmt);
++  if( rc!=SQLITE_OK ){
++    *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(sqlite3_db_handle(pStmt)));
++  }
++  return rc;
++}
++
++/*
++** Unless it is NULL, argument zSql points to a buffer allocated using
++** sqlite3_malloc containing an SQL statement. This function prepares the SQL
++** statement against database db and frees the buffer. If statement 
++** compilation is successful, *ppStmt is set to point to the new statement 
++** handle and SQLITE_OK is returned. 
++**
++** Otherwise, if an error occurs, *ppStmt is set to NULL and an error code
++** returned. In this case, *pzErrmsg may also be set to point to an error
++** message. It is the responsibility of the caller to free this error message
++** buffer using sqlite3_free().
++**
++** If argument zSql is NULL, this function assumes that an OOM has occurred.
++** In this case SQLITE_NOMEM is returned and *ppStmt set to NULL.
++*/
++static int prepareFreeAndCollectError(
++  sqlite3 *db, 
++  sqlite3_stmt **ppStmt,
++  char **pzErrmsg,
++  char *zSql
++){
++  int rc;
++  assert( *pzErrmsg==0 );
++  if( zSql==0 ){
++    rc = SQLITE_NOMEM;
++    *ppStmt = 0;
++  }else{
++    rc = prepareAndCollectError(db, ppStmt, pzErrmsg, zSql);
++    sqlite3_free(zSql);
++  }
++  return rc;
++}
++
++/*
++** Free the RbuObjIter.azTblCol[] and RbuObjIter.abTblPk[] arrays allocated
++** by an earlier call to rbuObjIterCacheTableInfo().
++*/
++static void rbuObjIterFreeCols(RbuObjIter *pIter){
++  int i;
++  for(i=0; i<pIter->nTblCol; i++){
++    sqlite3_free(pIter->azTblCol[i]);
++    sqlite3_free(pIter->azTblType[i]);
++  }
++  sqlite3_free(pIter->azTblCol);
++  pIter->azTblCol = 0;
++  pIter->azTblType = 0;
++  pIter->aiSrcOrder = 0;
++  pIter->abTblPk = 0;
++  pIter->abNotNull = 0;
++  pIter->nTblCol = 0;
++  pIter->eType = 0;               /* Invalid value */
++}
++
++/*
++** Finalize all statements and free all allocations that are specific to
++** the current object (table/index pair).
++*/
++static void rbuObjIterClearStatements(RbuObjIter *pIter){
++  RbuUpdateStmt *pUp;
++
++  sqlite3_finalize(pIter->pSelect);
++  sqlite3_finalize(pIter->pInsert);
++  sqlite3_finalize(pIter->pDelete);
++  sqlite3_finalize(pIter->pTmpInsert);
++  pUp = pIter->pRbuUpdate;
++  while( pUp ){
++    RbuUpdateStmt *pTmp = pUp->pNext;
++    sqlite3_finalize(pUp->pUpdate);
++    sqlite3_free(pUp);
++    pUp = pTmp;
++  }
++  
++  pIter->pSelect = 0;
++  pIter->pInsert = 0;
++  pIter->pDelete = 0;
++  pIter->pRbuUpdate = 0;
++  pIter->pTmpInsert = 0;
++  pIter->nCol = 0;
++}
++
++/*
++** Clean up any resources allocated as part of the iterator object passed
++** as the only argument.
++*/
++static void rbuObjIterFinalize(RbuObjIter *pIter){
++  rbuObjIterClearStatements(pIter);
++  sqlite3_finalize(pIter->pTblIter);
++  sqlite3_finalize(pIter->pIdxIter);
++  rbuObjIterFreeCols(pIter);
++  memset(pIter, 0, sizeof(RbuObjIter));
++}
++
++/*
++** Advance the iterator to the next position.
++**
++** If no error occurs, SQLITE_OK is returned and the iterator is left 
++** pointing to the next entry. Otherwise, an error code and message is 
++** left in the RBU handle passed as the first argument. A copy of the 
++** error code is returned.
++*/
++static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){
++  int rc = p->rc;
++  if( rc==SQLITE_OK ){
++
++    /* Free any SQLite statements used while processing the previous object */ 
++    rbuObjIterClearStatements(pIter);
++    if( pIter->zIdx==0 ){
++      rc = sqlite3_exec(p->dbMain,
++          "DROP TRIGGER IF EXISTS temp.rbu_insert_tr;"
++          "DROP TRIGGER IF EXISTS temp.rbu_update1_tr;"
++          "DROP TRIGGER IF EXISTS temp.rbu_update2_tr;"
++          "DROP TRIGGER IF EXISTS temp.rbu_delete_tr;"
++          , 0, 0, &p->zErrmsg
++      );
++    }
++
++    if( rc==SQLITE_OK ){
++      if( pIter->bCleanup ){
++        rbuObjIterFreeCols(pIter);
++        pIter->bCleanup = 0;
++        rc = sqlite3_step(pIter->pTblIter);
++        if( rc!=SQLITE_ROW ){
++          rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg);
++          pIter->zTbl = 0;
++        }else{
++          pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0);
++          pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1);
++          rc = (pIter->zDataTbl && pIter->zTbl) ? SQLITE_OK : SQLITE_NOMEM;
++        }
++      }else{
++        if( pIter->zIdx==0 ){
++          sqlite3_stmt *pIdx = pIter->pIdxIter;
++          rc = sqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC);
++        }
++        if( rc==SQLITE_OK ){
++          rc = sqlite3_step(pIter->pIdxIter);
++          if( rc!=SQLITE_ROW ){
++            rc = resetAndCollectError(pIter->pIdxIter, &p->zErrmsg);
++            pIter->bCleanup = 1;
++            pIter->zIdx = 0;
++          }else{
++            pIter->zIdx = (const char*)sqlite3_column_text(pIter->pIdxIter, 0);
++            pIter->iTnum = sqlite3_column_int(pIter->pIdxIter, 1);
++            pIter->bUnique = sqlite3_column_int(pIter->pIdxIter, 2);
++            rc = pIter->zIdx ? SQLITE_OK : SQLITE_NOMEM;
++          }
++        }
++      }
++    }
++  }
++
++  if( rc!=SQLITE_OK ){
++    rbuObjIterFinalize(pIter);
++    p->rc = rc;
++  }
++  return rc;
++}
++
++
++/*
++** The implementation of the rbu_target_name() SQL function. This function
++** accepts one or two arguments. The first argument is the name of a table -
++** the name of a table in the RBU database.  The second, if it is present, is 1
++** for a view or 0 for a table. 
++**
++** For a non-vacuum RBU handle, if the table name matches the pattern:
++**
++**     data[0-9]_<name>
++**
++** where <name> is any sequence of 1 or more characters, <name> is returned.
++** Otherwise, if the only argument does not match the above pattern, an SQL
++** NULL is returned.
++**
++**     "data_t1"     -> "t1"
++**     "data0123_t2" -> "t2"
++**     "dataAB_t3"   -> NULL
++**
++** For an rbu vacuum handle, a copy of the first argument is returned if
++** the second argument is either missing or 0 (not a view).
++*/
++static void rbuTargetNameFunc(
++  sqlite3_context *pCtx,
++  int argc,
++  sqlite3_value **argv
++){
++  sqlite3rbu *p = sqlite3_user_data(pCtx);
++  const char *zIn;
++  assert( argc==1 || argc==2 );
++
++  zIn = (const char*)sqlite3_value_text(argv[0]);
++  if( zIn ){
++    if( rbuIsVacuum(p) ){
++      if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
++        sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
++      }
++    }else{
++      if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
++        int i;
++        for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++);
++        if( zIn[i]=='_' && zIn[i+1] ){
++          sqlite3_result_text(pCtx, &zIn[i+1], -1, SQLITE_STATIC);
++        }
++      }
++    }
++  }
++}
++
++/*
++** Initialize the iterator structure passed as the second argument.
++**
++** If no error occurs, SQLITE_OK is returned and the iterator is left 
++** pointing to the first entry. Otherwise, an error code and message is 
++** left in the RBU handle passed as the first argument. A copy of the 
++** error code is returned.
++*/
++static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){
++  int rc;
++  memset(pIter, 0, sizeof(RbuObjIter));
++
++  rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, 
++    sqlite3_mprintf(
++      "SELECT rbu_target_name(name, type='view') AS target, name "
++      "FROM sqlite_master "
++      "WHERE type IN ('table', 'view') AND target IS NOT NULL "
++      " %s "
++      "ORDER BY name"
++  , rbuIsVacuum(p) ? "AND rootpage!=0 AND rootpage IS NOT NULL" : ""));
++
++  if( rc==SQLITE_OK ){
++    rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg,
++        "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' "
++        "  FROM main.sqlite_master "
++        "  WHERE type='index' AND tbl_name = ?"
++    );
++  }
++
++  pIter->bCleanup = 1;
++  p->rc = rc;
++  return rbuObjIterNext(p, pIter);
++}
++
++/*
++** This is a wrapper around "sqlite3_mprintf(zFmt, ...)". If an OOM occurs,
++** an error code is stored in the RBU handle passed as the first argument.
++**
++** If an error has already occurred (p->rc is already set to something other
++** than SQLITE_OK), then this function returns NULL without modifying the
++** stored error code. In this case it still calls sqlite3_free() on any 
++** printf() parameters associated with %z conversions.
++*/
++static char *rbuMPrintf(sqlite3rbu *p, const char *zFmt, ...){
++  char *zSql = 0;
++  va_list ap;
++  va_start(ap, zFmt);
++  zSql = sqlite3_vmprintf(zFmt, ap);
++  if( p->rc==SQLITE_OK ){
++    if( zSql==0 ) p->rc = SQLITE_NOMEM;
++  }else{
++    sqlite3_free(zSql);
++    zSql = 0;
++  }
++  va_end(ap);
++  return zSql;
++}
++
++/*
++** Argument zFmt is a sqlite3_mprintf() style format string. The trailing
++** arguments are the usual subsitution values. This function performs
++** the printf() style substitutions and executes the result as an SQL
++** statement on the RBU handles database.
++**
++** If an error occurs, an error code and error message is stored in the
++** RBU handle. If an error has already occurred when this function is
++** called, it is a no-op.
++*/
++static int rbuMPrintfExec(sqlite3rbu *p, sqlite3 *db, const char *zFmt, ...){
++  va_list ap;
++  char *zSql;
++  va_start(ap, zFmt);
++  zSql = sqlite3_vmprintf(zFmt, ap);
++  if( p->rc==SQLITE_OK ){
++    if( zSql==0 ){
++      p->rc = SQLITE_NOMEM;
++    }else{
++      p->rc = sqlite3_exec(db, zSql, 0, 0, &p->zErrmsg);
++    }
++  }
++  sqlite3_free(zSql);
++  va_end(ap);
++  return p->rc;
++}
++
++/*
++** Attempt to allocate and return a pointer to a zeroed block of nByte 
++** bytes. 
++**
++** If an error (i.e. an OOM condition) occurs, return NULL and leave an 
++** error code in the rbu handle passed as the first argument. Or, if an 
++** error has already occurred when this function is called, return NULL 
++** immediately without attempting the allocation or modifying the stored
++** error code.
++*/
++static void *rbuMalloc(sqlite3rbu *p, int nByte){
++  void *pRet = 0;
++  if( p->rc==SQLITE_OK ){
++    assert( nByte>0 );
++    pRet = sqlite3_malloc64(nByte);
++    if( pRet==0 ){
++      p->rc = SQLITE_NOMEM;
++    }else{
++      memset(pRet, 0, nByte);
++    }
++  }
++  return pRet;
++}
++
++
++/*
++** Allocate and zero the pIter->azTblCol[] and abTblPk[] arrays so that
++** there is room for at least nCol elements. If an OOM occurs, store an
++** error code in the RBU handle passed as the first argument.
++*/
++static void rbuAllocateIterArrays(sqlite3rbu *p, RbuObjIter *pIter, int nCol){
++  int nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol;
++  char **azNew;
++
++  azNew = (char**)rbuMalloc(p, nByte);
++  if( azNew ){
++    pIter->azTblCol = azNew;
++    pIter->azTblType = &azNew[nCol];
++    pIter->aiSrcOrder = (int*)&pIter->azTblType[nCol];
++    pIter->abTblPk = (u8*)&pIter->aiSrcOrder[nCol];
++    pIter->abNotNull = (u8*)&pIter->abTblPk[nCol];
++    pIter->abIndexed = (u8*)&pIter->abNotNull[nCol];
++  }
++}
++
++/*
++** The first argument must be a nul-terminated string. This function
++** returns a copy of the string in memory obtained from sqlite3_malloc().
++** It is the responsibility of the caller to eventually free this memory
++** using sqlite3_free().
++**
++** If an OOM condition is encountered when attempting to allocate memory,
++** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise,
++** if the allocation succeeds, (*pRc) is left unchanged.
++*/
++static char *rbuStrndup(const char *zStr, int *pRc){
++  char *zRet = 0;
++
++  assert( *pRc==SQLITE_OK );
++  if( zStr ){
++    size_t nCopy = strlen(zStr) + 1;
++    zRet = (char*)sqlite3_malloc64(nCopy);
++    if( zRet ){
++      memcpy(zRet, zStr, nCopy);
++    }else{
++      *pRc = SQLITE_NOMEM;
++    }
++  }
++
++  return zRet;
++}
++
++/*
++** Finalize the statement passed as the second argument.
++**
++** If the sqlite3_finalize() call indicates that an error occurs, and the
++** rbu handle error code is not already set, set the error code and error
++** message accordingly.
++*/
++static void rbuFinalize(sqlite3rbu *p, sqlite3_stmt *pStmt){
++  sqlite3 *db = sqlite3_db_handle(pStmt);
++  int rc = sqlite3_finalize(pStmt);
++  if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){
++    p->rc = rc;
++    p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++  }
++}
++
++/* Determine the type of a table.
++**
++**   peType is of type (int*), a pointer to an output parameter of type
++**   (int). This call sets the output parameter as follows, depending
++**   on the type of the table specified by parameters dbName and zTbl.
++**
++**     RBU_PK_NOTABLE:       No such table.
++**     RBU_PK_NONE:          Table has an implicit rowid.
++**     RBU_PK_IPK:           Table has an explicit IPK column.
++**     RBU_PK_EXTERNAL:      Table has an external PK index.
++**     RBU_PK_WITHOUT_ROWID: Table is WITHOUT ROWID.
++**     RBU_PK_VTAB:          Table is a virtual table.
++**
++**   Argument *piPk is also of type (int*), and also points to an output
++**   parameter. Unless the table has an external primary key index 
++**   (i.e. unless *peType is set to 3), then *piPk is set to zero. Or,
++**   if the table does have an external primary key index, then *piPk
++**   is set to the root page number of the primary key index before
++**   returning.
++**
++** ALGORITHM:
++**
++**   if( no entry exists in sqlite_master ){
++**     return RBU_PK_NOTABLE
++**   }else if( sql for the entry starts with "CREATE VIRTUAL" ){
++**     return RBU_PK_VTAB
++**   }else if( "PRAGMA index_list()" for the table contains a "pk" index ){
++**     if( the index that is the pk exists in sqlite_master ){
++**       *piPK = rootpage of that index.
++**       return RBU_PK_EXTERNAL
++**     }else{
++**       return RBU_PK_WITHOUT_ROWID
++**     }
++**   }else if( "PRAGMA table_info()" lists one or more "pk" columns ){
++**     return RBU_PK_IPK
++**   }else{
++**     return RBU_PK_NONE
++**   }
++*/
++static void rbuTableType(
++  sqlite3rbu *p,
++  const char *zTab,
++  int *peType,
++  int *piTnum,
++  int *piPk
++){
++  /*
++  ** 0) SELECT count(*) FROM sqlite_master where name=%Q AND IsVirtual(%Q)
++  ** 1) PRAGMA index_list = ?
++  ** 2) SELECT count(*) FROM sqlite_master where name=%Q 
++  ** 3) PRAGMA table_info = ?
++  */
++  sqlite3_stmt *aStmt[4] = {0, 0, 0, 0};
++
++  *peType = RBU_PK_NOTABLE;
++  *piPk = 0;
++
++  assert( p->rc==SQLITE_OK );
++  p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg, 
++    sqlite3_mprintf(
++          "SELECT (sql LIKE 'create virtual%%'), rootpage"
++          "  FROM sqlite_master"
++          " WHERE name=%Q", zTab
++  ));
++  if( p->rc!=SQLITE_OK || sqlite3_step(aStmt[0])!=SQLITE_ROW ){
++    /* Either an error, or no such table. */
++    goto rbuTableType_end;
++  }
++  if( sqlite3_column_int(aStmt[0], 0) ){
++    *peType = RBU_PK_VTAB;                     /* virtual table */
++    goto rbuTableType_end;
++  }
++  *piTnum = sqlite3_column_int(aStmt[0], 1);
++
++  p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[1], &p->zErrmsg, 
++    sqlite3_mprintf("PRAGMA index_list=%Q",zTab)
++  );
++  if( p->rc ) goto rbuTableType_end;
++  while( sqlite3_step(aStmt[1])==SQLITE_ROW ){
++    const u8 *zOrig = sqlite3_column_text(aStmt[1], 3);
++    const u8 *zIdx = sqlite3_column_text(aStmt[1], 1);
++    if( zOrig && zIdx && zOrig[0]=='p' ){
++      p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[2], &p->zErrmsg, 
++          sqlite3_mprintf(
++            "SELECT rootpage FROM sqlite_master WHERE name = %Q", zIdx
++      ));
++      if( p->rc==SQLITE_OK ){
++        if( sqlite3_step(aStmt[2])==SQLITE_ROW ){
++          *piPk = sqlite3_column_int(aStmt[2], 0);
++          *peType = RBU_PK_EXTERNAL;
++        }else{
++          *peType = RBU_PK_WITHOUT_ROWID;
++        }
++      }
++      goto rbuTableType_end;
++    }
++  }
++
++  p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[3], &p->zErrmsg, 
++    sqlite3_mprintf("PRAGMA table_info=%Q",zTab)
++  );
++  if( p->rc==SQLITE_OK ){
++    while( sqlite3_step(aStmt[3])==SQLITE_ROW ){
++      if( sqlite3_column_int(aStmt[3],5)>0 ){
++        *peType = RBU_PK_IPK;                /* explicit IPK column */
++        goto rbuTableType_end;
++      }
++    }
++    *peType = RBU_PK_NONE;
++  }
++
++rbuTableType_end: {
++    unsigned int i;
++    for(i=0; i<sizeof(aStmt)/sizeof(aStmt[0]); i++){
++      rbuFinalize(p, aStmt[i]);
++    }
++  }
++}
++
++/*
++** This is a helper function for rbuObjIterCacheTableInfo(). It populates
++** the pIter->abIndexed[] array.
++*/
++static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){
++  sqlite3_stmt *pList = 0;
++  int bIndex = 0;
++
++  if( p->rc==SQLITE_OK ){
++    memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol);
++    p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg,
++        sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
++    );
++  }
++
++  pIter->nIndex = 0;
++  while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
++    const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
++    sqlite3_stmt *pXInfo = 0;
++    if( zIdx==0 ) break;
++    p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
++        sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
++    );
++    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
++      int iCid = sqlite3_column_int(pXInfo, 1);
++      if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
++    }
++    rbuFinalize(p, pXInfo);
++    bIndex = 1;
++    pIter->nIndex++;
++  }
++
++  if( pIter->eType==RBU_PK_WITHOUT_ROWID ){
++    /* "PRAGMA index_list" includes the main PK b-tree */
++    pIter->nIndex--;
++  }
++
++  rbuFinalize(p, pList);
++  if( bIndex==0 ) pIter->abIndexed = 0;
++}
++
++
++/*
++** If they are not already populated, populate the pIter->azTblCol[],
++** pIter->abTblPk[], pIter->nTblCol and pIter->bRowid variables according to
++** the table (not index) that the iterator currently points to.
++**
++** Return SQLITE_OK if successful, or an SQLite error code otherwise. If
++** an error does occur, an error code and error message are also left in 
++** the RBU handle.
++*/
++static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
++  if( pIter->azTblCol==0 ){
++    sqlite3_stmt *pStmt = 0;
++    int nCol = 0;
++    int i;                        /* for() loop iterator variable */
++    int bRbuRowid = 0;            /* If input table has column "rbu_rowid" */
++    int iOrder = 0;
++    int iTnum = 0;
++
++    /* Figure out the type of table this step will deal with. */
++    assert( pIter->eType==0 );
++    rbuTableType(p, pIter->zTbl, &pIter->eType, &iTnum, &pIter->iPkTnum);
++    if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_NOTABLE ){
++      p->rc = SQLITE_ERROR;
++      p->zErrmsg = sqlite3_mprintf("no such table: %s", pIter->zTbl);
++    }
++    if( p->rc ) return p->rc;
++    if( pIter->zIdx==0 ) pIter->iTnum = iTnum;
++
++    assert( pIter->eType==RBU_PK_NONE || pIter->eType==RBU_PK_IPK 
++         || pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_WITHOUT_ROWID
++         || pIter->eType==RBU_PK_VTAB
++    );
++
++    /* Populate the azTblCol[] and nTblCol variables based on the columns
++    ** of the input table. Ignore any input table columns that begin with
++    ** "rbu_".  */
++    p->rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, 
++        sqlite3_mprintf("SELECT * FROM '%q'", pIter->zDataTbl)
++    );
++    if( p->rc==SQLITE_OK ){
++      nCol = sqlite3_column_count(pStmt);
++      rbuAllocateIterArrays(p, pIter, nCol);
++    }
++    for(i=0; p->rc==SQLITE_OK && i<nCol; i++){
++      const char *zName = (const char*)sqlite3_column_name(pStmt, i);
++      if( sqlite3_strnicmp("rbu_", zName, 4) ){
++        char *zCopy = rbuStrndup(zName, &p->rc);
++        pIter->aiSrcOrder[pIter->nTblCol] = pIter->nTblCol;
++        pIter->azTblCol[pIter->nTblCol++] = zCopy;
++      }
++      else if( 0==sqlite3_stricmp("rbu_rowid", zName) ){
++        bRbuRowid = 1;
++      }
++    }
++    sqlite3_finalize(pStmt);
++    pStmt = 0;
++
++    if( p->rc==SQLITE_OK
++     && rbuIsVacuum(p)==0
++     && bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
++    ){
++      p->rc = SQLITE_ERROR;
++      p->zErrmsg = sqlite3_mprintf(
++          "table %q %s rbu_rowid column", pIter->zDataTbl,
++          (bRbuRowid ? "may not have" : "requires")
++      );
++    }
++
++    /* Check that all non-HIDDEN columns in the destination table are also
++    ** present in the input table. Populate the abTblPk[], azTblType[] and
++    ** aiTblOrder[] arrays at the same time.  */
++    if( p->rc==SQLITE_OK ){
++      p->rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, 
++          sqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl)
++      );
++    }
++    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
++      const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
++      if( zName==0 ) break;  /* An OOM - finalize() below returns S_NOMEM */
++      for(i=iOrder; i<pIter->nTblCol; i++){
++        if( 0==strcmp(zName, pIter->azTblCol[i]) ) break;
++      }
++      if( i==pIter->nTblCol ){
++        p->rc = SQLITE_ERROR;
++        p->zErrmsg = sqlite3_mprintf("column missing from %q: %s",
++            pIter->zDataTbl, zName
++        );
++      }else{
++        int iPk = sqlite3_column_int(pStmt, 5);
++        int bNotNull = sqlite3_column_int(pStmt, 3);
++        const char *zType = (const char*)sqlite3_column_text(pStmt, 2);
++
++        if( i!=iOrder ){
++          SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]);
++          SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]);
++        }
++
++        pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
++        pIter->abTblPk[iOrder] = (iPk!=0);
++        pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
++        iOrder++;
++      }
++    }
++
++    rbuFinalize(p, pStmt);
++    rbuObjIterCacheIndexedCols(p, pIter);
++    assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 );
++    assert( pIter->eType!=RBU_PK_VTAB || pIter->nIndex==0 );
++  }
++
++  return p->rc;
++}
++
++/*
++** This function constructs and returns a pointer to a nul-terminated 
++** string containing some SQL clause or list based on one or more of the 
++** column names currently stored in the pIter->azTblCol[] array.
++*/
++static char *rbuObjIterGetCollist(
++  sqlite3rbu *p,                  /* RBU object */
++  RbuObjIter *pIter               /* Object iterator for column names */
++){
++  char *zList = 0;
++  const char *zSep = "";
++  int i;
++  for(i=0; i<pIter->nTblCol; i++){
++    const char *z = pIter->azTblCol[i];
++    zList = rbuMPrintf(p, "%z%s\"%w\"", zList, zSep, z);
++    zSep = ", ";
++  }
++  return zList;
++}
++
++/*
++** This function is used to create a SELECT list (the list of SQL 
++** expressions that follows a SELECT keyword) for a SELECT statement 
++** used to read from an data_xxx or rbu_tmp_xxx table while updating the 
++** index object currently indicated by the iterator object passed as the 
++** second argument. A "PRAGMA index_xinfo = <idxname>" statement is used 
++** to obtain the required information.
++**
++** If the index is of the following form:
++**
++**   CREATE INDEX i1 ON t1(c, b COLLATE nocase);
++**
++** and "t1" is a table with an explicit INTEGER PRIMARY KEY column 
++** "ipk", the returned string is:
++**
++**   "`c` COLLATE 'BINARY', `b` COLLATE 'NOCASE', `ipk` COLLATE 'BINARY'"
++**
++** As well as the returned string, three other malloc'd strings are 
++** returned via output parameters. As follows:
++**
++**   pzImposterCols: ...
++**   pzImposterPk: ...
++**   pzWhere: ...
++*/
++static char *rbuObjIterGetIndexCols(
++  sqlite3rbu *p,                  /* RBU object */
++  RbuObjIter *pIter,              /* Object iterator for column names */
++  char **pzImposterCols,          /* OUT: Columns for imposter table */
++  char **pzImposterPk,            /* OUT: Imposter PK clause */
++  char **pzWhere,                 /* OUT: WHERE clause */
++  int *pnBind                     /* OUT: Trbul number of columns */
++){
++  int rc = p->rc;                 /* Error code */
++  int rc2;                        /* sqlite3_finalize() return code */
++  char *zRet = 0;                 /* String to return */
++  char *zImpCols = 0;             /* String to return via *pzImposterCols */
++  char *zImpPK = 0;               /* String to return via *pzImposterPK */
++  char *zWhere = 0;               /* String to return via *pzWhere */
++  int nBind = 0;                  /* Value to return via *pnBind */
++  const char *zCom = "";          /* Set to ", " later on */
++  const char *zAnd = "";          /* Set to " AND " later on */
++  sqlite3_stmt *pXInfo = 0;       /* PRAGMA index_xinfo = ? */
++
++  if( rc==SQLITE_OK ){
++    assert( p->zErrmsg==0 );
++    rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
++        sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
++    );
++  }
++
++  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
++    int iCid = sqlite3_column_int(pXInfo, 1);
++    int bDesc = sqlite3_column_int(pXInfo, 3);
++    const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
++    const char *zCol;
++    const char *zType;
++
++    if( iCid<0 ){
++      /* An integer primary key. If the table has an explicit IPK, use
++      ** its name. Otherwise, use "rbu_rowid".  */
++      if( pIter->eType==RBU_PK_IPK ){
++        int i;
++        for(i=0; pIter->abTblPk[i]==0; i++);
++        assert( i<pIter->nTblCol );
++        zCol = pIter->azTblCol[i];
++      }else if( rbuIsVacuum(p) ){
++        zCol = "_rowid_";
++      }else{
++        zCol = "rbu_rowid";
++      }
++      zType = "INTEGER";
++    }else{
++      zCol = pIter->azTblCol[iCid];
++      zType = pIter->azTblType[iCid];
++    }
++
++    zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate);
++    if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){
++      const char *zOrder = (bDesc ? " DESC" : "");
++      zImpPK = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\"%s", 
++          zImpPK, zCom, nBind, zCol, zOrder
++      );
++    }
++    zImpCols = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\" %s COLLATE %Q", 
++        zImpCols, zCom, nBind, zCol, zType, zCollate
++    );
++    zWhere = sqlite3_mprintf(
++        "%z%s\"rbu_imp_%d%w\" IS ?", zWhere, zAnd, nBind, zCol
++    );
++    if( zRet==0 || zImpPK==0 || zImpCols==0 || zWhere==0 ) rc = SQLITE_NOMEM;
++    zCom = ", ";
++    zAnd = " AND ";
++    nBind++;
++  }
++
++  rc2 = sqlite3_finalize(pXInfo);
++  if( rc==SQLITE_OK ) rc = rc2;
++
++  if( rc!=SQLITE_OK ){
++    sqlite3_free(zRet);
++    sqlite3_free(zImpCols);
++    sqlite3_free(zImpPK);
++    sqlite3_free(zWhere);
++    zRet = 0;
++    zImpCols = 0;
++    zImpPK = 0;
++    zWhere = 0;
++    p->rc = rc;
++  }
++
++  *pzImposterCols = zImpCols;
++  *pzImposterPk = zImpPK;
++  *pzWhere = zWhere;
++  *pnBind = nBind;
++  return zRet;
++}
++
++/*
++** Assuming the current table columns are "a", "b" and "c", and the zObj
++** paramter is passed "old", return a string of the form:
++**
++**     "old.a, old.b, old.b"
++**
++** With the column names escaped.
++**
++** For tables with implicit rowids - RBU_PK_EXTERNAL and RBU_PK_NONE, append
++** the text ", old._rowid_" to the returned value.
++*/
++static char *rbuObjIterGetOldlist(
++  sqlite3rbu *p, 
++  RbuObjIter *pIter,
++  const char *zObj
++){
++  char *zList = 0;
++  if( p->rc==SQLITE_OK && pIter->abIndexed ){
++    const char *zS = "";
++    int i;
++    for(i=0; i<pIter->nTblCol; i++){
++      if( pIter->abIndexed[i] ){
++        const char *zCol = pIter->azTblCol[i];
++        zList = sqlite3_mprintf("%z%s%s.\"%w\"", zList, zS, zObj, zCol);
++      }else{
++        zList = sqlite3_mprintf("%z%sNULL", zList, zS);
++      }
++      zS = ", ";
++      if( zList==0 ){
++        p->rc = SQLITE_NOMEM;
++        break;
++      }
++    }
++
++    /* For a table with implicit rowids, append "old._rowid_" to the list. */
++    if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
++      zList = rbuMPrintf(p, "%z, %s._rowid_", zList, zObj);
++    }
++  }
++  return zList;
++}
++
++/*
++** Return an expression that can be used in a WHERE clause to match the
++** primary key of the current table. For example, if the table is:
++**
++**   CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c));
++**
++** Return the string:
++**
++**   "b = ?1 AND c = ?2"
++*/
++static char *rbuObjIterGetWhere(
++  sqlite3rbu *p, 
++  RbuObjIter *pIter
++){
++  char *zList = 0;
++  if( pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE ){
++    zList = rbuMPrintf(p, "_rowid_ = ?%d", pIter->nTblCol+1);
++  }else if( pIter->eType==RBU_PK_EXTERNAL ){
++    const char *zSep = "";
++    int i;
++    for(i=0; i<pIter->nTblCol; i++){
++      if( pIter->abTblPk[i] ){
++        zList = rbuMPrintf(p, "%z%sc%d=?%d", zList, zSep, i, i+1);
++        zSep = " AND ";
++      }
++    }
++    zList = rbuMPrintf(p, 
++        "_rowid_ = (SELECT id FROM rbu_imposter2 WHERE %z)", zList
++    );
++
++  }else{
++    const char *zSep = "";
++    int i;
++    for(i=0; i<pIter->nTblCol; i++){
++      if( pIter->abTblPk[i] ){
++        const char *zCol = pIter->azTblCol[i];
++        zList = rbuMPrintf(p, "%z%s\"%w\"=?%d", zList, zSep, zCol, i+1);
++        zSep = " AND ";
++      }
++    }
++  }
++  return zList;
++}
++
++/*
++** The SELECT statement iterating through the keys for the current object
++** (p->objiter.pSelect) currently points to a valid row. However, there
++** is something wrong with the rbu_control value in the rbu_control value
++** stored in the (p->nCol+1)'th column. Set the error code and error message
++** of the RBU handle to something reflecting this.
++*/
++static void rbuBadControlError(sqlite3rbu *p){
++  p->rc = SQLITE_ERROR;
++  p->zErrmsg = sqlite3_mprintf("invalid rbu_control value");
++}
++
++
++/*
++** Return a nul-terminated string containing the comma separated list of
++** assignments that should be included following the "SET" keyword of
++** an UPDATE statement used to update the table object that the iterator
++** passed as the second argument currently points to if the rbu_control
++** column of the data_xxx table entry is set to zMask.
++**
++** The memory for the returned string is obtained from sqlite3_malloc().
++** It is the responsibility of the caller to eventually free it using
++** sqlite3_free(). 
++**
++** If an OOM error is encountered when allocating space for the new
++** string, an error code is left in the rbu handle passed as the first
++** argument and NULL is returned. Or, if an error has already occurred
++** when this function is called, NULL is returned immediately, without
++** attempting the allocation or modifying the stored error code.
++*/
++static char *rbuObjIterGetSetlist(
++  sqlite3rbu *p,
++  RbuObjIter *pIter,
++  const char *zMask
++){
++  char *zList = 0;
++  if( p->rc==SQLITE_OK ){
++    int i;
++
++    if( (int)strlen(zMask)!=pIter->nTblCol ){
++      rbuBadControlError(p);
++    }else{
++      const char *zSep = "";
++      for(i=0; i<pIter->nTblCol; i++){
++        char c = zMask[pIter->aiSrcOrder[i]];
++        if( c=='x' ){
++          zList = rbuMPrintf(p, "%z%s\"%w\"=?%d", 
++              zList, zSep, pIter->azTblCol[i], i+1
++          );
++          zSep = ", ";
++        }
++        else if( c=='d' ){
++          zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_delta(\"%w\", ?%d)", 
++              zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1
++          );
++          zSep = ", ";
++        }
++        else if( c=='f' ){
++          zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_fossil_delta(\"%w\", ?%d)", 
++              zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1
++          );
++          zSep = ", ";
++        }
++      }
++    }
++  }
++  return zList;
++}
++
++/*
++** Return a nul-terminated string consisting of nByte comma separated
++** "?" expressions. For example, if nByte is 3, return a pointer to
++** a buffer containing the string "?,?,?".
++**
++** The memory for the returned string is obtained from sqlite3_malloc().
++** It is the responsibility of the caller to eventually free it using
++** sqlite3_free(). 
++**
++** If an OOM error is encountered when allocating space for the new
++** string, an error code is left in the rbu handle passed as the first
++** argument and NULL is returned. Or, if an error has already occurred
++** when this function is called, NULL is returned immediately, without
++** attempting the allocation or modifying the stored error code.
++*/
++static char *rbuObjIterGetBindlist(sqlite3rbu *p, int nBind){
++  char *zRet = 0;
++  int nByte = nBind*2 + 1;
++
++  zRet = (char*)rbuMalloc(p, nByte);
++  if( zRet ){
++    int i;
++    for(i=0; i<nBind; i++){
++      zRet[i*2] = '?';
++      zRet[i*2+1] = (i+1==nBind) ? '\0' : ',';
++    }
++  }
++  return zRet;
++}
++
++/*
++** The iterator currently points to a table (not index) of type 
++** RBU_PK_WITHOUT_ROWID. This function creates the PRIMARY KEY 
++** declaration for the corresponding imposter table. For example,
++** if the iterator points to a table created as:
++**
++**   CREATE TABLE t1(a, b, c, PRIMARY KEY(b, a DESC)) WITHOUT ROWID
++**
++** this function returns:
++**
++**   PRIMARY KEY("b", "a" DESC)
++*/
++static char *rbuWithoutRowidPK(sqlite3rbu *p, RbuObjIter *pIter){
++  char *z = 0;
++  assert( pIter->zIdx==0 );
++  if( p->rc==SQLITE_OK ){
++    const char *zSep = "PRIMARY KEY(";
++    sqlite3_stmt *pXList = 0;     /* PRAGMA index_list = (pIter->zTbl) */
++    sqlite3_stmt *pXInfo = 0;     /* PRAGMA index_xinfo = <pk-index> */
++   
++    p->rc = prepareFreeAndCollectError(p->dbMain, &pXList, &p->zErrmsg,
++        sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
++    );
++    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXList) ){
++      const char *zOrig = (const char*)sqlite3_column_text(pXList,3);
++      if( zOrig && strcmp(zOrig, "pk")==0 ){
++        const char *zIdx = (const char*)sqlite3_column_text(pXList,1);
++        if( zIdx ){
++          p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
++              sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
++          );
++        }
++        break;
++      }
++    }
++    rbuFinalize(p, pXList);
++
++    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
++      if( sqlite3_column_int(pXInfo, 5) ){
++        /* int iCid = sqlite3_column_int(pXInfo, 0); */
++        const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2);
++        const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : "";
++        z = rbuMPrintf(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc);
++        zSep = ", ";
++      }
++    }
++    z = rbuMPrintf(p, "%z)", z);
++    rbuFinalize(p, pXInfo);
++  }
++  return z;
++}
++
++/*
++** This function creates the second imposter table used when writing to
++** a table b-tree where the table has an external primary key. If the
++** iterator passed as the second argument does not currently point to
++** a table (not index) with an external primary key, this function is a
++** no-op. 
++**
++** Assuming the iterator does point to a table with an external PK, this
++** function creates a WITHOUT ROWID imposter table named "rbu_imposter2"
++** used to access that PK index. For example, if the target table is
++** declared as follows:
++**
++**   CREATE TABLE t1(a, b TEXT, c REAL, PRIMARY KEY(b, c));
++**
++** then the imposter table schema is:
++**
++**   CREATE TABLE rbu_imposter2(c1 TEXT, c2 REAL, id INTEGER) WITHOUT ROWID;
++**
++*/
++static void rbuCreateImposterTable2(sqlite3rbu *p, RbuObjIter *pIter){
++  if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_EXTERNAL ){
++    int tnum = pIter->iPkTnum;    /* Root page of PK index */
++    sqlite3_stmt *pQuery = 0;     /* SELECT name ... WHERE rootpage = $tnum */
++    const char *zIdx = 0;         /* Name of PK index */
++    sqlite3_stmt *pXInfo = 0;     /* PRAGMA main.index_xinfo = $zIdx */
++    const char *zComma = "";
++    char *zCols = 0;              /* Used to build up list of table cols */
++    char *zPk = 0;                /* Used to build up table PK declaration */
++
++    /* Figure out the name of the primary key index for the current table.
++    ** This is needed for the argument to "PRAGMA index_xinfo". Set
++    ** zIdx to point to a nul-terminated string containing this name. */
++    p->rc = prepareAndCollectError(p->dbMain, &pQuery, &p->zErrmsg, 
++        "SELECT name FROM sqlite_master WHERE rootpage = ?"
++    );
++    if( p->rc==SQLITE_OK ){
++      sqlite3_bind_int(pQuery, 1, tnum);
++      if( SQLITE_ROW==sqlite3_step(pQuery) ){
++        zIdx = (const char*)sqlite3_column_text(pQuery, 0);
++      }
++    }
++    if( zIdx ){
++      p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
++          sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
++      );
++    }
++    rbuFinalize(p, pQuery);
++
++    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
++      int bKey = sqlite3_column_int(pXInfo, 5);
++      if( bKey ){
++        int iCid = sqlite3_column_int(pXInfo, 1);
++        int bDesc = sqlite3_column_int(pXInfo, 3);
++        const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
++        zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma, 
++            iCid, pIter->azTblType[iCid], zCollate
++        );
++        zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":"");
++        zComma = ", ";
++      }
++    }
++    zCols = rbuMPrintf(p, "%z, id INTEGER", zCols);
++    rbuFinalize(p, pXInfo);
++
++    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum);
++    rbuMPrintfExec(p, p->dbMain,
++        "CREATE TABLE rbu_imposter2(%z, PRIMARY KEY(%z)) WITHOUT ROWID", 
++        zCols, zPk
++    );
++    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
++  }
++}
++
++/*
++** If an error has already occurred when this function is called, it 
++** immediately returns zero (without doing any work). Or, if an error
++** occurs during the execution of this function, it sets the error code
++** in the sqlite3rbu object indicated by the first argument and returns
++** zero.
++**
++** The iterator passed as the second argument is guaranteed to point to
++** a table (not an index) when this function is called. This function
++** attempts to create any imposter table required to write to the main
++** table b-tree of the table before returning. Non-zero is returned if
++** an imposter table are created, or zero otherwise.
++**
++** An imposter table is required in all cases except RBU_PK_VTAB. Only
++** virtual tables are written to directly. The imposter table has the 
++** same schema as the actual target table (less any UNIQUE constraints). 
++** More precisely, the "same schema" means the same columns, types, 
++** collation sequences. For tables that do not have an external PRIMARY
++** KEY, it also means the same PRIMARY KEY declaration.
++*/
++static void rbuCreateImposterTable(sqlite3rbu *p, RbuObjIter *pIter){
++  if( p->rc==SQLITE_OK && pIter->eType!=RBU_PK_VTAB ){
++    int tnum = pIter->iTnum;
++    const char *zComma = "";
++    char *zSql = 0;
++    int iCol;
++    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
++
++    for(iCol=0; p->rc==SQLITE_OK && iCol<pIter->nTblCol; iCol++){
++      const char *zPk = "";
++      const char *zCol = pIter->azTblCol[iCol];
++      const char *zColl = 0;
++
++      p->rc = sqlite3_table_column_metadata(
++          p->dbMain, "main", pIter->zTbl, zCol, 0, &zColl, 0, 0, 0
++      );
++
++      if( pIter->eType==RBU_PK_IPK && pIter->abTblPk[iCol] ){
++        /* If the target table column is an "INTEGER PRIMARY KEY", add
++        ** "PRIMARY KEY" to the imposter table column declaration. */
++        zPk = "PRIMARY KEY ";
++      }
++      zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s", 
++          zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl,
++          (pIter->abNotNull[iCol] ? " NOT NULL" : "")
++      );
++      zComma = ", ";
++    }
++
++    if( pIter->eType==RBU_PK_WITHOUT_ROWID ){
++      char *zPk = rbuWithoutRowidPK(p, pIter);
++      if( zPk ){
++        zSql = rbuMPrintf(p, "%z, %z", zSql, zPk);
++      }
++    }
++
++    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum);
++    rbuMPrintfExec(p, p->dbMain, "CREATE TABLE \"rbu_imp_%w\"(%z)%s", 
++        pIter->zTbl, zSql, 
++        (pIter->eType==RBU_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "")
++    );
++    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
++  }
++}
++
++/*
++** Prepare a statement used to insert rows into the "rbu_tmp_xxx" table.
++** Specifically a statement of the form:
++**
++**     INSERT INTO rbu_tmp_xxx VALUES(?, ?, ? ...);
++**
++** The number of bound variables is equal to the number of columns in
++** the target table, plus one (for the rbu_control column), plus one more 
++** (for the rbu_rowid column) if the target table is an implicit IPK or 
++** virtual table.
++*/
++static void rbuObjIterPrepareTmpInsert(
++  sqlite3rbu *p, 
++  RbuObjIter *pIter,
++  const char *zCollist,
++  const char *zRbuRowid
++){
++  int bRbuRowid = (pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE);
++  char *zBind = rbuObjIterGetBindlist(p, pIter->nTblCol + 1 + bRbuRowid);
++  if( zBind ){
++    assert( pIter->pTmpInsert==0 );
++    p->rc = prepareFreeAndCollectError(
++        p->dbRbu, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf(
++          "INSERT INTO %s.'rbu_tmp_%q'(rbu_control,%s%s) VALUES(%z)", 
++          p->zStateDb, pIter->zDataTbl, zCollist, zRbuRowid, zBind
++    ));
++  }
++}
++
++static void rbuTmpInsertFunc(
++  sqlite3_context *pCtx, 
++  int nVal,
++  sqlite3_value **apVal
++){
++  sqlite3rbu *p = sqlite3_user_data(pCtx);
++  int rc = SQLITE_OK;
++  int i;
++
++  assert( sqlite3_value_int(apVal[0])!=0
++      || p->objiter.eType==RBU_PK_EXTERNAL 
++      || p->objiter.eType==RBU_PK_NONE 
++  );
++  if( sqlite3_value_int(apVal[0])!=0 ){
++    p->nPhaseOneStep += p->objiter.nIndex;
++  }
++
++  for(i=0; rc==SQLITE_OK && i<nVal; i++){
++    rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]);
++  }
++  if( rc==SQLITE_OK ){
++    sqlite3_step(p->objiter.pTmpInsert);
++    rc = sqlite3_reset(p->objiter.pTmpInsert);
++  }
++
++  if( rc!=SQLITE_OK ){
++    sqlite3_result_error_code(pCtx, rc);
++  }
++}
++
++/*
++** Ensure that the SQLite statement handles required to update the 
++** target database object currently indicated by the iterator passed 
++** as the second argument are available.
++*/
++static int rbuObjIterPrepareAll(
++  sqlite3rbu *p, 
++  RbuObjIter *pIter,
++  int nOffset                     /* Add "LIMIT -1 OFFSET $nOffset" to SELECT */
++){
++  assert( pIter->bCleanup==0 );
++  if( pIter->pSelect==0 && rbuObjIterCacheTableInfo(p, pIter)==SQLITE_OK ){
++    const int tnum = pIter->iTnum;
++    char *zCollist = 0;           /* List of indexed columns */
++    char **pz = &p->zErrmsg;
++    const char *zIdx = pIter->zIdx;
++    char *zLimit = 0;
++
++    if( nOffset ){
++      zLimit = sqlite3_mprintf(" LIMIT -1 OFFSET %d", nOffset);
++      if( !zLimit ) p->rc = SQLITE_NOMEM;
++    }
++
++    if( zIdx ){
++      const char *zTbl = pIter->zTbl;
++      char *zImposterCols = 0;    /* Columns for imposter table */
++      char *zImposterPK = 0;      /* Primary key declaration for imposter */
++      char *zWhere = 0;           /* WHERE clause on PK columns */
++      char *zBind = 0;
++      int nBind = 0;
++
++      assert( pIter->eType!=RBU_PK_VTAB );
++      zCollist = rbuObjIterGetIndexCols(
++          p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind
++      );
++      zBind = rbuObjIterGetBindlist(p, nBind);
++
++      /* Create the imposter table used to write to this index. */
++      sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
++      sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum);
++      rbuMPrintfExec(p, p->dbMain,
++          "CREATE TABLE \"rbu_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID",
++          zTbl, zImposterCols, zImposterPK
++      );
++      sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
++
++      /* Create the statement to insert index entries */
++      pIter->nCol = nBind;
++      if( p->rc==SQLITE_OK ){
++        p->rc = prepareFreeAndCollectError(
++            p->dbMain, &pIter->pInsert, &p->zErrmsg,
++          sqlite3_mprintf("INSERT INTO \"rbu_imp_%w\" VALUES(%s)", zTbl, zBind)
++        );
++      }
++
++      /* And to delete index entries */
++      if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){
++        p->rc = prepareFreeAndCollectError(
++            p->dbMain, &pIter->pDelete, &p->zErrmsg,
++          sqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere)
++        );
++      }
++
++      /* Create the SELECT statement to read keys in sorted order */
++      if( p->rc==SQLITE_OK ){
++        char *zSql;
++        if( rbuIsVacuum(p) ){
++          zSql = sqlite3_mprintf(
++              "SELECT %s, 0 AS rbu_control FROM '%q' ORDER BY %s%s",
++              zCollist, 
++              pIter->zDataTbl,
++              zCollist, zLimit
++          );
++        }else
++
++        if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
++          zSql = sqlite3_mprintf(
++              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s",
++              zCollist, p->zStateDb, pIter->zDataTbl,
++              zCollist, zLimit
++          );
++        }else{
++          zSql = sqlite3_mprintf(
++              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' "
++              "UNION ALL "
++              "SELECT %s, rbu_control FROM '%q' "
++              "WHERE typeof(rbu_control)='integer' AND rbu_control!=1 "
++              "ORDER BY %s%s",
++              zCollist, p->zStateDb, pIter->zDataTbl, 
++              zCollist, pIter->zDataTbl, 
++              zCollist, zLimit
++          );
++        }
++        p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
++      }
++
++      sqlite3_free(zImposterCols);
++      sqlite3_free(zImposterPK);
++      sqlite3_free(zWhere);
++      sqlite3_free(zBind);
++    }else{
++      int bRbuRowid = (pIter->eType==RBU_PK_VTAB)
++                    ||(pIter->eType==RBU_PK_NONE)
++                    ||(pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p));
++      const char *zTbl = pIter->zTbl;       /* Table this step applies to */
++      const char *zWrite;                   /* Imposter table name */
++
++      char *zBindings = rbuObjIterGetBindlist(p, pIter->nTblCol + bRbuRowid);
++      char *zWhere = rbuObjIterGetWhere(p, pIter);
++      char *zOldlist = rbuObjIterGetOldlist(p, pIter, "old");
++      char *zNewlist = rbuObjIterGetOldlist(p, pIter, "new");
++
++      zCollist = rbuObjIterGetCollist(p, pIter);
++      pIter->nCol = pIter->nTblCol;
++
++      /* Create the imposter table or tables (if required). */
++      rbuCreateImposterTable(p, pIter);
++      rbuCreateImposterTable2(p, pIter);
++      zWrite = (pIter->eType==RBU_PK_VTAB ? "" : "rbu_imp_");
++
++      /* Create the INSERT statement to write to the target PK b-tree */
++      if( p->rc==SQLITE_OK ){
++        p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz,
++            sqlite3_mprintf(
++              "INSERT INTO \"%s%w\"(%s%s) VALUES(%s)", 
++              zWrite, zTbl, zCollist, (bRbuRowid ? ", _rowid_" : ""), zBindings
++            )
++        );
++      }
++
++      /* Create the DELETE statement to write to the target PK b-tree.
++      ** Because it only performs INSERT operations, this is not required for
++      ** an rbu vacuum handle.  */
++      if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){
++        p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz,
++            sqlite3_mprintf(
++              "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere
++            )
++        );
++      }
++
++      if( rbuIsVacuum(p)==0 && pIter->abIndexed ){
++        const char *zRbuRowid = "";
++        if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
++          zRbuRowid = ", rbu_rowid";
++        }
++
++        /* Create the rbu_tmp_xxx table and the triggers to populate it. */
++        rbuMPrintfExec(p, p->dbRbu,
++            "CREATE TABLE IF NOT EXISTS %s.'rbu_tmp_%q' AS "
++            "SELECT *%s FROM '%q' WHERE 0;"
++            , p->zStateDb, pIter->zDataTbl
++            , (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "")
++            , pIter->zDataTbl
++        );
++
++        rbuMPrintfExec(p, p->dbMain,
++            "CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" "
++            "BEGIN "
++            "  SELECT rbu_tmp_insert(3, %s);"
++            "END;"
++
++            "CREATE TEMP TRIGGER rbu_update1_tr BEFORE UPDATE ON \"%s%w\" "
++            "BEGIN "
++            "  SELECT rbu_tmp_insert(3, %s);"
++            "END;"
++
++            "CREATE TEMP TRIGGER rbu_update2_tr AFTER UPDATE ON \"%s%w\" "
++            "BEGIN "
++            "  SELECT rbu_tmp_insert(4, %s);"
++            "END;",
++            zWrite, zTbl, zOldlist,
++            zWrite, zTbl, zOldlist,
++            zWrite, zTbl, zNewlist
++        );
++
++        if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
++          rbuMPrintfExec(p, p->dbMain,
++              "CREATE TEMP TRIGGER rbu_insert_tr AFTER INSERT ON \"%s%w\" "
++              "BEGIN "
++              "  SELECT rbu_tmp_insert(0, %s);"
++              "END;",
++              zWrite, zTbl, zNewlist
++          );
++        }
++
++        rbuObjIterPrepareTmpInsert(p, pIter, zCollist, zRbuRowid);
++      }
++
++      /* Create the SELECT statement to read keys from data_xxx */
++      if( p->rc==SQLITE_OK ){
++        const char *zRbuRowid = "";
++        if( bRbuRowid ){
++          zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
++        }
++        p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
++            sqlite3_mprintf(
++              "SELECT %s,%s rbu_control%s FROM '%q'%s", 
++              zCollist, 
++              (rbuIsVacuum(p) ? "0 AS " : ""),
++              zRbuRowid,
++              pIter->zDataTbl, zLimit
++            )
++        );
++      }
++
++      sqlite3_free(zWhere);
++      sqlite3_free(zOldlist);
++      sqlite3_free(zNewlist);
++      sqlite3_free(zBindings);
++    }
++    sqlite3_free(zCollist);
++    sqlite3_free(zLimit);
++  }
++  
++  return p->rc;
++}
++
++/*
++** Set output variable *ppStmt to point to an UPDATE statement that may
++** be used to update the imposter table for the main table b-tree of the
++** table object that pIter currently points to, assuming that the 
++** rbu_control column of the data_xyz table contains zMask.
++** 
++** If the zMask string does not specify any columns to update, then this
++** is not an error. Output variable *ppStmt is set to NULL in this case.
++*/
++static int rbuGetUpdateStmt(
++  sqlite3rbu *p,                  /* RBU handle */
++  RbuObjIter *pIter,              /* Object iterator */
++  const char *zMask,              /* rbu_control value ('x.x.') */
++  sqlite3_stmt **ppStmt           /* OUT: UPDATE statement handle */
++){
++  RbuUpdateStmt **pp;
++  RbuUpdateStmt *pUp = 0;
++  int nUp = 0;
++
++  /* In case an error occurs */
++  *ppStmt = 0;
++
++  /* Search for an existing statement. If one is found, shift it to the front
++  ** of the LRU queue and return immediately. Otherwise, leave nUp pointing
++  ** to the number of statements currently in the cache and pUp to the
++  ** last object in the list.  */
++  for(pp=&pIter->pRbuUpdate; *pp; pp=&((*pp)->pNext)){
++    pUp = *pp;
++    if( strcmp(pUp->zMask, zMask)==0 ){
++      *pp = pUp->pNext;
++      pUp->pNext = pIter->pRbuUpdate;
++      pIter->pRbuUpdate = pUp;
++      *ppStmt = pUp->pUpdate; 
++      return SQLITE_OK;
++    }
++    nUp++;
++  }
++  assert( pUp==0 || pUp->pNext==0 );
++
++  if( nUp>=SQLITE_RBU_UPDATE_CACHESIZE ){
++    for(pp=&pIter->pRbuUpdate; *pp!=pUp; pp=&((*pp)->pNext));
++    *pp = 0;
++    sqlite3_finalize(pUp->pUpdate);
++    pUp->pUpdate = 0;
++  }else{
++    pUp = (RbuUpdateStmt*)rbuMalloc(p, sizeof(RbuUpdateStmt)+pIter->nTblCol+1);
++  }
++
++  if( pUp ){
++    char *zWhere = rbuObjIterGetWhere(p, pIter);
++    char *zSet = rbuObjIterGetSetlist(p, pIter, zMask);
++    char *zUpdate = 0;
++
++    pUp->zMask = (char*)&pUp[1];
++    memcpy(pUp->zMask, zMask, pIter->nTblCol);
++    pUp->pNext = pIter->pRbuUpdate;
++    pIter->pRbuUpdate = pUp;
++
++    if( zSet ){
++      const char *zPrefix = "";
++
++      if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_";
++      zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s", 
++          zPrefix, pIter->zTbl, zSet, zWhere
++      );
++      p->rc = prepareFreeAndCollectError(
++          p->dbMain, &pUp->pUpdate, &p->zErrmsg, zUpdate
++      );
++      *ppStmt = pUp->pUpdate;
++    }
++    sqlite3_free(zWhere);
++    sqlite3_free(zSet);
++  }
++
++  return p->rc;
++}
++
++static sqlite3 *rbuOpenDbhandle(
++  sqlite3rbu *p, 
++  const char *zName, 
++  int bUseVfs
++){
++  sqlite3 *db = 0;
++  if( p->rc==SQLITE_OK ){
++    const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI;
++    p->rc = sqlite3_open_v2(zName, &db, flags, bUseVfs ? p->zVfsName : 0);
++    if( p->rc ){
++      p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++      sqlite3_close(db);
++      db = 0;
++    }
++  }
++  return db;
++}
++
++/*
++** Free an RbuState object allocated by rbuLoadState().
++*/
++static void rbuFreeState(RbuState *p){
++  if( p ){
++    sqlite3_free(p->zTbl);
++    sqlite3_free(p->zIdx);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** Allocate an RbuState object and load the contents of the rbu_state 
++** table into it. Return a pointer to the new object. It is the 
++** responsibility of the caller to eventually free the object using
++** sqlite3_free().
++**
++** If an error occurs, leave an error code and message in the rbu handle
++** and return NULL.
++*/
++static RbuState *rbuLoadState(sqlite3rbu *p){
++  RbuState *pRet = 0;
++  sqlite3_stmt *pStmt = 0;
++  int rc;
++  int rc2;
++
++  pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState));
++  if( pRet==0 ) return 0;
++
++  rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, 
++      sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb)
++  );
++  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
++    switch( sqlite3_column_int(pStmt, 0) ){
++      case RBU_STATE_STAGE:
++        pRet->eStage = sqlite3_column_int(pStmt, 1);
++        if( pRet->eStage!=RBU_STAGE_OAL
++         && pRet->eStage!=RBU_STAGE_MOVE
++         && pRet->eStage!=RBU_STAGE_CKPT
++        ){
++          p->rc = SQLITE_CORRUPT;
++        }
++        break;
++
++      case RBU_STATE_TBL:
++        pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
++        break;
++
++      case RBU_STATE_IDX:
++        pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
++        break;
++
++      case RBU_STATE_ROW:
++        pRet->nRow = sqlite3_column_int(pStmt, 1);
++        break;
++
++      case RBU_STATE_PROGRESS:
++        pRet->nProgress = sqlite3_column_int64(pStmt, 1);
++        break;
++
++      case RBU_STATE_CKPT:
++        pRet->iWalCksum = sqlite3_column_int64(pStmt, 1);
++        break;
++
++      case RBU_STATE_COOKIE:
++        pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1);
++        break;
++
++      case RBU_STATE_OALSZ:
++        pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
++        break;
++
++      case RBU_STATE_PHASEONESTEP:
++        pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1);
++        break;
++
++      default:
++        rc = SQLITE_CORRUPT;
++        break;
++    }
++  }
++  rc2 = sqlite3_finalize(pStmt);
++  if( rc==SQLITE_OK ) rc = rc2;
++
++  p->rc = rc;
++  return pRet;
++}
++
++
++/*
++** Open the database handle and attach the RBU database as "rbu". If an
++** error occurs, leave an error code and message in the RBU handle.
++*/
++static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){
++  assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
++  assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
++
++  /* Open the RBU database */
++  p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
++
++  if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
++    sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
++    if( p->zState==0 ){
++      const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
++      p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile);
++    }
++  }
++
++  /* If using separate RBU and state databases, attach the state database to
++  ** the RBU db handle now.  */
++  if( p->zState ){
++    rbuMPrintfExec(p, p->dbRbu, "ATTACH %Q AS stat", p->zState);
++    memcpy(p->zStateDb, "stat", 4);
++  }else{
++    memcpy(p->zStateDb, "main", 4);
++  }
++
++#if 0
++  if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
++    p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, 0);
++  }
++#endif
++
++  /* If it has not already been created, create the rbu_state table */
++  rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb);
++
++#if 0
++  if( rbuIsVacuum(p) ){
++    if( p->rc==SQLITE_OK ){
++      int rc2;
++      int bOk = 0;
++      sqlite3_stmt *pCnt = 0;
++      p->rc = prepareAndCollectError(p->dbRbu, &pCnt, &p->zErrmsg,
++          "SELECT count(*) FROM stat.sqlite_master"
++      );
++      if( p->rc==SQLITE_OK 
++       && sqlite3_step(pCnt)==SQLITE_ROW
++       && 1==sqlite3_column_int(pCnt, 0)
++      ){
++        bOk = 1;
++      }
++      rc2 = sqlite3_finalize(pCnt);
++      if( p->rc==SQLITE_OK ) p->rc = rc2;
++
++      if( p->rc==SQLITE_OK && bOk==0 ){
++        p->rc = SQLITE_ERROR;
++        p->zErrmsg = sqlite3_mprintf("invalid state database");
++      }
++    
++      if( p->rc==SQLITE_OK ){
++        p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0);
++      }
++    }
++  }
++#endif
++
++  if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
++    int bOpen = 0;
++    int rc;
++    p->nRbu = 0;
++    p->pRbuFd = 0;
++    rc = sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
++    if( rc!=SQLITE_NOTFOUND ) p->rc = rc;
++    if( p->eStage>=RBU_STAGE_MOVE ){
++      bOpen = 1;
++    }else{
++      RbuState *pState = rbuLoadState(p);
++      if( pState ){
++        bOpen = (pState->eStage>=RBU_STAGE_MOVE);
++        rbuFreeState(pState);
++      }
++    }
++    if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, p->nRbu<=1);
++  }
++
++  p->eStage = 0;
++  if( p->rc==SQLITE_OK && p->dbMain==0 ){
++    if( !rbuIsVacuum(p) ){
++      p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
++    }else if( p->pRbuFd->pWalFd ){
++      if( pbRetry ){
++        p->pRbuFd->bNolock = 0;
++        sqlite3_close(p->dbRbu);
++        sqlite3_close(p->dbMain);
++        p->dbMain = 0;
++        p->dbRbu = 0;
++        *pbRetry = 1;
++        return;
++      }
++      p->rc = SQLITE_ERROR;
++      p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database");
++    }else{
++      char *zTarget;
++      char *zExtra = 0;
++      if( strlen(p->zRbu)>=5 && 0==memcmp("file:", p->zRbu, 5) ){
++        zExtra = &p->zRbu[5];
++        while( *zExtra ){
++          if( *zExtra++=='?' ) break;
++        }
++        if( *zExtra=='\0' ) zExtra = 0;
++      }
++
++      zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1%s%s", 
++          sqlite3_db_filename(p->dbRbu, "main"),
++          (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra)
++      );
++
++      if( zTarget==0 ){
++        p->rc = SQLITE_NOMEM;
++        return;
++      }
++      p->dbMain = rbuOpenDbhandle(p, zTarget, p->nRbu<=1);
++      sqlite3_free(zTarget);
++    }
++  }
++
++  if( p->rc==SQLITE_OK ){
++    p->rc = sqlite3_create_function(p->dbMain, 
++        "rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0
++    );
++  }
++
++  if( p->rc==SQLITE_OK ){
++    p->rc = sqlite3_create_function(p->dbMain, 
++        "rbu_fossil_delta", 2, SQLITE_UTF8, 0, rbuFossilDeltaFunc, 0, 0
++    );
++  }
++
++  if( p->rc==SQLITE_OK ){
++    p->rc = sqlite3_create_function(p->dbRbu, 
++        "rbu_target_name", -1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0
++    );
++  }
++
++  if( p->rc==SQLITE_OK ){
++    p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p);
++  }
++  rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_master");
++
++  /* Mark the database file just opened as an RBU target database. If 
++  ** this call returns SQLITE_NOTFOUND, then the RBU vfs is not in use.
++  ** This is an error.  */
++  if( p->rc==SQLITE_OK ){
++    p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p);
++  }
++
++  if( p->rc==SQLITE_NOTFOUND ){
++    p->rc = SQLITE_ERROR;
++    p->zErrmsg = sqlite3_mprintf("rbu vfs not found");
++  }
++}
++
++/*
++** This routine is a copy of the sqlite3FileSuffix3() routine from the core.
++** It is a no-op unless SQLITE_ENABLE_8_3_NAMES is defined.
++**
++** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database
++** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and
++** if filename in z[] has a suffix (a.k.a. "extension") that is longer than
++** three characters, then shorten the suffix on z[] to be the last three
++** characters of the original suffix.
++**
++** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always
++** do the suffix shortening regardless of URI parameter.
++**
++** Examples:
++**
++**     test.db-journal    =>   test.nal
++**     test.db-wal        =>   test.wal
++**     test.db-shm        =>   test.shm
++**     test.db-mj7f3319fa =>   test.9fa
++*/
++static void rbuFileSuffix3(const char *zBase, char *z){
++#ifdef SQLITE_ENABLE_8_3_NAMES
++#if SQLITE_ENABLE_8_3_NAMES<2
++  if( sqlite3_uri_boolean(zBase, "8_3_names", 0) )
++#endif
++  {
++    int i, sz;
++    sz = (int)strlen(z)&0xffffff;
++    for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
++    if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
++  }
++#endif
++}
++
++/*
++** Return the current wal-index header checksum for the target database 
++** as a 64-bit integer.
++**
++** The checksum is store in the first page of xShmMap memory as an 8-byte 
++** blob starting at byte offset 40.
++*/
++static i64 rbuShmChecksum(sqlite3rbu *p){
++  i64 iRet = 0;
++  if( p->rc==SQLITE_OK ){
++    sqlite3_file *pDb = p->pTargetFd->pReal;
++    u32 volatile *ptr;
++    p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr);
++    if( p->rc==SQLITE_OK ){
++      iRet = ((i64)ptr[10] << 32) + ptr[11];
++    }
++  }
++  return iRet;
++}
++
++/*
++** This function is called as part of initializing or reinitializing an
++** incremental checkpoint. 
++**
++** It populates the sqlite3rbu.aFrame[] array with the set of 
++** (wal frame -> db page) copy operations required to checkpoint the 
++** current wal file, and obtains the set of shm locks required to safely 
++** perform the copy operations directly on the file-system.
++**
++** If argument pState is not NULL, then the incremental checkpoint is
++** being resumed. In this case, if the checksum of the wal-index-header
++** following recovery is not the same as the checksum saved in the RbuState
++** object, then the rbu handle is set to DONE state. This occurs if some
++** other client appends a transaction to the wal file in the middle of
++** an incremental checkpoint.
++*/
++static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){
++
++  /* If pState is NULL, then the wal file may not have been opened and
++  ** recovered. Running a read-statement here to ensure that doing so
++  ** does not interfere with the "capture" process below.  */
++  if( pState==0 ){
++    p->eStage = 0;
++    if( p->rc==SQLITE_OK ){
++      p->rc = sqlite3_exec(p->dbMain, "SELECT * FROM sqlite_master", 0, 0, 0);
++    }
++  }
++
++  /* Assuming no error has occurred, run a "restart" checkpoint with the
++  ** sqlite3rbu.eStage variable set to CAPTURE. This turns on the following
++  ** special behaviour in the rbu VFS:
++  **
++  **   * If the exclusive shm WRITER or READ0 lock cannot be obtained,
++  **     the checkpoint fails with SQLITE_BUSY (normally SQLite would
++  **     proceed with running a passive checkpoint instead of failing).
++  **
++  **   * Attempts to read from the *-wal file or write to the database file
++  **     do not perform any IO. Instead, the frame/page combinations that
++  **     would be read/written are recorded in the sqlite3rbu.aFrame[]
++  **     array.
++  **
++  **   * Calls to xShmLock(UNLOCK) to release the exclusive shm WRITER, 
++  **     READ0 and CHECKPOINT locks taken as part of the checkpoint are
++  **     no-ops. These locks will not be released until the connection
++  **     is closed.
++  **
++  **   * Attempting to xSync() the database file causes an SQLITE_INTERNAL 
++  **     error.
++  **
++  ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the
++  ** checkpoint below fails with SQLITE_INTERNAL, and leaves the aFrame[]
++  ** array populated with a set of (frame -> page) mappings. Because the 
++  ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy 
++  ** data from the wal file into the database file according to the 
++  ** contents of aFrame[].
++  */
++  if( p->rc==SQLITE_OK ){
++    int rc2;
++    p->eStage = RBU_STAGE_CAPTURE;
++    rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0);
++    if( rc2!=SQLITE_INTERNAL ) p->rc = rc2;
++  }
++
++  if( p->rc==SQLITE_OK && p->nFrame>0 ){
++    p->eStage = RBU_STAGE_CKPT;
++    p->nStep = (pState ? pState->nRow : 0);
++    p->aBuf = rbuMalloc(p, p->pgsz);
++    p->iWalCksum = rbuShmChecksum(p);
++  }
++
++  if( p->rc==SQLITE_OK ){
++    if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){
++      p->rc = SQLITE_DONE;
++      p->eStage = RBU_STAGE_DONE;
++    }else{
++      int nSectorSize;
++      sqlite3_file *pDb = p->pTargetFd->pReal;
++      sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal;
++      assert( p->nPagePerSector==0 );
++      nSectorSize = pDb->pMethods->xSectorSize(pDb);
++      if( nSectorSize>p->pgsz ){
++        p->nPagePerSector = nSectorSize / p->pgsz;
++      }else{
++        p->nPagePerSector = 1;
++      }
++
++      /* Call xSync() on the wal file. This causes SQLite to sync the 
++      ** directory in which the target database and the wal file reside, in 
++      ** case it has not been synced since the rename() call in 
++      ** rbuMoveOalFile(). */
++      p->rc = pWal->pMethods->xSync(pWal, SQLITE_SYNC_NORMAL);
++    }
++  }
++}
++
++/*
++** Called when iAmt bytes are read from offset iOff of the wal file while
++** the rbu object is in capture mode. Record the frame number of the frame
++** being read in the aFrame[] array.
++*/
++static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){
++  const u32 mReq = (1<<WAL_LOCK_WRITE)|(1<<WAL_LOCK_CKPT)|(1<<WAL_LOCK_READ0);
++  u32 iFrame;
++
++  if( pRbu->mLock!=mReq ){
++    pRbu->rc = SQLITE_BUSY;
++    return SQLITE_INTERNAL;
++  }
++
++  pRbu->pgsz = iAmt;
++  if( pRbu->nFrame==pRbu->nFrameAlloc ){
++    int nNew = (pRbu->nFrameAlloc ? pRbu->nFrameAlloc : 64) * 2;
++    RbuFrame *aNew;
++    aNew = (RbuFrame*)sqlite3_realloc64(pRbu->aFrame, nNew * sizeof(RbuFrame));
++    if( aNew==0 ) return SQLITE_NOMEM;
++    pRbu->aFrame = aNew;
++    pRbu->nFrameAlloc = nNew;
++  }
++
++  iFrame = (u32)((iOff-32) / (i64)(iAmt+24)) + 1;
++  if( pRbu->iMaxFrame<iFrame ) pRbu->iMaxFrame = iFrame;
++  pRbu->aFrame[pRbu->nFrame].iWalFrame = iFrame;
++  pRbu->aFrame[pRbu->nFrame].iDbPage = 0;
++  pRbu->nFrame++;
++  return SQLITE_OK;
++}
++
++/*
++** Called when a page of data is written to offset iOff of the database
++** file while the rbu handle is in capture mode. Record the page number 
++** of the page being written in the aFrame[] array.
++*/
++static int rbuCaptureDbWrite(sqlite3rbu *pRbu, i64 iOff){
++  pRbu->aFrame[pRbu->nFrame-1].iDbPage = (u32)(iOff / pRbu->pgsz) + 1;
++  return SQLITE_OK;
++}
++
++/*
++** This is called as part of an incremental checkpoint operation. Copy
++** a single frame of data from the wal file into the database file, as
++** indicated by the RbuFrame object.
++*/
++static void rbuCheckpointFrame(sqlite3rbu *p, RbuFrame *pFrame){
++  sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal;
++  sqlite3_file *pDb = p->pTargetFd->pReal;
++  i64 iOff;
++
++  assert( p->rc==SQLITE_OK );
++  iOff = (i64)(pFrame->iWalFrame-1) * (p->pgsz + 24) + 32 + 24;
++  p->rc = pWal->pMethods->xRead(pWal, p->aBuf, p->pgsz, iOff);
++  if( p->rc ) return;
++
++  iOff = (i64)(pFrame->iDbPage-1) * p->pgsz;
++  p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
++}
++
++
++/*
++** Take an EXCLUSIVE lock on the database file.
++*/
++static void rbuLockDatabase(sqlite3rbu *p){
++  sqlite3_file *pReal = p->pTargetFd->pReal;
++  assert( p->rc==SQLITE_OK );
++  p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
++  if( p->rc==SQLITE_OK ){
++    p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE);
++  }
++}
++
++#if defined(_WIN32_WCE)
++static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
++  int nChar;
++  LPWSTR zWideFilename;
++
++  nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
++  if( nChar==0 ){
++    return 0;
++  }
++  zWideFilename = sqlite3_malloc64( nChar*sizeof(zWideFilename[0]) );
++  if( zWideFilename==0 ){
++    return 0;
++  }
++  memset(zWideFilename, 0, nChar*sizeof(zWideFilename[0]));
++  nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
++                                nChar);
++  if( nChar==0 ){
++    sqlite3_free(zWideFilename);
++    zWideFilename = 0;
++  }
++  return zWideFilename;
++}
++#endif
++
++/*
++** The RBU handle is currently in RBU_STAGE_OAL state, with a SHARED lock
++** on the database file. This proc moves the *-oal file to the *-wal path,
++** then reopens the database file (this time in vanilla, non-oal, WAL mode).
++** If an error occurs, leave an error code and error message in the rbu 
++** handle.
++*/
++static void rbuMoveOalFile(sqlite3rbu *p){
++  const char *zBase = sqlite3_db_filename(p->dbMain, "main");
++  const char *zMove = zBase;
++  char *zOal;
++  char *zWal;
++
++  if( rbuIsVacuum(p) ){
++    zMove = sqlite3_db_filename(p->dbRbu, "main");
++  }
++  zOal = sqlite3_mprintf("%s-oal", zMove);
++  zWal = sqlite3_mprintf("%s-wal", zMove);
++
++  assert( p->eStage==RBU_STAGE_MOVE );
++  assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
++  if( zWal==0 || zOal==0 ){
++    p->rc = SQLITE_NOMEM;
++  }else{
++    /* Move the *-oal file to *-wal. At this point connection p->db is
++    ** holding a SHARED lock on the target database file (because it is
++    ** in WAL mode). So no other connection may be writing the db. 
++    **
++    ** In order to ensure that there are no database readers, an EXCLUSIVE
++    ** lock is obtained here before the *-oal is moved to *-wal.
++    */
++    rbuLockDatabase(p);
++    if( p->rc==SQLITE_OK ){
++      rbuFileSuffix3(zBase, zWal);
++      rbuFileSuffix3(zBase, zOal);
++
++      /* Re-open the databases. */
++      rbuObjIterFinalize(&p->objiter);
++      sqlite3_close(p->dbRbu);
++      sqlite3_close(p->dbMain);
++      p->dbMain = 0;
++      p->dbRbu = 0;
++
++#if defined(_WIN32_WCE)
++      {
++        LPWSTR zWideOal;
++        LPWSTR zWideWal;
++
++        zWideOal = rbuWinUtf8ToUnicode(zOal);
++        if( zWideOal ){
++          zWideWal = rbuWinUtf8ToUnicode(zWal);
++          if( zWideWal ){
++            if( MoveFileW(zWideOal, zWideWal) ){
++              p->rc = SQLITE_OK;
++            }else{
++              p->rc = SQLITE_IOERR;
++            }
++            sqlite3_free(zWideWal);
++          }else{
++            p->rc = SQLITE_IOERR_NOMEM;
++          }
++          sqlite3_free(zWideOal);
++        }else{
++          p->rc = SQLITE_IOERR_NOMEM;
++        }
++      }
++#else
++      p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
++#endif
++
++      if( p->rc==SQLITE_OK ){
++        rbuOpenDatabase(p, 0);
++        rbuSetupCheckpoint(p, 0);
++      }
++    }
++  }
++
++  sqlite3_free(zWal);
++  sqlite3_free(zOal);
++}
++
++/*
++** The SELECT statement iterating through the keys for the current object
++** (p->objiter.pSelect) currently points to a valid row. This function
++** determines the type of operation requested by this row and returns
++** one of the following values to indicate the result:
++**
++**     * RBU_INSERT
++**     * RBU_DELETE
++**     * RBU_IDX_DELETE
++**     * RBU_UPDATE
++**
++** If RBU_UPDATE is returned, then output variable *pzMask is set to
++** point to the text value indicating the columns to update.
++**
++** If the rbu_control field contains an invalid value, an error code and
++** message are left in the RBU handle and zero returned.
++*/
++static int rbuStepType(sqlite3rbu *p, const char **pzMask){
++  int iCol = p->objiter.nCol;     /* Index of rbu_control column */
++  int res = 0;                    /* Return value */
++
++  switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){
++    case SQLITE_INTEGER: {
++      int iVal = sqlite3_column_int(p->objiter.pSelect, iCol);
++      switch( iVal ){
++        case 0: res = RBU_INSERT;     break;
++        case 1: res = RBU_DELETE;     break;
++        case 2: res = RBU_REPLACE;    break;
++        case 3: res = RBU_IDX_DELETE; break;
++        case 4: res = RBU_IDX_INSERT; break;
++      }
++      break;
++    }
++
++    case SQLITE_TEXT: {
++      const unsigned char *z = sqlite3_column_text(p->objiter.pSelect, iCol);
++      if( z==0 ){
++        p->rc = SQLITE_NOMEM;
++      }else{
++        *pzMask = (const char*)z;
++      }
++      res = RBU_UPDATE;
++
++      break;
++    }
++
++    default:
++      break;
++  }
++
++  if( res==0 ){
++    rbuBadControlError(p);
++  }
++  return res;
++}
++
++#ifdef SQLITE_DEBUG
++/*
++** Assert that column iCol of statement pStmt is named zName.
++*/
++static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){
++  const char *zCol = sqlite3_column_name(pStmt, iCol);
++  assert( 0==sqlite3_stricmp(zName, zCol) );
++}
++#else
++# define assertColumnName(x,y,z)
++#endif
++
++/*
++** Argument eType must be one of RBU_INSERT, RBU_DELETE, RBU_IDX_INSERT or
++** RBU_IDX_DELETE. This function performs the work of a single
++** sqlite3rbu_step() call for the type of operation specified by eType.
++*/
++static void rbuStepOneOp(sqlite3rbu *p, int eType){
++  RbuObjIter *pIter = &p->objiter;
++  sqlite3_value *pVal;
++  sqlite3_stmt *pWriter;
++  int i;
++
++  assert( p->rc==SQLITE_OK );
++  assert( eType!=RBU_DELETE || pIter->zIdx==0 );
++  assert( eType==RBU_DELETE || eType==RBU_IDX_DELETE
++       || eType==RBU_INSERT || eType==RBU_IDX_INSERT
++  );
++
++  /* If this is a delete, decrement nPhaseOneStep by nIndex. If the DELETE
++  ** statement below does actually delete a row, nPhaseOneStep will be
++  ** incremented by the same amount when SQL function rbu_tmp_insert()
++  ** is invoked by the trigger.  */
++  if( eType==RBU_DELETE ){
++    p->nPhaseOneStep -= p->objiter.nIndex;
++  }
++
++  if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){
++    pWriter = pIter->pDelete;
++  }else{
++    pWriter = pIter->pInsert;
++  }
++
++  for(i=0; i<pIter->nCol; i++){
++    /* If this is an INSERT into a table b-tree and the table has an
++    ** explicit INTEGER PRIMARY KEY, check that this is not an attempt
++    ** to write a NULL into the IPK column. That is not permitted.  */
++    if( eType==RBU_INSERT 
++     && pIter->zIdx==0 && pIter->eType==RBU_PK_IPK && pIter->abTblPk[i] 
++     && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
++    ){
++      p->rc = SQLITE_MISMATCH;
++      p->zErrmsg = sqlite3_mprintf("datatype mismatch");
++      return;
++    }
++
++    if( eType==RBU_DELETE && pIter->abTblPk[i]==0 ){
++      continue;
++    }
++
++    pVal = sqlite3_column_value(pIter->pSelect, i);
++    p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
++    if( p->rc ) return;
++  }
++  if( pIter->zIdx==0 ){
++    if( pIter->eType==RBU_PK_VTAB 
++     || pIter->eType==RBU_PK_NONE 
++     || (pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p)) 
++    ){
++      /* For a virtual table, or a table with no primary key, the 
++      ** SELECT statement is:
++      **
++      **   SELECT <cols>, rbu_control, rbu_rowid FROM ....
++      **
++      ** Hence column_value(pIter->nCol+1).
++      */
++      assertColumnName(pIter->pSelect, pIter->nCol+1, 
++          rbuIsVacuum(p) ? "rowid" : "rbu_rowid"
++      );
++      pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
++      p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
++    }
++  }
++  if( p->rc==SQLITE_OK ){
++    sqlite3_step(pWriter);
++    p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
++  }
++}
++
++/*
++** This function does the work for an sqlite3rbu_step() call.
++**
++** The object-iterator (p->objiter) currently points to a valid object,
++** and the input cursor (p->objiter.pSelect) currently points to a valid
++** input row. Perform whatever processing is required and return.
++**
++** If no  error occurs, SQLITE_OK is returned. Otherwise, an error code
++** and message is left in the RBU handle and a copy of the error code
++** returned.
++*/
++static int rbuStep(sqlite3rbu *p){
++  RbuObjIter *pIter = &p->objiter;
++  const char *zMask = 0;
++  int eType = rbuStepType(p, &zMask);
++
++  if( eType ){
++    assert( eType==RBU_INSERT     || eType==RBU_DELETE
++         || eType==RBU_REPLACE    || eType==RBU_IDX_DELETE
++         || eType==RBU_IDX_INSERT || eType==RBU_UPDATE
++    );
++    assert( eType!=RBU_UPDATE || pIter->zIdx==0 );
++
++    if( pIter->zIdx==0 && (eType==RBU_IDX_DELETE || eType==RBU_IDX_INSERT) ){
++      rbuBadControlError(p);
++    }
++    else if( eType==RBU_REPLACE ){
++      if( pIter->zIdx==0 ){
++        p->nPhaseOneStep += p->objiter.nIndex;
++        rbuStepOneOp(p, RBU_DELETE);
++      }
++      if( p->rc==SQLITE_OK ) rbuStepOneOp(p, RBU_INSERT);
++    }
++    else if( eType!=RBU_UPDATE ){
++      rbuStepOneOp(p, eType);
++    }
++    else{
++      sqlite3_value *pVal;
++      sqlite3_stmt *pUpdate = 0;
++      assert( eType==RBU_UPDATE );
++      p->nPhaseOneStep -= p->objiter.nIndex;
++      rbuGetUpdateStmt(p, pIter, zMask, &pUpdate);
++      if( pUpdate ){
++        int i;
++        for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){
++          char c = zMask[pIter->aiSrcOrder[i]];
++          pVal = sqlite3_column_value(pIter->pSelect, i);
++          if( pIter->abTblPk[i] || c!='.' ){
++            p->rc = sqlite3_bind_value(pUpdate, i+1, pVal);
++          }
++        }
++        if( p->rc==SQLITE_OK 
++         && (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) 
++        ){
++          /* Bind the rbu_rowid value to column _rowid_ */
++          assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid");
++          pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
++          p->rc = sqlite3_bind_value(pUpdate, pIter->nCol+1, pVal);
++        }
++        if( p->rc==SQLITE_OK ){
++          sqlite3_step(pUpdate);
++          p->rc = resetAndCollectError(pUpdate, &p->zErrmsg);
++        }
++      }
++    }
++  }
++  return p->rc;
++}
++
++/*
++** Increment the schema cookie of the main database opened by p->dbMain.
++**
++** Or, if this is an RBU vacuum, set the schema cookie of the main db
++** opened by p->dbMain to one more than the schema cookie of the main
++** db opened by p->dbRbu.
++*/
++static void rbuIncrSchemaCookie(sqlite3rbu *p){
++  if( p->rc==SQLITE_OK ){
++    sqlite3 *dbread = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
++    int iCookie = 1000000;
++    sqlite3_stmt *pStmt;
++
++    p->rc = prepareAndCollectError(dbread, &pStmt, &p->zErrmsg, 
++        "PRAGMA schema_version"
++    );
++    if( p->rc==SQLITE_OK ){
++      /* Coverage: it may be that this sqlite3_step() cannot fail. There
++      ** is already a transaction open, so the prepared statement cannot
++      ** throw an SQLITE_SCHEMA exception. The only database page the
++      ** statement reads is page 1, which is guaranteed to be in the cache.
++      ** And no memory allocations are required.  */
++      if( SQLITE_ROW==sqlite3_step(pStmt) ){
++        iCookie = sqlite3_column_int(pStmt, 0);
++      }
++      rbuFinalize(p, pStmt);
++    }
++    if( p->rc==SQLITE_OK ){
++      rbuMPrintfExec(p, p->dbMain, "PRAGMA schema_version = %d", iCookie+1);
++    }
++  }
++}
++
++/*
++** Update the contents of the rbu_state table within the rbu database. The
++** value stored in the RBU_STATE_STAGE column is eStage. All other values
++** are determined by inspecting the rbu handle passed as the first argument.
++*/
++static void rbuSaveState(sqlite3rbu *p, int eStage){
++  if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){
++    sqlite3_stmt *pInsert = 0;
++    rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd);
++    int rc;
++
++    assert( p->zErrmsg==0 );
++    rc = prepareFreeAndCollectError(p->dbRbu, &pInsert, &p->zErrmsg, 
++        sqlite3_mprintf(
++          "INSERT OR REPLACE INTO %s.rbu_state(k, v) VALUES "
++          "(%d, %d), "
++          "(%d, %Q), "
++          "(%d, %Q), "
++          "(%d, %d), "
++          "(%d, %d), "
++          "(%d, %lld), "
++          "(%d, %lld), "
++          "(%d, %lld), "
++          "(%d, %lld) ",
++          p->zStateDb,
++          RBU_STATE_STAGE, eStage,
++          RBU_STATE_TBL, p->objiter.zTbl, 
++          RBU_STATE_IDX, p->objiter.zIdx, 
++          RBU_STATE_ROW, p->nStep, 
++          RBU_STATE_PROGRESS, p->nProgress,
++          RBU_STATE_CKPT, p->iWalCksum,
++          RBU_STATE_COOKIE, (i64)pFd->iCookie,
++          RBU_STATE_OALSZ, p->iOalSz,
++          RBU_STATE_PHASEONESTEP, p->nPhaseOneStep
++      )
++    );
++    assert( pInsert==0 || rc==SQLITE_OK );
++
++    if( rc==SQLITE_OK ){
++      sqlite3_step(pInsert);
++      rc = sqlite3_finalize(pInsert);
++    }
++    if( rc!=SQLITE_OK ) p->rc = rc;
++  }
++}
++
++
++/*
++** The second argument passed to this function is the name of a PRAGMA 
++** setting - "page_size", "auto_vacuum", "user_version" or "application_id".
++** This function executes the following on sqlite3rbu.dbRbu:
++**
++**   "PRAGMA main.$zPragma"
++**
++** where $zPragma is the string passed as the second argument, then
++** on sqlite3rbu.dbMain:
++**
++**   "PRAGMA main.$zPragma = $val"
++**
++** where $val is the value returned by the first PRAGMA invocation.
++**
++** In short, it copies the value  of the specified PRAGMA setting from
++** dbRbu to dbMain.
++*/
++static void rbuCopyPragma(sqlite3rbu *p, const char *zPragma){
++  if( p->rc==SQLITE_OK ){
++    sqlite3_stmt *pPragma = 0;
++    p->rc = prepareFreeAndCollectError(p->dbRbu, &pPragma, &p->zErrmsg, 
++        sqlite3_mprintf("PRAGMA main.%s", zPragma)
++    );
++    if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPragma) ){
++      p->rc = rbuMPrintfExec(p, p->dbMain, "PRAGMA main.%s = %d",
++          zPragma, sqlite3_column_int(pPragma, 0)
++      );
++    }
++    rbuFinalize(p, pPragma);
++  }
++}
++
++/*
++** The RBU handle passed as the only argument has just been opened and 
++** the state database is empty. If this RBU handle was opened for an
++** RBU vacuum operation, create the schema in the target db.
++*/
++static void rbuCreateTargetSchema(sqlite3rbu *p){
++  sqlite3_stmt *pSql = 0;
++  sqlite3_stmt *pInsert = 0;
++
++  assert( rbuIsVacuum(p) );
++  p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg);
++  if( p->rc==SQLITE_OK ){
++    p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, 
++      "SELECT sql FROM sqlite_master WHERE sql!='' AND rootpage!=0"
++      " AND name!='sqlite_sequence' "
++      " ORDER BY type DESC"
++    );
++  }
++
++  while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
++    const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
++    p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg);
++  }
++  rbuFinalize(p, pSql);
++  if( p->rc!=SQLITE_OK ) return;
++
++  if( p->rc==SQLITE_OK ){
++    p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, 
++        "SELECT * FROM sqlite_master WHERE rootpage=0 OR rootpage IS NULL" 
++    );
++  }
++
++  if( p->rc==SQLITE_OK ){
++    p->rc = prepareAndCollectError(p->dbMain, &pInsert, &p->zErrmsg, 
++        "INSERT INTO sqlite_master VALUES(?,?,?,?,?)"
++    );
++  }
++
++  while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
++    int i;
++    for(i=0; i<5; i++){
++      sqlite3_bind_value(pInsert, i+1, sqlite3_column_value(pSql, i));
++    }
++    sqlite3_step(pInsert);
++    p->rc = sqlite3_reset(pInsert);
++  }
++  if( p->rc==SQLITE_OK ){
++    p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=0",0,0,&p->zErrmsg);
++  }
++
++  rbuFinalize(p, pSql);
++  rbuFinalize(p, pInsert);
++}
++
++/*
++** Step the RBU object.
++*/
++SQLITE_API int sqlite3rbu_step(sqlite3rbu *p){
++  if( p ){
++    switch( p->eStage ){
++      case RBU_STAGE_OAL: {
++        RbuObjIter *pIter = &p->objiter;
++
++        /* If this is an RBU vacuum operation and the state table was empty
++        ** when this handle was opened, create the target database schema. */
++        if( rbuIsVacuum(p) && p->nProgress==0 && p->rc==SQLITE_OK ){
++          rbuCreateTargetSchema(p);
++          rbuCopyPragma(p, "user_version");
++          rbuCopyPragma(p, "application_id");
++        }
++
++        while( p->rc==SQLITE_OK && pIter->zTbl ){
++
++          if( pIter->bCleanup ){
++            /* Clean up the rbu_tmp_xxx table for the previous table. It 
++            ** cannot be dropped as there are currently active SQL statements.
++            ** But the contents can be deleted.  */
++            if( rbuIsVacuum(p)==0 && pIter->abIndexed ){
++              rbuMPrintfExec(p, p->dbRbu, 
++                  "DELETE FROM %s.'rbu_tmp_%q'", p->zStateDb, pIter->zDataTbl
++              );
++            }
++          }else{
++            rbuObjIterPrepareAll(p, pIter, 0);
++
++            /* Advance to the next row to process. */
++            if( p->rc==SQLITE_OK ){
++              int rc = sqlite3_step(pIter->pSelect);
++              if( rc==SQLITE_ROW ){
++                p->nProgress++;
++                p->nStep++;
++                return rbuStep(p);
++              }
++              p->rc = sqlite3_reset(pIter->pSelect);
++              p->nStep = 0;
++            }
++          }
++
++          rbuObjIterNext(p, pIter);
++        }
++
++        if( p->rc==SQLITE_OK ){
++          assert( pIter->zTbl==0 );
++          rbuSaveState(p, RBU_STAGE_MOVE);
++          rbuIncrSchemaCookie(p);
++          if( p->rc==SQLITE_OK ){
++            p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
++          }
++          if( p->rc==SQLITE_OK ){
++            p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, &p->zErrmsg);
++          }
++          p->eStage = RBU_STAGE_MOVE;
++        }
++        break;
++      }
++
++      case RBU_STAGE_MOVE: {
++        if( p->rc==SQLITE_OK ){
++          rbuMoveOalFile(p);
++          p->nProgress++;
++        }
++        break;
++      }
++
++      case RBU_STAGE_CKPT: {
++        if( p->rc==SQLITE_OK ){
++          if( p->nStep>=p->nFrame ){
++            sqlite3_file *pDb = p->pTargetFd->pReal;
++  
++            /* Sync the db file */
++            p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
++  
++            /* Update nBackfill */
++            if( p->rc==SQLITE_OK ){
++              void volatile *ptr;
++              p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, &ptr);
++              if( p->rc==SQLITE_OK ){
++                ((u32 volatile*)ptr)[24] = p->iMaxFrame;
++              }
++            }
++  
++            if( p->rc==SQLITE_OK ){
++              p->eStage = RBU_STAGE_DONE;
++              p->rc = SQLITE_DONE;
++            }
++          }else{
++            /* At one point the following block copied a single frame from the
++            ** wal file to the database file. So that one call to sqlite3rbu_step()
++            ** checkpointed a single frame. 
++            **
++            ** However, if the sector-size is larger than the page-size, and the
++            ** application calls sqlite3rbu_savestate() or close() immediately
++            ** after this step, then rbu_step() again, then a power failure occurs,
++            ** then the database page written here may be damaged. Work around
++            ** this by checkpointing frames until the next page in the aFrame[]
++            ** lies on a different disk sector to the current one. */
++            u32 iSector;
++            do{
++              RbuFrame *pFrame = &p->aFrame[p->nStep];
++              iSector = (pFrame->iDbPage-1) / p->nPagePerSector;
++              rbuCheckpointFrame(p, pFrame);
++              p->nStep++;
++            }while( p->nStep<p->nFrame 
++                 && iSector==((p->aFrame[p->nStep].iDbPage-1) / p->nPagePerSector)
++                 && p->rc==SQLITE_OK
++            );
++          }
++          p->nProgress++;
++        }
++        break;
++      }
++
++      default:
++        break;
++    }
++    return p->rc;
++  }else{
++    return SQLITE_NOMEM;
++  }
++}
++
++/*
++** Compare strings z1 and z2, returning 0 if they are identical, or non-zero
++** otherwise. Either or both argument may be NULL. Two NULL values are
++** considered equal, and NULL is considered distinct from all other values.
++*/
++static int rbuStrCompare(const char *z1, const char *z2){
++  if( z1==0 && z2==0 ) return 0;
++  if( z1==0 || z2==0 ) return 1;
++  return (sqlite3_stricmp(z1, z2)!=0);
++}
++
++/*
++** This function is called as part of sqlite3rbu_open() when initializing
++** an rbu handle in OAL stage. If the rbu update has not started (i.e.
++** the rbu_state table was empty) it is a no-op. Otherwise, it arranges
++** things so that the next call to sqlite3rbu_step() continues on from
++** where the previous rbu handle left off.
++**
++** If an error occurs, an error code and error message are left in the
++** rbu handle passed as the first argument.
++*/
++static void rbuSetupOal(sqlite3rbu *p, RbuState *pState){
++  assert( p->rc==SQLITE_OK );
++  if( pState->zTbl ){
++    RbuObjIter *pIter = &p->objiter;
++    int rc = SQLITE_OK;
++
++    while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup 
++       || rbuStrCompare(pIter->zIdx, pState->zIdx)
++       || rbuStrCompare(pIter->zTbl, pState->zTbl) 
++    )){
++      rc = rbuObjIterNext(p, pIter);
++    }
++
++    if( rc==SQLITE_OK && !pIter->zTbl ){
++      rc = SQLITE_ERROR;
++      p->zErrmsg = sqlite3_mprintf("rbu_state mismatch error");
++    }
++
++    if( rc==SQLITE_OK ){
++      p->nStep = pState->nRow;
++      rc = rbuObjIterPrepareAll(p, &p->objiter, p->nStep);
++    }
++
++    p->rc = rc;
++  }
++}
++
++/*
++** If there is a "*-oal" file in the file-system corresponding to the
++** target database in the file-system, delete it. If an error occurs,
++** leave an error code and error message in the rbu handle.
++*/
++static void rbuDeleteOalFile(sqlite3rbu *p){
++  char *zOal = rbuMPrintf(p, "%s-oal", p->zTarget);
++  if( zOal ){
++    sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
++    assert( pVfs && p->rc==SQLITE_OK && p->zErrmsg==0 );
++    pVfs->xDelete(pVfs, zOal, 0);
++    sqlite3_free(zOal);
++  }
++}
++
++/*
++** Allocate a private rbu VFS for the rbu handle passed as the only
++** argument. This VFS will be used unless the call to sqlite3rbu_open()
++** specified a URI with a vfs=? option in place of a target database
++** file name.
++*/
++static void rbuCreateVfs(sqlite3rbu *p){
++  int rnd;
++  char zRnd[64];
++
++  assert( p->rc==SQLITE_OK );
++  sqlite3_randomness(sizeof(int), (void*)&rnd);
++  sqlite3_snprintf(sizeof(zRnd), zRnd, "rbu_vfs_%d", rnd);
++  p->rc = sqlite3rbu_create_vfs(zRnd, 0);
++  if( p->rc==SQLITE_OK ){
++    sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd);
++    assert( pVfs );
++    p->zVfsName = pVfs->zName;
++  }
++}
++
++/*
++** Destroy the private VFS created for the rbu handle passed as the only
++** argument by an earlier call to rbuCreateVfs().
++*/
++static void rbuDeleteVfs(sqlite3rbu *p){
++  if( p->zVfsName ){
++    sqlite3rbu_destroy_vfs(p->zVfsName);
++    p->zVfsName = 0;
++  }
++}
++
++/*
++** This user-defined SQL function is invoked with a single argument - the
++** name of a table expected to appear in the target database. It returns
++** the number of auxilliary indexes on the table.
++*/
++static void rbuIndexCntFunc(
++  sqlite3_context *pCtx, 
++  int nVal,
++  sqlite3_value **apVal
++){
++  sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx);
++  sqlite3_stmt *pStmt = 0;
++  char *zErrmsg = 0;
++  int rc;
++
++  assert( nVal==1 );
++  
++  rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg, 
++      sqlite3_mprintf("SELECT count(*) FROM sqlite_master "
++        "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0]))
++  );
++  if( rc!=SQLITE_OK ){
++    sqlite3_result_error(pCtx, zErrmsg, -1);
++  }else{
++    int nIndex = 0;
++    if( SQLITE_ROW==sqlite3_step(pStmt) ){
++      nIndex = sqlite3_column_int(pStmt, 0);
++    }
++    rc = sqlite3_finalize(pStmt);
++    if( rc==SQLITE_OK ){
++      sqlite3_result_int(pCtx, nIndex);
++    }else{
++      sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1);
++    }
++  }
++
++  sqlite3_free(zErrmsg);
++}
++
++/*
++** If the RBU database contains the rbu_count table, use it to initialize
++** the sqlite3rbu.nPhaseOneStep variable. The schema of the rbu_count table
++** is assumed to contain the same columns as:
++**
++**   CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
++**
++** There should be one row in the table for each data_xxx table in the
++** database. The 'tbl' column should contain the name of a data_xxx table,
++** and the cnt column the number of rows it contains.
++**
++** sqlite3rbu.nPhaseOneStep is initialized to the sum of (1 + nIndex) * cnt
++** for all rows in the rbu_count table, where nIndex is the number of 
++** indexes on the corresponding target database table.
++*/
++static void rbuInitPhaseOneSteps(sqlite3rbu *p){
++  if( p->rc==SQLITE_OK ){
++    sqlite3_stmt *pStmt = 0;
++    int bExists = 0;                /* True if rbu_count exists */
++
++    p->nPhaseOneStep = -1;
++
++    p->rc = sqlite3_create_function(p->dbRbu, 
++        "rbu_index_cnt", 1, SQLITE_UTF8, (void*)p, rbuIndexCntFunc, 0, 0
++    );
++  
++    /* Check for the rbu_count table. If it does not exist, or if an error
++    ** occurs, nPhaseOneStep will be left set to -1. */
++    if( p->rc==SQLITE_OK ){
++      p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
++          "SELECT 1 FROM sqlite_master WHERE tbl_name = 'rbu_count'"
++      );
++    }
++    if( p->rc==SQLITE_OK ){
++      if( SQLITE_ROW==sqlite3_step(pStmt) ){
++        bExists = 1;
++      }
++      p->rc = sqlite3_finalize(pStmt);
++    }
++  
++    if( p->rc==SQLITE_OK && bExists ){
++      p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
++          "SELECT sum(cnt * (1 + rbu_index_cnt(rbu_target_name(tbl))))"
++          "FROM rbu_count"
++      );
++      if( p->rc==SQLITE_OK ){
++        if( SQLITE_ROW==sqlite3_step(pStmt) ){
++          p->nPhaseOneStep = sqlite3_column_int64(pStmt, 0);
++        }
++        p->rc = sqlite3_finalize(pStmt);
++      }
++    }
++  }
++}
++
++
++static sqlite3rbu *openRbuHandle(
++  const char *zTarget, 
++  const char *zRbu,
++  const char *zState
++){
++  sqlite3rbu *p;
++  size_t nTarget = zTarget ? strlen(zTarget) : 0;
++  size_t nRbu = strlen(zRbu);
++  size_t nByte = sizeof(sqlite3rbu) + nTarget+1 + nRbu+1;
++
++  p = (sqlite3rbu*)sqlite3_malloc64(nByte);
++  if( p ){
++    RbuState *pState = 0;
++
++    /* Create the custom VFS. */
++    memset(p, 0, sizeof(sqlite3rbu));
++    rbuCreateVfs(p);
++
++    /* Open the target, RBU and state databases */
++    if( p->rc==SQLITE_OK ){
++      char *pCsr = (char*)&p[1];
++      int bRetry = 0;
++      if( zTarget ){
++        p->zTarget = pCsr;
++        memcpy(p->zTarget, zTarget, nTarget+1);
++        pCsr += nTarget+1;
++      }
++      p->zRbu = pCsr;
++      memcpy(p->zRbu, zRbu, nRbu+1);
++      pCsr += nRbu+1;
++      if( zState ){
++        p->zState = rbuMPrintf(p, "%s", zState);
++      }
++
++      /* If the first attempt to open the database file fails and the bRetry
++      ** flag it set, this means that the db was not opened because it seemed
++      ** to be a wal-mode db. But, this may have happened due to an earlier
++      ** RBU vacuum operation leaving an old wal file in the directory.
++      ** If this is the case, it will have been checkpointed and deleted
++      ** when the handle was closed and a second attempt to open the 
++      ** database may succeed.  */
++      rbuOpenDatabase(p, &bRetry);
++      if( bRetry ){
++        rbuOpenDatabase(p, 0);
++      }
++    }
++
++    if( p->rc==SQLITE_OK ){
++      pState = rbuLoadState(p);
++      assert( pState || p->rc!=SQLITE_OK );
++      if( p->rc==SQLITE_OK ){
++
++        if( pState->eStage==0 ){ 
++          rbuDeleteOalFile(p);
++          rbuInitPhaseOneSteps(p);
++          p->eStage = RBU_STAGE_OAL;
++        }else{
++          p->eStage = pState->eStage;
++          p->nPhaseOneStep = pState->nPhaseOneStep;
++        }
++        p->nProgress = pState->nProgress;
++        p->iOalSz = pState->iOalSz;
++      }
++    }
++    assert( p->rc!=SQLITE_OK || p->eStage!=0 );
++
++    if( p->rc==SQLITE_OK && p->pTargetFd->pWalFd ){
++      if( p->eStage==RBU_STAGE_OAL ){
++        p->rc = SQLITE_ERROR;
++        p->zErrmsg = sqlite3_mprintf("cannot update wal mode database");
++      }else if( p->eStage==RBU_STAGE_MOVE ){
++        p->eStage = RBU_STAGE_CKPT;
++        p->nStep = 0;
++      }
++    }
++
++    if( p->rc==SQLITE_OK 
++     && (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE)
++     && pState->eStage!=0
++    ){
++      rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd);
++      if( pFd->iCookie!=pState->iCookie ){   
++        /* At this point (pTargetFd->iCookie) contains the value of the
++        ** change-counter cookie (the thing that gets incremented when a 
++        ** transaction is committed in rollback mode) currently stored on 
++        ** page 1 of the database file. */
++        p->rc = SQLITE_BUSY;
++        p->zErrmsg = sqlite3_mprintf("database modified during rbu %s",
++            (rbuIsVacuum(p) ? "vacuum" : "update")
++        );
++      }
++    }
++
++    if( p->rc==SQLITE_OK ){
++      if( p->eStage==RBU_STAGE_OAL ){
++        sqlite3 *db = p->dbMain;
++        p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg);
++
++        /* Point the object iterator at the first object */
++        if( p->rc==SQLITE_OK ){
++          p->rc = rbuObjIterFirst(p, &p->objiter);
++        }
++
++        /* If the RBU database contains no data_xxx tables, declare the RBU
++        ** update finished.  */
++        if( p->rc==SQLITE_OK && p->objiter.zTbl==0 ){
++          p->rc = SQLITE_DONE;
++          p->eStage = RBU_STAGE_DONE;
++        }else{
++          if( p->rc==SQLITE_OK && pState->eStage==0 && rbuIsVacuum(p) ){
++            rbuCopyPragma(p, "page_size");
++            rbuCopyPragma(p, "auto_vacuum");
++          }
++
++          /* Open transactions both databases. The *-oal file is opened or
++          ** created at this point. */
++          if( p->rc==SQLITE_OK ){
++            p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
++          }
++
++          /* Check if the main database is a zipvfs db. If it is, set the upper
++          ** level pager to use "journal_mode=off". This prevents it from 
++          ** generating a large journal using a temp file.  */
++          if( p->rc==SQLITE_OK ){
++            int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0);
++            if( frc==SQLITE_OK ){
++              p->rc = sqlite3_exec(
++                db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg);
++            }
++          }
++
++          if( p->rc==SQLITE_OK ){
++            rbuSetupOal(p, pState);
++          }
++        }
++      }else if( p->eStage==RBU_STAGE_MOVE ){
++        /* no-op */
++      }else if( p->eStage==RBU_STAGE_CKPT ){
++        rbuSetupCheckpoint(p, pState);
++      }else if( p->eStage==RBU_STAGE_DONE ){
++        p->rc = SQLITE_DONE;
++      }else{
++        p->rc = SQLITE_CORRUPT;
++      }
++    }
++
++    rbuFreeState(pState);
++  }
++
++  return p;
++}
++
++/*
++** Allocate and return an RBU handle with all fields zeroed except for the
++** error code, which is set to SQLITE_MISUSE.
++*/
++static sqlite3rbu *rbuMisuseError(void){
++  sqlite3rbu *pRet;
++  pRet = sqlite3_malloc64(sizeof(sqlite3rbu));
++  if( pRet ){
++    memset(pRet, 0, sizeof(sqlite3rbu));
++    pRet->rc = SQLITE_MISUSE;
++  }
++  return pRet;
++}
++
++/*
++** Open and return a new RBU handle. 
++*/
++SQLITE_API sqlite3rbu *sqlite3rbu_open(
++  const char *zTarget, 
++  const char *zRbu,
++  const char *zState
++){
++  if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
++  /* TODO: Check that zTarget and zRbu are non-NULL */
++  return openRbuHandle(zTarget, zRbu, zState);
++}
++
++/*
++** Open a handle to begin or resume an RBU VACUUM operation.
++*/
++SQLITE_API sqlite3rbu *sqlite3rbu_vacuum(
++  const char *zTarget, 
++  const char *zState
++){
++  if( zTarget==0 ){ return rbuMisuseError(); }
++  /* TODO: Check that both arguments are non-NULL */
++  return openRbuHandle(0, zTarget, zState);
++}
++
++/*
++** Return the database handle used by pRbu.
++*/
++SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){
++  sqlite3 *db = 0;
++  if( pRbu ){
++    db = (bRbu ? pRbu->dbRbu : pRbu->dbMain);
++  }
++  return db;
++}
++
++
++/*
++** If the error code currently stored in the RBU handle is SQLITE_CONSTRAINT,
++** then edit any error message string so as to remove all occurrences of
++** the pattern "rbu_imp_[0-9]*".
++*/
++static void rbuEditErrmsg(sqlite3rbu *p){
++  if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){
++    unsigned int i;
++    size_t nErrmsg = strlen(p->zErrmsg);
++    for(i=0; i<(nErrmsg-8); i++){
++      if( memcmp(&p->zErrmsg[i], "rbu_imp_", 8)==0 ){
++        int nDel = 8;
++        while( p->zErrmsg[i+nDel]>='0' && p->zErrmsg[i+nDel]<='9' ) nDel++;
++        memmove(&p->zErrmsg[i], &p->zErrmsg[i+nDel], nErrmsg + 1 - i - nDel);
++        nErrmsg -= nDel;
++      }
++    }
++  }
++}
++
++/*
++** Close the RBU handle.
++*/
++SQLITE_API int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
++  int rc;
++  if( p ){
++
++    /* Commit the transaction to the *-oal file. */
++    if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){
++      p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
++    }
++
++    /* Sync the db file if currently doing an incremental checkpoint */
++    if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
++      sqlite3_file *pDb = p->pTargetFd->pReal;
++      p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
++    }
++
++    rbuSaveState(p, p->eStage);
++
++    if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){
++      p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, &p->zErrmsg);
++    }
++
++    /* Close any open statement handles. */
++    rbuObjIterFinalize(&p->objiter);
++
++    /* If this is an RBU vacuum handle and the vacuum has either finished
++    ** successfully or encountered an error, delete the contents of the 
++    ** state table. This causes the next call to sqlite3rbu_vacuum() 
++    ** specifying the current target and state databases to start a new
++    ** vacuum from scratch.  */
++    if( rbuIsVacuum(p) && p->rc!=SQLITE_OK && p->dbRbu ){
++      int rc2 = sqlite3_exec(p->dbRbu, "DELETE FROM stat.rbu_state", 0, 0, 0);
++      if( p->rc==SQLITE_DONE && rc2!=SQLITE_OK ) p->rc = rc2;
++    }
++
++    /* Close the open database handle and VFS object. */
++    sqlite3_close(p->dbRbu);
++    sqlite3_close(p->dbMain);
++    rbuDeleteVfs(p);
++    sqlite3_free(p->aBuf);
++    sqlite3_free(p->aFrame);
++
++    rbuEditErrmsg(p);
++    rc = p->rc;
++    if( pzErrmsg ){
++      *pzErrmsg = p->zErrmsg;
++    }else{
++      sqlite3_free(p->zErrmsg);
++    }
++    sqlite3_free(p->zState);
++    sqlite3_free(p);
++  }else{
++    rc = SQLITE_NOMEM;
++    *pzErrmsg = 0;
++  }
++  return rc;
++}
++
++/*
++** Return the total number of key-value operations (inserts, deletes or 
++** updates) that have been performed on the target database since the
++** current RBU update was started.
++*/
++SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu){
++  return pRbu->nProgress;
++}
++
++/*
++** Return permyriadage progress indications for the two main stages of
++** an RBU update.
++*/
++SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){
++  const int MAX_PROGRESS = 10000;
++  switch( p->eStage ){
++    case RBU_STAGE_OAL:
++      if( p->nPhaseOneStep>0 ){
++        *pnOne = (int)(MAX_PROGRESS * (i64)p->nProgress/(i64)p->nPhaseOneStep);
++      }else{
++        *pnOne = -1;
++      }
++      *pnTwo = 0;
++      break;
++
++    case RBU_STAGE_MOVE:
++      *pnOne = MAX_PROGRESS;
++      *pnTwo = 0;
++      break;
++
++    case RBU_STAGE_CKPT:
++      *pnOne = MAX_PROGRESS;
++      *pnTwo = (int)(MAX_PROGRESS * (i64)p->nStep / (i64)p->nFrame);
++      break;
++
++    case RBU_STAGE_DONE:
++      *pnOne = MAX_PROGRESS;
++      *pnTwo = MAX_PROGRESS;
++      break;
++
++    default:
++      assert( 0 );
++  }
++}
++
++/*
++** Return the current state of the RBU vacuum or update operation.
++*/
++SQLITE_API int sqlite3rbu_state(sqlite3rbu *p){
++  int aRes[] = {
++    0, SQLITE_RBU_STATE_OAL, SQLITE_RBU_STATE_MOVE,
++    0, SQLITE_RBU_STATE_CHECKPOINT, SQLITE_RBU_STATE_DONE
++  };
++
++  assert( RBU_STAGE_OAL==1 );
++  assert( RBU_STAGE_MOVE==2 );
++  assert( RBU_STAGE_CKPT==4 );
++  assert( RBU_STAGE_DONE==5 );
++  assert( aRes[RBU_STAGE_OAL]==SQLITE_RBU_STATE_OAL );
++  assert( aRes[RBU_STAGE_MOVE]==SQLITE_RBU_STATE_MOVE );
++  assert( aRes[RBU_STAGE_CKPT]==SQLITE_RBU_STATE_CHECKPOINT );
++  assert( aRes[RBU_STAGE_DONE]==SQLITE_RBU_STATE_DONE );
++
++  if( p->rc!=SQLITE_OK && p->rc!=SQLITE_DONE ){
++    return SQLITE_RBU_STATE_ERROR;
++  }else{
++    assert( p->rc!=SQLITE_DONE || p->eStage==RBU_STAGE_DONE );
++    assert( p->eStage==RBU_STAGE_OAL
++         || p->eStage==RBU_STAGE_MOVE
++         || p->eStage==RBU_STAGE_CKPT
++         || p->eStage==RBU_STAGE_DONE
++    );
++    return aRes[p->eStage];
++  }
++}
++
++SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){
++  int rc = p->rc;
++  if( rc==SQLITE_DONE ) return SQLITE_OK;
++
++  assert( p->eStage>=RBU_STAGE_OAL && p->eStage<=RBU_STAGE_DONE );
++  if( p->eStage==RBU_STAGE_OAL ){
++    assert( rc!=SQLITE_DONE );
++    if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0);
++  }
++
++  /* Sync the db file */
++  if( rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
++    sqlite3_file *pDb = p->pTargetFd->pReal;
++    rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
++  }
++
++  p->rc = rc;
++  rbuSaveState(p, p->eStage);
++  rc = p->rc;
++
++  if( p->eStage==RBU_STAGE_OAL ){
++    assert( rc!=SQLITE_DONE );
++    if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0);
++    if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, 0);
++    if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0,0);
++  }
++
++  p->rc = rc;
++  return rc;
++}
++
++/**************************************************************************
++** Beginning of RBU VFS shim methods. The VFS shim modifies the behaviour
++** of a standard VFS in the following ways:
++**
++** 1. Whenever the first page of a main database file is read or 
++**    written, the value of the change-counter cookie is stored in
++**    rbu_file.iCookie. Similarly, the value of the "write-version"
++**    database header field is stored in rbu_file.iWriteVer. This ensures
++**    that the values are always trustworthy within an open transaction.
++**
++** 2. Whenever an SQLITE_OPEN_WAL file is opened, the (rbu_file.pWalFd)
++**    member variable of the associated database file descriptor is set
++**    to point to the new file. A mutex protected linked list of all main 
++**    db fds opened using a particular RBU VFS is maintained at 
++**    rbu_vfs.pMain to facilitate this.
++**
++** 3. Using a new file-control "SQLITE_FCNTL_RBU", a main db rbu_file 
++**    object can be marked as the target database of an RBU update. This
++**    turns on the following extra special behaviour:
++**
++** 3a. If xAccess() is called to check if there exists a *-wal file 
++**     associated with an RBU target database currently in RBU_STAGE_OAL
++**     stage (preparing the *-oal file), the following special handling
++**     applies:
++**
++**      * if the *-wal file does exist, return SQLITE_CANTOPEN. An RBU
++**        target database may not be in wal mode already.
++**
++**      * if the *-wal file does not exist, set the output parameter to
++**        non-zero (to tell SQLite that it does exist) anyway.
++**
++**     Then, when xOpen() is called to open the *-wal file associated with
++**     the RBU target in RBU_STAGE_OAL stage, instead of opening the *-wal
++**     file, the rbu vfs opens the corresponding *-oal file instead. 
++**
++** 3b. The *-shm pages returned by xShmMap() for a target db file in
++**     RBU_STAGE_OAL mode are actually stored in heap memory. This is to
++**     avoid creating a *-shm file on disk. Additionally, xShmLock() calls
++**     are no-ops on target database files in RBU_STAGE_OAL mode. This is
++**     because assert() statements in some VFS implementations fail if 
++**     xShmLock() is called before xShmMap().
++**
++** 3c. If an EXCLUSIVE lock is attempted on a target database file in any
++**     mode except RBU_STAGE_DONE (all work completed and checkpointed), it 
++**     fails with an SQLITE_BUSY error. This is to stop RBU connections
++**     from automatically checkpointing a *-wal (or *-oal) file from within
++**     sqlite3_close().
++**
++** 3d. In RBU_STAGE_CAPTURE mode, all xRead() calls on the wal file, and
++**     all xWrite() calls on the target database file perform no IO. 
++**     Instead the frame and page numbers that would be read and written
++**     are recorded. Additionally, successful attempts to obtain exclusive
++**     xShmLock() WRITER, CHECKPOINTER and READ0 locks on the target 
++**     database file are recorded. xShmLock() calls to unlock the same
++**     locks are no-ops (so that once obtained, these locks are never
++**     relinquished). Finally, calls to xSync() on the target database
++**     file fail with SQLITE_INTERNAL errors.
++*/
++
++static void rbuUnlockShm(rbu_file *p){
++  if( p->pRbu ){
++    int (*xShmLock)(sqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock;
++    int i;
++    for(i=0; i<SQLITE_SHM_NLOCK;i++){
++      if( (1<<i) & p->pRbu->mLock ){
++        xShmLock(p->pReal, i, 1, SQLITE_SHM_UNLOCK|SQLITE_SHM_EXCLUSIVE);
++      }
++    }
++    p->pRbu->mLock = 0;
++  }
++}
++
++/*
++** Close an rbu file.
++*/
++static int rbuVfsClose(sqlite3_file *pFile){
++  rbu_file *p = (rbu_file*)pFile;
++  int rc;
++  int i;
++
++  /* Free the contents of the apShm[] array. And the array itself. */
++  for(i=0; i<p->nShm; i++){
++    sqlite3_free(p->apShm[i]);
++  }
++  sqlite3_free(p->apShm);
++  p->apShm = 0;
++  sqlite3_free(p->zDel);
++
++  if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
++    rbu_file **pp;
++    sqlite3_mutex_enter(p->pRbuVfs->mutex);
++    for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
++    *pp = p->pMainNext;
++    sqlite3_mutex_leave(p->pRbuVfs->mutex);
++    rbuUnlockShm(p);
++    p->pReal->pMethods->xShmUnmap(p->pReal, 0);
++  }
++
++  /* Close the underlying file handle */
++  rc = p->pReal->pMethods->xClose(p->pReal);
++  return rc;
++}
++
++
++/*
++** Read and return an unsigned 32-bit big-endian integer from the buffer 
++** passed as the only argument.
++*/
++static u32 rbuGetU32(u8 *aBuf){
++  return ((u32)aBuf[0] << 24)
++       + ((u32)aBuf[1] << 16)
++       + ((u32)aBuf[2] <<  8)
++       + ((u32)aBuf[3]);
++}
++
++/*
++** Write an unsigned 32-bit value in big-endian format to the supplied
++** buffer.
++*/
++static void rbuPutU32(u8 *aBuf, u32 iVal){
++  aBuf[0] = (iVal >> 24) & 0xFF;
++  aBuf[1] = (iVal >> 16) & 0xFF;
++  aBuf[2] = (iVal >>  8) & 0xFF;
++  aBuf[3] = (iVal >>  0) & 0xFF;
++}
++
++static void rbuPutU16(u8 *aBuf, u16 iVal){
++  aBuf[0] = (iVal >>  8) & 0xFF;
++  aBuf[1] = (iVal >>  0) & 0xFF;
++}
++
++/*
++** Read data from an rbuVfs-file.
++*/
++static int rbuVfsRead(
++  sqlite3_file *pFile, 
++  void *zBuf, 
++  int iAmt, 
++  sqlite_int64 iOfst
++){
++  rbu_file *p = (rbu_file*)pFile;
++  sqlite3rbu *pRbu = p->pRbu;
++  int rc;
++
++  if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
++    assert( p->openFlags & SQLITE_OPEN_WAL );
++    rc = rbuCaptureWalRead(p->pRbu, iOfst, iAmt);
++  }else{
++    if( pRbu && pRbu->eStage==RBU_STAGE_OAL 
++     && (p->openFlags & SQLITE_OPEN_WAL) 
++     && iOfst>=pRbu->iOalSz 
++    ){
++      rc = SQLITE_OK;
++      memset(zBuf, 0, iAmt);
++    }else{
++      rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
++#if 1
++      /* If this is being called to read the first page of the target 
++      ** database as part of an rbu vacuum operation, synthesize the 
++      ** contents of the first page if it does not yet exist. Otherwise,
++      ** SQLite will not check for a *-wal file.  */
++      if( pRbu && rbuIsVacuum(pRbu) 
++          && rc==SQLITE_IOERR_SHORT_READ && iOfst==0
++          && (p->openFlags & SQLITE_OPEN_MAIN_DB)
++          && pRbu->rc==SQLITE_OK
++      ){
++        sqlite3_file *pFd = (sqlite3_file*)pRbu->pRbuFd;
++        rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst);
++        if( rc==SQLITE_OK ){
++          u8 *aBuf = (u8*)zBuf;
++          u32 iRoot = rbuGetU32(&aBuf[52]) ? 1 : 0;
++          rbuPutU32(&aBuf[52], iRoot);      /* largest root page number */
++          rbuPutU32(&aBuf[36], 0);          /* number of free pages */
++          rbuPutU32(&aBuf[32], 0);          /* first page on free list trunk */
++          rbuPutU32(&aBuf[28], 1);          /* size of db file in pages */
++          rbuPutU32(&aBuf[24], pRbu->pRbuFd->iCookie+1);  /* Change counter */
++
++          if( iAmt>100 ){
++            memset(&aBuf[100], 0, iAmt-100);
++            rbuPutU16(&aBuf[105], iAmt & 0xFFFF);
++            aBuf[100] = 0x0D;
++          }
++        }
++      }
++#endif
++    }
++    if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
++      /* These look like magic numbers. But they are stable, as they are part
++       ** of the definition of the SQLite file format, which may not change. */
++      u8 *pBuf = (u8*)zBuf;
++      p->iCookie = rbuGetU32(&pBuf[24]);
++      p->iWriteVer = pBuf[19];
++    }
++  }
++  return rc;
++}
++
++/*
++** Write data to an rbuVfs-file.
++*/
++static int rbuVfsWrite(
++  sqlite3_file *pFile, 
++  const void *zBuf, 
++  int iAmt, 
++  sqlite_int64 iOfst
++){
++  rbu_file *p = (rbu_file*)pFile;
++  sqlite3rbu *pRbu = p->pRbu;
++  int rc;
++
++  if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
++    assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
++    rc = rbuCaptureDbWrite(p->pRbu, iOfst);
++  }else{
++    if( pRbu && pRbu->eStage==RBU_STAGE_OAL 
++     && (p->openFlags & SQLITE_OPEN_WAL) 
++     && iOfst>=pRbu->iOalSz
++    ){
++      pRbu->iOalSz = iAmt + iOfst;
++    }
++    rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
++    if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
++      /* These look like magic numbers. But they are stable, as they are part
++      ** of the definition of the SQLite file format, which may not change. */
++      u8 *pBuf = (u8*)zBuf;
++      p->iCookie = rbuGetU32(&pBuf[24]);
++      p->iWriteVer = pBuf[19];
++    }
++  }
++  return rc;
++}
++
++/*
++** Truncate an rbuVfs-file.
++*/
++static int rbuVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
++  rbu_file *p = (rbu_file*)pFile;
++  return p->pReal->pMethods->xTruncate(p->pReal, size);
++}
++
++/*
++** Sync an rbuVfs-file.
++*/
++static int rbuVfsSync(sqlite3_file *pFile, int flags){
++  rbu_file *p = (rbu_file *)pFile;
++  if( p->pRbu && p->pRbu->eStage==RBU_STAGE_CAPTURE ){
++    if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
++      return SQLITE_INTERNAL;
++    }
++    return SQLITE_OK;
++  }
++  return p->pReal->pMethods->xSync(p->pReal, flags);
++}
++
++/*
++** Return the current file-size of an rbuVfs-file.
++*/
++static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
++  rbu_file *p = (rbu_file *)pFile;
++  int rc;
++  rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
++
++  /* If this is an RBU vacuum operation and this is the target database,
++  ** pretend that it has at least one page. Otherwise, SQLite will not
++  ** check for the existance of a *-wal file. rbuVfsRead() contains 
++  ** similar logic.  */
++  if( rc==SQLITE_OK && *pSize==0 
++   && p->pRbu && rbuIsVacuum(p->pRbu) 
++   && (p->openFlags & SQLITE_OPEN_MAIN_DB)
++  ){
++    *pSize = 1024;
++  }
++  return rc;
++}
++
++/*
++** Lock an rbuVfs-file.
++*/
++static int rbuVfsLock(sqlite3_file *pFile, int eLock){
++  rbu_file *p = (rbu_file*)pFile;
++  sqlite3rbu *pRbu = p->pRbu;
++  int rc = SQLITE_OK;
++
++  assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
++  if( eLock==SQLITE_LOCK_EXCLUSIVE 
++   && (p->bNolock || (pRbu && pRbu->eStage!=RBU_STAGE_DONE))
++  ){
++    /* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this 
++    ** prevents it from checkpointing the database from sqlite3_close(). */
++    rc = SQLITE_BUSY;
++  }else{
++    rc = p->pReal->pMethods->xLock(p->pReal, eLock);
++  }
++
++  return rc;
++}
++
++/*
++** Unlock an rbuVfs-file.
++*/
++static int rbuVfsUnlock(sqlite3_file *pFile, int eLock){
++  rbu_file *p = (rbu_file *)pFile;
++  return p->pReal->pMethods->xUnlock(p->pReal, eLock);
++}
++
++/*
++** Check if another file-handle holds a RESERVED lock on an rbuVfs-file.
++*/
++static int rbuVfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
++  rbu_file *p = (rbu_file *)pFile;
++  return p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
++}
++
++/*
++** File control method. For custom operations on an rbuVfs-file.
++*/
++static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
++  rbu_file *p = (rbu_file *)pFile;
++  int (*xControl)(sqlite3_file*,int,void*) = p->pReal->pMethods->xFileControl;
++  int rc;
++
++  assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB)
++       || p->openFlags & (SQLITE_OPEN_TRANSIENT_DB|SQLITE_OPEN_TEMP_JOURNAL)
++  );
++  if( op==SQLITE_FCNTL_RBU ){
++    sqlite3rbu *pRbu = (sqlite3rbu*)pArg;
++
++    /* First try to find another RBU vfs lower down in the vfs stack. If
++    ** one is found, this vfs will operate in pass-through mode. The lower
++    ** level vfs will do the special RBU handling.  */
++    rc = xControl(p->pReal, op, pArg);
++
++    if( rc==SQLITE_NOTFOUND ){
++      /* Now search for a zipvfs instance lower down in the VFS stack. If
++      ** one is found, this is an error.  */
++      void *dummy = 0;
++      rc = xControl(p->pReal, SQLITE_FCNTL_ZIPVFS, &dummy);
++      if( rc==SQLITE_OK ){
++        rc = SQLITE_ERROR;
++        pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error");
++      }else if( rc==SQLITE_NOTFOUND ){
++        pRbu->pTargetFd = p;
++        p->pRbu = pRbu;
++        if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
++        rc = SQLITE_OK;
++      }
++    }
++    return rc;
++  }
++  else if( op==SQLITE_FCNTL_RBUCNT ){
++    sqlite3rbu *pRbu = (sqlite3rbu*)pArg;
++    pRbu->nRbu++;
++    pRbu->pRbuFd = p;
++    p->bNolock = 1;
++  }
++
++  rc = xControl(p->pReal, op, pArg);
++  if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
++    rbu_vfs *pRbuVfs = p->pRbuVfs;
++    char *zIn = *(char**)pArg;
++    char *zOut = sqlite3_mprintf("rbu(%s)/%z", pRbuVfs->base.zName, zIn);
++    *(char**)pArg = zOut;
++    if( zOut==0 ) rc = SQLITE_NOMEM;
++  }
++
++  return rc;
++}
++
++/*
++** Return the sector-size in bytes for an rbuVfs-file.
++*/
++static int rbuVfsSectorSize(sqlite3_file *pFile){
++  rbu_file *p = (rbu_file *)pFile;
++  return p->pReal->pMethods->xSectorSize(p->pReal);
++}
++
++/*
++** Return the device characteristic flags supported by an rbuVfs-file.
++*/
++static int rbuVfsDeviceCharacteristics(sqlite3_file *pFile){
++  rbu_file *p = (rbu_file *)pFile;
++  return p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
++}
++
++/*
++** Take or release a shared-memory lock.
++*/
++static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
++  rbu_file *p = (rbu_file*)pFile;
++  sqlite3rbu *pRbu = p->pRbu;
++  int rc = SQLITE_OK;
++
++#ifdef SQLITE_AMALGAMATION
++    assert( WAL_CKPT_LOCK==1 );
++#endif
++
++  assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
++  if( pRbu && (pRbu->eStage==RBU_STAGE_OAL || pRbu->eStage==RBU_STAGE_MOVE) ){
++    /* Magic number 1 is the WAL_CKPT_LOCK lock. Preventing SQLite from
++    ** taking this lock also prevents any checkpoints from occurring. 
++    ** todo: really, it's not clear why this might occur, as 
++    ** wal_autocheckpoint ought to be turned off.  */
++    if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
++  }else{
++    int bCapture = 0;
++    if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE)
++     && pRbu && pRbu->eStage==RBU_STAGE_CAPTURE
++     && (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0)
++    ){
++      bCapture = 1;
++    }
++
++    if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){
++      rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
++      if( bCapture && rc==SQLITE_OK ){
++        pRbu->mLock |= (1 << ofst);
++      }
++    }
++  }
++
++  return rc;
++}
++
++/*
++** Obtain a pointer to a mapping of a single 32KiB page of the *-shm file.
++*/
++static int rbuVfsShmMap(
++  sqlite3_file *pFile, 
++  int iRegion, 
++  int szRegion, 
++  int isWrite, 
++  void volatile **pp
++){
++  rbu_file *p = (rbu_file*)pFile;
++  int rc = SQLITE_OK;
++  int eStage = (p->pRbu ? p->pRbu->eStage : 0);
++
++  /* If not in RBU_STAGE_OAL, allow this call to pass through. Or, if this
++  ** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space 
++  ** instead of a file on disk.  */
++  assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
++  if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
++    if( iRegion<=p->nShm ){
++      int nByte = (iRegion+1) * sizeof(char*);
++      char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
++      if( apNew==0 ){
++        rc = SQLITE_NOMEM;
++      }else{
++        memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
++        p->apShm = apNew;
++        p->nShm = iRegion+1;
++      }
++    }
++
++    if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
++      char *pNew = (char*)sqlite3_malloc64(szRegion);
++      if( pNew==0 ){
++        rc = SQLITE_NOMEM;
++      }else{
++        memset(pNew, 0, szRegion);
++        p->apShm[iRegion] = pNew;
++      }
++    }
++
++    if( rc==SQLITE_OK ){
++      *pp = p->apShm[iRegion];
++    }else{
++      *pp = 0;
++    }
++  }else{
++    assert( p->apShm==0 );
++    rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
++  }
++
++  return rc;
++}
++
++/*
++** Memory barrier.
++*/
++static void rbuVfsShmBarrier(sqlite3_file *pFile){
++  rbu_file *p = (rbu_file *)pFile;
++  p->pReal->pMethods->xShmBarrier(p->pReal);
++}
++
++/*
++** The xShmUnmap method.
++*/
++static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){
++  rbu_file *p = (rbu_file*)pFile;
++  int rc = SQLITE_OK;
++  int eStage = (p->pRbu ? p->pRbu->eStage : 0);
++
++  assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
++  if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
++    /* no-op */
++  }else{
++    /* Release the checkpointer and writer locks */
++    rbuUnlockShm(p);
++    rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
++  }
++  return rc;
++}
++
++/*
++** Given that zWal points to a buffer containing a wal file name passed to 
++** either the xOpen() or xAccess() VFS method, return a pointer to the
++** file-handle opened by the same database connection on the corresponding
++** database file.
++*/
++static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
++  rbu_file *pDb;
++  sqlite3_mutex_enter(pRbuVfs->mutex);
++  for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
++  sqlite3_mutex_leave(pRbuVfs->mutex);
++  return pDb;
++}
++
++/* 
++** A main database named zName has just been opened. The following 
++** function returns a pointer to a buffer owned by SQLite that contains
++** the name of the *-wal file this db connection will use. SQLite
++** happens to pass a pointer to this buffer when using xAccess()
++** or xOpen() to operate on the *-wal file.  
++*/
++static const char *rbuMainToWal(const char *zName, int flags){
++  int n = (int)strlen(zName);
++  const char *z = &zName[n];
++  if( flags & SQLITE_OPEN_URI ){
++    int odd = 0;
++    while( 1 ){
++      if( z[0]==0 ){
++        odd = 1 - odd;
++        if( odd && z[1]==0 ) break;
++      }
++      z++;
++    }
++    z += 2;
++  }else{
++    while( *z==0 ) z++;
++  }
++  z += (n + 8 + 1);
++  return z;
++}
++
++/*
++** Open an rbu file handle.
++*/
++static int rbuVfsOpen(
++  sqlite3_vfs *pVfs,
++  const char *zName,
++  sqlite3_file *pFile,
++  int flags,
++  int *pOutFlags
++){
++  static sqlite3_io_methods rbuvfs_io_methods = {
++    2,                            /* iVersion */
++    rbuVfsClose,                  /* xClose */
++    rbuVfsRead,                   /* xRead */
++    rbuVfsWrite,                  /* xWrite */
++    rbuVfsTruncate,               /* xTruncate */
++    rbuVfsSync,                   /* xSync */
++    rbuVfsFileSize,               /* xFileSize */
++    rbuVfsLock,                   /* xLock */
++    rbuVfsUnlock,                 /* xUnlock */
++    rbuVfsCheckReservedLock,      /* xCheckReservedLock */
++    rbuVfsFileControl,            /* xFileControl */
++    rbuVfsSectorSize,             /* xSectorSize */
++    rbuVfsDeviceCharacteristics,  /* xDeviceCharacteristics */
++    rbuVfsShmMap,                 /* xShmMap */
++    rbuVfsShmLock,                /* xShmLock */
++    rbuVfsShmBarrier,             /* xShmBarrier */
++    rbuVfsShmUnmap,               /* xShmUnmap */
++    0, 0                          /* xFetch, xUnfetch */
++  };
++  rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs;
++  sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs;
++  rbu_file *pFd = (rbu_file *)pFile;
++  int rc = SQLITE_OK;
++  const char *zOpen = zName;
++  int oflags = flags;
++
++  memset(pFd, 0, sizeof(rbu_file));
++  pFd->pReal = (sqlite3_file*)&pFd[1];
++  pFd->pRbuVfs = pRbuVfs;
++  pFd->openFlags = flags;
++  if( zName ){
++    if( flags & SQLITE_OPEN_MAIN_DB ){
++      /* A main database has just been opened. The following block sets
++      ** (pFd->zWal) to point to a buffer owned by SQLite that contains
++      ** the name of the *-wal file this db connection will use. SQLite
++      ** happens to pass a pointer to this buffer when using xAccess()
++      ** or xOpen() to operate on the *-wal file.  */
++      pFd->zWal = rbuMainToWal(zName, flags);
++    }
++    else if( flags & SQLITE_OPEN_WAL ){
++      rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
++      if( pDb ){
++        if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
++          /* This call is to open a *-wal file. Intead, open the *-oal. This
++          ** code ensures that the string passed to xOpen() is terminated by a
++          ** pair of '\0' bytes in case the VFS attempts to extract a URI 
++          ** parameter from it.  */
++          const char *zBase = zName;
++          size_t nCopy;
++          char *zCopy;
++          if( rbuIsVacuum(pDb->pRbu) ){
++            zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main");
++            zBase = rbuMainToWal(zBase, SQLITE_OPEN_URI);
++          }
++          nCopy = strlen(zBase);
++          zCopy = sqlite3_malloc64(nCopy+2);
++          if( zCopy ){
++            memcpy(zCopy, zBase, nCopy);
++            zCopy[nCopy-3] = 'o';
++            zCopy[nCopy] = '\0';
++            zCopy[nCopy+1] = '\0';
++            zOpen = (const char*)(pFd->zDel = zCopy);
++          }else{
++            rc = SQLITE_NOMEM;
++          }
++          pFd->pRbu = pDb->pRbu;
++        }
++        pDb->pWalFd = pFd;
++      }
++    }
++  }
++
++  if( oflags & SQLITE_OPEN_MAIN_DB 
++   && sqlite3_uri_boolean(zName, "rbu_memory", 0) 
++  ){
++    assert( oflags & SQLITE_OPEN_MAIN_DB );
++    oflags =  SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
++              SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
++    zOpen = 0;
++  }
++
++  if( rc==SQLITE_OK ){
++    rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags);
++  }
++  if( pFd->pReal->pMethods ){
++    /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
++    ** pointer and, if the file is a main database file, link it into the
++    ** mutex protected linked list of all such files.  */
++    pFile->pMethods = &rbuvfs_io_methods;
++    if( flags & SQLITE_OPEN_MAIN_DB ){
++      sqlite3_mutex_enter(pRbuVfs->mutex);
++      pFd->pMainNext = pRbuVfs->pMain;
++      pRbuVfs->pMain = pFd;
++      sqlite3_mutex_leave(pRbuVfs->mutex);
++    }
++  }else{
++    sqlite3_free(pFd->zDel);
++  }
++
++  return rc;
++}
++
++/*
++** Delete the file located at zPath.
++*/
++static int rbuVfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
++  sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
++  return pRealVfs->xDelete(pRealVfs, zPath, dirSync);
++}
++
++/*
++** Test for access permissions. Return true if the requested permission
++** is available, or false otherwise.
++*/
++static int rbuVfsAccess(
++  sqlite3_vfs *pVfs, 
++  const char *zPath, 
++  int flags, 
++  int *pResOut
++){
++  rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs;
++  sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs;
++  int rc;
++
++  rc = pRealVfs->xAccess(pRealVfs, zPath, flags, pResOut);
++
++  /* If this call is to check if a *-wal file associated with an RBU target
++  ** database connection exists, and the RBU update is in RBU_STAGE_OAL,
++  ** the following special handling is activated:
++  **
++  **   a) if the *-wal file does exist, return SQLITE_CANTOPEN. This
++  **      ensures that the RBU extension never tries to update a database
++  **      in wal mode, even if the first page of the database file has
++  **      been damaged. 
++  **
++  **   b) if the *-wal file does not exist, claim that it does anyway,
++  **      causing SQLite to call xOpen() to open it. This call will also
++  **      be intercepted (see the rbuVfsOpen() function) and the *-oal
++  **      file opened instead.
++  */
++  if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
++    rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath);
++    if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
++      if( *pResOut ){
++        rc = SQLITE_CANTOPEN;
++      }else{
++        *pResOut = 1;
++      }
++    }
++  }
++
++  return rc;
++}
++
++/*
++** Populate buffer zOut with the full canonical pathname corresponding
++** to the pathname in zPath. zOut is guaranteed to point to a buffer
++** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
++*/
++static int rbuVfsFullPathname(
++  sqlite3_vfs *pVfs, 
++  const char *zPath, 
++  int nOut, 
++  char *zOut
++){
++  sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
++  return pRealVfs->xFullPathname(pRealVfs, zPath, nOut, zOut);
++}
++
++#ifndef SQLITE_OMIT_LOAD_EXTENSION
++/*
++** Open the dynamic library located at zPath and return a handle.
++*/
++static void *rbuVfsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
++  sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
++  return pRealVfs->xDlOpen(pRealVfs, zPath);
++}
++
++/*
++** Populate the buffer zErrMsg (size nByte bytes) with a human readable
++** utf-8 string describing the most recent error encountered associated 
++** with dynamic libraries.
++*/
++static void rbuVfsDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
++  sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
++  pRealVfs->xDlError(pRealVfs, nByte, zErrMsg);
++}
++
++/*
++** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
++*/
++static void (*rbuVfsDlSym(
++  sqlite3_vfs *pVfs, 
++  void *pArg, 
++  const char *zSym
++))(void){
++  sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
++  return pRealVfs->xDlSym(pRealVfs, pArg, zSym);
++}
++
++/*
++** Close the dynamic library handle pHandle.
++*/
++static void rbuVfsDlClose(sqlite3_vfs *pVfs, void *pHandle){
++  sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
++  pRealVfs->xDlClose(pRealVfs, pHandle);
++}
++#endif /* SQLITE_OMIT_LOAD_EXTENSION */
++
++/*
++** Populate the buffer pointed to by zBufOut with nByte bytes of 
++** random data.
++*/
++static int rbuVfsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
++  sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
++  return pRealVfs->xRandomness(pRealVfs, nByte, zBufOut);
++}
++
++/*
++** Sleep for nMicro microseconds. Return the number of microseconds 
++** actually slept.
++*/
++static int rbuVfsSleep(sqlite3_vfs *pVfs, int nMicro){
++  sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
++  return pRealVfs->xSleep(pRealVfs, nMicro);
++}
++
++/*
++** Return the current time as a Julian Day number in *pTimeOut.
++*/
++static int rbuVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
++  sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
++  return pRealVfs->xCurrentTime(pRealVfs, pTimeOut);
++}
++
++/*
++** No-op.
++*/
++static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
++  return 0;
++}
++
++/*
++** Deregister and destroy an RBU vfs created by an earlier call to
++** sqlite3rbu_create_vfs().
++*/
++SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName){
++  sqlite3_vfs *pVfs = sqlite3_vfs_find(zName);
++  if( pVfs && pVfs->xOpen==rbuVfsOpen ){
++    sqlite3_mutex_free(((rbu_vfs*)pVfs)->mutex);
++    sqlite3_vfs_unregister(pVfs);
++    sqlite3_free(pVfs);
++  }
++}
++
++/*
++** Create an RBU VFS named zName that accesses the underlying file-system
++** via existing VFS zParent. The new object is registered as a non-default
++** VFS with SQLite before returning.
++*/
++SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent){
++
++  /* Template for VFS */
++  static sqlite3_vfs vfs_template = {
++    1,                            /* iVersion */
++    0,                            /* szOsFile */
++    0,                            /* mxPathname */
++    0,                            /* pNext */
++    0,                            /* zName */
++    0,                            /* pAppData */
++    rbuVfsOpen,                   /* xOpen */
++    rbuVfsDelete,                 /* xDelete */
++    rbuVfsAccess,                 /* xAccess */
++    rbuVfsFullPathname,           /* xFullPathname */
++
++#ifndef SQLITE_OMIT_LOAD_EXTENSION
++    rbuVfsDlOpen,                 /* xDlOpen */
++    rbuVfsDlError,                /* xDlError */
++    rbuVfsDlSym,                  /* xDlSym */
++    rbuVfsDlClose,                /* xDlClose */
++#else
++    0, 0, 0, 0,
++#endif
++
++    rbuVfsRandomness,             /* xRandomness */
++    rbuVfsSleep,                  /* xSleep */
++    rbuVfsCurrentTime,            /* xCurrentTime */
++    rbuVfsGetLastError,           /* xGetLastError */
++    0,                            /* xCurrentTimeInt64 (version 2) */
++    0, 0, 0                       /* Unimplemented version 3 methods */
++  };
++
++  rbu_vfs *pNew = 0;              /* Newly allocated VFS */
++  int rc = SQLITE_OK;
++  size_t nName;
++  size_t nByte;
++
++  nName = strlen(zName);
++  nByte = sizeof(rbu_vfs) + nName + 1;
++  pNew = (rbu_vfs*)sqlite3_malloc64(nByte);
++  if( pNew==0 ){
++    rc = SQLITE_NOMEM;
++  }else{
++    sqlite3_vfs *pParent;           /* Parent VFS */
++    memset(pNew, 0, nByte);
++    pParent = sqlite3_vfs_find(zParent);
++    if( pParent==0 ){
++      rc = SQLITE_NOTFOUND;
++    }else{
++      char *zSpace;
++      memcpy(&pNew->base, &vfs_template, sizeof(sqlite3_vfs));
++      pNew->base.mxPathname = pParent->mxPathname;
++      pNew->base.szOsFile = sizeof(rbu_file) + pParent->szOsFile;
++      pNew->pRealVfs = pParent;
++      pNew->base.zName = (const char*)(zSpace = (char*)&pNew[1]);
++      memcpy(zSpace, zName, nName);
++
++      /* Allocate the mutex and register the new VFS (not as the default) */
++      pNew->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE);
++      if( pNew->mutex==0 ){
++        rc = SQLITE_NOMEM;
++      }else{
++        rc = sqlite3_vfs_register(&pNew->base, 0);
++      }
++    }
++
++    if( rc!=SQLITE_OK ){
++      sqlite3_mutex_free(pNew->mutex);
++      sqlite3_free(pNew);
++    }
++  }
++
++  return rc;
++}
++
++
++/**************************************************************************/
++
++#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */
++
++/************** End of sqlite3rbu.c ******************************************/
+ /************** Begin file dbstat.c ******************************************/
+ /*
+ ** 2010 July 12
+@@ -155298,8 +178560,12 @@
+ ** information from an SQLite database in order to implement the
+ ** "sqlite3_analyzer" utility.  See the ../tool/spaceanal.tcl script
+ ** for an example implementation.
++**
++** Additional information is available on the "dbstat.html" page of the
++** official SQLite documentation.
+ */
  
--#if SQLITE_OS_WINRT
--  { "CreateFile2",             (SYSCALL)CreateFile2,             0 },
-+#if defined(SQLITE_WIN32_HAS_WIDE)
-+  { "FormatMessageW",          (SYSCALL)FormatMessageW,          0 },
- #else
--  { "CreateFile2",             (SYSCALL)0,                       0 },
-+  { "FormatMessageW",          (SYSCALL)0,                       0 },
- #endif
++/* #include "sqliteInt.h"   ** Requires access to internal data structures ** */
+ #if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \
+     && !defined(SQLITE_OMIT_VIRTUALTABLE)
  
--#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
--        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent)
-+#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
-+        DWORD,va_list*))aSyscall[15].pCurrent)
+@@ -155336,16 +178602,17 @@
+ */
+ #define VTAB_SCHEMA                                                         \
+   "CREATE TABLE xx( "                                                       \
+-  "  name       STRING,           /* Name of table or index */"             \
+-  "  path       INTEGER,          /* Path to page from root */"             \
++  "  name       TEXT,             /* Name of table or index */"             \
++  "  path       TEXT,             /* Path to page from root */"             \
+   "  pageno     INTEGER,          /* Page number */"                        \
+-  "  pagetype   STRING,           /* 'internal', 'leaf' or 'overflow' */"   \
++  "  pagetype   TEXT,             /* 'internal', 'leaf' or 'overflow' */"   \
+   "  ncell      INTEGER,          /* Cells on page (0 for overflow) */"     \
+   "  payload    INTEGER,          /* Bytes of payload on this page */"      \
+   "  unused     INTEGER,          /* Bytes of unused space on this page */" \
+   "  mx_payload INTEGER,          /* Largest payload size of all cells */"  \
+   "  pgoffset   INTEGER,          /* Offset of page in file */"             \
+-  "  pgsize     INTEGER           /* Size of the page */"                   \
++  "  pgsize     INTEGER,          /* Size of the page */"                   \
++  "  schema     TEXT HIDDEN       /* Database schema being analyzed */"     \
+   ");"
+ 
+ 
+@@ -155383,6 +178650,7 @@
+   sqlite3_vtab_cursor base;
+   sqlite3_stmt *pStmt;            /* Iterates through set of root pages */
+   int isEof;                      /* After pStmt has returned SQLITE_DONE */
++  int iDb;                        /* Schema used for this query */
+ 
+   StatPage aPage[32];
+   int iPage;                      /* Current entry in aPage[] */
+@@ -155425,7 +178693,9 @@
+   int iDb;
+ 
+   if( argc>=4 ){
+-    iDb = sqlite3FindDbName(db, argv[3]);
++    Token nm;
++    sqlite3TokenInit(&nm, (char*)argv[3]);
++    iDb = sqlite3FindDb(db, &nm);
+     if( iDb<0 ){
+       *pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
+       return SQLITE_ERROR;
+@@ -155436,7 +178706,7 @@
+   rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
+   if( rc==SQLITE_OK ){
+     pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
+-    if( pTab==0 ) rc = SQLITE_NOMEM;
++    if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
+   }
  
--#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
--  { "LoadPackagedLibrary",     (SYSCALL)LoadPackagedLibrary,     0 },
-+#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
-+  { "FreeLibrary",             (SYSCALL)FreeLibrary,             0 },
- #else
--  { "LoadPackagedLibrary",     (SYSCALL)0,                       0 },
-+  { "FreeLibrary",             (SYSCALL)0,                       0 },
- #endif
+   assert( rc==SQLITE_OK || pTab==0 );
+@@ -155460,9 +178730,32 @@
  
--#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
--        DWORD))aSyscall[69].pCurrent)
-+#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
+ /*
+ ** There is no "best-index". This virtual table always does a linear
+-** scan of the binary VFS log file.
++** scan.  However, a schema=? constraint should cause this table to
++** operate on a different database schema, so check for it.
++**
++** idxNum is normally 0, but will be 1 if a schema=? constraint exists.
+ */
+ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
++  int i;
++
++  pIdxInfo->estimatedCost = 1.0e6;  /* Initial cost estimate */
++
++  /* Look for a valid schema=? constraint.  If found, change the idxNum to
++  ** 1 and request the value of that constraint be sent to xFilter.  And
++  ** lower the cost estimate to encourage the constrained version to be
++  ** used.
++  */
++  for(i=0; i<pIdxInfo->nConstraint; i++){
++    if( pIdxInfo->aConstraint[i].usable==0 ) continue;
++    if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
++    if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
++    pIdxInfo->idxNum = 1;
++    pIdxInfo->estimatedCost = 1.0;
++    pIdxInfo->aConstraintUsage[i].argvIndex = 1;
++    pIdxInfo->aConstraintUsage[i].omit = 1;
++    break;
++  }
++
  
--#if SQLITE_OS_WINRT
--  { "GetTickCount64",          (SYSCALL)GetTickCount64,          0 },
--#else
--  { "GetTickCount64",          (SYSCALL)0,                       0 },
--#endif
-+  { "GetCurrentProcessId",     (SYSCALL)GetCurrentProcessId,     0 },
+   /* Records are always returned in ascending order of (name, path). 
+   ** If this will satisfy the client, set the orderByConsumed flag so that 
+@@ -155482,7 +178775,6 @@
+     pIdxInfo->orderByConsumed = 1;
+   }
  
--#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent)
-+#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent)
+-  pIdxInfo->estimatedCost = 10.0;
+   return SQLITE_OK;
+ }
  
--#if SQLITE_OS_WINRT
--  { "GetNativeSystemInfo",     (SYSCALL)GetNativeSystemInfo,     0 },
-+#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
-+  { "GetDiskFreeSpaceA",       (SYSCALL)GetDiskFreeSpaceA,       0 },
- #else
--  { "GetNativeSystemInfo",     (SYSCALL)0,                       0 },
-+  { "GetDiskFreeSpaceA",       (SYSCALL)0,                       0 },
- #endif
+@@ -155492,36 +178784,18 @@
+ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
+   StatTable *pTab = (StatTable *)pVTab;
+   StatCursor *pCsr;
+-  int rc;
  
--#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
--        LPSYSTEM_INFO))aSyscall[71].pCurrent)
-+#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
-+        LPDWORD))aSyscall[18].pCurrent)
+   pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
+   if( pCsr==0 ){
+-    rc = SQLITE_NOMEM;
++    return SQLITE_NOMEM_BKPT;
+   }else{
+-    char *zSql;
+     memset(pCsr, 0, sizeof(StatCursor));
+     pCsr->base.pVtab = pVTab;
+-
+-    zSql = sqlite3_mprintf(
+-        "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
+-        "  UNION ALL  "
+-        "SELECT name, rootpage, type"
+-        "  FROM \"%w\".sqlite_master WHERE rootpage!=0"
+-        "  ORDER BY name", pTab->db->aDb[pTab->iDb].zName);
+-    if( zSql==0 ){
+-      rc = SQLITE_NOMEM;
+-    }else{
+-      rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
+-      sqlite3_free(zSql);
+-    }
+-    if( rc!=SQLITE_OK ){
+-      sqlite3_free(pCsr);
+-      pCsr = 0;
+-    }
++    pCsr->iDb = pTab->iDb;
+   }
  
--#if defined(SQLITE_WIN32_HAS_ANSI)
--  { "OutputDebugStringA",      (SYSCALL)OutputDebugStringA,      0 },
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "GetDiskFreeSpaceW",       (SYSCALL)GetDiskFreeSpaceW,       0 },
- #else
--  { "OutputDebugStringA",      (SYSCALL)0,                       0 },
-+  { "GetDiskFreeSpaceW",       (SYSCALL)0,                       0 },
- #endif
+   *ppCursor = (sqlite3_vtab_cursor *)pCsr;
+-  return rc;
++  return SQLITE_OK;
+ }
  
--#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent)
-+#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
-+        LPDWORD))aSyscall[19].pCurrent)
+ static void statClearPage(StatPage *p){
+@@ -155546,6 +178820,7 @@
+   pCsr->iPage = 0;
+   sqlite3_free(pCsr->zPath);
+   pCsr->zPath = 0;
++  pCsr->isEof = 0;
+ }
  
--#if defined(SQLITE_WIN32_HAS_WIDE)
--  { "OutputDebugStringW",      (SYSCALL)OutputDebugStringW,      0 },
-+#if defined(SQLITE_WIN32_HAS_ANSI)
-+  { "GetFileAttributesA",      (SYSCALL)GetFileAttributesA,      0 },
- #else
--  { "OutputDebugStringW",      (SYSCALL)0,                       0 },
-+  { "GetFileAttributesA",      (SYSCALL)0,                       0 },
- #endif
+ /*
+@@ -155618,7 +178893,7 @@
+     nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
+     sqlite3BtreeLeave(pBt);
+     p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell));
+-    if( p->aCell==0 ) return SQLITE_NOMEM;
++    if( p->aCell==0 ) return SQLITE_NOMEM_BKPT;
+     memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
+ 
+     for(i=0; i<p->nCell; i++){
+@@ -155651,13 +178926,13 @@
+           pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
+           pCell->nOvfl = nOvfl;
+           pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
+-          if( pCell->aOvfl==0 ) return SQLITE_NOMEM;
++          if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
+           pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
+           for(j=1; j<nOvfl; j++){
+             int rc;
+             u32 iPrev = pCell->aOvfl[j-1];
+             DbPage *pPg = 0;
+-            rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg);
++            rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg, 0);
+             if( rc!=SQLITE_OK ){
+               assert( pPg==0 );
+               return rc;
+@@ -155708,7 +178983,7 @@
+   char *z;
+   StatCursor *pCsr = (StatCursor *)pCursor;
+   StatTable *pTab = (StatTable *)pCursor->pVtab;
+-  Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
++  Btree *pBt = pTab->db->aDb[pCsr->iDb].pBt;
+   Pager *pPager = sqlite3BtreePager(pBt);
+ 
+   sqlite3_free(pCsr->zPath);
+@@ -155725,12 +179000,12 @@
+         pCsr->isEof = 1;
+         return sqlite3_reset(pCsr->pStmt);
+       }
+-      rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
++      rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg, 0);
+       pCsr->aPage[0].iPgno = iRoot;
+       pCsr->aPage[0].iCell = 0;
+       pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
+       pCsr->iPage = 0;
+-      if( z==0 ) rc = SQLITE_NOMEM;
++      if( z==0 ) rc = SQLITE_NOMEM_BKPT;
+     }else{
+       pCsr->isEof = 1;
+       return sqlite3_reset(pCsr->pStmt);
+@@ -155765,7 +179040,7 @@
+         }
+         pCell->iOvfl++;
+         statSizeAndOffset(pCsr);
+-        return z==0 ? SQLITE_NOMEM : SQLITE_OK;
++        return z==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
+       }
+       if( p->iRightChildPg ) break;
+       p->iCell++;
+@@ -155785,11 +179060,11 @@
+     }else{
+       p[1].iPgno = p->aCell[p->iCell].iChildPg;
+     }
+-    rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg);
++    rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg, 0);
+     p[1].iCell = 0;
+     p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
+     p->iCell++;
+-    if( z==0 ) rc = SQLITE_NOMEM;
++    if( z==0 ) rc = SQLITE_NOMEM_BKPT;
+   }
  
--#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)
--
--  { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },
--
--#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
-+#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
  
--#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
--  { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "GetFileAttributesW",      (SYSCALL)GetFileAttributesW,      0 },
- #else
--  { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
-+  { "GetFileAttributesW",      (SYSCALL)0,                       0 },
- #endif
+@@ -155823,7 +179098,7 @@
+       pCsr->nUnused = p->nUnused;
+       pCsr->nMxPayload = p->nMxPayload;
+       pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
+-      if( z==0 ) rc = SQLITE_NOMEM;
++      if( z==0 ) rc = SQLITE_NOMEM_BKPT;
+       nPayload = 0;
+       for(i=0; i<p->nCell; i++){
+         nPayload += p->aCell[i].nLocal;
+@@ -155846,9 +179121,43 @@
+   int argc, sqlite3_value **argv
+ ){
+   StatCursor *pCsr = (StatCursor *)pCursor;
++  StatTable *pTab = (StatTable*)(pCursor->pVtab);
++  char *zSql;
++  int rc = SQLITE_OK;
++  char *zMaster;
+ 
++  if( idxNum==1 ){
++    const char *zDbase = (const char*)sqlite3_value_text(argv[0]);
++    pCsr->iDb = sqlite3FindDbName(pTab->db, zDbase);
++    if( pCsr->iDb<0 ){
++      sqlite3_free(pCursor->pVtab->zErrMsg);
++      pCursor->pVtab->zErrMsg = sqlite3_mprintf("no such schema: %s", zDbase);
++      return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM_BKPT;
++    }
++  }else{
++    pCsr->iDb = pTab->iDb;
++  }
+   statResetCsr(pCsr);
+-  return statNext(pCursor);
++  sqlite3_finalize(pCsr->pStmt);
++  pCsr->pStmt = 0;
++  zMaster = pCsr->iDb==1 ? "sqlite_temp_master" : "sqlite_master";
++  zSql = sqlite3_mprintf(
++      "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
++      "  UNION ALL  "
++      "SELECT name, rootpage, type"
++      "  FROM \"%w\".%s WHERE rootpage!=0"
++      "  ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName, zMaster);
++  if( zSql==0 ){
++    return SQLITE_NOMEM_BKPT;
++  }else{
++    rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
++    sqlite3_free(zSql);
++  }
++
++  if( rc==SQLITE_OK ){
++    rc = statNext(pCursor);
++  }
++  return rc;
+ }
  
--#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
--        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
--
--/*
--** NOTE: On some sub-platforms, the InterlockedCompareExchange "function"
--**       is really just a macro that uses a compiler intrinsic (e.g. x64).
--**       So do not try to make this is into a redefinable interface.
--*/
--#if defined(InterlockedCompareExchange)
--  { "InterlockedCompareExchange", (SYSCALL)0,                    0 },
-+#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
+ static int statColumn(
+@@ -155885,10 +179194,15 @@
+     case 8:            /* pgoffset */
+       sqlite3_result_int64(ctx, pCsr->iOffset);
+       break;
+-    default:           /* pgsize */
+-      assert( i==9 );
++    case 9:            /* pgsize */
+       sqlite3_result_int(ctx, pCsr->szPage);
+       break;
++    default: {          /* schema */
++      sqlite3 *db = sqlite3_context_db_handle(ctx);
++      int iDb = pCsr->iDb;
++      sqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC);
++      break;
++    }
+   }
+   return SQLITE_OK;
+ }
+@@ -155902,7 +179216,7 @@
+ /*
+ ** Invoke this routine to register the "dbstat" virtual table module
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_dbstat_register(sqlite3 *db){
++SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){
+   static sqlite3_module dbstat_module = {
+     0,                            /* iVersion */
+     statConnect,                  /* xCreate */
+@@ -155924,9 +179238,28500 @@
+     0,                            /* xRollback */
+     0,                            /* xFindMethod */
+     0,                            /* xRename */
++    0,                            /* xSavepoint */
++    0,                            /* xRelease */
++    0,                            /* xRollbackTo */
+   };
+   return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
+ }
++#elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
++SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
+ #endif /* SQLITE_ENABLE_DBSTAT_VTAB */
  
--#define osInterlockedCompareExchange InterlockedCompareExchange
-+#if defined(SQLITE_WIN32_HAS_WIDE)
-+  { "GetFileAttributesExW",    (SYSCALL)GetFileAttributesExW,    0 },
- #else
--  { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 },
-+  { "GetFileAttributesExW",    (SYSCALL)0,                       0 },
+ /************** End of dbstat.c **********************************************/
++/************** Begin file sqlite3session.c **********************************/
++
++#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
++/* #include "sqlite3session.h" */
++/* #include <assert.h> */
++/* #include <string.h> */
++
++#ifndef SQLITE_AMALGAMATION
++/* # include "sqliteInt.h" */
++/* # include "vdbeInt.h" */
++#endif
++
++typedef struct SessionTable SessionTable;
++typedef struct SessionChange SessionChange;
++typedef struct SessionBuffer SessionBuffer;
++typedef struct SessionInput SessionInput;
++
++/*
++** Minimum chunk size used by streaming versions of functions.
++*/
++#ifndef SESSIONS_STRM_CHUNK_SIZE
++# ifdef SQLITE_TEST
++#   define SESSIONS_STRM_CHUNK_SIZE 64
++# else
++#   define SESSIONS_STRM_CHUNK_SIZE 1024
++# endif
++#endif
++
++typedef struct SessionHook SessionHook;
++struct SessionHook {
++  void *pCtx;
++  int (*xOld)(void*,int,sqlite3_value**);
++  int (*xNew)(void*,int,sqlite3_value**);
++  int (*xCount)(void*);
++  int (*xDepth)(void*);
++};
++
++/*
++** Session handle structure.
++*/
++struct sqlite3_session {
++  sqlite3 *db;                    /* Database handle session is attached to */
++  char *zDb;                      /* Name of database session is attached to */
++  int bEnable;                    /* True if currently recording */
++  int bIndirect;                  /* True if all changes are indirect */
++  int bAutoAttach;                /* True to auto-attach tables */
++  int rc;                         /* Non-zero if an error has occurred */
++  void *pFilterCtx;               /* First argument to pass to xTableFilter */
++  int (*xTableFilter)(void *pCtx, const char *zTab);
++  sqlite3_session *pNext;         /* Next session object on same db. */
++  SessionTable *pTable;           /* List of attached tables */
++  SessionHook hook;               /* APIs to grab new and old data with */
++};
++
++/*
++** Instances of this structure are used to build strings or binary records.
++*/
++struct SessionBuffer {
++  u8 *aBuf;                       /* Pointer to changeset buffer */
++  int nBuf;                       /* Size of buffer aBuf */
++  int nAlloc;                     /* Size of allocation containing aBuf */
++};
++
++/*
++** An object of this type is used internally as an abstraction for 
++** input data. Input data may be supplied either as a single large buffer
++** (e.g. sqlite3changeset_start()) or using a stream function (e.g.
++**  sqlite3changeset_start_strm()).
++*/
++struct SessionInput {
++  int bNoDiscard;                 /* If true, discard no data */
++  int iCurrent;                   /* Offset in aData[] of current change */
++  int iNext;                      /* Offset in aData[] of next change */
++  u8 *aData;                      /* Pointer to buffer containing changeset */
++  int nData;                      /* Number of bytes in aData */
++
++  SessionBuffer buf;              /* Current read buffer */
++  int (*xInput)(void*, void*, int*);        /* Input stream call (or NULL) */
++  void *pIn;                                /* First argument to xInput */
++  int bEof;                       /* Set to true after xInput finished */
++};
++
++/*
++** Structure for changeset iterators.
++*/
++struct sqlite3_changeset_iter {
++  SessionInput in;                /* Input buffer or stream */
++  SessionBuffer tblhdr;           /* Buffer to hold apValue/zTab/abPK/ */
++  int bPatchset;                  /* True if this is a patchset */
++  int rc;                         /* Iterator error code */
++  sqlite3_stmt *pConflict;        /* Points to conflicting row, if any */
++  char *zTab;                     /* Current table */
++  int nCol;                       /* Number of columns in zTab */
++  int op;                         /* Current operation */
++  int bIndirect;                  /* True if current change was indirect */
++  u8 *abPK;                       /* Primary key array */
++  sqlite3_value **apValue;        /* old.* and new.* values */
++};
++
++/*
++** Each session object maintains a set of the following structures, one
++** for each table the session object is monitoring. The structures are
++** stored in a linked list starting at sqlite3_session.pTable.
++**
++** The keys of the SessionTable.aChange[] hash table are all rows that have
++** been modified in any way since the session object was attached to the
++** table.
++**
++** The data associated with each hash-table entry is a structure containing
++** a subset of the initial values that the modified row contained at the
++** start of the session. Or no initial values if the row was inserted.
++*/
++struct SessionTable {
++  SessionTable *pNext;
++  char *zName;                    /* Local name of table */
++  int nCol;                       /* Number of columns in table zName */
++  const char **azCol;             /* Column names */
++  u8 *abPK;                       /* Array of primary key flags */
++  int nEntry;                     /* Total number of entries in hash table */
++  int nChange;                    /* Size of apChange[] array */
++  SessionChange **apChange;       /* Hash table buckets */
++};
++
++/* 
++** RECORD FORMAT:
++**
++** The following record format is similar to (but not compatible with) that 
++** used in SQLite database files. This format is used as part of the 
++** change-set binary format, and so must be architecture independent.
++**
++** Unlike the SQLite database record format, each field is self-contained -
++** there is no separation of header and data. Each field begins with a
++** single byte describing its type, as follows:
++**
++**       0x00: Undefined value.
++**       0x01: Integer value.
++**       0x02: Real value.
++**       0x03: Text value.
++**       0x04: Blob value.
++**       0x05: SQL NULL value.
++**
++** Note that the above match the definitions of SQLITE_INTEGER, SQLITE_TEXT
++** and so on in sqlite3.h. For undefined and NULL values, the field consists
++** only of the single type byte. For other types of values, the type byte
++** is followed by:
++**
++**   Text values:
++**     A varint containing the number of bytes in the value (encoded using
++**     UTF-8). Followed by a buffer containing the UTF-8 representation
++**     of the text value. There is no nul terminator.
++**
++**   Blob values:
++**     A varint containing the number of bytes in the value, followed by
++**     a buffer containing the value itself.
++**
++**   Integer values:
++**     An 8-byte big-endian integer value.
++**
++**   Real values:
++**     An 8-byte big-endian IEEE 754-2008 real value.
++**
++** Varint values are encoded in the same way as varints in the SQLite 
++** record format.
++**
++** CHANGESET FORMAT:
++**
++** A changeset is a collection of DELETE, UPDATE and INSERT operations on
++** one or more tables. Operations on a single table are grouped together,
++** but may occur in any order (i.e. deletes, updates and inserts are all
++** mixed together).
++**
++** Each group of changes begins with a table header:
++**
++**   1 byte: Constant 0x54 (capital 'T')
++**   Varint: Number of columns in the table.
++**   nCol bytes: 0x01 for PK columns, 0x00 otherwise.
++**   N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
++**
++** Followed by one or more changes to the table.
++**
++**   1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09).
++**   1 byte: The "indirect-change" flag.
++**   old.* record: (delete and update only)
++**   new.* record: (insert and update only)
++**
++** The "old.*" and "new.*" records, if present, are N field records in the
++** format described above under "RECORD FORMAT", where N is the number of
++** columns in the table. The i'th field of each record is associated with
++** the i'th column of the table, counting from left to right in the order
++** in which columns were declared in the CREATE TABLE statement.
++**
++** The new.* record that is part of each INSERT change contains the values
++** that make up the new row. Similarly, the old.* record that is part of each
++** DELETE change contains the values that made up the row that was deleted 
++** from the database. In the changeset format, the records that are part
++** of INSERT or DELETE changes never contain any undefined (type byte 0x00)
++** fields.
++**
++** Within the old.* record associated with an UPDATE change, all fields
++** associated with table columns that are not PRIMARY KEY columns and are
++** not modified by the UPDATE change are set to "undefined". Other fields
++** are set to the values that made up the row before the UPDATE that the
++** change records took place. Within the new.* record, fields associated 
++** with table columns modified by the UPDATE change contain the new 
++** values. Fields associated with table columns that are not modified
++** are set to "undefined".
++**
++** PATCHSET FORMAT:
++**
++** A patchset is also a collection of changes. It is similar to a changeset,
++** but leaves undefined those fields that are not useful if no conflict
++** resolution is required when applying the changeset.
++**
++** Each group of changes begins with a table header:
++**
++**   1 byte: Constant 0x50 (capital 'P')
++**   Varint: Number of columns in the table.
++**   nCol bytes: 0x01 for PK columns, 0x00 otherwise.
++**   N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
++**
++** Followed by one or more changes to the table.
++**
++**   1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09).
++**   1 byte: The "indirect-change" flag.
++**   single record: (PK fields for DELETE, PK and modified fields for UPDATE,
++**                   full record for INSERT).
++**
++** As in the changeset format, each field of the single record that is part
++** of a patchset change is associated with the correspondingly positioned
++** table column, counting from left to right within the CREATE TABLE 
++** statement.
++**
++** For a DELETE change, all fields within the record except those associated
++** with PRIMARY KEY columns are set to "undefined". The PRIMARY KEY fields
++** contain the values identifying the row to delete.
++**
++** For an UPDATE change, all fields except those associated with PRIMARY KEY
++** columns and columns that are modified by the UPDATE are set to "undefined".
++** PRIMARY KEY fields contain the values identifying the table row to update,
++** and fields associated with modified columns contain the new column values.
++**
++** The records associated with INSERT changes are in the same format as for
++** changesets. It is not possible for a record associated with an INSERT
++** change to contain a field set to "undefined".
++*/
++
++/*
++** For each row modified during a session, there exists a single instance of
++** this structure stored in a SessionTable.aChange[] hash table.
++*/
++struct SessionChange {
++  int op;                         /* One of UPDATE, DELETE, INSERT */
++  int bIndirect;                  /* True if this change is "indirect" */
++  int nRecord;                    /* Number of bytes in buffer aRecord[] */
++  u8 *aRecord;                    /* Buffer containing old.* record */
++  SessionChange *pNext;           /* For hash-table collisions */
++};
++
++/*
++** Write a varint with value iVal into the buffer at aBuf. Return the 
++** number of bytes written.
++*/
++static int sessionVarintPut(u8 *aBuf, int iVal){
++  return putVarint32(aBuf, iVal);
++}
++
++/*
++** Return the number of bytes required to store value iVal as a varint.
++*/
++static int sessionVarintLen(int iVal){
++  return sqlite3VarintLen(iVal);
++}
++
++/*
++** Read a varint value from aBuf[] into *piVal. Return the number of 
++** bytes read.
++*/
++static int sessionVarintGet(u8 *aBuf, int *piVal){
++  return getVarint32(aBuf, *piVal);
++}
++
++/* Load an unaligned and unsigned 32-bit integer */
++#define SESSION_UINT32(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
++
++/*
++** Read a 64-bit big-endian integer value from buffer aRec[]. Return
++** the value read.
++*/
++static sqlite3_int64 sessionGetI64(u8 *aRec){
++  u64 x = SESSION_UINT32(aRec);
++  u32 y = SESSION_UINT32(aRec+4);
++  x = (x<<32) + y;
++  return (sqlite3_int64)x;
++}
++
++/*
++** Write a 64-bit big-endian integer value to the buffer aBuf[].
++*/
++static void sessionPutI64(u8 *aBuf, sqlite3_int64 i){
++  aBuf[0] = (i>>56) & 0xFF;
++  aBuf[1] = (i>>48) & 0xFF;
++  aBuf[2] = (i>>40) & 0xFF;
++  aBuf[3] = (i>>32) & 0xFF;
++  aBuf[4] = (i>>24) & 0xFF;
++  aBuf[5] = (i>>16) & 0xFF;
++  aBuf[6] = (i>> 8) & 0xFF;
++  aBuf[7] = (i>> 0) & 0xFF;
++}
++
++/*
++** This function is used to serialize the contents of value pValue (see
++** comment titled "RECORD FORMAT" above).
++**
++** If it is non-NULL, the serialized form of the value is written to 
++** buffer aBuf. *pnWrite is set to the number of bytes written before
++** returning. Or, if aBuf is NULL, the only thing this function does is
++** set *pnWrite.
++**
++** If no error occurs, SQLITE_OK is returned. Or, if an OOM error occurs
++** within a call to sqlite3_value_text() (may fail if the db is utf-16)) 
++** SQLITE_NOMEM is returned.
++*/
++static int sessionSerializeValue(
++  u8 *aBuf,                       /* If non-NULL, write serialized value here */
++  sqlite3_value *pValue,          /* Value to serialize */
++  int *pnWrite                    /* IN/OUT: Increment by bytes written */
++){
++  int nByte;                      /* Size of serialized value in bytes */
++
++  if( pValue ){
++    int eType;                    /* Value type (SQLITE_NULL, TEXT etc.) */
++  
++    eType = sqlite3_value_type(pValue);
++    if( aBuf ) aBuf[0] = eType;
++  
++    switch( eType ){
++      case SQLITE_NULL: 
++        nByte = 1;
++        break;
++  
++      case SQLITE_INTEGER: 
++      case SQLITE_FLOAT:
++        if( aBuf ){
++          /* TODO: SQLite does something special to deal with mixed-endian
++          ** floating point values (e.g. ARM7). This code probably should
++          ** too.  */
++          u64 i;
++          if( eType==SQLITE_INTEGER ){
++            i = (u64)sqlite3_value_int64(pValue);
++          }else{
++            double r;
++            assert( sizeof(double)==8 && sizeof(u64)==8 );
++            r = sqlite3_value_double(pValue);
++            memcpy(&i, &r, 8);
++          }
++          sessionPutI64(&aBuf[1], i);
++        }
++        nByte = 9; 
++        break;
++  
++      default: {
++        u8 *z;
++        int n;
++        int nVarint;
++  
++        assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
++        if( eType==SQLITE_TEXT ){
++          z = (u8 *)sqlite3_value_text(pValue);
++        }else{
++          z = (u8 *)sqlite3_value_blob(pValue);
++        }
++        n = sqlite3_value_bytes(pValue);
++        if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
++        nVarint = sessionVarintLen(n);
++  
++        if( aBuf ){
++          sessionVarintPut(&aBuf[1], n);
++          if( n ) memcpy(&aBuf[nVarint + 1], z, n);
++        }
++  
++        nByte = 1 + nVarint + n;
++        break;
++      }
++    }
++  }else{
++    nByte = 1;
++    if( aBuf ) aBuf[0] = '\0';
++  }
++
++  if( pnWrite ) *pnWrite += nByte;
++  return SQLITE_OK;
++}
++
++
++/*
++** This macro is used to calculate hash key values for data structures. In
++** order to use this macro, the entire data structure must be represented
++** as a series of unsigned integers. In order to calculate a hash-key value
++** for a data structure represented as three such integers, the macro may
++** then be used as follows:
++**
++**    int hash_key_value;
++**    hash_key_value = HASH_APPEND(0, <value 1>);
++**    hash_key_value = HASH_APPEND(hash_key_value, <value 2>);
++**    hash_key_value = HASH_APPEND(hash_key_value, <value 3>);
++**
++** In practice, the data structures this macro is used for are the primary
++** key values of modified rows.
++*/
++#define HASH_APPEND(hash, add) ((hash) << 3) ^ (hash) ^ (unsigned int)(add)
++
++/*
++** Append the hash of the 64-bit integer passed as the second argument to the
++** hash-key value passed as the first. Return the new hash-key value.
++*/
++static unsigned int sessionHashAppendI64(unsigned int h, i64 i){
++  h = HASH_APPEND(h, i & 0xFFFFFFFF);
++  return HASH_APPEND(h, (i>>32)&0xFFFFFFFF);
++}
++
++/*
++** Append the hash of the blob passed via the second and third arguments to 
++** the hash-key value passed as the first. Return the new hash-key value.
++*/
++static unsigned int sessionHashAppendBlob(unsigned int h, int n, const u8 *z){
++  int i;
++  for(i=0; i<n; i++) h = HASH_APPEND(h, z[i]);
++  return h;
++}
++
++/*
++** Append the hash of the data type passed as the second argument to the
++** hash-key value passed as the first. Return the new hash-key value.
++*/
++static unsigned int sessionHashAppendType(unsigned int h, int eType){
++  return HASH_APPEND(h, eType);
++}
++
++/*
++** This function may only be called from within a pre-update callback.
++** It calculates a hash based on the primary key values of the old.* or 
++** new.* row currently available and, assuming no error occurs, writes it to
++** *piHash before returning. If the primary key contains one or more NULL
++** values, *pbNullPK is set to true before returning.
++**
++** If an error occurs, an SQLite error code is returned and the final values
++** of *piHash asn *pbNullPK are undefined. Otherwise, SQLITE_OK is returned
++** and the output variables are set as described above.
++*/
++static int sessionPreupdateHash(
++  sqlite3_session *pSession,      /* Session object that owns pTab */
++  SessionTable *pTab,             /* Session table handle */
++  int bNew,                       /* True to hash the new.* PK */
++  int *piHash,                    /* OUT: Hash value */
++  int *pbNullPK                   /* OUT: True if there are NULL values in PK */
++){
++  unsigned int h = 0;             /* Hash value to return */
++  int i;                          /* Used to iterate through columns */
++
++  assert( *pbNullPK==0 );
++  assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) );
++  for(i=0; i<pTab->nCol; i++){
++    if( pTab->abPK[i] ){
++      int rc;
++      int eType;
++      sqlite3_value *pVal;
++
++      if( bNew ){
++        rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal);
++      }else{
++        rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal);
++      }
++      if( rc!=SQLITE_OK ) return rc;
++
++      eType = sqlite3_value_type(pVal);
++      h = sessionHashAppendType(h, eType);
++      if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
++        i64 iVal;
++        if( eType==SQLITE_INTEGER ){
++          iVal = sqlite3_value_int64(pVal);
++        }else{
++          double rVal = sqlite3_value_double(pVal);
++          assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
++          memcpy(&iVal, &rVal, 8);
++        }
++        h = sessionHashAppendI64(h, iVal);
++      }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
++        const u8 *z;
++        int n;
++        if( eType==SQLITE_TEXT ){
++          z = (const u8 *)sqlite3_value_text(pVal);
++        }else{
++          z = (const u8 *)sqlite3_value_blob(pVal);
++        }
++        n = sqlite3_value_bytes(pVal);
++        if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
++        h = sessionHashAppendBlob(h, n, z);
++      }else{
++        assert( eType==SQLITE_NULL );
++        *pbNullPK = 1;
++      }
++    }
++  }
++
++  *piHash = (h % pTab->nChange);
++  return SQLITE_OK;
++}
++
++/*
++** The buffer that the argument points to contains a serialized SQL value.
++** Return the number of bytes of space occupied by the value (including
++** the type byte).
++*/
++static int sessionSerialLen(u8 *a){
++  int e = *a;
++  int n;
++  if( e==0 ) return 1;
++  if( e==SQLITE_NULL ) return 1;
++  if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9;
++  return sessionVarintGet(&a[1], &n) + 1 + n;
++}
++
++/*
++** Based on the primary key values stored in change aRecord, calculate a
++** hash key. Assume the has table has nBucket buckets. The hash keys
++** calculated by this function are compatible with those calculated by
++** sessionPreupdateHash().
++**
++** The bPkOnly argument is non-zero if the record at aRecord[] is from
++** a patchset DELETE. In this case the non-PK fields are omitted entirely.
++*/
++static unsigned int sessionChangeHash(
++  SessionTable *pTab,             /* Table handle */
++  int bPkOnly,                    /* Record consists of PK fields only */
++  u8 *aRecord,                    /* Change record */
++  int nBucket                     /* Assume this many buckets in hash table */
++){
++  unsigned int h = 0;             /* Value to return */
++  int i;                          /* Used to iterate through columns */
++  u8 *a = aRecord;                /* Used to iterate through change record */
++
++  for(i=0; i<pTab->nCol; i++){
++    int eType = *a;
++    int isPK = pTab->abPK[i];
++    if( bPkOnly && isPK==0 ) continue;
++
++    /* It is not possible for eType to be SQLITE_NULL here. The session 
++    ** module does not record changes for rows with NULL values stored in
++    ** primary key columns. */
++    assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT 
++         || eType==SQLITE_TEXT || eType==SQLITE_BLOB 
++         || eType==SQLITE_NULL || eType==0 
++    );
++    assert( !isPK || (eType!=0 && eType!=SQLITE_NULL) );
++
++    if( isPK ){
++      a++;
++      h = sessionHashAppendType(h, eType);
++      if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
++        h = sessionHashAppendI64(h, sessionGetI64(a));
++        a += 8;
++      }else{
++        int n; 
++        a += sessionVarintGet(a, &n);
++        h = sessionHashAppendBlob(h, n, a);
++        a += n;
++      }
++    }else{
++      a += sessionSerialLen(a);
++    }
++  }
++  return (h % nBucket);
++}
++
++/*
++** Arguments aLeft and aRight are pointers to change records for table pTab.
++** This function returns true if the two records apply to the same row (i.e.
++** have the same values stored in the primary key columns), or false 
++** otherwise.
++*/
++static int sessionChangeEqual(
++  SessionTable *pTab,             /* Table used for PK definition */
++  int bLeftPkOnly,                /* True if aLeft[] contains PK fields only */
++  u8 *aLeft,                      /* Change record */
++  int bRightPkOnly,               /* True if aRight[] contains PK fields only */
++  u8 *aRight                      /* Change record */
++){
++  u8 *a1 = aLeft;                 /* Cursor to iterate through aLeft */
++  u8 *a2 = aRight;                /* Cursor to iterate through aRight */
++  int iCol;                       /* Used to iterate through table columns */
++
++  for(iCol=0; iCol<pTab->nCol; iCol++){
++    if( pTab->abPK[iCol] ){
++      int n1 = sessionSerialLen(a1);
++      int n2 = sessionSerialLen(a2);
++
++      if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){
++        return 0;
++      }
++      a1 += n1;
++      a2 += n2;
++    }else{
++      if( bLeftPkOnly==0 ) a1 += sessionSerialLen(a1);
++      if( bRightPkOnly==0 ) a2 += sessionSerialLen(a2);
++    }
++  }
++
++  return 1;
++}
++
++/*
++** Arguments aLeft and aRight both point to buffers containing change
++** records with nCol columns. This function "merges" the two records into
++** a single records which is written to the buffer at *paOut. *paOut is
++** then set to point to one byte after the last byte written before 
++** returning.
++**
++** The merging of records is done as follows: For each column, if the 
++** aRight record contains a value for the column, copy the value from
++** their. Otherwise, if aLeft contains a value, copy it. If neither
++** record contains a value for a given column, then neither does the
++** output record.
++*/
++static void sessionMergeRecord(
++  u8 **paOut, 
++  int nCol,
++  u8 *aLeft,
++  u8 *aRight
++){
++  u8 *a1 = aLeft;                 /* Cursor used to iterate through aLeft */
++  u8 *a2 = aRight;                /* Cursor used to iterate through aRight */
++  u8 *aOut = *paOut;              /* Output cursor */
++  int iCol;                       /* Used to iterate from 0 to nCol */
++
++  for(iCol=0; iCol<nCol; iCol++){
++    int n1 = sessionSerialLen(a1);
++    int n2 = sessionSerialLen(a2);
++    if( *a2 ){
++      memcpy(aOut, a2, n2);
++      aOut += n2;
++    }else{
++      memcpy(aOut, a1, n1);
++      aOut += n1;
++    }
++    a1 += n1;
++    a2 += n2;
++  }
++
++  *paOut = aOut;
++}
++
++/*
++** This is a helper function used by sessionMergeUpdate().
++**
++** When this function is called, both *paOne and *paTwo point to a value 
++** within a change record. Before it returns, both have been advanced so 
++** as to point to the next value in the record.
++**
++** If, when this function is called, *paTwo points to a valid value (i.e.
++** *paTwo[0] is not 0x00 - the "no value" placeholder), a copy of the *paTwo
++** pointer is returned and *pnVal is set to the number of bytes in the 
++** serialized value. Otherwise, a copy of *paOne is returned and *pnVal
++** set to the number of bytes in the value at *paOne. If *paOne points
++** to the "no value" placeholder, *pnVal is set to 1. In other words:
++**
++**   if( *paTwo is valid ) return *paTwo;
++**   return *paOne;
++**
++*/
++static u8 *sessionMergeValue(
++  u8 **paOne,                     /* IN/OUT: Left-hand buffer pointer */
++  u8 **paTwo,                     /* IN/OUT: Right-hand buffer pointer */
++  int *pnVal                      /* OUT: Bytes in returned value */
++){
++  u8 *a1 = *paOne;
++  u8 *a2 = *paTwo;
++  u8 *pRet = 0;
++  int n1;
++
++  assert( a1 );
++  if( a2 ){
++    int n2 = sessionSerialLen(a2);
++    if( *a2 ){
++      *pnVal = n2;
++      pRet = a2;
++    }
++    *paTwo = &a2[n2];
++  }
++
++  n1 = sessionSerialLen(a1);
++  if( pRet==0 ){
++    *pnVal = n1;
++    pRet = a1;
++  }
++  *paOne = &a1[n1];
++
++  return pRet;
++}
++
++/*
++** This function is used by changeset_concat() to merge two UPDATE changes
++** on the same row.
++*/
++static int sessionMergeUpdate(
++  u8 **paOut,                     /* IN/OUT: Pointer to output buffer */
++  SessionTable *pTab,             /* Table change pertains to */
++  int bPatchset,                  /* True if records are patchset records */
++  u8 *aOldRecord1,                /* old.* record for first change */
++  u8 *aOldRecord2,                /* old.* record for second change */
++  u8 *aNewRecord1,                /* new.* record for first change */
++  u8 *aNewRecord2                 /* new.* record for second change */
++){
++  u8 *aOld1 = aOldRecord1;
++  u8 *aOld2 = aOldRecord2;
++  u8 *aNew1 = aNewRecord1;
++  u8 *aNew2 = aNewRecord2;
++
++  u8 *aOut = *paOut;
++  int i;
++
++  if( bPatchset==0 ){
++    int bRequired = 0;
++
++    assert( aOldRecord1 && aNewRecord1 );
++
++    /* Write the old.* vector first. */
++    for(i=0; i<pTab->nCol; i++){
++      int nOld;
++      u8 *aOld;
++      int nNew;
++      u8 *aNew;
++
++      aOld = sessionMergeValue(&aOld1, &aOld2, &nOld);
++      aNew = sessionMergeValue(&aNew1, &aNew2, &nNew);
++      if( pTab->abPK[i] || nOld!=nNew || memcmp(aOld, aNew, nNew) ){
++        if( pTab->abPK[i]==0 ) bRequired = 1;
++        memcpy(aOut, aOld, nOld);
++        aOut += nOld;
++      }else{
++        *(aOut++) = '\0';
++      }
++    }
++
++    if( !bRequired ) return 0;
++  }
++
++  /* Write the new.* vector */
++  aOld1 = aOldRecord1;
++  aOld2 = aOldRecord2;
++  aNew1 = aNewRecord1;
++  aNew2 = aNewRecord2;
++  for(i=0; i<pTab->nCol; i++){
++    int nOld;
++    u8 *aOld;
++    int nNew;
++    u8 *aNew;
++
++    aOld = sessionMergeValue(&aOld1, &aOld2, &nOld);
++    aNew = sessionMergeValue(&aNew1, &aNew2, &nNew);
++    if( bPatchset==0 
++     && (pTab->abPK[i] || (nOld==nNew && 0==memcmp(aOld, aNew, nNew))) 
++    ){
++      *(aOut++) = '\0';
++    }else{
++      memcpy(aOut, aNew, nNew);
++      aOut += nNew;
++    }
++  }
++
++  *paOut = aOut;
++  return 1;
++}
++
++/*
++** This function is only called from within a pre-update-hook callback.
++** It determines if the current pre-update-hook change affects the same row
++** as the change stored in argument pChange. If so, it returns true. Otherwise
++** if the pre-update-hook does not affect the same row as pChange, it returns
++** false.
++*/
++static int sessionPreupdateEqual(
++  sqlite3_session *pSession,      /* Session object that owns SessionTable */
++  SessionTable *pTab,             /* Table associated with change */
++  SessionChange *pChange,         /* Change to compare to */
++  int op                          /* Current pre-update operation */
++){
++  int iCol;                       /* Used to iterate through columns */
++  u8 *a = pChange->aRecord;       /* Cursor used to scan change record */
++
++  assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
++  for(iCol=0; iCol<pTab->nCol; iCol++){
++    if( !pTab->abPK[iCol] ){
++      a += sessionSerialLen(a);
++    }else{
++      sqlite3_value *pVal;        /* Value returned by preupdate_new/old */
++      int rc;                     /* Error code from preupdate_new/old */
++      int eType = *a++;           /* Type of value from change record */
++
++      /* The following calls to preupdate_new() and preupdate_old() can not
++      ** fail. This is because they cache their return values, and by the
++      ** time control flows to here they have already been called once from
++      ** within sessionPreupdateHash(). The first two asserts below verify
++      ** this (that the method has already been called). */
++      if( op==SQLITE_INSERT ){
++        /* assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); */
++        rc = pSession->hook.xNew(pSession->hook.pCtx, iCol, &pVal);
++      }else{
++        /* assert( db->pPreUpdate->pUnpacked ); */
++        rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal);
++      }
++      assert( rc==SQLITE_OK );
++      if( sqlite3_value_type(pVal)!=eType ) return 0;
++
++      /* A SessionChange object never has a NULL value in a PK column */
++      assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
++           || eType==SQLITE_BLOB    || eType==SQLITE_TEXT
++      );
++
++      if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
++        i64 iVal = sessionGetI64(a);
++        a += 8;
++        if( eType==SQLITE_INTEGER ){
++          if( sqlite3_value_int64(pVal)!=iVal ) return 0;
++        }else{
++          double rVal;
++          assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
++          memcpy(&rVal, &iVal, 8);
++          if( sqlite3_value_double(pVal)!=rVal ) return 0;
++        }
++      }else{
++        int n;
++        const u8 *z;
++        a += sessionVarintGet(a, &n);
++        if( sqlite3_value_bytes(pVal)!=n ) return 0;
++        if( eType==SQLITE_TEXT ){
++          z = sqlite3_value_text(pVal);
++        }else{
++          z = sqlite3_value_blob(pVal);
++        }
++        if( memcmp(a, z, n) ) return 0;
++        a += n;
++        break;
++      }
++    }
++  }
++
++  return 1;
++}
++
++/*
++** If required, grow the hash table used to store changes on table pTab 
++** (part of the session pSession). If a fatal OOM error occurs, set the
++** session object to failed and return SQLITE_ERROR. Otherwise, return
++** SQLITE_OK.
++**
++** It is possible that a non-fatal OOM error occurs in this function. In
++** that case the hash-table does not grow, but SQLITE_OK is returned anyway.
++** Growing the hash table in this case is a performance optimization only,
++** it is not required for correct operation.
++*/
++static int sessionGrowHash(int bPatchset, SessionTable *pTab){
++  if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){
++    int i;
++    SessionChange **apNew;
++    int nNew = (pTab->nChange ? pTab->nChange : 128) * 2;
++
++    apNew = (SessionChange **)sqlite3_malloc(sizeof(SessionChange *) * nNew);
++    if( apNew==0 ){
++      if( pTab->nChange==0 ){
++        return SQLITE_ERROR;
++      }
++      return SQLITE_OK;
++    }
++    memset(apNew, 0, sizeof(SessionChange *) * nNew);
++
++    for(i=0; i<pTab->nChange; i++){
++      SessionChange *p;
++      SessionChange *pNext;
++      for(p=pTab->apChange[i]; p; p=pNext){
++        int bPkOnly = (p->op==SQLITE_DELETE && bPatchset);
++        int iHash = sessionChangeHash(pTab, bPkOnly, p->aRecord, nNew);
++        pNext = p->pNext;
++        p->pNext = apNew[iHash];
++        apNew[iHash] = p;
++      }
++    }
++
++    sqlite3_free(pTab->apChange);
++    pTab->nChange = nNew;
++    pTab->apChange = apNew;
++  }
++
++  return SQLITE_OK;
++}
++
++/*
++** This function queries the database for the names of the columns of table
++** zThis, in schema zDb. It is expected that the table has nCol columns. If
++** not, SQLITE_SCHEMA is returned and none of the output variables are
++** populated.
++**
++** Otherwise, if they are not NULL, variable *pnCol is set to the number
++** of columns in the database table and variable *pzTab is set to point to a
++** nul-terminated copy of the table name. *pazCol (if not NULL) is set to
++** point to an array of pointers to column names. And *pabPK (again, if not
++** NULL) is set to point to an array of booleans - true if the corresponding
++** column is part of the primary key.
++**
++** For example, if the table is declared as:
++**
++**     CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z));
++**
++** Then the four output variables are populated as follows:
++**
++**     *pnCol  = 4
++**     *pzTab  = "tbl1"
++**     *pazCol = {"w", "x", "y", "z"}
++**     *pabPK  = {1, 0, 0, 1}
++**
++** All returned buffers are part of the same single allocation, which must
++** be freed using sqlite3_free() by the caller. If pazCol was not NULL, then
++** pointer *pazCol should be freed to release all memory. Otherwise, pointer
++** *pabPK. It is illegal for both pazCol and pabPK to be NULL.
++*/
++static int sessionTableInfo(
++  sqlite3 *db,                    /* Database connection */
++  const char *zDb,                /* Name of attached database (e.g. "main") */
++  const char *zThis,              /* Table name */
++  int *pnCol,                     /* OUT: number of columns */
++  const char **pzTab,             /* OUT: Copy of zThis */
++  const char ***pazCol,           /* OUT: Array of column names for table */
++  u8 **pabPK                      /* OUT: Array of booleans - true for PK col */
++){
++  char *zPragma;
++  sqlite3_stmt *pStmt;
++  int rc;
++  int nByte;
++  int nDbCol = 0;
++  int nThis;
++  int i;
++  u8 *pAlloc = 0;
++  char **azCol = 0;
++  u8 *abPK = 0;
++
++  assert( pazCol && pabPK );
++
++  nThis = sqlite3Strlen30(zThis);
++  zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
++  if( !zPragma ) return SQLITE_NOMEM;
++
++  rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
++  sqlite3_free(zPragma);
++  if( rc!=SQLITE_OK ) return rc;
++
++  nByte = nThis + 1;
++  while( SQLITE_ROW==sqlite3_step(pStmt) ){
++    nByte += sqlite3_column_bytes(pStmt, 1);
++    nDbCol++;
++  }
++  rc = sqlite3_reset(pStmt);
++
++  if( rc==SQLITE_OK ){
++    nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1);
++    pAlloc = sqlite3_malloc(nByte);
++    if( pAlloc==0 ){
++      rc = SQLITE_NOMEM;
++    }
++  }
++  if( rc==SQLITE_OK ){
++    azCol = (char **)pAlloc;
++    pAlloc = (u8 *)&azCol[nDbCol];
++    abPK = (u8 *)pAlloc;
++    pAlloc = &abPK[nDbCol];
++    if( pzTab ){
++      memcpy(pAlloc, zThis, nThis+1);
++      *pzTab = (char *)pAlloc;
++      pAlloc += nThis+1;
++    }
++  
++    i = 0;
++    while( SQLITE_ROW==sqlite3_step(pStmt) ){
++      int nName = sqlite3_column_bytes(pStmt, 1);
++      const unsigned char *zName = sqlite3_column_text(pStmt, 1);
++      if( zName==0 ) break;
++      memcpy(pAlloc, zName, nName+1);
++      azCol[i] = (char *)pAlloc;
++      pAlloc += nName+1;
++      abPK[i] = sqlite3_column_int(pStmt, 5);
++      i++;
++    }
++    rc = sqlite3_reset(pStmt);
++  
++  }
++
++  /* If successful, populate the output variables. Otherwise, zero them and
++  ** free any allocation made. An error code will be returned in this case.
++  */
++  if( rc==SQLITE_OK ){
++    *pazCol = (const char **)azCol;
++    *pabPK = abPK;
++    *pnCol = nDbCol;
++  }else{
++    *pazCol = 0;
++    *pabPK = 0;
++    *pnCol = 0;
++    if( pzTab ) *pzTab = 0;
++    sqlite3_free(azCol);
++  }
++  sqlite3_finalize(pStmt);
++  return rc;
++}
++
++/*
++** This function is only called from within a pre-update handler for a
++** write to table pTab, part of session pSession. If this is the first
++** write to this table, initalize the SessionTable.nCol, azCol[] and
++** abPK[] arrays accordingly.
++**
++** If an error occurs, an error code is stored in sqlite3_session.rc and
++** non-zero returned. Or, if no error occurs but the table has no primary
++** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to
++** indicate that updates on this table should be ignored. SessionTable.abPK 
++** is set to NULL in this case.
++*/
++static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
++  if( pTab->nCol==0 ){
++    u8 *abPK;
++    assert( pTab->azCol==0 || pTab->abPK==0 );
++    pSession->rc = sessionTableInfo(pSession->db, pSession->zDb, 
++        pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK
++    );
++    if( pSession->rc==SQLITE_OK ){
++      int i;
++      for(i=0; i<pTab->nCol; i++){
++        if( abPK[i] ){
++          pTab->abPK = abPK;
++          break;
++        }
++      }
++    }
++  }
++  return (pSession->rc || pTab->abPK==0);
++}
++
++/*
++** This function is only called from with a pre-update-hook reporting a 
++** change on table pTab (attached to session pSession). The type of change
++** (UPDATE, INSERT, DELETE) is specified by the first argument.
++**
++** Unless one is already present or an error occurs, an entry is added
++** to the changed-rows hash table associated with table pTab.
++*/
++static void sessionPreupdateOneChange(
++  int op,                         /* One of SQLITE_UPDATE, INSERT, DELETE */
++  sqlite3_session *pSession,      /* Session object pTab is attached to */
++  SessionTable *pTab              /* Table that change applies to */
++){
++  int iHash; 
++  int bNull = 0; 
++  int rc = SQLITE_OK;
++
++  if( pSession->rc ) return;
++
++  /* Load table details if required */
++  if( sessionInitTable(pSession, pTab) ) return;
++
++  /* Check the number of columns in this xPreUpdate call matches the 
++  ** number of columns in the table.  */
++  if( pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) ){
++    pSession->rc = SQLITE_SCHEMA;
++    return;
++  }
++
++  /* Grow the hash table if required */
++  if( sessionGrowHash(0, pTab) ){
++    pSession->rc = SQLITE_NOMEM;
++    return;
++  }
++
++  /* Calculate the hash-key for this change. If the primary key of the row
++  ** includes a NULL value, exit early. Such changes are ignored by the
++  ** session module. */
++  rc = sessionPreupdateHash(pSession, pTab, op==SQLITE_INSERT, &iHash, &bNull);
++  if( rc!=SQLITE_OK ) goto error_out;
++
++  if( bNull==0 ){
++    /* Search the hash table for an existing record for this row. */
++    SessionChange *pC;
++    for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){
++      if( sessionPreupdateEqual(pSession, pTab, pC, op) ) break;
++    }
++
++    if( pC==0 ){
++      /* Create a new change object containing all the old values (if
++      ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK
++      ** values (if this is an INSERT). */
++      SessionChange *pChange; /* New change object */
++      int nByte;              /* Number of bytes to allocate */
++      int i;                  /* Used to iterate through columns */
++  
++      assert( rc==SQLITE_OK );
++      pTab->nEntry++;
++  
++      /* Figure out how large an allocation is required */
++      nByte = sizeof(SessionChange);
++      for(i=0; i<pTab->nCol; i++){
++        sqlite3_value *p = 0;
++        if( op!=SQLITE_INSERT ){
++          TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p);
++          assert( trc==SQLITE_OK );
++        }else if( pTab->abPK[i] ){
++          TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p);
++          assert( trc==SQLITE_OK );
++        }
++
++        /* This may fail if SQLite value p contains a utf-16 string that must
++        ** be converted to utf-8 and an OOM error occurs while doing so. */
++        rc = sessionSerializeValue(0, p, &nByte);
++        if( rc!=SQLITE_OK ) goto error_out;
++      }
++  
++      /* Allocate the change object */
++      pChange = (SessionChange *)sqlite3_malloc(nByte);
++      if( !pChange ){
++        rc = SQLITE_NOMEM;
++        goto error_out;
++      }else{
++        memset(pChange, 0, sizeof(SessionChange));
++        pChange->aRecord = (u8 *)&pChange[1];
++      }
++  
++      /* Populate the change object. None of the preupdate_old(),
++      ** preupdate_new() or SerializeValue() calls below may fail as all
++      ** required values and encodings have already been cached in memory.
++      ** It is not possible for an OOM to occur in this block. */
++      nByte = 0;
++      for(i=0; i<pTab->nCol; i++){
++        sqlite3_value *p = 0;
++        if( op!=SQLITE_INSERT ){
++          pSession->hook.xOld(pSession->hook.pCtx, i, &p);
++        }else if( pTab->abPK[i] ){
++          pSession->hook.xNew(pSession->hook.pCtx, i, &p);
++        }
++        sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte);
++      }
++
++      /* Add the change to the hash-table */
++      if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){
++        pChange->bIndirect = 1;
++      }
++      pChange->nRecord = nByte;
++      pChange->op = op;
++      pChange->pNext = pTab->apChange[iHash];
++      pTab->apChange[iHash] = pChange;
++
++    }else if( pC->bIndirect ){
++      /* If the existing change is considered "indirect", but this current
++      ** change is "direct", mark the change object as direct. */
++      if( pSession->hook.xDepth(pSession->hook.pCtx)==0 
++       && pSession->bIndirect==0 
++      ){
++        pC->bIndirect = 0;
++      }
++    }
++  }
++
++  /* If an error has occurred, mark the session object as failed. */
++ error_out:
++  if( rc!=SQLITE_OK ){
++    pSession->rc = rc;
++  }
++}
++
++static int sessionFindTable(
++  sqlite3_session *pSession, 
++  const char *zName,
++  SessionTable **ppTab
++){
++  int rc = SQLITE_OK;
++  int nName = sqlite3Strlen30(zName);
++  SessionTable *pRet;
++
++  /* Search for an existing table */
++  for(pRet=pSession->pTable; pRet; pRet=pRet->pNext){
++    if( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ) break;
++  }
++
++  if( pRet==0 && pSession->bAutoAttach ){
++    /* If there is a table-filter configured, invoke it. If it returns 0,
++    ** do not automatically add the new table. */
++    if( pSession->xTableFilter==0
++     || pSession->xTableFilter(pSession->pFilterCtx, zName) 
++    ){
++      rc = sqlite3session_attach(pSession, zName);
++      if( rc==SQLITE_OK ){
++        for(pRet=pSession->pTable; pRet->pNext; pRet=pRet->pNext);
++        assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) );
++      }
++    }
++  }
++
++  assert( rc==SQLITE_OK || pRet==0 );
++  *ppTab = pRet;
++  return rc;
++}
++
++/*
++** The 'pre-update' hook registered by this module with SQLite databases.
++*/
++static void xPreUpdate(
++  void *pCtx,                     /* Copy of third arg to preupdate_hook() */
++  sqlite3 *db,                    /* Database handle */
++  int op,                         /* SQLITE_UPDATE, DELETE or INSERT */
++  char const *zDb,                /* Database name */
++  char const *zName,              /* Table name */
++  sqlite3_int64 iKey1,            /* Rowid of row about to be deleted/updated */
++  sqlite3_int64 iKey2             /* New rowid value (for a rowid UPDATE) */
++){
++  sqlite3_session *pSession;
++  int nDb = sqlite3Strlen30(zDb);
++
++  assert( sqlite3_mutex_held(db->mutex) );
++
++  for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){
++    SessionTable *pTab;
++
++    /* If this session is attached to a different database ("main", "temp" 
++    ** etc.), or if it is not currently enabled, there is nothing to do. Skip 
++    ** to the next session object attached to this database. */
++    if( pSession->bEnable==0 ) continue;
++    if( pSession->rc ) continue;
++    if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue;
++
++    pSession->rc = sessionFindTable(pSession, zName, &pTab);
++    if( pTab ){
++      assert( pSession->rc==SQLITE_OK );
++      sessionPreupdateOneChange(op, pSession, pTab);
++      if( op==SQLITE_UPDATE ){
++        sessionPreupdateOneChange(SQLITE_INSERT, pSession, pTab);
++      }
++    }
++  }
++}
++
++/*
++** The pre-update hook implementations.
++*/
++static int sessionPreupdateOld(void *pCtx, int iVal, sqlite3_value **ppVal){
++  return sqlite3_preupdate_old((sqlite3*)pCtx, iVal, ppVal);
++}
++static int sessionPreupdateNew(void *pCtx, int iVal, sqlite3_value **ppVal){
++  return sqlite3_preupdate_new((sqlite3*)pCtx, iVal, ppVal);
++}
++static int sessionPreupdateCount(void *pCtx){
++  return sqlite3_preupdate_count((sqlite3*)pCtx);
++}
++static int sessionPreupdateDepth(void *pCtx){
++  return sqlite3_preupdate_depth((sqlite3*)pCtx);
++}
++
++/*
++** Install the pre-update hooks on the session object passed as the only
++** argument.
++*/
++static void sessionPreupdateHooks(
++  sqlite3_session *pSession
++){
++  pSession->hook.pCtx = (void*)pSession->db;
++  pSession->hook.xOld = sessionPreupdateOld;
++  pSession->hook.xNew = sessionPreupdateNew;
++  pSession->hook.xCount = sessionPreupdateCount;
++  pSession->hook.xDepth = sessionPreupdateDepth;
++}
++
++typedef struct SessionDiffCtx SessionDiffCtx;
++struct SessionDiffCtx {
++  sqlite3_stmt *pStmt;
++  int nOldOff;
++};
++
++/*
++** The diff hook implementations.
++*/
++static int sessionDiffOld(void *pCtx, int iVal, sqlite3_value **ppVal){
++  SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
++  *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff);
++  return SQLITE_OK;
++}
++static int sessionDiffNew(void *pCtx, int iVal, sqlite3_value **ppVal){
++  SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
++  *ppVal = sqlite3_column_value(p->pStmt, iVal);
++   return SQLITE_OK;
++}
++static int sessionDiffCount(void *pCtx){
++  SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
++  return p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt);
++}
++static int sessionDiffDepth(void *pCtx){
++  return 0;
++}
++
++/*
++** Install the diff hooks on the session object passed as the only
++** argument.
++*/
++static void sessionDiffHooks(
++  sqlite3_session *pSession,
++  SessionDiffCtx *pDiffCtx
++){
++  pSession->hook.pCtx = (void*)pDiffCtx;
++  pSession->hook.xOld = sessionDiffOld;
++  pSession->hook.xNew = sessionDiffNew;
++  pSession->hook.xCount = sessionDiffCount;
++  pSession->hook.xDepth = sessionDiffDepth;
++}
++
++static char *sessionExprComparePK(
++  int nCol,
++  const char *zDb1, const char *zDb2, 
++  const char *zTab,
++  const char **azCol, u8 *abPK
++){
++  int i;
++  const char *zSep = "";
++  char *zRet = 0;
++
++  for(i=0; i<nCol; i++){
++    if( abPK[i] ){
++      zRet = sqlite3_mprintf("%z%s\"%w\".\"%w\".\"%w\"=\"%w\".\"%w\".\"%w\"",
++          zRet, zSep, zDb1, zTab, azCol[i], zDb2, zTab, azCol[i]
++      );
++      zSep = " AND ";
++      if( zRet==0 ) break;
++    }
++  }
++
++  return zRet;
++}
++
++static char *sessionExprCompareOther(
++  int nCol,
++  const char *zDb1, const char *zDb2, 
++  const char *zTab,
++  const char **azCol, u8 *abPK
++){
++  int i;
++  const char *zSep = "";
++  char *zRet = 0;
++  int bHave = 0;
++
++  for(i=0; i<nCol; i++){
++    if( abPK[i]==0 ){
++      bHave = 1;
++      zRet = sqlite3_mprintf(
++          "%z%s\"%w\".\"%w\".\"%w\" IS NOT \"%w\".\"%w\".\"%w\"",
++          zRet, zSep, zDb1, zTab, azCol[i], zDb2, zTab, azCol[i]
++      );
++      zSep = " OR ";
++      if( zRet==0 ) break;
++    }
++  }
++
++  if( bHave==0 ){
++    assert( zRet==0 );
++    zRet = sqlite3_mprintf("0");
++  }
++
++  return zRet;
++}
++
++static char *sessionSelectFindNew(
++  int nCol,
++  const char *zDb1,      /* Pick rows in this db only */
++  const char *zDb2,      /* But not in this one */
++  const char *zTbl,      /* Table name */
++  const char *zExpr
++){
++  char *zRet = sqlite3_mprintf(
++      "SELECT * FROM \"%w\".\"%w\" WHERE NOT EXISTS ("
++      "  SELECT 1 FROM \"%w\".\"%w\" WHERE %s"
++      ")",
++      zDb1, zTbl, zDb2, zTbl, zExpr
++  );
++  return zRet;
++}
++
++static int sessionDiffFindNew(
++  int op,
++  sqlite3_session *pSession,
++  SessionTable *pTab,
++  const char *zDb1,
++  const char *zDb2,
++  char *zExpr
++){
++  int rc = SQLITE_OK;
++  char *zStmt = sessionSelectFindNew(pTab->nCol, zDb1, zDb2, pTab->zName,zExpr);
++
++  if( zStmt==0 ){
++    rc = SQLITE_NOMEM;
++  }else{
++    sqlite3_stmt *pStmt;
++    rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0);
++    if( rc==SQLITE_OK ){
++      SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
++      pDiffCtx->pStmt = pStmt;
++      pDiffCtx->nOldOff = 0;
++      while( SQLITE_ROW==sqlite3_step(pStmt) ){
++        sessionPreupdateOneChange(op, pSession, pTab);
++      }
++      rc = sqlite3_finalize(pStmt);
++    }
++    sqlite3_free(zStmt);
++  }
++
++  return rc;
++}
++
++static int sessionDiffFindModified(
++  sqlite3_session *pSession, 
++  SessionTable *pTab, 
++  const char *zFrom, 
++  const char *zExpr
++){
++  int rc = SQLITE_OK;
++
++  char *zExpr2 = sessionExprCompareOther(pTab->nCol,
++      pSession->zDb, zFrom, pTab->zName, pTab->azCol, pTab->abPK
++  );
++  if( zExpr2==0 ){
++    rc = SQLITE_NOMEM;
++  }else{
++    char *zStmt = sqlite3_mprintf(
++        "SELECT * FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)",
++        pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2
++    );
++    if( zStmt==0 ){
++      rc = SQLITE_NOMEM;
++    }else{
++      sqlite3_stmt *pStmt;
++      rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0);
++
++      if( rc==SQLITE_OK ){
++        SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
++        pDiffCtx->pStmt = pStmt;
++        pDiffCtx->nOldOff = pTab->nCol;
++        while( SQLITE_ROW==sqlite3_step(pStmt) ){
++          sessionPreupdateOneChange(SQLITE_UPDATE, pSession, pTab);
++        }
++        rc = sqlite3_finalize(pStmt);
++      }
++      sqlite3_free(zStmt);
++    }
++  }
++
++  return rc;
++}
++
++SQLITE_API int sqlite3session_diff(
++  sqlite3_session *pSession,
++  const char *zFrom,
++  const char *zTbl,
++  char **pzErrMsg
++){
++  const char *zDb = pSession->zDb;
++  int rc = pSession->rc;
++  SessionDiffCtx d;
++
++  memset(&d, 0, sizeof(d));
++  sessionDiffHooks(pSession, &d);
++
++  sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
++  if( pzErrMsg ) *pzErrMsg = 0;
++  if( rc==SQLITE_OK ){
++    char *zExpr = 0;
++    sqlite3 *db = pSession->db;
++    SessionTable *pTo;            /* Table zTbl */
++
++    /* Locate and if necessary initialize the target table object */
++    rc = sessionFindTable(pSession, zTbl, &pTo);
++    if( pTo==0 ) goto diff_out;
++    if( sessionInitTable(pSession, pTo) ){
++      rc = pSession->rc;
++      goto diff_out;
++    }
++
++    /* Check the table schemas match */
++    if( rc==SQLITE_OK ){
++      int bHasPk = 0;
++      int bMismatch = 0;
++      int nCol;                   /* Columns in zFrom.zTbl */
++      u8 *abPK;
++      const char **azCol = 0;
++      rc = sessionTableInfo(db, zFrom, zTbl, &nCol, 0, &azCol, &abPK);
++      if( rc==SQLITE_OK ){
++        if( pTo->nCol!=nCol ){
++          bMismatch = 1;
++        }else{
++          int i;
++          for(i=0; i<nCol; i++){
++            if( pTo->abPK[i]!=abPK[i] ) bMismatch = 1;
++            if( sqlite3_stricmp(azCol[i], pTo->azCol[i]) ) bMismatch = 1;
++            if( abPK[i] ) bHasPk = 1;
++          }
++        }
++
++      }
++      sqlite3_free((char*)azCol);
++      if( bMismatch ){
++        *pzErrMsg = sqlite3_mprintf("table schemas do not match");
++        rc = SQLITE_SCHEMA;
++      }
++      if( bHasPk==0 ){
++        /* Ignore tables with no primary keys */
++        goto diff_out;
++      }
++    }
++
++    if( rc==SQLITE_OK ){
++      zExpr = sessionExprComparePK(pTo->nCol, 
++          zDb, zFrom, pTo->zName, pTo->azCol, pTo->abPK
++      );
++    }
++
++    /* Find new rows */
++    if( rc==SQLITE_OK ){
++      rc = sessionDiffFindNew(SQLITE_INSERT, pSession, pTo, zDb, zFrom, zExpr);
++    }
++
++    /* Find old rows */
++    if( rc==SQLITE_OK ){
++      rc = sessionDiffFindNew(SQLITE_DELETE, pSession, pTo, zFrom, zDb, zExpr);
++    }
++
++    /* Find modified rows */
++    if( rc==SQLITE_OK ){
++      rc = sessionDiffFindModified(pSession, pTo, zFrom, zExpr);
++    }
++
++    sqlite3_free(zExpr);
++  }
++
++ diff_out:
++  sessionPreupdateHooks(pSession);
++  sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
++  return rc;
++}
++
++/*
++** Create a session object. This session object will record changes to
++** database zDb attached to connection db.
++*/
++SQLITE_API int sqlite3session_create(
++  sqlite3 *db,                    /* Database handle */
++  const char *zDb,                /* Name of db (e.g. "main") */
++  sqlite3_session **ppSession     /* OUT: New session object */
++){
++  sqlite3_session *pNew;          /* Newly allocated session object */
++  sqlite3_session *pOld;          /* Session object already attached to db */
++  int nDb = sqlite3Strlen30(zDb); /* Length of zDb in bytes */
++
++  /* Zero the output value in case an error occurs. */
++  *ppSession = 0;
++
++  /* Allocate and populate the new session object. */
++  pNew = (sqlite3_session *)sqlite3_malloc(sizeof(sqlite3_session) + nDb + 1);
++  if( !pNew ) return SQLITE_NOMEM;
++  memset(pNew, 0, sizeof(sqlite3_session));
++  pNew->db = db;
++  pNew->zDb = (char *)&pNew[1];
++  pNew->bEnable = 1;
++  memcpy(pNew->zDb, zDb, nDb+1);
++  sessionPreupdateHooks(pNew);
++
++  /* Add the new session object to the linked list of session objects 
++  ** attached to database handle $db. Do this under the cover of the db
++  ** handle mutex.  */
++  sqlite3_mutex_enter(sqlite3_db_mutex(db));
++  pOld = (sqlite3_session*)sqlite3_preupdate_hook(db, xPreUpdate, (void*)pNew);
++  pNew->pNext = pOld;
++  sqlite3_mutex_leave(sqlite3_db_mutex(db));
++
++  *ppSession = pNew;
++  return SQLITE_OK;
++}
++
++/*
++** Free the list of table objects passed as the first argument. The contents
++** of the changed-rows hash tables are also deleted.
++*/
++static void sessionDeleteTable(SessionTable *pList){
++  SessionTable *pNext;
++  SessionTable *pTab;
++
++  for(pTab=pList; pTab; pTab=pNext){
++    int i;
++    pNext = pTab->pNext;
++    for(i=0; i<pTab->nChange; i++){
++      SessionChange *p;
++      SessionChange *pNextChange;
++      for(p=pTab->apChange[i]; p; p=pNextChange){
++        pNextChange = p->pNext;
++        sqlite3_free(p);
++      }
++    }
++    sqlite3_free((char*)pTab->azCol);  /* cast works around VC++ bug */
++    sqlite3_free(pTab->apChange);
++    sqlite3_free(pTab);
++  }
++}
++
++/*
++** Delete a session object previously allocated using sqlite3session_create().
++*/
++SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){
++  sqlite3 *db = pSession->db;
++  sqlite3_session *pHead;
++  sqlite3_session **pp;
++
++  /* Unlink the session from the linked list of sessions attached to the
++  ** database handle. Hold the db mutex while doing so.  */
++  sqlite3_mutex_enter(sqlite3_db_mutex(db));
++  pHead = (sqlite3_session*)sqlite3_preupdate_hook(db, 0, 0);
++  for(pp=&pHead; ALWAYS((*pp)!=0); pp=&((*pp)->pNext)){
++    if( (*pp)==pSession ){
++      *pp = (*pp)->pNext;
++      if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void*)pHead);
++      break;
++    }
++  }
++  sqlite3_mutex_leave(sqlite3_db_mutex(db));
++
++  /* Delete all attached table objects. And the contents of their 
++  ** associated hash-tables. */
++  sessionDeleteTable(pSession->pTable);
++
++  /* Free the session object itself. */
++  sqlite3_free(pSession);
++}
++
++/*
++** Set a table filter on a Session Object.
++*/
++SQLITE_API void sqlite3session_table_filter(
++  sqlite3_session *pSession, 
++  int(*xFilter)(void*, const char*),
++  void *pCtx                      /* First argument passed to xFilter */
++){
++  pSession->bAutoAttach = 1;
++  pSession->pFilterCtx = pCtx;
++  pSession->xTableFilter = xFilter;
++}
++
++/*
++** Attach a table to a session. All subsequent changes made to the table
++** while the session object is enabled will be recorded.
++**
++** Only tables that have a PRIMARY KEY defined may be attached. It does
++** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias)
++** or not.
++*/
++SQLITE_API int sqlite3session_attach(
++  sqlite3_session *pSession,      /* Session object */
++  const char *zName               /* Table name */
++){
++  int rc = SQLITE_OK;
++  sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
++
++  if( !zName ){
++    pSession->bAutoAttach = 1;
++  }else{
++    SessionTable *pTab;           /* New table object (if required) */
++    int nName;                    /* Number of bytes in string zName */
++
++    /* First search for an existing entry. If one is found, this call is
++    ** a no-op. Return early. */
++    nName = sqlite3Strlen30(zName);
++    for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
++      if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
++    }
++
++    if( !pTab ){
++      /* Allocate new SessionTable object. */
++      pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1);
++      if( !pTab ){
++        rc = SQLITE_NOMEM;
++      }else{
++        /* Populate the new SessionTable object and link it into the list.
++        ** The new object must be linked onto the end of the list, not 
++        ** simply added to the start of it in order to ensure that tables
++        ** appear in the correct order when a changeset or patchset is
++        ** eventually generated. */
++        SessionTable **ppTab;
++        memset(pTab, 0, sizeof(SessionTable));
++        pTab->zName = (char *)&pTab[1];
++        memcpy(pTab->zName, zName, nName+1);
++        for(ppTab=&pSession->pTable; *ppTab; ppTab=&(*ppTab)->pNext);
++        *ppTab = pTab;
++      }
++    }
++  }
++
++  sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
++  return rc;
++}
++
++/*
++** Ensure that there is room in the buffer to append nByte bytes of data.
++** If not, use sqlite3_realloc() to grow the buffer so that there is.
++**
++** If successful, return zero. Otherwise, if an OOM condition is encountered,
++** set *pRc to SQLITE_NOMEM and return non-zero.
++*/
++static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
++  if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
++    u8 *aNew;
++    int nNew = p->nAlloc ? p->nAlloc : 128;
++    do {
++      nNew = nNew*2;
++    }while( nNew<(p->nBuf+nByte) );
++
++    aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew);
++    if( 0==aNew ){
++      *pRc = SQLITE_NOMEM;
++    }else{
++      p->aBuf = aNew;
++      p->nAlloc = nNew;
++    }
++  }
++  return (*pRc!=SQLITE_OK);
++}
++
++/*
++** Append the value passed as the second argument to the buffer passed
++** as the first.
++**
++** This function is a no-op if *pRc is non-zero when it is called.
++** Otherwise, if an error occurs, *pRc is set to an SQLite error code
++** before returning.
++*/
++static void sessionAppendValue(SessionBuffer *p, sqlite3_value *pVal, int *pRc){
++  int rc = *pRc;
++  if( rc==SQLITE_OK ){
++    int nByte = 0;
++    rc = sessionSerializeValue(0, pVal, &nByte);
++    sessionBufferGrow(p, nByte, &rc);
++    if( rc==SQLITE_OK ){
++      rc = sessionSerializeValue(&p->aBuf[p->nBuf], pVal, 0);
++      p->nBuf += nByte;
++    }else{
++      *pRc = rc;
++    }
++  }
++}
++
++/*
++** This function is a no-op if *pRc is other than SQLITE_OK when it is 
++** called. Otherwise, append a single byte to the buffer. 
++**
++** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
++** returning.
++*/
++static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){
++  if( 0==sessionBufferGrow(p, 1, pRc) ){
++    p->aBuf[p->nBuf++] = v;
++  }
++}
++
++/*
++** This function is a no-op if *pRc is other than SQLITE_OK when it is 
++** called. Otherwise, append a single varint to the buffer. 
++**
++** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
++** returning.
++*/
++static void sessionAppendVarint(SessionBuffer *p, int v, int *pRc){
++  if( 0==sessionBufferGrow(p, 9, pRc) ){
++    p->nBuf += sessionVarintPut(&p->aBuf[p->nBuf], v);
++  }
++}
++
++/*
++** This function is a no-op if *pRc is other than SQLITE_OK when it is 
++** called. Otherwise, append a blob of data to the buffer. 
++**
++** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
++** returning.
++*/
++static void sessionAppendBlob(
++  SessionBuffer *p, 
++  const u8 *aBlob, 
++  int nBlob, 
++  int *pRc
++){
++  if( nBlob>0 && 0==sessionBufferGrow(p, nBlob, pRc) ){
++    memcpy(&p->aBuf[p->nBuf], aBlob, nBlob);
++    p->nBuf += nBlob;
++  }
++}
++
++/*
++** This function is a no-op if *pRc is other than SQLITE_OK when it is 
++** called. Otherwise, append a string to the buffer. All bytes in the string
++** up to (but not including) the nul-terminator are written to the buffer.
++**
++** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
++** returning.
++*/
++static void sessionAppendStr(
++  SessionBuffer *p, 
++  const char *zStr, 
++  int *pRc
++){
++  int nStr = sqlite3Strlen30(zStr);
++  if( 0==sessionBufferGrow(p, nStr, pRc) ){
++    memcpy(&p->aBuf[p->nBuf], zStr, nStr);
++    p->nBuf += nStr;
++  }
++}
++
++/*
++** This function is a no-op if *pRc is other than SQLITE_OK when it is 
++** called. Otherwise, append the string representation of integer iVal
++** to the buffer. No nul-terminator is written.
++**
++** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
++** returning.
++*/
++static void sessionAppendInteger(
++  SessionBuffer *p,               /* Buffer to append to */
++  int iVal,                       /* Value to write the string rep. of */
++  int *pRc                        /* IN/OUT: Error code */
++){
++  char aBuf[24];
++  sqlite3_snprintf(sizeof(aBuf)-1, aBuf, "%d", iVal);
++  sessionAppendStr(p, aBuf, pRc);
++}
++
++/*
++** This function is a no-op if *pRc is other than SQLITE_OK when it is 
++** called. Otherwise, append the string zStr enclosed in quotes (") and
++** with any embedded quote characters escaped to the buffer. No 
++** nul-terminator byte is written.
++**
++** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
++** returning.
++*/
++static void sessionAppendIdent(
++  SessionBuffer *p,               /* Buffer to a append to */
++  const char *zStr,               /* String to quote, escape and append */
++  int *pRc                        /* IN/OUT: Error code */
++){
++  int nStr = sqlite3Strlen30(zStr)*2 + 2 + 1;
++  if( 0==sessionBufferGrow(p, nStr, pRc) ){
++    char *zOut = (char *)&p->aBuf[p->nBuf];
++    const char *zIn = zStr;
++    *zOut++ = '"';
++    while( *zIn ){
++      if( *zIn=='"' ) *zOut++ = '"';
++      *zOut++ = *(zIn++);
++    }
++    *zOut++ = '"';
++    p->nBuf = (int)((u8 *)zOut - p->aBuf);
++  }
++}
++
++/*
++** This function is a no-op if *pRc is other than SQLITE_OK when it is
++** called. Otherwse, it appends the serialized version of the value stored
++** in column iCol of the row that SQL statement pStmt currently points
++** to to the buffer.
++*/
++static void sessionAppendCol(
++  SessionBuffer *p,               /* Buffer to append to */
++  sqlite3_stmt *pStmt,            /* Handle pointing to row containing value */
++  int iCol,                       /* Column to read value from */
++  int *pRc                        /* IN/OUT: Error code */
++){
++  if( *pRc==SQLITE_OK ){
++    int eType = sqlite3_column_type(pStmt, iCol);
++    sessionAppendByte(p, (u8)eType, pRc);
++    if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
++      sqlite3_int64 i;
++      u8 aBuf[8];
++      if( eType==SQLITE_INTEGER ){
++        i = sqlite3_column_int64(pStmt, iCol);
++      }else{
++        double r = sqlite3_column_double(pStmt, iCol);
++        memcpy(&i, &r, 8);
++      }
++      sessionPutI64(aBuf, i);
++      sessionAppendBlob(p, aBuf, 8, pRc);
++    }
++    if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){
++      u8 *z;
++      int nByte;
++      if( eType==SQLITE_BLOB ){
++        z = (u8 *)sqlite3_column_blob(pStmt, iCol);
++      }else{
++        z = (u8 *)sqlite3_column_text(pStmt, iCol);
++      }
++      nByte = sqlite3_column_bytes(pStmt, iCol);
++      if( z || (eType==SQLITE_BLOB && nByte==0) ){
++        sessionAppendVarint(p, nByte, pRc);
++        sessionAppendBlob(p, z, nByte, pRc);
++      }else{
++        *pRc = SQLITE_NOMEM;
++      }
++    }
++  }
++}
++
++/*
++**
++** This function appends an update change to the buffer (see the comments 
++** under "CHANGESET FORMAT" at the top of the file). An update change 
++** consists of:
++**
++**   1 byte:  SQLITE_UPDATE (0x17)
++**   n bytes: old.* record (see RECORD FORMAT)
++**   m bytes: new.* record (see RECORD FORMAT)
++**
++** The SessionChange object passed as the third argument contains the
++** values that were stored in the row when the session began (the old.*
++** values). The statement handle passed as the second argument points
++** at the current version of the row (the new.* values).
++**
++** If all of the old.* values are equal to their corresponding new.* value
++** (i.e. nothing has changed), then no data at all is appended to the buffer.
++**
++** Otherwise, the old.* record contains all primary key values and the 
++** original values of any fields that have been modified. The new.* record 
++** contains the new values of only those fields that have been modified.
++*/ 
++static int sessionAppendUpdate(
++  SessionBuffer *pBuf,            /* Buffer to append to */
++  int bPatchset,                  /* True for "patchset", 0 for "changeset" */
++  sqlite3_stmt *pStmt,            /* Statement handle pointing at new row */
++  SessionChange *p,               /* Object containing old values */
++  u8 *abPK                        /* Boolean array - true for PK columns */
++){
++  int rc = SQLITE_OK;
++  SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */
++  int bNoop = 1;                /* Set to zero if any values are modified */
++  int nRewind = pBuf->nBuf;     /* Set to zero if any values are modified */
++  int i;                        /* Used to iterate through columns */
++  u8 *pCsr = p->aRecord;        /* Used to iterate through old.* values */
++
++  sessionAppendByte(pBuf, SQLITE_UPDATE, &rc);
++  sessionAppendByte(pBuf, p->bIndirect, &rc);
++  for(i=0; i<sqlite3_column_count(pStmt); i++){
++    int bChanged = 0;
++    int nAdvance;
++    int eType = *pCsr;
++    switch( eType ){
++      case SQLITE_NULL:
++        nAdvance = 1;
++        if( sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
++          bChanged = 1;
++        }
++        break;
++
++      case SQLITE_FLOAT:
++      case SQLITE_INTEGER: {
++        nAdvance = 9;
++        if( eType==sqlite3_column_type(pStmt, i) ){
++          sqlite3_int64 iVal = sessionGetI64(&pCsr[1]);
++          if( eType==SQLITE_INTEGER ){
++            if( iVal==sqlite3_column_int64(pStmt, i) ) break;
++          }else{
++            double dVal;
++            memcpy(&dVal, &iVal, 8);
++            if( dVal==sqlite3_column_double(pStmt, i) ) break;
++          }
++        }
++        bChanged = 1;
++        break;
++      }
++
++      default: {
++        int n;
++        int nHdr = 1 + sessionVarintGet(&pCsr[1], &n);
++        assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
++        nAdvance = nHdr + n;
++        if( eType==sqlite3_column_type(pStmt, i) 
++         && n==sqlite3_column_bytes(pStmt, i) 
++         && (n==0 || 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), n))
++        ){
++          break;
++        }
++        bChanged = 1;
++      }
++    }
++
++    /* If at least one field has been modified, this is not a no-op. */
++    if( bChanged ) bNoop = 0;
++
++    /* Add a field to the old.* record. This is omitted if this modules is
++    ** currently generating a patchset. */
++    if( bPatchset==0 ){
++      if( bChanged || abPK[i] ){
++        sessionAppendBlob(pBuf, pCsr, nAdvance, &rc);
++      }else{
++        sessionAppendByte(pBuf, 0, &rc);
++      }
++    }
++
++    /* Add a field to the new.* record. Or the only record if currently
++    ** generating a patchset.  */
++    if( bChanged || (bPatchset && abPK[i]) ){
++      sessionAppendCol(&buf2, pStmt, i, &rc);
++    }else{
++      sessionAppendByte(&buf2, 0, &rc);
++    }
++
++    pCsr += nAdvance;
++  }
++
++  if( bNoop ){
++    pBuf->nBuf = nRewind;
++  }else{
++    sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, &rc);
++  }
++  sqlite3_free(buf2.aBuf);
++
++  return rc;
++}
++
++/*
++** Append a DELETE change to the buffer passed as the first argument. Use
++** the changeset format if argument bPatchset is zero, or the patchset
++** format otherwise.
++*/
++static int sessionAppendDelete(
++  SessionBuffer *pBuf,            /* Buffer to append to */
++  int bPatchset,                  /* True for "patchset", 0 for "changeset" */
++  SessionChange *p,               /* Object containing old values */
++  int nCol,                       /* Number of columns in table */
++  u8 *abPK                        /* Boolean array - true for PK columns */
++){
++  int rc = SQLITE_OK;
++
++  sessionAppendByte(pBuf, SQLITE_DELETE, &rc);
++  sessionAppendByte(pBuf, p->bIndirect, &rc);
++
++  if( bPatchset==0 ){
++    sessionAppendBlob(pBuf, p->aRecord, p->nRecord, &rc);
++  }else{
++    int i;
++    u8 *a = p->aRecord;
++    for(i=0; i<nCol; i++){
++      u8 *pStart = a;
++      int eType = *a++;
++
++      switch( eType ){
++        case 0:
++        case SQLITE_NULL:
++          assert( abPK[i]==0 );
++          break;
++
++        case SQLITE_FLOAT:
++        case SQLITE_INTEGER:
++          a += 8;
++          break;
++
++        default: {
++          int n;
++          a += sessionVarintGet(a, &n);
++          a += n;
++          break;
++        }
++      }
++      if( abPK[i] ){
++        sessionAppendBlob(pBuf, pStart, (int)(a-pStart), &rc);
++      }
++    }
++    assert( (a - p->aRecord)==p->nRecord );
++  }
++
++  return rc;
++}
++
++/*
++** Formulate and prepare a SELECT statement to retrieve a row from table
++** zTab in database zDb based on its primary key. i.e.
++**
++**   SELECT * FROM zDb.zTab WHERE pk1 = ? AND pk2 = ? AND ...
++*/
++static int sessionSelectStmt(
++  sqlite3 *db,                    /* Database handle */
++  const char *zDb,                /* Database name */
++  const char *zTab,               /* Table name */
++  int nCol,                       /* Number of columns in table */
++  const char **azCol,             /* Names of table columns */
++  u8 *abPK,                       /* PRIMARY KEY  array */
++  sqlite3_stmt **ppStmt           /* OUT: Prepared SELECT statement */
++){
++  int rc = SQLITE_OK;
++  int i;
++  const char *zSep = "";
++  SessionBuffer buf = {0, 0, 0};
++
++  sessionAppendStr(&buf, "SELECT * FROM ", &rc);
++  sessionAppendIdent(&buf, zDb, &rc);
++  sessionAppendStr(&buf, ".", &rc);
++  sessionAppendIdent(&buf, zTab, &rc);
++  sessionAppendStr(&buf, " WHERE ", &rc);
++  for(i=0; i<nCol; i++){
++    if( abPK[i] ){
++      sessionAppendStr(&buf, zSep, &rc);
++      sessionAppendIdent(&buf, azCol[i], &rc);
++      sessionAppendStr(&buf, " = ?", &rc);
++      sessionAppendInteger(&buf, i+1, &rc);
++      zSep = " AND ";
++    }
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, ppStmt, 0);
++  }
++  sqlite3_free(buf.aBuf);
++  return rc;
++}
++
++/*
++** Bind the PRIMARY KEY values from the change passed in argument pChange
++** to the SELECT statement passed as the first argument. The SELECT statement
++** is as prepared by function sessionSelectStmt().
++**
++** Return SQLITE_OK if all PK values are successfully bound, or an SQLite
++** error code (e.g. SQLITE_NOMEM) otherwise.
++*/
++static int sessionSelectBind(
++  sqlite3_stmt *pSelect,          /* SELECT from sessionSelectStmt() */
++  int nCol,                       /* Number of columns in table */
++  u8 *abPK,                       /* PRIMARY KEY array */
++  SessionChange *pChange          /* Change structure */
++){
++  int i;
++  int rc = SQLITE_OK;
++  u8 *a = pChange->aRecord;
++
++  for(i=0; i<nCol && rc==SQLITE_OK; i++){
++    int eType = *a++;
++
++    switch( eType ){
++      case 0:
++      case SQLITE_NULL:
++        assert( abPK[i]==0 );
++        break;
++
++      case SQLITE_INTEGER: {
++        if( abPK[i] ){
++          i64 iVal = sessionGetI64(a);
++          rc = sqlite3_bind_int64(pSelect, i+1, iVal);
++        }
++        a += 8;
++        break;
++      }
++
++      case SQLITE_FLOAT: {
++        if( abPK[i] ){
++          double rVal;
++          i64 iVal = sessionGetI64(a);
++          memcpy(&rVal, &iVal, 8);
++          rc = sqlite3_bind_double(pSelect, i+1, rVal);
++        }
++        a += 8;
++        break;
++      }
++
++      case SQLITE_TEXT: {
++        int n;
++        a += sessionVarintGet(a, &n);
++        if( abPK[i] ){
++          rc = sqlite3_bind_text(pSelect, i+1, (char *)a, n, SQLITE_TRANSIENT);
++        }
++        a += n;
++        break;
++      }
++
++      default: {
++        int n;
++        assert( eType==SQLITE_BLOB );
++        a += sessionVarintGet(a, &n);
++        if( abPK[i] ){
++          rc = sqlite3_bind_blob(pSelect, i+1, a, n, SQLITE_TRANSIENT);
++        }
++        a += n;
++        break;
++      }
++    }
++  }
++
++  return rc;
++}
++
++/*
++** This function is a no-op if *pRc is set to other than SQLITE_OK when it
++** is called. Otherwise, append a serialized table header (part of the binary 
++** changeset format) to buffer *pBuf. If an error occurs, set *pRc to an
++** SQLite error code before returning.
++*/
++static void sessionAppendTableHdr(
++  SessionBuffer *pBuf,            /* Append header to this buffer */
++  int bPatchset,                  /* Use the patchset format if true */
++  SessionTable *pTab,             /* Table object to append header for */
++  int *pRc                        /* IN/OUT: Error code */
++){
++  /* Write a table header */
++  sessionAppendByte(pBuf, (bPatchset ? 'P' : 'T'), pRc);
++  sessionAppendVarint(pBuf, pTab->nCol, pRc);
++  sessionAppendBlob(pBuf, pTab->abPK, pTab->nCol, pRc);
++  sessionAppendBlob(pBuf, (u8 *)pTab->zName, (int)strlen(pTab->zName)+1, pRc);
++}
++
++/*
++** Generate either a changeset (if argument bPatchset is zero) or a patchset
++** (if it is non-zero) based on the current contents of the session object
++** passed as the first argument.
++**
++** If no error occurs, SQLITE_OK is returned and the new changeset/patchset
++** stored in output variables *pnChangeset and *ppChangeset. Or, if an error
++** occurs, an SQLite error code is returned and both output variables set 
++** to 0.
++*/
++static int sessionGenerateChangeset(
++  sqlite3_session *pSession,      /* Session object */
++  int bPatchset,                  /* True for patchset, false for changeset */
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut,                     /* First argument for xOutput */
++  int *pnChangeset,               /* OUT: Size of buffer at *ppChangeset */
++  void **ppChangeset              /* OUT: Buffer containing changeset */
++){
++  sqlite3 *db = pSession->db;     /* Source database handle */
++  SessionTable *pTab;             /* Used to iterate through attached tables */
++  SessionBuffer buf = {0,0,0};    /* Buffer in which to accumlate changeset */
++  int rc;                         /* Return code */
++
++  assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0 ) );
++
++  /* Zero the output variables in case an error occurs. If this session
++  ** object is already in the error state (sqlite3_session.rc != SQLITE_OK),
++  ** this call will be a no-op.  */
++  if( xOutput==0 ){
++    *pnChangeset = 0;
++    *ppChangeset = 0;
++  }
++
++  if( pSession->rc ) return pSession->rc;
++  rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0);
++  if( rc!=SQLITE_OK ) return rc;
++
++  sqlite3_mutex_enter(sqlite3_db_mutex(db));
++
++  for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
++    if( pTab->nEntry ){
++      const char *zName = pTab->zName;
++      int nCol;                   /* Number of columns in table */
++      u8 *abPK;                   /* Primary key array */
++      const char **azCol = 0;     /* Table columns */
++      int i;                      /* Used to iterate through hash buckets */
++      sqlite3_stmt *pSel = 0;     /* SELECT statement to query table pTab */
++      int nRewind = buf.nBuf;     /* Initial size of write buffer */
++      int nNoop;                  /* Size of buffer after writing tbl header */
++
++      /* Check the table schema is still Ok. */
++      rc = sessionTableInfo(db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK);
++      if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){
++        rc = SQLITE_SCHEMA;
++      }
++
++      /* Write a table header */
++      sessionAppendTableHdr(&buf, bPatchset, pTab, &rc);
++
++      /* Build and compile a statement to execute: */
++      if( rc==SQLITE_OK ){
++        rc = sessionSelectStmt(
++            db, pSession->zDb, zName, nCol, azCol, abPK, &pSel);
++      }
++
++      nNoop = buf.nBuf;
++      for(i=0; i<pTab->nChange && rc==SQLITE_OK; i++){
++        SessionChange *p;         /* Used to iterate through changes */
++
++        for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){
++          rc = sessionSelectBind(pSel, nCol, abPK, p);
++          if( rc!=SQLITE_OK ) continue;
++          if( sqlite3_step(pSel)==SQLITE_ROW ){
++            if( p->op==SQLITE_INSERT ){
++              int iCol;
++              sessionAppendByte(&buf, SQLITE_INSERT, &rc);
++              sessionAppendByte(&buf, p->bIndirect, &rc);
++              for(iCol=0; iCol<nCol; iCol++){
++                sessionAppendCol(&buf, pSel, iCol, &rc);
++              }
++            }else{
++              rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK);
++            }
++          }else if( p->op!=SQLITE_INSERT ){
++            rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK);
++          }
++          if( rc==SQLITE_OK ){
++            rc = sqlite3_reset(pSel);
++          }
++
++          /* If the buffer is now larger than SESSIONS_STRM_CHUNK_SIZE, pass
++          ** its contents to the xOutput() callback. */
++          if( xOutput 
++           && rc==SQLITE_OK 
++           && buf.nBuf>nNoop 
++           && buf.nBuf>SESSIONS_STRM_CHUNK_SIZE 
++          ){
++            rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
++            nNoop = -1;
++            buf.nBuf = 0;
++          }
++
++        }
++      }
++
++      sqlite3_finalize(pSel);
++      if( buf.nBuf==nNoop ){
++        buf.nBuf = nRewind;
++      }
++      sqlite3_free((char*)azCol);  /* cast works around VC++ bug */
++    }
++  }
++
++  if( rc==SQLITE_OK ){
++    if( xOutput==0 ){
++      *pnChangeset = buf.nBuf;
++      *ppChangeset = buf.aBuf;
++      buf.aBuf = 0;
++    }else if( buf.nBuf>0 ){
++      rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
++    }
++  }
++
++  sqlite3_free(buf.aBuf);
++  sqlite3_exec(db, "RELEASE changeset", 0, 0, 0);
++  sqlite3_mutex_leave(sqlite3_db_mutex(db));
++  return rc;
++}
++
++/*
++** Obtain a changeset object containing all changes recorded by the 
++** session object passed as the first argument.
++**
++** It is the responsibility of the caller to eventually free the buffer 
++** using sqlite3_free().
++*/
++SQLITE_API int sqlite3session_changeset(
++  sqlite3_session *pSession,      /* Session object */
++  int *pnChangeset,               /* OUT: Size of buffer at *ppChangeset */
++  void **ppChangeset              /* OUT: Buffer containing changeset */
++){
++  return sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset, ppChangeset);
++}
++
++/*
++** Streaming version of sqlite3session_changeset().
++*/
++SQLITE_API int sqlite3session_changeset_strm(
++  sqlite3_session *pSession,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++){
++  return sessionGenerateChangeset(pSession, 0, xOutput, pOut, 0, 0);
++}
++
++/*
++** Streaming version of sqlite3session_patchset().
++*/
++SQLITE_API int sqlite3session_patchset_strm(
++  sqlite3_session *pSession,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++){
++  return sessionGenerateChangeset(pSession, 1, xOutput, pOut, 0, 0);
++}
++
++/*
++** Obtain a patchset object containing all changes recorded by the 
++** session object passed as the first argument.
++**
++** It is the responsibility of the caller to eventually free the buffer 
++** using sqlite3_free().
++*/
++SQLITE_API int sqlite3session_patchset(
++  sqlite3_session *pSession,      /* Session object */
++  int *pnPatchset,                /* OUT: Size of buffer at *ppChangeset */
++  void **ppPatchset               /* OUT: Buffer containing changeset */
++){
++  return sessionGenerateChangeset(pSession, 1, 0, 0, pnPatchset, ppPatchset);
++}
++
++/*
++** Enable or disable the session object passed as the first argument.
++*/
++SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable){
++  int ret;
++  sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
++  if( bEnable>=0 ){
++    pSession->bEnable = bEnable;
++  }
++  ret = pSession->bEnable;
++  sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
++  return ret;
++}
++
++/*
++** Enable or disable the session object passed as the first argument.
++*/
++SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect){
++  int ret;
++  sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
++  if( bIndirect>=0 ){
++    pSession->bIndirect = bIndirect;
++  }
++  ret = pSession->bIndirect;
++  sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
++  return ret;
++}
++
++/*
++** Return true if there have been no changes to monitored tables recorded
++** by the session object passed as the only argument.
++*/
++SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession){
++  int ret = 0;
++  SessionTable *pTab;
++
++  sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
++  for(pTab=pSession->pTable; pTab && ret==0; pTab=pTab->pNext){
++    ret = (pTab->nEntry>0);
++  }
++  sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
++
++  return (ret==0);
++}
++
++/*
++** Do the work for either sqlite3changeset_start() or start_strm().
++*/
++static int sessionChangesetStart(
++  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int nChangeset,                 /* Size of buffer pChangeset in bytes */
++  void *pChangeset                /* Pointer to buffer containing changeset */
++){
++  sqlite3_changeset_iter *pRet;   /* Iterator to return */
++  int nByte;                      /* Number of bytes to allocate for iterator */
++
++  assert( xInput==0 || (pChangeset==0 && nChangeset==0) );
++
++  /* Zero the output variable in case an error occurs. */
++  *pp = 0;
++
++  /* Allocate and initialize the iterator structure. */
++  nByte = sizeof(sqlite3_changeset_iter);
++  pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte);
++  if( !pRet ) return SQLITE_NOMEM;
++  memset(pRet, 0, sizeof(sqlite3_changeset_iter));
++  pRet->in.aData = (u8 *)pChangeset;
++  pRet->in.nData = nChangeset;
++  pRet->in.xInput = xInput;
++  pRet->in.pIn = pIn;
++  pRet->in.bEof = (xInput ? 0 : 1);
++
++  /* Populate the output variable and return success. */
++  *pp = pRet;
++  return SQLITE_OK;
++}
++
++/*
++** Create an iterator used to iterate through the contents of a changeset.
++*/
++SQLITE_API int sqlite3changeset_start(
++  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
++  int nChangeset,                 /* Size of buffer pChangeset in bytes */
++  void *pChangeset                /* Pointer to buffer containing changeset */
++){
++  return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset);
++}
++
++/*
++** Streaming version of sqlite3changeset_start().
++*/
++SQLITE_API int sqlite3changeset_start_strm(
++  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn
++){
++  return sessionChangesetStart(pp, xInput, pIn, 0, 0);
++}
++
++/*
++** If the SessionInput object passed as the only argument is a streaming
++** object and the buffer is full, discard some data to free up space.
++*/
++static void sessionDiscardData(SessionInput *pIn){
++  if( pIn->bEof && pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){
++    int nMove = pIn->buf.nBuf - pIn->iNext;
++    assert( nMove>=0 );
++    if( nMove>0 ){
++      memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove);
++    }
++    pIn->buf.nBuf -= pIn->iNext;
++    pIn->iNext = 0;
++    pIn->nData = pIn->buf.nBuf;
++  }
++}
++
++/*
++** Ensure that there are at least nByte bytes available in the buffer. Or,
++** if there are not nByte bytes remaining in the input, that all available
++** data is in the buffer.
++**
++** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
++*/
++static int sessionInputBuffer(SessionInput *pIn, int nByte){
++  int rc = SQLITE_OK;
++  if( pIn->xInput ){
++    while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
++      int nNew = SESSIONS_STRM_CHUNK_SIZE;
++
++      if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
++      if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
++        rc = pIn->xInput(pIn->pIn, &pIn->buf.aBuf[pIn->buf.nBuf], &nNew);
++        if( nNew==0 ){
++          pIn->bEof = 1;
++        }else{
++          pIn->buf.nBuf += nNew;
++        }
++      }
++
++      pIn->aData = pIn->buf.aBuf;
++      pIn->nData = pIn->buf.nBuf;
++    }
++  }
++  return rc;
++}
++
++/*
++** When this function is called, *ppRec points to the start of a record
++** that contains nCol values. This function advances the pointer *ppRec
++** until it points to the byte immediately following that record.
++*/
++static void sessionSkipRecord(
++  u8 **ppRec,                     /* IN/OUT: Record pointer */
++  int nCol                        /* Number of values in record */
++){
++  u8 *aRec = *ppRec;
++  int i;
++  for(i=0; i<nCol; i++){
++    int eType = *aRec++;
++    if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
++      int nByte;
++      aRec += sessionVarintGet((u8*)aRec, &nByte);
++      aRec += nByte;
++    }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
++      aRec += 8;
++    }
++  }
++
++  *ppRec = aRec;
++}
++
++/*
++** This function sets the value of the sqlite3_value object passed as the
++** first argument to a copy of the string or blob held in the aData[] 
++** buffer. SQLITE_OK is returned if successful, or SQLITE_NOMEM if an OOM
++** error occurs.
++*/
++static int sessionValueSetStr(
++  sqlite3_value *pVal,            /* Set the value of this object */
++  u8 *aData,                      /* Buffer containing string or blob data */
++  int nData,                      /* Size of buffer aData[] in bytes */
++  u8 enc                          /* String encoding (0 for blobs) */
++){
++  /* In theory this code could just pass SQLITE_TRANSIENT as the final
++  ** argument to sqlite3ValueSetStr() and have the copy created 
++  ** automatically. But doing so makes it difficult to detect any OOM
++  ** error. Hence the code to create the copy externally. */
++  u8 *aCopy = sqlite3_malloc(nData+1);
++  if( aCopy==0 ) return SQLITE_NOMEM;
++  memcpy(aCopy, aData, nData);
++  sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free);
++  return SQLITE_OK;
++}
++
++/*
++** Deserialize a single record from a buffer in memory. See "RECORD FORMAT"
++** for details.
++**
++** When this function is called, *paChange points to the start of the record
++** to deserialize. Assuming no error occurs, *paChange is set to point to
++** one byte after the end of the same record before this function returns.
++** If the argument abPK is NULL, then the record contains nCol values. Or,
++** if abPK is other than NULL, then the record contains only the PK fields
++** (in other words, it is a patchset DELETE record).
++**
++** If successful, each element of the apOut[] array (allocated by the caller)
++** is set to point to an sqlite3_value object containing the value read
++** from the corresponding position in the record. If that value is not
++** included in the record (i.e. because the record is part of an UPDATE change
++** and the field was not modified), the corresponding element of apOut[] is
++** set to NULL.
++**
++** It is the responsibility of the caller to free all sqlite_value structures
++** using sqlite3_free().
++**
++** If an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
++** The apOut[] array may have been partially populated in this case.
++*/
++static int sessionReadRecord(
++  SessionInput *pIn,              /* Input data */
++  int nCol,                       /* Number of values in record */
++  u8 *abPK,                       /* Array of primary key flags, or NULL */
++  sqlite3_value **apOut           /* Write values to this array */
++){
++  int i;                          /* Used to iterate through columns */
++  int rc = SQLITE_OK;
++
++  for(i=0; i<nCol && rc==SQLITE_OK; i++){
++    int eType = 0;                /* Type of value (SQLITE_NULL, TEXT etc.) */
++    if( abPK && abPK[i]==0 ) continue;
++    rc = sessionInputBuffer(pIn, 9);
++    if( rc==SQLITE_OK ){
++      eType = pIn->aData[pIn->iNext++];
++    }
++
++    assert( apOut[i]==0 );
++    if( eType ){
++      apOut[i] = sqlite3ValueNew(0);
++      if( !apOut[i] ) rc = SQLITE_NOMEM;
++    }
++
++    if( rc==SQLITE_OK ){
++      u8 *aVal = &pIn->aData[pIn->iNext];
++      if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
++        int nByte;
++        pIn->iNext += sessionVarintGet(aVal, &nByte);
++        rc = sessionInputBuffer(pIn, nByte);
++        if( rc==SQLITE_OK ){
++          u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0);
++          rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc);
++        }
++        pIn->iNext += nByte;
++      }
++      if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
++        sqlite3_int64 v = sessionGetI64(aVal);
++        if( eType==SQLITE_INTEGER ){
++          sqlite3VdbeMemSetInt64(apOut[i], v);
++        }else{
++          double d;
++          memcpy(&d, &v, 8);
++          sqlite3VdbeMemSetDouble(apOut[i], d);
++        }
++        pIn->iNext += 8;
++      }
++    }
++  }
++
++  return rc;
++}
++
++/*
++** The input pointer currently points to the second byte of a table-header.
++** Specifically, to the following:
++**
++**   + number of columns in table (varint)
++**   + array of PK flags (1 byte per column),
++**   + table name (nul terminated).
++**
++** This function ensures that all of the above is present in the input 
++** buffer (i.e. that it can be accessed without any calls to xInput()).
++** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code.
++** The input pointer is not moved.
++*/
++static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){
++  int rc = SQLITE_OK;
++  int nCol = 0;
++  int nRead = 0;
++
++  rc = sessionInputBuffer(pIn, 9);
++  if( rc==SQLITE_OK ){
++    nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol);
++    rc = sessionInputBuffer(pIn, nRead+nCol+100);
++    nRead += nCol;
++  }
++
++  while( rc==SQLITE_OK ){
++    while( (pIn->iNext + nRead)<pIn->nData && pIn->aData[pIn->iNext + nRead] ){
++      nRead++;
++    }
++    if( (pIn->iNext + nRead)<pIn->nData ) break;
++    rc = sessionInputBuffer(pIn, nRead + 100);
++  }
++  *pnByte = nRead+1;
++  return rc;
++}
++
++/*
++** The input pointer currently points to the first byte of the first field
++** of a record consisting of nCol columns. This function ensures the entire
++** record is buffered. It does not move the input pointer.
++**
++** If successful, SQLITE_OK is returned and *pnByte is set to the size of
++** the record in bytes. Otherwise, an SQLite error code is returned. The
++** final value of *pnByte is undefined in this case.
++*/
++static int sessionChangesetBufferRecord(
++  SessionInput *pIn,              /* Input data */
++  int nCol,                       /* Number of columns in record */
++  int *pnByte                     /* OUT: Size of record in bytes */
++){
++  int rc = SQLITE_OK;
++  int nByte = 0;
++  int i;
++  for(i=0; rc==SQLITE_OK && i<nCol; i++){
++    int eType;
++    rc = sessionInputBuffer(pIn, nByte + 10);
++    if( rc==SQLITE_OK ){
++      eType = pIn->aData[pIn->iNext + nByte++];
++      if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
++        int n;
++        nByte += sessionVarintGet(&pIn->aData[pIn->iNext+nByte], &n);
++        nByte += n;
++        rc = sessionInputBuffer(pIn, nByte);
++      }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
++        nByte += 8;
++      }
++    }
++  }
++  *pnByte = nByte;
++  return rc;
++}
++
++/*
++** The input pointer currently points to the second byte of a table-header.
++** Specifically, to the following:
++**
++**   + number of columns in table (varint)
++**   + array of PK flags (1 byte per column),
++**   + table name (nul terminated).
++**
++** This function decodes the table-header and populates the p->nCol, 
++** p->zTab and p->abPK[] variables accordingly. The p->apValue[] array is 
++** also allocated or resized according to the new value of p->nCol. The
++** input pointer is left pointing to the byte following the table header.
++**
++** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code
++** is returned and the final values of the various fields enumerated above
++** are undefined.
++*/
++static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
++  int rc;
++  int nCopy;
++  assert( p->rc==SQLITE_OK );
++
++  rc = sessionChangesetBufferTblhdr(&p->in, &nCopy);
++  if( rc==SQLITE_OK ){
++    int nByte;
++    int nVarint;
++    nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol);
++    nCopy -= nVarint;
++    p->in.iNext += nVarint;
++    nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy;
++    p->tblhdr.nBuf = 0;
++    sessionBufferGrow(&p->tblhdr, nByte, &rc);
++  }
++
++  if( rc==SQLITE_OK ){
++    int iPK = sizeof(sqlite3_value*)*p->nCol*2;
++    memset(p->tblhdr.aBuf, 0, iPK);
++    memcpy(&p->tblhdr.aBuf[iPK], &p->in.aData[p->in.iNext], nCopy);
++    p->in.iNext += nCopy;
++  }
++
++  p->apValue = (sqlite3_value**)p->tblhdr.aBuf;
++  p->abPK = (u8*)&p->apValue[p->nCol*2];
++  p->zTab = (char*)&p->abPK[p->nCol];
++  return (p->rc = rc);
++}
++
++/*
++** Advance the changeset iterator to the next change.
++**
++** If both paRec and pnRec are NULL, then this function works like the public
++** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the
++** sqlite3changeset_new() and old() APIs may be used to query for values.
++**
++** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change
++** record is written to *paRec before returning and the number of bytes in
++** the record to *pnRec.
++**
++** Either way, this function returns SQLITE_ROW if the iterator is 
++** successfully advanced to the next change in the changeset, an SQLite 
++** error code if an error occurs, or SQLITE_DONE if there are no further 
++** changes in the changeset.
++*/
++static int sessionChangesetNext(
++  sqlite3_changeset_iter *p,      /* Changeset iterator */
++  u8 **paRec,                     /* If non-NULL, store record pointer here */
++  int *pnRec                      /* If non-NULL, store size of record here */
++){
++  int i;
++  u8 op;
++
++  assert( (paRec==0 && pnRec==0) || (paRec && pnRec) );
++
++  /* If the iterator is in the error-state, return immediately. */
++  if( p->rc!=SQLITE_OK ) return p->rc;
++
++  /* Free the current contents of p->apValue[], if any. */
++  if( p->apValue ){
++    for(i=0; i<p->nCol*2; i++){
++      sqlite3ValueFree(p->apValue[i]);
++    }
++    memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2);
++  }
++
++  /* Make sure the buffer contains at least 10 bytes of input data, or all
++  ** remaining data if there are less than 10 bytes available. This is
++  ** sufficient either for the 'T' or 'P' byte and the varint that follows
++  ** it, or for the two single byte values otherwise. */
++  p->rc = sessionInputBuffer(&p->in, 2);
++  if( p->rc!=SQLITE_OK ) return p->rc;
++
++  /* If the iterator is already at the end of the changeset, return DONE. */
++  if( p->in.iNext>=p->in.nData ){
++    return SQLITE_DONE;
++  }
++
++  sessionDiscardData(&p->in);
++  p->in.iCurrent = p->in.iNext;
++
++  op = p->in.aData[p->in.iNext++];
++  while( op=='T' || op=='P' ){
++    p->bPatchset = (op=='P');
++    if( sessionChangesetReadTblhdr(p) ) return p->rc;
++    if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc;
++    p->in.iCurrent = p->in.iNext;
++    if( p->in.iNext>=p->in.nData ) return SQLITE_DONE;
++    op = p->in.aData[p->in.iNext++];
++  }
++
++  p->op = op;
++  p->bIndirect = p->in.aData[p->in.iNext++];
++  if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){
++    return (p->rc = SQLITE_CORRUPT_BKPT);
++  }
++
++  if( paRec ){ 
++    int nVal;                     /* Number of values to buffer */
++    if( p->bPatchset==0 && op==SQLITE_UPDATE ){
++      nVal = p->nCol * 2;
++    }else if( p->bPatchset && op==SQLITE_DELETE ){
++      nVal = 0;
++      for(i=0; i<p->nCol; i++) if( p->abPK[i] ) nVal++;
++    }else{
++      nVal = p->nCol;
++    }
++    p->rc = sessionChangesetBufferRecord(&p->in, nVal, pnRec);
++    if( p->rc!=SQLITE_OK ) return p->rc;
++    *paRec = &p->in.aData[p->in.iNext];
++    p->in.iNext += *pnRec;
++  }else{
++
++    /* If this is an UPDATE or DELETE, read the old.* record. */
++    if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
++      u8 *abPK = p->bPatchset ? p->abPK : 0;
++      p->rc = sessionReadRecord(&p->in, p->nCol, abPK, p->apValue);
++      if( p->rc!=SQLITE_OK ) return p->rc;
++    }
++
++    /* If this is an INSERT or UPDATE, read the new.* record. */
++    if( p->op!=SQLITE_DELETE ){
++      p->rc = sessionReadRecord(&p->in, p->nCol, 0, &p->apValue[p->nCol]);
++      if( p->rc!=SQLITE_OK ) return p->rc;
++    }
++
++    if( p->bPatchset && p->op==SQLITE_UPDATE ){
++      /* If this is an UPDATE that is part of a patchset, then all PK and
++      ** modified fields are present in the new.* record. The old.* record
++      ** is currently completely empty. This block shifts the PK fields from
++      ** new.* to old.*, to accommodate the code that reads these arrays.  */
++      for(i=0; i<p->nCol; i++){
++        assert( p->apValue[i]==0 );
++        assert( p->abPK[i]==0 || p->apValue[i+p->nCol] );
++        if( p->abPK[i] ){
++          p->apValue[i] = p->apValue[i+p->nCol];
++          p->apValue[i+p->nCol] = 0;
++        }
++      }
++    }
++  }
++
++  return SQLITE_ROW;
++}
++
++/*
++** Advance an iterator created by sqlite3changeset_start() to the next
++** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE
++** or SQLITE_CORRUPT.
++**
++** This function may not be called on iterators passed to a conflict handler
++** callback by changeset_apply().
++*/
++SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *p){
++  return sessionChangesetNext(p, 0, 0);
++}
++
++/*
++** The following function extracts information on the current change
++** from a changeset iterator. It may only be called after changeset_next()
++** has returned SQLITE_ROW.
++*/
++SQLITE_API int sqlite3changeset_op(
++  sqlite3_changeset_iter *pIter,  /* Iterator handle */
++  const char **pzTab,             /* OUT: Pointer to table name */
++  int *pnCol,                     /* OUT: Number of columns in table */
++  int *pOp,                       /* OUT: SQLITE_INSERT, DELETE or UPDATE */
++  int *pbIndirect                 /* OUT: True if change is indirect */
++){
++  *pOp = pIter->op;
++  *pnCol = pIter->nCol;
++  *pzTab = pIter->zTab;
++  if( pbIndirect ) *pbIndirect = pIter->bIndirect;
++  return SQLITE_OK;
++}
++
++/*
++** Return information regarding the PRIMARY KEY and number of columns in
++** the database table affected by the change that pIter currently points
++** to. This function may only be called after changeset_next() returns
++** SQLITE_ROW.
++*/
++SQLITE_API int sqlite3changeset_pk(
++  sqlite3_changeset_iter *pIter,  /* Iterator object */
++  unsigned char **pabPK,          /* OUT: Array of boolean - true for PK cols */
++  int *pnCol                      /* OUT: Number of entries in output array */
++){
++  *pabPK = pIter->abPK;
++  if( pnCol ) *pnCol = pIter->nCol;
++  return SQLITE_OK;
++}
++
++/*
++** This function may only be called while the iterator is pointing to an
++** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()).
++** Otherwise, SQLITE_MISUSE is returned.
++**
++** It sets *ppValue to point to an sqlite3_value structure containing the
++** iVal'th value in the old.* record. Or, if that particular value is not
++** included in the record (because the change is an UPDATE and the field
++** was not modified and is not a PK column), set *ppValue to NULL.
++**
++** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
++** not modified. Otherwise, SQLITE_OK.
++*/
++SQLITE_API int sqlite3changeset_old(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int iVal,                       /* Index of old.* value to retrieve */
++  sqlite3_value **ppValue         /* OUT: Old value (or NULL pointer) */
++){
++  if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_DELETE ){
++    return SQLITE_MISUSE;
++  }
++  if( iVal<0 || iVal>=pIter->nCol ){
++    return SQLITE_RANGE;
++  }
++  *ppValue = pIter->apValue[iVal];
++  return SQLITE_OK;
++}
++
++/*
++** This function may only be called while the iterator is pointing to an
++** SQLITE_UPDATE or SQLITE_INSERT change (see sqlite3changeset_op()).
++** Otherwise, SQLITE_MISUSE is returned.
++**
++** It sets *ppValue to point to an sqlite3_value structure containing the
++** iVal'th value in the new.* record. Or, if that particular value is not
++** included in the record (because the change is an UPDATE and the field
++** was not modified), set *ppValue to NULL.
++**
++** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
++** not modified. Otherwise, SQLITE_OK.
++*/
++SQLITE_API int sqlite3changeset_new(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int iVal,                       /* Index of new.* value to retrieve */
++  sqlite3_value **ppValue         /* OUT: New value (or NULL pointer) */
++){
++  if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_INSERT ){
++    return SQLITE_MISUSE;
++  }
++  if( iVal<0 || iVal>=pIter->nCol ){
++    return SQLITE_RANGE;
++  }
++  *ppValue = pIter->apValue[pIter->nCol+iVal];
++  return SQLITE_OK;
++}
++
++/*
++** The following two macros are used internally. They are similar to the
++** sqlite3changeset_new() and sqlite3changeset_old() functions, except that
++** they omit all error checking and return a pointer to the requested value.
++*/
++#define sessionChangesetNew(pIter, iVal) (pIter)->apValue[(pIter)->nCol+(iVal)]
++#define sessionChangesetOld(pIter, iVal) (pIter)->apValue[(iVal)]
++
++/*
++** This function may only be called with a changeset iterator that has been
++** passed to an SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT 
++** conflict-handler function. Otherwise, SQLITE_MISUSE is returned.
++**
++** If successful, *ppValue is set to point to an sqlite3_value structure
++** containing the iVal'th value of the conflicting record.
++**
++** If value iVal is out-of-range or some other error occurs, an SQLite error
++** code is returned. Otherwise, SQLITE_OK.
++*/
++SQLITE_API int sqlite3changeset_conflict(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int iVal,                       /* Index of conflict record value to fetch */
++  sqlite3_value **ppValue         /* OUT: Value from conflicting row */
++){
++  if( !pIter->pConflict ){
++    return SQLITE_MISUSE;
++  }
++  if( iVal<0 || iVal>=pIter->nCol ){
++    return SQLITE_RANGE;
++  }
++  *ppValue = sqlite3_column_value(pIter->pConflict, iVal);
++  return SQLITE_OK;
++}
++
++/*
++** This function may only be called with an iterator passed to an
++** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
++** it sets the output variable to the total number of known foreign key
++** violations in the destination database and returns SQLITE_OK.
++**
++** In all other cases this function returns SQLITE_MISUSE.
++*/
++SQLITE_API int sqlite3changeset_fk_conflicts(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int *pnOut                      /* OUT: Number of FK violations */
++){
++  if( pIter->pConflict || pIter->apValue ){
++    return SQLITE_MISUSE;
++  }
++  *pnOut = pIter->nCol;
++  return SQLITE_OK;
++}
++
++
++/*
++** Finalize an iterator allocated with sqlite3changeset_start().
++**
++** This function may not be called on iterators passed to a conflict handler
++** callback by changeset_apply().
++*/
++SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *p){
++  int rc = SQLITE_OK;
++  if( p ){
++    int i;                        /* Used to iterate through p->apValue[] */
++    rc = p->rc;
++    if( p->apValue ){
++      for(i=0; i<p->nCol*2; i++) sqlite3ValueFree(p->apValue[i]);
++    }
++    sqlite3_free(p->tblhdr.aBuf);
++    sqlite3_free(p->in.buf.aBuf);
++    sqlite3_free(p);
++  }
++  return rc;
++}
++
++static int sessionChangesetInvert(
++  SessionInput *pInput,           /* Input changeset */
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut,
++  int *pnInverted,                /* OUT: Number of bytes in output changeset */
++  void **ppInverted               /* OUT: Inverse of pChangeset */
++){
++  int rc = SQLITE_OK;             /* Return value */
++  SessionBuffer sOut;             /* Output buffer */
++  int nCol = 0;                   /* Number of cols in current table */
++  u8 *abPK = 0;                   /* PK array for current table */
++  sqlite3_value **apVal = 0;      /* Space for values for UPDATE inversion */
++  SessionBuffer sPK = {0, 0, 0};  /* PK array for current table */
++
++  /* Initialize the output buffer */
++  memset(&sOut, 0, sizeof(SessionBuffer));
++
++  /* Zero the output variables in case an error occurs. */
++  if( ppInverted ){
++    *ppInverted = 0;
++    *pnInverted = 0;
++  }
++
++  while( 1 ){
++    u8 eType;
++
++    /* Test for EOF. */
++    if( (rc = sessionInputBuffer(pInput, 2)) ) goto finished_invert;
++    if( pInput->iNext>=pInput->nData ) break;
++    eType = pInput->aData[pInput->iNext];
++
++    switch( eType ){
++      case 'T': {
++        /* A 'table' record consists of:
++        **
++        **   * A constant 'T' character,
++        **   * Number of columns in said table (a varint),
++        **   * An array of nCol bytes (sPK),
++        **   * A nul-terminated table name.
++        */
++        int nByte;
++        int nVar;
++        pInput->iNext++;
++        if( (rc = sessionChangesetBufferTblhdr(pInput, &nByte)) ){
++          goto finished_invert;
++        }
++        nVar = sessionVarintGet(&pInput->aData[pInput->iNext], &nCol);
++        sPK.nBuf = 0;
++        sessionAppendBlob(&sPK, &pInput->aData[pInput->iNext+nVar], nCol, &rc);
++        sessionAppendByte(&sOut, eType, &rc);
++        sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc);
++        if( rc ) goto finished_invert;
++
++        pInput->iNext += nByte;
++        sqlite3_free(apVal);
++        apVal = 0;
++        abPK = sPK.aBuf;
++        break;
++      }
++
++      case SQLITE_INSERT:
++      case SQLITE_DELETE: {
++        int nByte;
++        int bIndirect = pInput->aData[pInput->iNext+1];
++        int eType2 = (eType==SQLITE_DELETE ? SQLITE_INSERT : SQLITE_DELETE);
++        pInput->iNext += 2;
++        assert( rc==SQLITE_OK );
++        rc = sessionChangesetBufferRecord(pInput, nCol, &nByte);
++        sessionAppendByte(&sOut, eType2, &rc);
++        sessionAppendByte(&sOut, bIndirect, &rc);
++        sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc);
++        pInput->iNext += nByte;
++        if( rc ) goto finished_invert;
++        break;
++      }
++
++      case SQLITE_UPDATE: {
++        int iCol;
++
++        if( 0==apVal ){
++          apVal = (sqlite3_value **)sqlite3_malloc(sizeof(apVal[0])*nCol*2);
++          if( 0==apVal ){
++            rc = SQLITE_NOMEM;
++            goto finished_invert;
++          }
++          memset(apVal, 0, sizeof(apVal[0])*nCol*2);
++        }
++
++        /* Write the header for the new UPDATE change. Same as the original. */
++        sessionAppendByte(&sOut, eType, &rc);
++        sessionAppendByte(&sOut, pInput->aData[pInput->iNext+1], &rc);
++
++        /* Read the old.* and new.* records for the update change. */
++        pInput->iNext += 2;
++        rc = sessionReadRecord(pInput, nCol, 0, &apVal[0]);
++        if( rc==SQLITE_OK ){
++          rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol]);
++        }
++
++        /* Write the new old.* record. Consists of the PK columns from the
++        ** original old.* record, and the other values from the original
++        ** new.* record. */
++        for(iCol=0; iCol<nCol; iCol++){
++          sqlite3_value *pVal = apVal[iCol + (abPK[iCol] ? 0 : nCol)];
++          sessionAppendValue(&sOut, pVal, &rc);
++        }
++
++        /* Write the new new.* record. Consists of a copy of all values
++        ** from the original old.* record, except for the PK columns, which
++        ** are set to "undefined". */
++        for(iCol=0; iCol<nCol; iCol++){
++          sqlite3_value *pVal = (abPK[iCol] ? 0 : apVal[iCol]);
++          sessionAppendValue(&sOut, pVal, &rc);
++        }
++
++        for(iCol=0; iCol<nCol*2; iCol++){
++          sqlite3ValueFree(apVal[iCol]);
++        }
++        memset(apVal, 0, sizeof(apVal[0])*nCol*2);
++        if( rc!=SQLITE_OK ){
++          goto finished_invert;
++        }
++
++        break;
++      }
++
++      default:
++        rc = SQLITE_CORRUPT_BKPT;
++        goto finished_invert;
++    }
++
++    assert( rc==SQLITE_OK );
++    if( xOutput && sOut.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
++      rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
++      sOut.nBuf = 0;
++      if( rc!=SQLITE_OK ) goto finished_invert;
++    }
++  }
++
++  assert( rc==SQLITE_OK );
++  if( pnInverted ){
++    *pnInverted = sOut.nBuf;
++    *ppInverted = sOut.aBuf;
++    sOut.aBuf = 0;
++  }else if( sOut.nBuf>0 ){
++    rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
++  }
++
++ finished_invert:
++  sqlite3_free(sOut.aBuf);
++  sqlite3_free(apVal);
++  sqlite3_free(sPK.aBuf);
++  return rc;
++}
++
++
++/*
++** Invert a changeset object.
++*/
++SQLITE_API int sqlite3changeset_invert(
++  int nChangeset,                 /* Number of bytes in input */
++  const void *pChangeset,         /* Input changeset */
++  int *pnInverted,                /* OUT: Number of bytes in output changeset */
++  void **ppInverted               /* OUT: Inverse of pChangeset */
++){
++  SessionInput sInput;
++
++  /* Set up the input stream */
++  memset(&sInput, 0, sizeof(SessionInput));
++  sInput.nData = nChangeset;
++  sInput.aData = (u8*)pChangeset;
++
++  return sessionChangesetInvert(&sInput, 0, 0, pnInverted, ppInverted);
++}
++
++/*
++** Streaming version of sqlite3changeset_invert().
++*/
++SQLITE_API int sqlite3changeset_invert_strm(
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++){
++  SessionInput sInput;
++  int rc;
++
++  /* Set up the input stream */
++  memset(&sInput, 0, sizeof(SessionInput));
++  sInput.xInput = xInput;
++  sInput.pIn = pIn;
++
++  rc = sessionChangesetInvert(&sInput, xOutput, pOut, 0, 0);
++  sqlite3_free(sInput.buf.aBuf);
++  return rc;
++}
++
++typedef struct SessionApplyCtx SessionApplyCtx;
++struct SessionApplyCtx {
++  sqlite3 *db;
++  sqlite3_stmt *pDelete;          /* DELETE statement */
++  sqlite3_stmt *pUpdate;          /* UPDATE statement */
++  sqlite3_stmt *pInsert;          /* INSERT statement */
++  sqlite3_stmt *pSelect;          /* SELECT statement */
++  int nCol;                       /* Size of azCol[] and abPK[] arrays */
++  const char **azCol;             /* Array of column names */
++  u8 *abPK;                       /* Boolean array - true if column is in PK */
++
++  int bDeferConstraints;          /* True to defer constraints */
++  SessionBuffer constraints;      /* Deferred constraints are stored here */
++};
++
++/*
++** Formulate a statement to DELETE a row from database db. Assuming a table
++** structure like this:
++**
++**     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
++**
++** The DELETE statement looks like this:
++**
++**     DELETE FROM x WHERE a = :1 AND c = :3 AND (:5 OR b IS :2 AND d IS :4)
++**
++** Variable :5 (nCol+1) is a boolean. It should be set to 0 if we require
++** matching b and d values, or 1 otherwise. The second case comes up if the
++** conflict handler is invoked with NOTFOUND and returns CHANGESET_REPLACE.
++**
++** If successful, SQLITE_OK is returned and SessionApplyCtx.pDelete is left
++** pointing to the prepared version of the SQL statement.
++*/
++static int sessionDeleteRow(
++  sqlite3 *db,                    /* Database handle */
++  const char *zTab,               /* Table name */
++  SessionApplyCtx *p              /* Session changeset-apply context */
++){
++  int i;
++  const char *zSep = "";
++  int rc = SQLITE_OK;
++  SessionBuffer buf = {0, 0, 0};
++  int nPk = 0;
++
++  sessionAppendStr(&buf, "DELETE FROM ", &rc);
++  sessionAppendIdent(&buf, zTab, &rc);
++  sessionAppendStr(&buf, " WHERE ", &rc);
++
++  for(i=0; i<p->nCol; i++){
++    if( p->abPK[i] ){
++      nPk++;
++      sessionAppendStr(&buf, zSep, &rc);
++      sessionAppendIdent(&buf, p->azCol[i], &rc);
++      sessionAppendStr(&buf, " = ?", &rc);
++      sessionAppendInteger(&buf, i+1, &rc);
++      zSep = " AND ";
++    }
++  }
++
++  if( nPk<p->nCol ){
++    sessionAppendStr(&buf, " AND (?", &rc);
++    sessionAppendInteger(&buf, p->nCol+1, &rc);
++    sessionAppendStr(&buf, " OR ", &rc);
++
++    zSep = "";
++    for(i=0; i<p->nCol; i++){
++      if( !p->abPK[i] ){
++        sessionAppendStr(&buf, zSep, &rc);
++        sessionAppendIdent(&buf, p->azCol[i], &rc);
++        sessionAppendStr(&buf, " IS ?", &rc);
++        sessionAppendInteger(&buf, i+1, &rc);
++        zSep = "AND ";
++      }
++    }
++    sessionAppendStr(&buf, ")", &rc);
++  }
++
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0);
++  }
++  sqlite3_free(buf.aBuf);
++
++  return rc;
++}
++
++/*
++** Formulate and prepare a statement to UPDATE a row from database db. 
++** Assuming a table structure like this:
++**
++**     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
++**
++** The UPDATE statement looks like this:
++**
++**     UPDATE x SET
++**     a = CASE WHEN ?2  THEN ?3  ELSE a END,
++**     b = CASE WHEN ?5  THEN ?6  ELSE b END,
++**     c = CASE WHEN ?8  THEN ?9  ELSE c END,
++**     d = CASE WHEN ?11 THEN ?12 ELSE d END
++**     WHERE a = ?1 AND c = ?7 AND (?13 OR 
++**       (?5==0 OR b IS ?4) AND (?11==0 OR d IS ?10) AND
++**     )
++**
++** For each column in the table, there are three variables to bind:
++**
++**     ?(i*3+1)    The old.* value of the column, if any.
++**     ?(i*3+2)    A boolean flag indicating that the value is being modified.
++**     ?(i*3+3)    The new.* value of the column, if any.
++**
++** Also, a boolean flag that, if set to true, causes the statement to update
++** a row even if the non-PK values do not match. This is required if the
++** conflict-handler is invoked with CHANGESET_DATA and returns
++** CHANGESET_REPLACE. This is variable "?(nCol*3+1)".
++**
++** If successful, SQLITE_OK is returned and SessionApplyCtx.pUpdate is left
++** pointing to the prepared version of the SQL statement.
++*/
++static int sessionUpdateRow(
++  sqlite3 *db,                    /* Database handle */
++  const char *zTab,               /* Table name */
++  SessionApplyCtx *p              /* Session changeset-apply context */
++){
++  int rc = SQLITE_OK;
++  int i;
++  const char *zSep = "";
++  SessionBuffer buf = {0, 0, 0};
++
++  /* Append "UPDATE tbl SET " */
++  sessionAppendStr(&buf, "UPDATE ", &rc);
++  sessionAppendIdent(&buf, zTab, &rc);
++  sessionAppendStr(&buf, " SET ", &rc);
++
++  /* Append the assignments */
++  for(i=0; i<p->nCol; i++){
++    sessionAppendStr(&buf, zSep, &rc);
++    sessionAppendIdent(&buf, p->azCol[i], &rc);
++    sessionAppendStr(&buf, " = CASE WHEN ?", &rc);
++    sessionAppendInteger(&buf, i*3+2, &rc);
++    sessionAppendStr(&buf, " THEN ?", &rc);
++    sessionAppendInteger(&buf, i*3+3, &rc);
++    sessionAppendStr(&buf, " ELSE ", &rc);
++    sessionAppendIdent(&buf, p->azCol[i], &rc);
++    sessionAppendStr(&buf, " END", &rc);
++    zSep = ", ";
++  }
++
++  /* Append the PK part of the WHERE clause */
++  sessionAppendStr(&buf, " WHERE ", &rc);
++  for(i=0; i<p->nCol; i++){
++    if( p->abPK[i] ){
++      sessionAppendIdent(&buf, p->azCol[i], &rc);
++      sessionAppendStr(&buf, " = ?", &rc);
++      sessionAppendInteger(&buf, i*3+1, &rc);
++      sessionAppendStr(&buf, " AND ", &rc);
++    }
++  }
++
++  /* Append the non-PK part of the WHERE clause */
++  sessionAppendStr(&buf, " (?", &rc);
++  sessionAppendInteger(&buf, p->nCol*3+1, &rc);
++  sessionAppendStr(&buf, " OR 1", &rc);
++  for(i=0; i<p->nCol; i++){
++    if( !p->abPK[i] ){
++      sessionAppendStr(&buf, " AND (?", &rc);
++      sessionAppendInteger(&buf, i*3+2, &rc);
++      sessionAppendStr(&buf, "=0 OR ", &rc);
++      sessionAppendIdent(&buf, p->azCol[i], &rc);
++      sessionAppendStr(&buf, " IS ?", &rc);
++      sessionAppendInteger(&buf, i*3+1, &rc);
++      sessionAppendStr(&buf, ")", &rc);
++    }
++  }
++  sessionAppendStr(&buf, ")", &rc);
++
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pUpdate, 0);
++  }
++  sqlite3_free(buf.aBuf);
++
++  return rc;
++}
++
++/*
++** Formulate and prepare an SQL statement to query table zTab by primary
++** key. Assuming the following table structure:
++**
++**     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
++**
++** The SELECT statement looks like this:
++**
++**     SELECT * FROM x WHERE a = ?1 AND c = ?3
++**
++** If successful, SQLITE_OK is returned and SessionApplyCtx.pSelect is left
++** pointing to the prepared version of the SQL statement.
++*/
++static int sessionSelectRow(
++  sqlite3 *db,                    /* Database handle */
++  const char *zTab,               /* Table name */
++  SessionApplyCtx *p              /* Session changeset-apply context */
++){
++  return sessionSelectStmt(
++      db, "main", zTab, p->nCol, p->azCol, p->abPK, &p->pSelect);
++}
++
++/*
++** Formulate and prepare an INSERT statement to add a record to table zTab.
++** For example:
++**
++**     INSERT INTO main."zTab" VALUES(?1, ?2, ?3 ...);
++**
++** If successful, SQLITE_OK is returned and SessionApplyCtx.pInsert is left
++** pointing to the prepared version of the SQL statement.
++*/
++static int sessionInsertRow(
++  sqlite3 *db,                    /* Database handle */
++  const char *zTab,               /* Table name */
++  SessionApplyCtx *p              /* Session changeset-apply context */
++){
++  int rc = SQLITE_OK;
++  int i;
++  SessionBuffer buf = {0, 0, 0};
++
++  sessionAppendStr(&buf, "INSERT INTO main.", &rc);
++  sessionAppendIdent(&buf, zTab, &rc);
++  sessionAppendStr(&buf, "(", &rc);
++  for(i=0; i<p->nCol; i++){
++    if( i!=0 ) sessionAppendStr(&buf, ", ", &rc);
++    sessionAppendIdent(&buf, p->azCol[i], &rc);
++  }
++
++  sessionAppendStr(&buf, ") VALUES(?", &rc);
++  for(i=1; i<p->nCol; i++){
++    sessionAppendStr(&buf, ", ?", &rc);
++  }
++  sessionAppendStr(&buf, ")", &rc);
++
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0);
++  }
++  sqlite3_free(buf.aBuf);
++  return rc;
++}
++
++/*
++** A wrapper around sqlite3_bind_value() that detects an extra problem. 
++** See comments in the body of this function for details.
++*/
++static int sessionBindValue(
++  sqlite3_stmt *pStmt,            /* Statement to bind value to */
++  int i,                          /* Parameter number to bind to */
++  sqlite3_value *pVal             /* Value to bind */
++){
++  int eType = sqlite3_value_type(pVal);
++  /* COVERAGE: The (pVal->z==0) branch is never true using current versions
++  ** of SQLite. If a malloc fails in an sqlite3_value_xxx() function, either
++  ** the (pVal->z) variable remains as it was or the type of the value is
++  ** set to SQLITE_NULL.  */
++  if( (eType==SQLITE_TEXT || eType==SQLITE_BLOB) && pVal->z==0 ){
++    /* This condition occurs when an earlier OOM in a call to
++    ** sqlite3_value_text() or sqlite3_value_blob() (perhaps from within
++    ** a conflict-handler) has zeroed the pVal->z pointer. Return NOMEM. */
++    return SQLITE_NOMEM;
++  }
++  return sqlite3_bind_value(pStmt, i, pVal);
++}
++
++/*
++** Iterator pIter must point to an SQLITE_INSERT entry. This function 
++** transfers new.* values from the current iterator entry to statement
++** pStmt. The table being inserted into has nCol columns.
++**
++** New.* value $i from the iterator is bound to variable ($i+1) of 
++** statement pStmt. If parameter abPK is NULL, all values from 0 to (nCol-1)
++** are transfered to the statement. Otherwise, if abPK is not NULL, it points
++** to an array nCol elements in size. In this case only those values for 
++** which abPK[$i] is true are read from the iterator and bound to the 
++** statement.
++**
++** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK.
++*/
++static int sessionBindRow(
++  sqlite3_changeset_iter *pIter,  /* Iterator to read values from */
++  int(*xValue)(sqlite3_changeset_iter *, int, sqlite3_value **),
++  int nCol,                       /* Number of columns */
++  u8 *abPK,                       /* If not NULL, bind only if true */
++  sqlite3_stmt *pStmt             /* Bind values to this statement */
++){
++  int i;
++  int rc = SQLITE_OK;
++
++  /* Neither sqlite3changeset_old or sqlite3changeset_new can fail if the
++  ** argument iterator points to a suitable entry. Make sure that xValue 
++  ** is one of these to guarantee that it is safe to ignore the return 
++  ** in the code below. */
++  assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new );
++
++  for(i=0; rc==SQLITE_OK && i<nCol; i++){
++    if( !abPK || abPK[i] ){
++      sqlite3_value *pVal;
++      (void)xValue(pIter, i, &pVal);
++      rc = sessionBindValue(pStmt, i+1, pVal);
++    }
++  }
++  return rc;
++}
++
++/*
++** SQL statement pSelect is as generated by the sessionSelectRow() function.
++** This function binds the primary key values from the change that changeset
++** iterator pIter points to to the SELECT and attempts to seek to the table
++** entry. If a row is found, the SELECT statement left pointing at the row 
++** and SQLITE_ROW is returned. Otherwise, if no row is found and no error
++** has occured, the statement is reset and SQLITE_OK is returned. If an
++** error occurs, the statement is reset and an SQLite error code is returned.
++**
++** If this function returns SQLITE_ROW, the caller must eventually reset() 
++** statement pSelect. If any other value is returned, the statement does
++** not require a reset().
++**
++** If the iterator currently points to an INSERT record, bind values from the
++** new.* record to the SELECT statement. Or, if it points to a DELETE or
++** UPDATE, bind values from the old.* record. 
++*/
++static int sessionSeekToRow(
++  sqlite3 *db,                    /* Database handle */
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  u8 *abPK,                       /* Primary key flags array */
++  sqlite3_stmt *pSelect           /* SELECT statement from sessionSelectRow() */
++){
++  int rc;                         /* Return code */
++  int nCol;                       /* Number of columns in table */
++  int op;                         /* Changset operation (SQLITE_UPDATE etc.) */
++  const char *zDummy;             /* Unused */
++
++  sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
++  rc = sessionBindRow(pIter, 
++      op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old,
++      nCol, abPK, pSelect
++  );
++
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_step(pSelect);
++    if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect);
++  }
++
++  return rc;
++}
++
++/*
++** Invoke the conflict handler for the change that the changeset iterator
++** currently points to.
++**
++** Argument eType must be either CHANGESET_DATA or CHANGESET_CONFLICT.
++** If argument pbReplace is NULL, then the type of conflict handler invoked
++** depends solely on eType, as follows:
++**
++**    eType value                 Value passed to xConflict
++**    -------------------------------------------------
++**    CHANGESET_DATA              CHANGESET_NOTFOUND
++**    CHANGESET_CONFLICT          CHANGESET_CONSTRAINT
++**
++** Or, if pbReplace is not NULL, then an attempt is made to find an existing
++** record with the same primary key as the record about to be deleted, updated
++** or inserted. If such a record can be found, it is available to the conflict
++** handler as the "conflicting" record. In this case the type of conflict
++** handler invoked is as follows:
++**
++**    eType value         PK Record found?   Value passed to xConflict
++**    ----------------------------------------------------------------
++**    CHANGESET_DATA      Yes                CHANGESET_DATA
++**    CHANGESET_DATA      No                 CHANGESET_NOTFOUND
++**    CHANGESET_CONFLICT  Yes                CHANGESET_CONFLICT
++**    CHANGESET_CONFLICT  No                 CHANGESET_CONSTRAINT
++**
++** If pbReplace is not NULL, and a record with a matching PK is found, and
++** the conflict handler function returns SQLITE_CHANGESET_REPLACE, *pbReplace
++** is set to non-zero before returning SQLITE_OK.
++**
++** If the conflict handler returns SQLITE_CHANGESET_ABORT, SQLITE_ABORT is
++** returned. Or, if the conflict handler returns an invalid value, 
++** SQLITE_MISUSE. If the conflict handler returns SQLITE_CHANGESET_OMIT,
++** this function returns SQLITE_OK.
++*/
++static int sessionConflictHandler(
++  int eType,                      /* Either CHANGESET_DATA or CONFLICT */
++  SessionApplyCtx *p,             /* changeset_apply() context */
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  int(*xConflict)(void *, int, sqlite3_changeset_iter*),
++  void *pCtx,                     /* First argument for conflict handler */
++  int *pbReplace                  /* OUT: Set to true if PK row is found */
++){
++  int res = 0;                    /* Value returned by conflict handler */
++  int rc;
++  int nCol;
++  int op;
++  const char *zDummy;
++
++  sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
++
++  assert( eType==SQLITE_CHANGESET_CONFLICT || eType==SQLITE_CHANGESET_DATA );
++  assert( SQLITE_CHANGESET_CONFLICT+1==SQLITE_CHANGESET_CONSTRAINT );
++  assert( SQLITE_CHANGESET_DATA+1==SQLITE_CHANGESET_NOTFOUND );
++
++  /* Bind the new.* PRIMARY KEY values to the SELECT statement. */
++  if( pbReplace ){
++    rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
++  }else{
++    rc = SQLITE_OK;
++  }
++
++  if( rc==SQLITE_ROW ){
++    /* There exists another row with the new.* primary key. */
++    pIter->pConflict = p->pSelect;
++    res = xConflict(pCtx, eType, pIter);
++    pIter->pConflict = 0;
++    rc = sqlite3_reset(p->pSelect);
++  }else if( rc==SQLITE_OK ){
++    if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){
++      /* Instead of invoking the conflict handler, append the change blob
++      ** to the SessionApplyCtx.constraints buffer. */
++      u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent];
++      int nBlob = pIter->in.iNext - pIter->in.iCurrent;
++      sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
++      res = SQLITE_CHANGESET_OMIT;
++    }else{
++      /* No other row with the new.* primary key. */
++      res = xConflict(pCtx, eType+1, pIter);
++      if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE;
++    }
++  }
++
++  if( rc==SQLITE_OK ){
++    switch( res ){
++      case SQLITE_CHANGESET_REPLACE:
++        assert( pbReplace );
++        *pbReplace = 1;
++        break;
++
++      case SQLITE_CHANGESET_OMIT:
++        break;
++
++      case SQLITE_CHANGESET_ABORT:
++        rc = SQLITE_ABORT;
++        break;
++
++      default:
++        rc = SQLITE_MISUSE;
++        break;
++    }
++  }
++
++  return rc;
++}
++
++/*
++** Attempt to apply the change that the iterator passed as the first argument
++** currently points to to the database. If a conflict is encountered, invoke
++** the conflict handler callback.
++**
++** If argument pbRetry is NULL, then ignore any CHANGESET_DATA conflict. If
++** one is encountered, update or delete the row with the matching primary key
++** instead. Or, if pbRetry is not NULL and a CHANGESET_DATA conflict occurs,
++** invoke the conflict handler. If it returns CHANGESET_REPLACE, set *pbRetry
++** to true before returning. In this case the caller will invoke this function
++** again, this time with pbRetry set to NULL.
++**
++** If argument pbReplace is NULL and a CHANGESET_CONFLICT conflict is 
++** encountered invoke the conflict handler with CHANGESET_CONSTRAINT instead.
++** Or, if pbReplace is not NULL, invoke it with CHANGESET_CONFLICT. If such
++** an invocation returns SQLITE_CHANGESET_REPLACE, set *pbReplace to true
++** before retrying. In this case the caller attempts to remove the conflicting
++** row before invoking this function again, this time with pbReplace set 
++** to NULL.
++**
++** If any conflict handler returns SQLITE_CHANGESET_ABORT, this function
++** returns SQLITE_ABORT. Otherwise, if no error occurs, SQLITE_OK is 
++** returned.
++*/
++static int sessionApplyOneOp(
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
++  SessionApplyCtx *p,             /* changeset_apply() context */
++  int(*xConflict)(void *, int, sqlite3_changeset_iter *),
++  void *pCtx,                     /* First argument for the conflict handler */
++  int *pbReplace,                 /* OUT: True to remove PK row and retry */
++  int *pbRetry                    /* OUT: True to retry. */
++){
++  const char *zDummy;
++  int op;
++  int nCol;
++  int rc = SQLITE_OK;
++
++  assert( p->pDelete && p->pUpdate && p->pInsert && p->pSelect );
++  assert( p->azCol && p->abPK );
++  assert( !pbReplace || *pbReplace==0 );
++
++  sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
++
++  if( op==SQLITE_DELETE ){
++
++    /* Bind values to the DELETE statement. If conflict handling is required,
++    ** bind values for all columns and set bound variable (nCol+1) to true.
++    ** Or, if conflict handling is not required, bind just the PK column
++    ** values and, if it exists, set (nCol+1) to false. Conflict handling
++    ** is not required if:
++    **
++    **   * this is a patchset, or
++    **   * (pbRetry==0), or
++    **   * all columns of the table are PK columns (in this case there is
++    **     no (nCol+1) variable to bind to).
++    */
++    u8 *abPK = (pIter->bPatchset ? p->abPK : 0);
++    rc = sessionBindRow(pIter, sqlite3changeset_old, nCol, abPK, p->pDelete);
++    if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){
++      rc = sqlite3_bind_int(p->pDelete, nCol+1, (pbRetry==0 || abPK));
++    }
++    if( rc!=SQLITE_OK ) return rc;
++
++    sqlite3_step(p->pDelete);
++    rc = sqlite3_reset(p->pDelete);
++    if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
++      rc = sessionConflictHandler(
++          SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
++      );
++    }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
++      rc = sessionConflictHandler(
++          SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
++      );
++    }
++
++  }else if( op==SQLITE_UPDATE ){
++    int i;
++
++    /* Bind values to the UPDATE statement. */
++    for(i=0; rc==SQLITE_OK && i<nCol; i++){
++      sqlite3_value *pOld = sessionChangesetOld(pIter, i);
++      sqlite3_value *pNew = sessionChangesetNew(pIter, i);
++
++      sqlite3_bind_int(p->pUpdate, i*3+2, !!pNew);
++      if( pOld ){
++        rc = sessionBindValue(p->pUpdate, i*3+1, pOld);
++      }
++      if( rc==SQLITE_OK && pNew ){
++        rc = sessionBindValue(p->pUpdate, i*3+3, pNew);
++      }
++    }
++    if( rc==SQLITE_OK ){
++      sqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0 || pIter->bPatchset);
++    }
++    if( rc!=SQLITE_OK ) return rc;
++
++    /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict,
++    ** the result will be SQLITE_OK with 0 rows modified. */
++    sqlite3_step(p->pUpdate);
++    rc = sqlite3_reset(p->pUpdate);
++
++    if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
++      /* A NOTFOUND or DATA error. Search the table to see if it contains
++      ** a row with a matching primary key. If so, this is a DATA conflict.
++      ** Otherwise, if there is no primary key match, it is a NOTFOUND. */
++
++      rc = sessionConflictHandler(
++          SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
++      );
++
++    }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
++      /* This is always a CONSTRAINT conflict. */
++      rc = sessionConflictHandler(
++          SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
++      );
++    }
++
++  }else{
++    assert( op==SQLITE_INSERT );
++    rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
++    if( rc!=SQLITE_OK ) return rc;
++
++    sqlite3_step(p->pInsert);
++    rc = sqlite3_reset(p->pInsert);
++    if( (rc&0xff)==SQLITE_CONSTRAINT ){
++      rc = sessionConflictHandler(
++          SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
++      );
++    }
++  }
++
++  return rc;
++}
++
++/*
++** Attempt to apply the change that the iterator passed as the first argument
++** currently points to to the database. If a conflict is encountered, invoke
++** the conflict handler callback.
++**
++** The difference between this function and sessionApplyOne() is that this
++** function handles the case where the conflict-handler is invoked and 
++** returns SQLITE_CHANGESET_REPLACE - indicating that the change should be
++** retried in some manner.
++*/
++static int sessionApplyOneWithRetry(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  sqlite3_changeset_iter *pIter,  /* Changeset iterator to read change from */
++  SessionApplyCtx *pApply,        /* Apply context */
++  int(*xConflict)(void*, int, sqlite3_changeset_iter*),
++  void *pCtx                      /* First argument passed to xConflict */
++){
++  int bReplace = 0;
++  int bRetry = 0;
++  int rc;
++
++  rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry);
++  assert( rc==SQLITE_OK || (bRetry==0 && bReplace==0) );
++
++  /* If the bRetry flag is set, the change has not been applied due to an
++  ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and
++  ** a row with the correct PK is present in the db, but one or more other
++  ** fields do not contain the expected values) and the conflict handler 
++  ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation,
++  ** but pass NULL as the final argument so that sessionApplyOneOp() ignores
++  ** the SQLITE_CHANGESET_DATA problem.  */
++  if( bRetry ){
++    assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE );
++    rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
++  }
++
++  /* If the bReplace flag is set, the change is an INSERT that has not
++  ** been performed because the database already contains a row with the
++  ** specified primary key and the conflict handler returned
++  ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row
++  ** before reattempting the INSERT.  */
++  else if( bReplace ){
++    assert( pIter->op==SQLITE_INSERT );
++    rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0);
++    if( rc==SQLITE_OK ){
++      rc = sessionBindRow(pIter, 
++          sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete);
++      sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1);
++    }
++    if( rc==SQLITE_OK ){
++      sqlite3_step(pApply->pDelete);
++      rc = sqlite3_reset(pApply->pDelete);
++    }
++    if( rc==SQLITE_OK ){
++      rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
++    }
++    if( rc==SQLITE_OK ){
++      rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0);
++    }
++  }
++
++  return rc;
++}
++
++/*
++** Retry the changes accumulated in the pApply->constraints buffer.
++*/
++static int sessionRetryConstraints(
++  sqlite3 *db, 
++  int bPatchset,
++  const char *zTab,
++  SessionApplyCtx *pApply,
++  int(*xConflict)(void*, int, sqlite3_changeset_iter*),
++  void *pCtx                      /* First argument passed to xConflict */
++){
++  int rc = SQLITE_OK;
++
++  while( pApply->constraints.nBuf ){
++    sqlite3_changeset_iter *pIter2 = 0;
++    SessionBuffer cons = pApply->constraints;
++    memset(&pApply->constraints, 0, sizeof(SessionBuffer));
++
++    rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf);
++    if( rc==SQLITE_OK ){
++      int nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
++      int rc2;
++      pIter2->bPatchset = bPatchset;
++      pIter2->zTab = (char*)zTab;
++      pIter2->nCol = pApply->nCol;
++      pIter2->abPK = pApply->abPK;
++      sessionBufferGrow(&pIter2->tblhdr, nByte, &rc);
++      pIter2->apValue = (sqlite3_value**)pIter2->tblhdr.aBuf;
++      if( rc==SQLITE_OK ) memset(pIter2->apValue, 0, nByte);
++
++      while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter2) ){
++        rc = sessionApplyOneWithRetry(db, pIter2, pApply, xConflict, pCtx);
++      }
++
++      rc2 = sqlite3changeset_finalize(pIter2);
++      if( rc==SQLITE_OK ) rc = rc2;
++    }
++    assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 );
++
++    sqlite3_free(cons.aBuf);
++    if( rc!=SQLITE_OK ) break;
++    if( pApply->constraints.nBuf>=cons.nBuf ){
++      /* No progress was made on the last round. */
++      pApply->bDeferConstraints = 0;
++    }
++  }
++
++  return rc;
++}
++
++/*
++** Argument pIter is a changeset iterator that has been initialized, but
++** not yet passed to sqlite3changeset_next(). This function applies the 
++** changeset to the main database attached to handle "db". The supplied
++** conflict handler callback is invoked to resolve any conflicts encountered
++** while applying the change.
++*/
++static int sessionChangesetApply(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  sqlite3_changeset_iter *pIter,  /* Changeset to apply */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of fifth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx                      /* First argument passed to xConflict */
++){
++  int schemaMismatch = 0;
++  int rc;                         /* Return code */
++  const char *zTab = 0;           /* Name of current table */
++  int nTab = 0;                   /* Result of sqlite3Strlen30(zTab) */
++  SessionApplyCtx sApply;         /* changeset_apply() context object */
++  int bPatchset;
++
++  assert( xConflict!=0 );
++
++  pIter->in.bNoDiscard = 1;
++  memset(&sApply, 0, sizeof(sApply));
++  sqlite3_mutex_enter(sqlite3_db_mutex(db));
++  rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0);
++  }
++  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){
++    int nCol;
++    int op;
++    const char *zNew;
++    
++    sqlite3changeset_op(pIter, &zNew, &nCol, &op, 0);
++
++    if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){
++      u8 *abPK;
++
++      rc = sessionRetryConstraints(
++          db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx
++      );
++      if( rc!=SQLITE_OK ) break;
++
++      sqlite3_free((char*)sApply.azCol);  /* cast works around VC++ bug */
++      sqlite3_finalize(sApply.pDelete);
++      sqlite3_finalize(sApply.pUpdate); 
++      sqlite3_finalize(sApply.pInsert);
++      sqlite3_finalize(sApply.pSelect);
++      memset(&sApply, 0, sizeof(sApply));
++      sApply.db = db;
++      sApply.bDeferConstraints = 1;
++
++      /* If an xFilter() callback was specified, invoke it now. If the 
++      ** xFilter callback returns zero, skip this table. If it returns
++      ** non-zero, proceed. */
++      schemaMismatch = (xFilter && (0==xFilter(pCtx, zNew)));
++      if( schemaMismatch ){
++        zTab = sqlite3_mprintf("%s", zNew);
++        if( zTab==0 ){
++          rc = SQLITE_NOMEM;
++          break;
++        }
++        nTab = (int)strlen(zTab);
++        sApply.azCol = (const char **)zTab;
++      }else{
++        int nMinCol = 0;
++        int i;
++
++        sqlite3changeset_pk(pIter, &abPK, 0);
++        rc = sessionTableInfo(
++            db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK
++        );
++        if( rc!=SQLITE_OK ) break;
++        for(i=0; i<sApply.nCol; i++){
++          if( sApply.abPK[i] ) nMinCol = i+1;
++        }
++  
++        if( sApply.nCol==0 ){
++          schemaMismatch = 1;
++          sqlite3_log(SQLITE_SCHEMA, 
++              "sqlite3changeset_apply(): no such table: %s", zTab
++          );
++        }
++        else if( sApply.nCol<nCol ){
++          schemaMismatch = 1;
++          sqlite3_log(SQLITE_SCHEMA, 
++              "sqlite3changeset_apply(): table %s has %d columns, "
++              "expected %d or more", 
++              zTab, sApply.nCol, nCol
++          );
++        }
++        else if( nCol<nMinCol || memcmp(sApply.abPK, abPK, nCol)!=0 ){
++          schemaMismatch = 1;
++          sqlite3_log(SQLITE_SCHEMA, "sqlite3changeset_apply(): "
++              "primary key mismatch for table %s", zTab
++          );
++        }
++        else{
++          sApply.nCol = nCol;
++          if((rc = sessionSelectRow(db, zTab, &sApply))
++          || (rc = sessionUpdateRow(db, zTab, &sApply))
++          || (rc = sessionDeleteRow(db, zTab, &sApply))
++          || (rc = sessionInsertRow(db, zTab, &sApply))
++          ){
++            break;
++          }
++        }
++        nTab = sqlite3Strlen30(zTab);
++      }
++    }
++
++    /* If there is a schema mismatch on the current table, proceed to the
++    ** next change. A log message has already been issued. */
++    if( schemaMismatch ) continue;
++
++    rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx);
++  }
++
++  bPatchset = pIter->bPatchset;
++  if( rc==SQLITE_OK ){
++    rc = sqlite3changeset_finalize(pIter);
++  }else{
++    sqlite3changeset_finalize(pIter);
++  }
++
++  if( rc==SQLITE_OK ){
++    rc = sessionRetryConstraints(db, bPatchset, zTab, &sApply, xConflict, pCtx);
++  }
++
++  if( rc==SQLITE_OK ){
++    int nFk, notUsed;
++    sqlite3_db_status(db, SQLITE_DBSTATUS_DEFERRED_FKS, &nFk, &notUsed, 0);
++    if( nFk!=0 ){
++      int res = SQLITE_CHANGESET_ABORT;
++      sqlite3_changeset_iter sIter;
++      memset(&sIter, 0, sizeof(sIter));
++      sIter.nCol = nFk;
++      res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter);
++      if( res!=SQLITE_CHANGESET_OMIT ){
++        rc = SQLITE_CONSTRAINT;
++      }
++    }
++  }
++  sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0);
++
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
++  }else{
++    sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
++    sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
++  }
++
++  sqlite3_finalize(sApply.pInsert);
++  sqlite3_finalize(sApply.pDelete);
++  sqlite3_finalize(sApply.pUpdate);
++  sqlite3_finalize(sApply.pSelect);
++  sqlite3_free((char*)sApply.azCol);  /* cast works around VC++ bug */
++  sqlite3_free((char*)sApply.constraints.aBuf);
++  sqlite3_mutex_leave(sqlite3_db_mutex(db));
++  return rc;
++}
++
++/*
++** Apply the changeset passed via pChangeset/nChangeset to the main database
++** attached to handle "db". Invoke the supplied conflict handler callback
++** to resolve any conflicts encountered while applying the change.
++*/
++SQLITE_API int sqlite3changeset_apply(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  int nChangeset,                 /* Size of changeset in bytes */
++  void *pChangeset,               /* Changeset blob */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of fifth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx                      /* First argument passed to xConflict */
++){
++  sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
++  int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
++  if( rc==SQLITE_OK ){
++    rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx);
++  }
++  return rc;
++}
++
++/*
++** Apply the changeset passed via xInput/pIn to the main database
++** attached to handle "db". Invoke the supplied conflict handler callback
++** to resolve any conflicts encountered while applying the change.
++*/
++SQLITE_API int sqlite3changeset_apply_strm(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
++  void *pIn,                                          /* First arg for xInput */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx                      /* First argument passed to xConflict */
++){
++  sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
++  int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
++  if( rc==SQLITE_OK ){
++    rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx);
++  }
++  return rc;
++}
++
++/*
++** sqlite3_changegroup handle.
++*/
++struct sqlite3_changegroup {
++  int rc;                         /* Error code */
++  int bPatch;                     /* True to accumulate patchsets */
++  SessionTable *pList;            /* List of tables in current patch */
++};
++
++/*
++** This function is called to merge two changes to the same row together as
++** part of an sqlite3changeset_concat() operation. A new change object is
++** allocated and a pointer to it stored in *ppNew.
++*/
++static int sessionChangeMerge(
++  SessionTable *pTab,             /* Table structure */
++  int bPatchset,                  /* True for patchsets */
++  SessionChange *pExist,          /* Existing change */
++  int op2,                        /* Second change operation */
++  int bIndirect,                  /* True if second change is indirect */
++  u8 *aRec,                       /* Second change record */
++  int nRec,                       /* Number of bytes in aRec */
++  SessionChange **ppNew           /* OUT: Merged change */
++){
++  SessionChange *pNew = 0;
++
++  if( !pExist ){
++    pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange) + nRec);
++    if( !pNew ){
++      return SQLITE_NOMEM;
++    }
++    memset(pNew, 0, sizeof(SessionChange));
++    pNew->op = op2;
++    pNew->bIndirect = bIndirect;
++    pNew->nRecord = nRec;
++    pNew->aRecord = (u8*)&pNew[1];
++    memcpy(pNew->aRecord, aRec, nRec);
++  }else{
++    int op1 = pExist->op;
++
++    /* 
++    **   op1=INSERT, op2=INSERT      ->      Unsupported. Discard op2.
++    **   op1=INSERT, op2=UPDATE      ->      INSERT.
++    **   op1=INSERT, op2=DELETE      ->      (none)
++    **
++    **   op1=UPDATE, op2=INSERT      ->      Unsupported. Discard op2.
++    **   op1=UPDATE, op2=UPDATE      ->      UPDATE.
++    **   op1=UPDATE, op2=DELETE      ->      DELETE.
++    **
++    **   op1=DELETE, op2=INSERT      ->      UPDATE.
++    **   op1=DELETE, op2=UPDATE      ->      Unsupported. Discard op2.
++    **   op1=DELETE, op2=DELETE      ->      Unsupported. Discard op2.
++    */   
++    if( (op1==SQLITE_INSERT && op2==SQLITE_INSERT)
++     || (op1==SQLITE_UPDATE && op2==SQLITE_INSERT)
++     || (op1==SQLITE_DELETE && op2==SQLITE_UPDATE)
++     || (op1==SQLITE_DELETE && op2==SQLITE_DELETE)
++    ){
++      pNew = pExist;
++    }else if( op1==SQLITE_INSERT && op2==SQLITE_DELETE ){
++      sqlite3_free(pExist);
++      assert( pNew==0 );
++    }else{
++      u8 *aExist = pExist->aRecord;
++      int nByte;
++      u8 *aCsr;
++
++      /* Allocate a new SessionChange object. Ensure that the aRecord[]
++      ** buffer of the new object is large enough to hold any record that
++      ** may be generated by combining the input records.  */
++      nByte = sizeof(SessionChange) + pExist->nRecord + nRec;
++      pNew = (SessionChange *)sqlite3_malloc(nByte);
++      if( !pNew ){
++        sqlite3_free(pExist);
++        return SQLITE_NOMEM;
++      }
++      memset(pNew, 0, sizeof(SessionChange));
++      pNew->bIndirect = (bIndirect && pExist->bIndirect);
++      aCsr = pNew->aRecord = (u8 *)&pNew[1];
++
++      if( op1==SQLITE_INSERT ){             /* INSERT + UPDATE */
++        u8 *a1 = aRec;
++        assert( op2==SQLITE_UPDATE );
++        pNew->op = SQLITE_INSERT;
++        if( bPatchset==0 ) sessionSkipRecord(&a1, pTab->nCol);
++        sessionMergeRecord(&aCsr, pTab->nCol, aExist, a1);
++      }else if( op1==SQLITE_DELETE ){       /* DELETE + INSERT */
++        assert( op2==SQLITE_INSERT );
++        pNew->op = SQLITE_UPDATE;
++        if( bPatchset ){
++          memcpy(aCsr, aRec, nRec);
++          aCsr += nRec;
++        }else{
++          if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist, 0,aRec,0) ){
++            sqlite3_free(pNew);
++            pNew = 0;
++          }
++        }
++      }else if( op2==SQLITE_UPDATE ){       /* UPDATE + UPDATE */
++        u8 *a1 = aExist;
++        u8 *a2 = aRec;
++        assert( op1==SQLITE_UPDATE );
++        if( bPatchset==0 ){
++          sessionSkipRecord(&a1, pTab->nCol);
++          sessionSkipRecord(&a2, pTab->nCol);
++        }
++        pNew->op = SQLITE_UPDATE;
++        if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aRec, aExist,a1,a2) ){
++          sqlite3_free(pNew);
++          pNew = 0;
++        }
++      }else{                                /* UPDATE + DELETE */
++        assert( op1==SQLITE_UPDATE && op2==SQLITE_DELETE );
++        pNew->op = SQLITE_DELETE;
++        if( bPatchset ){
++          memcpy(aCsr, aRec, nRec);
++          aCsr += nRec;
++        }else{
++          sessionMergeRecord(&aCsr, pTab->nCol, aRec, aExist);
++        }
++      }
++
++      if( pNew ){
++        pNew->nRecord = (int)(aCsr - pNew->aRecord);
++      }
++      sqlite3_free(pExist);
++    }
++  }
++
++  *ppNew = pNew;
++  return SQLITE_OK;
++}
++
++/*
++** Add all changes in the changeset traversed by the iterator passed as
++** the first argument to the changegroup hash tables.
++*/
++static int sessionChangesetToHash(
++  sqlite3_changeset_iter *pIter,   /* Iterator to read from */
++  sqlite3_changegroup *pGrp        /* Changegroup object to add changeset to */
++){
++  u8 *aRec;
++  int nRec;
++  int rc = SQLITE_OK;
++  SessionTable *pTab = 0;
++
++
++  while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec) ){
++    const char *zNew;
++    int nCol;
++    int op;
++    int iHash;
++    int bIndirect;
++    SessionChange *pChange;
++    SessionChange *pExist = 0;
++    SessionChange **pp;
++
++    if( pGrp->pList==0 ){
++      pGrp->bPatch = pIter->bPatchset;
++    }else if( pIter->bPatchset!=pGrp->bPatch ){
++      rc = SQLITE_ERROR;
++      break;
++    }
++
++    sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect);
++    if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){
++      /* Search the list for a matching table */
++      int nNew = (int)strlen(zNew);
++      u8 *abPK;
++
++      sqlite3changeset_pk(pIter, &abPK, 0);
++      for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){
++        if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break;
++      }
++      if( !pTab ){
++        SessionTable **ppTab;
++
++        pTab = sqlite3_malloc(sizeof(SessionTable) + nCol + nNew+1);
++        if( !pTab ){
++          rc = SQLITE_NOMEM;
++          break;
++        }
++        memset(pTab, 0, sizeof(SessionTable));
++        pTab->nCol = nCol;
++        pTab->abPK = (u8*)&pTab[1];
++        memcpy(pTab->abPK, abPK, nCol);
++        pTab->zName = (char*)&pTab->abPK[nCol];
++        memcpy(pTab->zName, zNew, nNew+1);
++
++        /* The new object must be linked on to the end of the list, not
++        ** simply added to the start of it. This is to ensure that the
++        ** tables within the output of sqlite3changegroup_output() are in 
++        ** the right order.  */
++        for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext);
++        *ppTab = pTab;
++      }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){
++        rc = SQLITE_SCHEMA;
++        break;
++      }
++    }
++
++    if( sessionGrowHash(pIter->bPatchset, pTab) ){
++      rc = SQLITE_NOMEM;
++      break;
++    }
++    iHash = sessionChangeHash(
++        pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange
++    );
++
++    /* Search for existing entry. If found, remove it from the hash table. 
++    ** Code below may link it back in.
++    */
++    for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){
++      int bPkOnly1 = 0;
++      int bPkOnly2 = 0;
++      if( pIter->bPatchset ){
++        bPkOnly1 = (*pp)->op==SQLITE_DELETE;
++        bPkOnly2 = op==SQLITE_DELETE;
++      }
++      if( sessionChangeEqual(pTab, bPkOnly1, (*pp)->aRecord, bPkOnly2, aRec) ){
++        pExist = *pp;
++        *pp = (*pp)->pNext;
++        pTab->nEntry--;
++        break;
++      }
++    }
++
++    rc = sessionChangeMerge(pTab, 
++        pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange
++    );
++    if( rc ) break;
++    if( pChange ){
++      pChange->pNext = pTab->apChange[iHash];
++      pTab->apChange[iHash] = pChange;
++      pTab->nEntry++;
++    }
++  }
++
++  if( rc==SQLITE_OK ) rc = pIter->rc;
++  return rc;
++}
++
++/*
++** Serialize a changeset (or patchset) based on all changesets (or patchsets)
++** added to the changegroup object passed as the first argument.
++**
++** If xOutput is not NULL, then the changeset/patchset is returned to the
++** user via one or more calls to xOutput, as with the other streaming
++** interfaces. 
++**
++** Or, if xOutput is NULL, then (*ppOut) is populated with a pointer to a
++** buffer containing the output changeset before this function returns. In
++** this case (*pnOut) is set to the size of the output buffer in bytes. It
++** is the responsibility of the caller to free the output buffer using
++** sqlite3_free() when it is no longer required.
++**
++** If successful, SQLITE_OK is returned. Or, if an error occurs, an SQLite
++** error code. If an error occurs and xOutput is NULL, (*ppOut) and (*pnOut)
++** are both set to 0 before returning.
++*/
++static int sessionChangegroupOutput(
++  sqlite3_changegroup *pGrp,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut,
++  int *pnOut,
++  void **ppOut
++){
++  int rc = SQLITE_OK;
++  SessionBuffer buf = {0, 0, 0};
++  SessionTable *pTab;
++  assert( xOutput==0 || (ppOut==0 && pnOut==0) );
++
++  /* Create the serialized output changeset based on the contents of the
++  ** hash tables attached to the SessionTable objects in list p->pList. 
++  */
++  for(pTab=pGrp->pList; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
++    int i;
++    if( pTab->nEntry==0 ) continue;
++
++    sessionAppendTableHdr(&buf, pGrp->bPatch, pTab, &rc);
++    for(i=0; i<pTab->nChange; i++){
++      SessionChange *p;
++      for(p=pTab->apChange[i]; p; p=p->pNext){
++        sessionAppendByte(&buf, p->op, &rc);
++        sessionAppendByte(&buf, p->bIndirect, &rc);
++        sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
++      }
++    }
++
++    if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
++      rc = xOutput(pOut, buf.aBuf, buf.nBuf);
++      buf.nBuf = 0;
++    }
++  }
++
++  if( rc==SQLITE_OK ){
++    if( xOutput ){
++      if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
++    }else{
++      *ppOut = buf.aBuf;
++      *pnOut = buf.nBuf;
++      buf.aBuf = 0;
++    }
++  }
++  sqlite3_free(buf.aBuf);
++
++  return rc;
++}
++
++/*
++** Allocate a new, empty, sqlite3_changegroup.
++*/
++SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp){
++  int rc = SQLITE_OK;             /* Return code */
++  sqlite3_changegroup *p;         /* New object */
++  p = (sqlite3_changegroup*)sqlite3_malloc(sizeof(sqlite3_changegroup));
++  if( p==0 ){
++    rc = SQLITE_NOMEM;
++  }else{
++    memset(p, 0, sizeof(sqlite3_changegroup));
++  }
++  *pp = p;
++  return rc;
++}
++
++/*
++** Add the changeset currently stored in buffer pData, size nData bytes,
++** to changeset-group p.
++*/
++SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){
++  sqlite3_changeset_iter *pIter;  /* Iterator opened on pData/nData */
++  int rc;                         /* Return code */
++
++  rc = sqlite3changeset_start(&pIter, nData, pData);
++  if( rc==SQLITE_OK ){
++    rc = sessionChangesetToHash(pIter, pGrp);
++  }
++  sqlite3changeset_finalize(pIter);
++  return rc;
++}
++
++/*
++** Obtain a buffer containing a changeset representing the concatenation
++** of all changesets added to the group so far.
++*/
++SQLITE_API int sqlite3changegroup_output(
++    sqlite3_changegroup *pGrp,
++    int *pnData,
++    void **ppData
++){
++  return sessionChangegroupOutput(pGrp, 0, 0, pnData, ppData);
++}
++
++/*
++** Streaming versions of changegroup_add().
++*/
++SQLITE_API int sqlite3changegroup_add_strm(
++  sqlite3_changegroup *pGrp,
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn
++){
++  sqlite3_changeset_iter *pIter;  /* Iterator opened on pData/nData */
++  int rc;                         /* Return code */
++
++  rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
++  if( rc==SQLITE_OK ){
++    rc = sessionChangesetToHash(pIter, pGrp);
++  }
++  sqlite3changeset_finalize(pIter);
++  return rc;
++}
++
++/*
++** Streaming versions of changegroup_output().
++*/
++SQLITE_API int sqlite3changegroup_output_strm(
++  sqlite3_changegroup *pGrp,
++  int (*xOutput)(void *pOut, const void *pData, int nData), 
++  void *pOut
++){
++  return sessionChangegroupOutput(pGrp, xOutput, pOut, 0, 0);
++}
++
++/*
++** Delete a changegroup object.
++*/
++SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){
++  if( pGrp ){
++    sessionDeleteTable(pGrp->pList);
++    sqlite3_free(pGrp);
++  }
++}
++
++/* 
++** Combine two changesets together.
++*/
++SQLITE_API int sqlite3changeset_concat(
++  int nLeft,                      /* Number of bytes in lhs input */
++  void *pLeft,                    /* Lhs input changeset */
++  int nRight                      /* Number of bytes in rhs input */,
++  void *pRight,                   /* Rhs input changeset */
++  int *pnOut,                     /* OUT: Number of bytes in output changeset */
++  void **ppOut                    /* OUT: changeset (left <concat> right) */
++){
++  sqlite3_changegroup *pGrp;
++  int rc;
++
++  rc = sqlite3changegroup_new(&pGrp);
++  if( rc==SQLITE_OK ){
++    rc = sqlite3changegroup_add(pGrp, nLeft, pLeft);
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3changegroup_add(pGrp, nRight, pRight);
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
++  }
++  sqlite3changegroup_delete(pGrp);
++
++  return rc;
++}
++
++/*
++** Streaming version of sqlite3changeset_concat().
++*/
++SQLITE_API int sqlite3changeset_concat_strm(
++  int (*xInputA)(void *pIn, void *pData, int *pnData),
++  void *pInA,
++  int (*xInputB)(void *pIn, void *pData, int *pnData),
++  void *pInB,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++){
++  sqlite3_changegroup *pGrp;
++  int rc;
++
++  rc = sqlite3changegroup_new(&pGrp);
++  if( rc==SQLITE_OK ){
++    rc = sqlite3changegroup_add_strm(pGrp, xInputA, pInA);
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3changegroup_add_strm(pGrp, xInputB, pInB);
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3changegroup_output_strm(pGrp, xOutput, pOut);
++  }
++  sqlite3changegroup_delete(pGrp);
++
++  return rc;
++}
++
++#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
++
++/************** End of sqlite3session.c **************************************/
++/************** Begin file json1.c *******************************************/
++/*
++** 2015-08-12
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This SQLite extension implements JSON functions.  The interface is
++** modeled after MySQL JSON functions:
++**
++**     https://dev.mysql.com/doc/refman/5.7/en/json.html
++**
++** For the time being, all JSON is stored as pure text.  (We might add
++** a JSONB type in the future which stores a binary encoding of JSON in
++** a BLOB, but there is no support for JSONB in the current implementation.
++** This implementation parses JSON text at 250 MB/s, so it is hard to see
++** how JSONB might improve on that.)
++*/
++#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1)
++#if !defined(SQLITEINT_H)
++/* #include "sqlite3ext.h" */
++#endif
++SQLITE_EXTENSION_INIT1
++/* #include <assert.h> */
++/* #include <string.h> */
++/* #include <stdlib.h> */
++/* #include <stdarg.h> */
++
++/* Mark a function parameter as unused, to suppress nuisance compiler
++** warnings. */
++#ifndef UNUSED_PARAM
++# define UNUSED_PARAM(X)  (void)(X)
++#endif
++
++#ifndef LARGEST_INT64
++# define LARGEST_INT64  (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
++# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
++#endif
++
++/*
++** Versions of isspace(), isalnum() and isdigit() to which it is safe
++** to pass signed char values.
++*/
++#ifdef sqlite3Isdigit
++   /* Use the SQLite core versions if this routine is part of the
++   ** SQLite amalgamation */
++#  define safe_isdigit(x)  sqlite3Isdigit(x)
++#  define safe_isalnum(x)  sqlite3Isalnum(x)
++#  define safe_isxdigit(x) sqlite3Isxdigit(x)
++#else
++   /* Use the standard library for separate compilation */
++#include <ctype.h>  /* amalgamator: keep */
++#  define safe_isdigit(x)  isdigit((unsigned char)(x))
++#  define safe_isalnum(x)  isalnum((unsigned char)(x))
++#  define safe_isxdigit(x) isxdigit((unsigned char)(x))
++#endif
++
++/*
++** Growing our own isspace() routine this way is twice as fast as
++** the library isspace() function, resulting in a 7% overall performance
++** increase for the parser.  (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
++*/
++static const char jsonIsSpace[] = {
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 1, 1, 0, 0, 1, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  1, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++};
++#define safe_isspace(x) (jsonIsSpace[(unsigned char)x])
++
++#ifndef SQLITE_AMALGAMATION
++  /* Unsigned integer types.  These are already defined in the sqliteInt.h,
++  ** but the definitions need to be repeated for separate compilation. */
++  typedef sqlite3_uint64 u64;
++  typedef unsigned int u32;
++  typedef unsigned short int u16;
++  typedef unsigned char u8;
++#endif
++
++/* Objects */
++typedef struct JsonString JsonString;
++typedef struct JsonNode JsonNode;
++typedef struct JsonParse JsonParse;
++
++/* An instance of this object represents a JSON string
++** under construction.  Really, this is a generic string accumulator
++** that can be and is used to create strings other than JSON.
++*/
++struct JsonString {
++  sqlite3_context *pCtx;   /* Function context - put error messages here */
++  char *zBuf;              /* Append JSON content here */
++  u64 nAlloc;              /* Bytes of storage available in zBuf[] */
++  u64 nUsed;               /* Bytes of zBuf[] currently used */
++  u8 bStatic;              /* True if zBuf is static space */
++  u8 bErr;                 /* True if an error has been encountered */
++  char zSpace[100];        /* Initial static space */
++};
++
++/* JSON type values
++*/
++#define JSON_NULL     0
++#define JSON_TRUE     1
++#define JSON_FALSE    2
++#define JSON_INT      3
++#define JSON_REAL     4
++#define JSON_STRING   5
++#define JSON_ARRAY    6
++#define JSON_OBJECT   7
++
++/* The "subtype" set for JSON values */
++#define JSON_SUBTYPE  74    /* Ascii for "J" */
++
++/*
++** Names of the various JSON types:
++*/
++static const char * const jsonType[] = {
++  "null", "true", "false", "integer", "real", "text", "array", "object"
++};
++
++/* Bit values for the JsonNode.jnFlag field
++*/
++#define JNODE_RAW     0x01         /* Content is raw, not JSON encoded */
++#define JNODE_ESCAPE  0x02         /* Content is text with \ escapes */
++#define JNODE_REMOVE  0x04         /* Do not output */
++#define JNODE_REPLACE 0x08         /* Replace with JsonNode.u.iReplace */
++#define JNODE_PATCH   0x10         /* Patch with JsonNode.u.pPatch */
++#define JNODE_APPEND  0x20         /* More ARRAY/OBJECT entries at u.iAppend */
++#define JNODE_LABEL   0x40         /* Is a label of an object */
++
++
++/* A single node of parsed JSON
++*/
++struct JsonNode {
++  u8 eType;              /* One of the JSON_ type values */
++  u8 jnFlags;            /* JNODE flags */
++  u32 n;                 /* Bytes of content, or number of sub-nodes */
++  union {
++    const char *zJContent; /* Content for INT, REAL, and STRING */
++    u32 iAppend;           /* More terms for ARRAY and OBJECT */
++    u32 iKey;              /* Key for ARRAY objects in json_tree() */
++    u32 iReplace;          /* Replacement content for JNODE_REPLACE */
++    JsonNode *pPatch;      /* Node chain of patch for JNODE_PATCH */
++  } u;
++};
++
++/* A completely parsed JSON string
++*/
++struct JsonParse {
++  u32 nNode;         /* Number of slots of aNode[] used */
++  u32 nAlloc;        /* Number of slots of aNode[] allocated */
++  JsonNode *aNode;   /* Array of nodes containing the parse */
++  const char *zJson; /* Original JSON string */
++  u32 *aUp;          /* Index of parent of each node */
++  u8 oom;            /* Set to true if out of memory */
++  u8 nErr;           /* Number of errors seen */
++  u16 iDepth;        /* Nesting depth */
++  int nJson;         /* Length of the zJson string in bytes */
++};
++
++/*
++** Maximum nesting depth of JSON for this implementation.
++**
++** This limit is needed to avoid a stack overflow in the recursive
++** descent parser.  A depth of 2000 is far deeper than any sane JSON
++** should go.
++*/
++#define JSON_MAX_DEPTH  2000
++
++/**************************************************************************
++** Utility routines for dealing with JsonString objects
++**************************************************************************/
++
++/* Set the JsonString object to an empty string
++*/
++static void jsonZero(JsonString *p){
++  p->zBuf = p->zSpace;
++  p->nAlloc = sizeof(p->zSpace);
++  p->nUsed = 0;
++  p->bStatic = 1;
++}
++
++/* Initialize the JsonString object
++*/
++static void jsonInit(JsonString *p, sqlite3_context *pCtx){
++  p->pCtx = pCtx;
++  p->bErr = 0;
++  jsonZero(p);
++}
++
++
++/* Free all allocated memory and reset the JsonString object back to its
++** initial state.
++*/
++static void jsonReset(JsonString *p){
++  if( !p->bStatic ) sqlite3_free(p->zBuf);
++  jsonZero(p);
++}
++
++
++/* Report an out-of-memory (OOM) condition 
++*/
++static void jsonOom(JsonString *p){
++  p->bErr = 1;
++  sqlite3_result_error_nomem(p->pCtx);
++  jsonReset(p);
++}
++
++/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
++** Return zero on success.  Return non-zero on an OOM error
++*/
++static int jsonGrow(JsonString *p, u32 N){
++  u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
++  char *zNew;
++  if( p->bStatic ){
++    if( p->bErr ) return 1;
++    zNew = sqlite3_malloc64(nTotal);
++    if( zNew==0 ){
++      jsonOom(p);
++      return SQLITE_NOMEM;
++    }
++    memcpy(zNew, p->zBuf, (size_t)p->nUsed);
++    p->zBuf = zNew;
++    p->bStatic = 0;
++  }else{
++    zNew = sqlite3_realloc64(p->zBuf, nTotal);
++    if( zNew==0 ){
++      jsonOom(p);
++      return SQLITE_NOMEM;
++    }
++    p->zBuf = zNew;
++  }
++  p->nAlloc = nTotal;
++  return SQLITE_OK;
++}
++
++/* Append N bytes from zIn onto the end of the JsonString string.
++*/
++static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
++  if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
++  memcpy(p->zBuf+p->nUsed, zIn, N);
++  p->nUsed += N;
++}
++
++/* Append formatted text (not to exceed N bytes) to the JsonString.
++*/
++static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
++  va_list ap;
++  if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
++  va_start(ap, zFormat);
++  sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
++  va_end(ap);
++  p->nUsed += (int)strlen(p->zBuf+p->nUsed);
++}
++
++/* Append a single character
++*/
++static void jsonAppendChar(JsonString *p, char c){
++  if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
++  p->zBuf[p->nUsed++] = c;
++}
++
++/* Append a comma separator to the output buffer, if the previous
++** character is not '[' or '{'.
++*/
++static void jsonAppendSeparator(JsonString *p){
++  char c;
++  if( p->nUsed==0 ) return;
++  c = p->zBuf[p->nUsed-1];
++  if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
++}
++
++/* Append the N-byte string in zIn to the end of the JsonString string
++** under construction.  Enclose the string in "..." and escape
++** any double-quotes or backslash characters contained within the
++** string.
++*/
++static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
++  u32 i;
++  if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
++  p->zBuf[p->nUsed++] = '"';
++  for(i=0; i<N; i++){
++    unsigned char c = ((unsigned const char*)zIn)[i];
++    if( c=='"' || c=='\\' ){
++      json_simple_escape:
++      if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
++      p->zBuf[p->nUsed++] = '\\';
++    }else if( c<=0x1f ){
++      static const char aSpecial[] = {
++         0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
++         0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0,   0,   0, 0, 0
++      };
++      assert( sizeof(aSpecial)==32 );
++      assert( aSpecial['\b']=='b' );
++      assert( aSpecial['\f']=='f' );
++      assert( aSpecial['\n']=='n' );
++      assert( aSpecial['\r']=='r' );
++      assert( aSpecial['\t']=='t' );
++      if( aSpecial[c] ){
++        c = aSpecial[c];
++        goto json_simple_escape;
++      }
++      if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
++      p->zBuf[p->nUsed++] = '\\';
++      p->zBuf[p->nUsed++] = 'u';
++      p->zBuf[p->nUsed++] = '0';
++      p->zBuf[p->nUsed++] = '0';
++      p->zBuf[p->nUsed++] = '0' + (c>>4);
++      c = "0123456789abcdef"[c&0xf];
++    }
++    p->zBuf[p->nUsed++] = c;
++  }
++  p->zBuf[p->nUsed++] = '"';
++  assert( p->nUsed<p->nAlloc );
++}
++
++/*
++** Append a function parameter value to the JSON string under 
++** construction.
++*/
++static void jsonAppendValue(
++  JsonString *p,                 /* Append to this JSON string */
++  sqlite3_value *pValue          /* Value to append */
++){
++  switch( sqlite3_value_type(pValue) ){
++    case SQLITE_NULL: {
++      jsonAppendRaw(p, "null", 4);
++      break;
++    }
++    case SQLITE_INTEGER:
++    case SQLITE_FLOAT: {
++      const char *z = (const char*)sqlite3_value_text(pValue);
++      u32 n = (u32)sqlite3_value_bytes(pValue);
++      jsonAppendRaw(p, z, n);
++      break;
++    }
++    case SQLITE_TEXT: {
++      const char *z = (const char*)sqlite3_value_text(pValue);
++      u32 n = (u32)sqlite3_value_bytes(pValue);
++      if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
++        jsonAppendRaw(p, z, n);
++      }else{
++        jsonAppendString(p, z, n);
++      }
++      break;
++    }
++    default: {
++      if( p->bErr==0 ){
++        sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
++        p->bErr = 2;
++        jsonReset(p);
++      }
++      break;
++    }
++  }
++}
++
++
++/* Make the JSON in p the result of the SQL function.
++*/
++static void jsonResult(JsonString *p){
++  if( p->bErr==0 ){
++    sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, 
++                          p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
++                          SQLITE_UTF8);
++    jsonZero(p);
++  }
++  assert( p->bStatic );
++}
++
++/**************************************************************************
++** Utility routines for dealing with JsonNode and JsonParse objects
++**************************************************************************/
++
++/*
++** Return the number of consecutive JsonNode slots need to represent
++** the parsed JSON at pNode.  The minimum answer is 1.  For ARRAY and
++** OBJECT types, the number might be larger.
++**
++** Appended elements are not counted.  The value returned is the number
++** by which the JsonNode counter should increment in order to go to the
++** next peer value.
++*/
++static u32 jsonNodeSize(JsonNode *pNode){
++  return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
++}
++
++/*
++** Reclaim all memory allocated by a JsonParse object.  But do not
++** delete the JsonParse object itself.
++*/
++static void jsonParseReset(JsonParse *pParse){
++  sqlite3_free(pParse->aNode);
++  pParse->aNode = 0;
++  pParse->nNode = 0;
++  pParse->nAlloc = 0;
++  sqlite3_free(pParse->aUp);
++  pParse->aUp = 0;
++}
++
++/*
++** Free a JsonParse object that was obtained from sqlite3_malloc().
++*/
++static void jsonParseFree(JsonParse *pParse){
++  jsonParseReset(pParse);
++  sqlite3_free(pParse);
++}
++
++/*
++** Convert the JsonNode pNode into a pure JSON string and
++** append to pOut.  Subsubstructure is also included.  Return
++** the number of JsonNode objects that are encoded.
++*/
++static void jsonRenderNode(
++  JsonNode *pNode,               /* The node to render */
++  JsonString *pOut,              /* Write JSON here */
++  sqlite3_value **aReplace       /* Replacement values */
++){
++  if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
++    if( pNode->jnFlags & JNODE_REPLACE ){
++      jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
++      return;
++    }
++    pNode = pNode->u.pPatch;
++  }
++  switch( pNode->eType ){
++    default: {
++      assert( pNode->eType==JSON_NULL );
++      jsonAppendRaw(pOut, "null", 4);
++      break;
++    }
++    case JSON_TRUE: {
++      jsonAppendRaw(pOut, "true", 4);
++      break;
++    }
++    case JSON_FALSE: {
++      jsonAppendRaw(pOut, "false", 5);
++      break;
++    }
++    case JSON_STRING: {
++      if( pNode->jnFlags & JNODE_RAW ){
++        jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
++        break;
++      }
++      /* Fall through into the next case */
++    }
++    case JSON_REAL:
++    case JSON_INT: {
++      jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
++      break;
++    }
++    case JSON_ARRAY: {
++      u32 j = 1;
++      jsonAppendChar(pOut, '[');
++      for(;;){
++        while( j<=pNode->n ){
++          if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
++            jsonAppendSeparator(pOut);
++            jsonRenderNode(&pNode[j], pOut, aReplace);
++          }
++          j += jsonNodeSize(&pNode[j]);
++        }
++        if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
++        pNode = &pNode[pNode->u.iAppend];
++        j = 1;
++      }
++      jsonAppendChar(pOut, ']');
++      break;
++    }
++    case JSON_OBJECT: {
++      u32 j = 1;
++      jsonAppendChar(pOut, '{');
++      for(;;){
++        while( j<=pNode->n ){
++          if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
++            jsonAppendSeparator(pOut);
++            jsonRenderNode(&pNode[j], pOut, aReplace);
++            jsonAppendChar(pOut, ':');
++            jsonRenderNode(&pNode[j+1], pOut, aReplace);
++          }
++          j += 1 + jsonNodeSize(&pNode[j+1]);
++        }
++        if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
++        pNode = &pNode[pNode->u.iAppend];
++        j = 1;
++      }
++      jsonAppendChar(pOut, '}');
++      break;
++    }
++  }
++}
++
++/*
++** Return a JsonNode and all its descendents as a JSON string.
++*/
++static void jsonReturnJson(
++  JsonNode *pNode,            /* Node to return */
++  sqlite3_context *pCtx,      /* Return value for this function */
++  sqlite3_value **aReplace    /* Array of replacement values */
++){
++  JsonString s;
++  jsonInit(&s, pCtx);
++  jsonRenderNode(pNode, &s, aReplace);
++  jsonResult(&s);
++  sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
++}
++
++/*
++** Make the JsonNode the return value of the function.
++*/
++static void jsonReturn(
++  JsonNode *pNode,            /* Node to return */
++  sqlite3_context *pCtx,      /* Return value for this function */
++  sqlite3_value **aReplace    /* Array of replacement values */
++){
++  switch( pNode->eType ){
++    default: {
++      assert( pNode->eType==JSON_NULL );
++      sqlite3_result_null(pCtx);
++      break;
++    }
++    case JSON_TRUE: {
++      sqlite3_result_int(pCtx, 1);
++      break;
++    }
++    case JSON_FALSE: {
++      sqlite3_result_int(pCtx, 0);
++      break;
++    }
++    case JSON_INT: {
++      sqlite3_int64 i = 0;
++      const char *z = pNode->u.zJContent;
++      if( z[0]=='-' ){ z++; }
++      while( z[0]>='0' && z[0]<='9' ){
++        unsigned v = *(z++) - '0';
++        if( i>=LARGEST_INT64/10 ){
++          if( i>LARGEST_INT64/10 ) goto int_as_real;
++          if( z[0]>='0' && z[0]<='9' ) goto int_as_real;
++          if( v==9 ) goto int_as_real;
++          if( v==8 ){
++            if( pNode->u.zJContent[0]=='-' ){
++              sqlite3_result_int64(pCtx, SMALLEST_INT64);
++              goto int_done;
++            }else{
++              goto int_as_real;
++            }
++          }
++        }
++        i = i*10 + v;
++      }
++      if( pNode->u.zJContent[0]=='-' ){ i = -i; }
++      sqlite3_result_int64(pCtx, i);
++      int_done:
++      break;
++      int_as_real: /* fall through to real */;
++    }
++    case JSON_REAL: {
++      double r;
++#ifdef SQLITE_AMALGAMATION
++      const char *z = pNode->u.zJContent;
++      sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
++#else
++      r = strtod(pNode->u.zJContent, 0);
++#endif
++      sqlite3_result_double(pCtx, r);
++      break;
++    }
++    case JSON_STRING: {
++#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
++      ** json_insert() and json_replace() and those routines do not
++      ** call jsonReturn() */
++      if( pNode->jnFlags & JNODE_RAW ){
++        sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
++                            SQLITE_TRANSIENT);
++      }else 
++#endif
++      assert( (pNode->jnFlags & JNODE_RAW)==0 );
++      if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
++        /* JSON formatted without any backslash-escapes */
++        sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
++                            SQLITE_TRANSIENT);
++      }else{
++        /* Translate JSON formatted string into raw text */
++        u32 i;
++        u32 n = pNode->n;
++        const char *z = pNode->u.zJContent;
++        char *zOut;
++        u32 j;
++        zOut = sqlite3_malloc( n+1 );
++        if( zOut==0 ){
++          sqlite3_result_error_nomem(pCtx);
++          break;
++        }
++        for(i=1, j=0; i<n-1; i++){
++          char c = z[i];
++          if( c!='\\' ){
++            zOut[j++] = c;
++          }else{
++            c = z[++i];
++            if( c=='u' ){
++              u32 v = 0, k;
++              for(k=0; k<4; i++, k++){
++                assert( i<n-2 );
++                c = z[i+1];
++                assert( safe_isxdigit(c) );
++                if( c<='9' ) v = v*16 + c - '0';
++                else if( c<='F' ) v = v*16 + c - 'A' + 10;
++                else v = v*16 + c - 'a' + 10;
++              }
++              if( v==0 ) break;
++              if( v<=0x7f ){
++                zOut[j++] = (char)v;
++              }else if( v<=0x7ff ){
++                zOut[j++] = (char)(0xc0 | (v>>6));
++                zOut[j++] = 0x80 | (v&0x3f);
++              }else{
++                zOut[j++] = (char)(0xe0 | (v>>12));
++                zOut[j++] = 0x80 | ((v>>6)&0x3f);
++                zOut[j++] = 0x80 | (v&0x3f);
++              }
++            }else{
++              if( c=='b' ){
++                c = '\b';
++              }else if( c=='f' ){
++                c = '\f';
++              }else if( c=='n' ){
++                c = '\n';
++              }else if( c=='r' ){
++                c = '\r';
++              }else if( c=='t' ){
++                c = '\t';
++              }
++              zOut[j++] = c;
++            }
++          }
++        }
++        zOut[j] = 0;
++        sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
++      }
++      break;
++    }
++    case JSON_ARRAY:
++    case JSON_OBJECT: {
++      jsonReturnJson(pNode, pCtx, aReplace);
++      break;
++    }
++  }
++}
++
++/* Forward reference */
++static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
++
++/*
++** A macro to hint to the compiler that a function should not be
++** inlined.
++*/
++#if defined(__GNUC__)
++#  define JSON_NOINLINE  __attribute__((noinline))
++#elif defined(_MSC_VER) && _MSC_VER>=1310
++#  define JSON_NOINLINE  __declspec(noinline)
++#else
++#  define JSON_NOINLINE
++#endif
++
++
++static JSON_NOINLINE int jsonParseAddNodeExpand(
++  JsonParse *pParse,        /* Append the node to this object */
++  u32 eType,                /* Node type */
++  u32 n,                    /* Content size or sub-node count */
++  const char *zContent      /* Content */
++){
++  u32 nNew;
++  JsonNode *pNew;
++  assert( pParse->nNode>=pParse->nAlloc );
++  if( pParse->oom ) return -1;
++  nNew = pParse->nAlloc*2 + 10;
++  pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
++  if( pNew==0 ){
++    pParse->oom = 1;
++    return -1;
++  }
++  pParse->nAlloc = nNew;
++  pParse->aNode = pNew;
++  assert( pParse->nNode<pParse->nAlloc );
++  return jsonParseAddNode(pParse, eType, n, zContent);
++}
++
++/*
++** Create a new JsonNode instance based on the arguments and append that
++** instance to the JsonParse.  Return the index in pParse->aNode[] of the
++** new node, or -1 if a memory allocation fails.
++*/
++static int jsonParseAddNode(
++  JsonParse *pParse,        /* Append the node to this object */
++  u32 eType,                /* Node type */
++  u32 n,                    /* Content size or sub-node count */
++  const char *zContent      /* Content */
++){
++  JsonNode *p;
++  if( pParse->nNode>=pParse->nAlloc ){
++    return jsonParseAddNodeExpand(pParse, eType, n, zContent);
++  }
++  p = &pParse->aNode[pParse->nNode];
++  p->eType = (u8)eType;
++  p->jnFlags = 0;
++  p->n = n;
++  p->u.zJContent = zContent;
++  return pParse->nNode++;
++}
++
++/*
++** Return true if z[] begins with 4 (or more) hexadecimal digits
++*/
++static int jsonIs4Hex(const char *z){
++  int i;
++  for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0;
++  return 1;
++}
++
++/*
++** Parse a single JSON value which begins at pParse->zJson[i].  Return the
++** index of the first character past the end of the value parsed.
++**
++** Return negative for a syntax error.  Special cases:  return -2 if the
++** first non-whitespace character is '}' and return -3 if the first
++** non-whitespace character is ']'.
++*/
++static int jsonParseValue(JsonParse *pParse, u32 i){
++  char c;
++  u32 j;
++  int iThis;
++  int x;
++  JsonNode *pNode;
++  const char *z = pParse->zJson;
++  while( safe_isspace(z[i]) ){ i++; }
++  if( (c = z[i])=='{' ){
++    /* Parse object */
++    iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
++    if( iThis<0 ) return -1;
++    for(j=i+1;;j++){
++      while( safe_isspace(z[j]) ){ j++; }
++      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
++      x = jsonParseValue(pParse, j);
++      if( x<0 ){
++        pParse->iDepth--;
++        if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
++        return -1;
++      }
++      if( pParse->oom ) return -1;
++      pNode = &pParse->aNode[pParse->nNode-1];
++      if( pNode->eType!=JSON_STRING ) return -1;
++      pNode->jnFlags |= JNODE_LABEL;
++      j = x;
++      while( safe_isspace(z[j]) ){ j++; }
++      if( z[j]!=':' ) return -1;
++      j++;
++      x = jsonParseValue(pParse, j);
++      pParse->iDepth--;
++      if( x<0 ) return -1;
++      j = x;
++      while( safe_isspace(z[j]) ){ j++; }
++      c = z[j];
++      if( c==',' ) continue;
++      if( c!='}' ) return -1;
++      break;
++    }
++    pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
++    return j+1;
++  }else if( c=='[' ){
++    /* Parse array */
++    iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
++    if( iThis<0 ) return -1;
++    for(j=i+1;;j++){
++      while( safe_isspace(z[j]) ){ j++; }
++      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
++      x = jsonParseValue(pParse, j);
++      pParse->iDepth--;
++      if( x<0 ){
++        if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
++        return -1;
++      }
++      j = x;
++      while( safe_isspace(z[j]) ){ j++; }
++      c = z[j];
++      if( c==',' ) continue;
++      if( c!=']' ) return -1;
++      break;
++    }
++    pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
++    return j+1;
++  }else if( c=='"' ){
++    /* Parse string */
++    u8 jnFlags = 0;
++    j = i+1;
++    for(;;){
++      c = z[j];
++      if( (c & ~0x1f)==0 ){
++        /* Control characters are not allowed in strings */
++        return -1;
++      }
++      if( c=='\\' ){
++        c = z[++j];
++        if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
++           || c=='n' || c=='r' || c=='t'
++           || (c=='u' && jsonIs4Hex(z+j+1)) ){
++          jnFlags = JNODE_ESCAPE;
++        }else{
++          return -1;
++        }
++      }else if( c=='"' ){
++        break;
++      }
++      j++;
++    }
++    jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
++    if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
++    return j+1;
++  }else if( c=='n'
++         && strncmp(z+i,"null",4)==0
++         && !safe_isalnum(z[i+4]) ){
++    jsonParseAddNode(pParse, JSON_NULL, 0, 0);
++    return i+4;
++  }else if( c=='t'
++         && strncmp(z+i,"true",4)==0
++         && !safe_isalnum(z[i+4]) ){
++    jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
++    return i+4;
++  }else if( c=='f'
++         && strncmp(z+i,"false",5)==0
++         && !safe_isalnum(z[i+5]) ){
++    jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
++    return i+5;
++  }else if( c=='-' || (c>='0' && c<='9') ){
++    /* Parse number */
++    u8 seenDP = 0;
++    u8 seenE = 0;
++    assert( '-' < '0' );
++    if( c<='0' ){
++      j = c=='-' ? i+1 : i;
++      if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
++    }
++    j = i+1;
++    for(;; j++){
++      c = z[j];
++      if( c>='0' && c<='9' ) continue;
++      if( c=='.' ){
++        if( z[j-1]=='-' ) return -1;
++        if( seenDP ) return -1;
++        seenDP = 1;
++        continue;
++      }
++      if( c=='e' || c=='E' ){
++        if( z[j-1]<'0' ) return -1;
++        if( seenE ) return -1;
++        seenDP = seenE = 1;
++        c = z[j+1];
++        if( c=='+' || c=='-' ){
++          j++;
++          c = z[j+1];
++        }
++        if( c<'0' || c>'9' ) return -1;
++        continue;
++      }
++      break;
++    }
++    if( z[j-1]<'0' ) return -1;
++    jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
++                        j - i, &z[i]);
++    return j;
++  }else if( c=='}' ){
++    return -2;  /* End of {...} */
++  }else if( c==']' ){
++    return -3;  /* End of [...] */
++  }else if( c==0 ){
++    return 0;   /* End of file */
++  }else{
++    return -1;  /* Syntax error */
++  }
++}
++
++/*
++** Parse a complete JSON string.  Return 0 on success or non-zero if there
++** are any errors.  If an error occurs, free all memory associated with
++** pParse.
++**
++** pParse is uninitialized when this routine is called.
++*/
++static int jsonParse(
++  JsonParse *pParse,           /* Initialize and fill this JsonParse object */
++  sqlite3_context *pCtx,       /* Report errors here */
++  const char *zJson            /* Input JSON text to be parsed */
++){
++  int i;
++  memset(pParse, 0, sizeof(*pParse));
++  if( zJson==0 ) return 1;
++  pParse->zJson = zJson;
++  i = jsonParseValue(pParse, 0);
++  if( pParse->oom ) i = -1;
++  if( i>0 ){
++    assert( pParse->iDepth==0 );
++    while( safe_isspace(zJson[i]) ) i++;
++    if( zJson[i] ) i = -1;
++  }
++  if( i<=0 ){
++    if( pCtx!=0 ){
++      if( pParse->oom ){
++        sqlite3_result_error_nomem(pCtx);
++      }else{
++        sqlite3_result_error(pCtx, "malformed JSON", -1);
++      }
++    }
++    jsonParseReset(pParse);
++    return 1;
++  }
++  return 0;
++}
++
++/* Mark node i of pParse as being a child of iParent.  Call recursively
++** to fill in all the descendants of node i.
++*/
++static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
++  JsonNode *pNode = &pParse->aNode[i];
++  u32 j;
++  pParse->aUp[i] = iParent;
++  switch( pNode->eType ){
++    case JSON_ARRAY: {
++      for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
++        jsonParseFillInParentage(pParse, i+j, i);
++      }
++      break;
++    }
++    case JSON_OBJECT: {
++      for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
++        pParse->aUp[i+j] = i;
++        jsonParseFillInParentage(pParse, i+j+1, i);
++      }
++      break;
++    }
++    default: {
++      break;
++    }
++  }
++}
++
++/*
++** Compute the parentage of all nodes in a completed parse.
++*/
++static int jsonParseFindParents(JsonParse *pParse){
++  u32 *aUp;
++  assert( pParse->aUp==0 );
++  aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
++  if( aUp==0 ){
++    pParse->oom = 1;
++    return SQLITE_NOMEM;
++  }
++  jsonParseFillInParentage(pParse, 0, 0);
++  return SQLITE_OK;
++}
++
++/*
++** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
++*/
++#define JSON_CACHE_ID  (-429938)
++
++/*
++** Obtain a complete parse of the JSON found in the first argument
++** of the argv array.  Use the sqlite3_get_auxdata() cache for this
++** parse if it is available.  If the cache is not available or if it
++** is no longer valid, parse the JSON again and return the new parse,
++** and also register the new parse so that it will be available for
++** future sqlite3_get_auxdata() calls.
++*/
++static JsonParse *jsonParseCached(
++  sqlite3_context *pCtx,
++  sqlite3_value **argv
++){
++  const char *zJson = (const char*)sqlite3_value_text(argv[0]);
++  int nJson = sqlite3_value_bytes(argv[0]);
++  JsonParse *p;
++  if( zJson==0 ) return 0;
++  p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
++  if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){
++    p->nErr = 0;
++    return p; /* The cached entry matches, so return it */
++  }
++  p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
++  if( p==0 ){
++    sqlite3_result_error_nomem(pCtx);
++    return 0;
++  }
++  memset(p, 0, sizeof(*p));
++  p->zJson = (char*)&p[1];
++  memcpy((char*)p->zJson, zJson, nJson+1);
++  if( jsonParse(p, pCtx, p->zJson) ){
++    sqlite3_free(p);
++    return 0;
++  }
++  p->nJson = nJson;
++  sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree);
++  return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
++}
++
++/*
++** Compare the OBJECT label at pNode against zKey,nKey.  Return true on
++** a match.
++*/
++static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
++  if( pNode->jnFlags & JNODE_RAW ){
++    if( pNode->n!=nKey ) return 0;
++    return strncmp(pNode->u.zJContent, zKey, nKey)==0;
++  }else{
++    if( pNode->n!=nKey+2 ) return 0;
++    return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
++  }
++}
++
++/* forward declaration */
++static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
++
++/*
++** Search along zPath to find the node specified.  Return a pointer
++** to that node, or NULL if zPath is malformed or if there is no such
++** node.
++**
++** If pApnd!=0, then try to append new nodes to complete zPath if it is
++** possible to do so and if no existing node corresponds to zPath.  If
++** new nodes are appended *pApnd is set to 1.
++*/
++static JsonNode *jsonLookupStep(
++  JsonParse *pParse,      /* The JSON to search */
++  u32 iRoot,              /* Begin the search at this node */
++  const char *zPath,      /* The path to search */
++  int *pApnd,             /* Append nodes to complete path if not NULL */
++  const char **pzErr      /* Make *pzErr point to any syntax error in zPath */
++){
++  u32 i, j, nKey;
++  const char *zKey;
++  JsonNode *pRoot = &pParse->aNode[iRoot];
++  if( zPath[0]==0 ) return pRoot;
++  if( zPath[0]=='.' ){
++    if( pRoot->eType!=JSON_OBJECT ) return 0;
++    zPath++;
++    if( zPath[0]=='"' ){
++      zKey = zPath + 1;
++      for(i=1; zPath[i] && zPath[i]!='"'; i++){}
++      nKey = i-1;
++      if( zPath[i] ){
++        i++;
++      }else{
++        *pzErr = zPath;
++        return 0;
++      }
++    }else{
++      zKey = zPath;
++      for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
++      nKey = i;
++    }
++    if( nKey==0 ){
++      *pzErr = zPath;
++      return 0;
++    }
++    j = 1;
++    for(;;){
++      while( j<=pRoot->n ){
++        if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
++          return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
++        }
++        j++;
++        j += jsonNodeSize(&pRoot[j]);
++      }
++      if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
++      iRoot += pRoot->u.iAppend;
++      pRoot = &pParse->aNode[iRoot];
++      j = 1;
++    }
++    if( pApnd ){
++      u32 iStart, iLabel;
++      JsonNode *pNode;
++      iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
++      iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
++      zPath += i;
++      pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
++      if( pParse->oom ) return 0;
++      if( pNode ){
++        pRoot = &pParse->aNode[iRoot];
++        pRoot->u.iAppend = iStart - iRoot;
++        pRoot->jnFlags |= JNODE_APPEND;
++        pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
++      }
++      return pNode;
++    }
++  }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
++    if( pRoot->eType!=JSON_ARRAY ) return 0;
++    i = 0;
++    j = 1;
++    while( safe_isdigit(zPath[j]) ){
++      i = i*10 + zPath[j] - '0';
++      j++;
++    }
++    if( zPath[j]!=']' ){
++      *pzErr = zPath;
++      return 0;
++    }
++    zPath += j + 1;
++    j = 1;
++    for(;;){
++      while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
++        if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
++        j += jsonNodeSize(&pRoot[j]);
++      }
++      if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
++      iRoot += pRoot->u.iAppend;
++      pRoot = &pParse->aNode[iRoot];
++      j = 1;
++    }
++    if( j<=pRoot->n ){
++      return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
++    }
++    if( i==0 && pApnd ){
++      u32 iStart;
++      JsonNode *pNode;
++      iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
++      pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
++      if( pParse->oom ) return 0;
++      if( pNode ){
++        pRoot = &pParse->aNode[iRoot];
++        pRoot->u.iAppend = iStart - iRoot;
++        pRoot->jnFlags |= JNODE_APPEND;
++      }
++      return pNode;
++    }
++  }else{
++    *pzErr = zPath;
++  }
++  return 0;
++}
++
++/*
++** Append content to pParse that will complete zPath.  Return a pointer
++** to the inserted node, or return NULL if the append fails.
++*/
++static JsonNode *jsonLookupAppend(
++  JsonParse *pParse,     /* Append content to the JSON parse */
++  const char *zPath,     /* Description of content to append */
++  int *pApnd,            /* Set this flag to 1 */
++  const char **pzErr     /* Make this point to any syntax error */
++){
++  *pApnd = 1;
++  if( zPath[0]==0 ){
++    jsonParseAddNode(pParse, JSON_NULL, 0, 0);
++    return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
++  }
++  if( zPath[0]=='.' ){
++    jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
++  }else if( strncmp(zPath,"[0]",3)==0 ){
++    jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
++  }else{
++    return 0;
++  }
++  if( pParse->oom ) return 0;
++  return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
++}
++
++/*
++** Return the text of a syntax error message on a JSON path.  Space is
++** obtained from sqlite3_malloc().
++*/
++static char *jsonPathSyntaxError(const char *zErr){
++  return sqlite3_mprintf("JSON path error near '%q'", zErr);
++}
++
++/*
++** Do a node lookup using zPath.  Return a pointer to the node on success.
++** Return NULL if not found or if there is an error.
++**
++** On an error, write an error message into pCtx and increment the
++** pParse->nErr counter.
++**
++** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
++** nodes are appended.
++*/
++static JsonNode *jsonLookup(
++  JsonParse *pParse,      /* The JSON to search */
++  const char *zPath,      /* The path to search */
++  int *pApnd,             /* Append nodes to complete path if not NULL */
++  sqlite3_context *pCtx   /* Report errors here, if not NULL */
++){
++  const char *zErr = 0;
++  JsonNode *pNode = 0;
++  char *zMsg;
++
++  if( zPath==0 ) return 0;
++  if( zPath[0]!='$' ){
++    zErr = zPath;
++    goto lookup_err;
++  }
++  zPath++;
++  pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
++  if( zErr==0 ) return pNode;
++
++lookup_err:
++  pParse->nErr++;
++  assert( zErr!=0 && pCtx!=0 );
++  zMsg = jsonPathSyntaxError(zErr);
++  if( zMsg ){
++    sqlite3_result_error(pCtx, zMsg, -1);
++    sqlite3_free(zMsg);
++  }else{
++    sqlite3_result_error_nomem(pCtx);
++  }
++  return 0;
++}
++
++
++/*
++** Report the wrong number of arguments for json_insert(), json_replace()
++** or json_set().
++*/
++static void jsonWrongNumArgs(
++  sqlite3_context *pCtx,
++  const char *zFuncName
++){
++  char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
++                               zFuncName);
++  sqlite3_result_error(pCtx, zMsg, -1);
++  sqlite3_free(zMsg);     
++}
++
++/*
++** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
++*/
++static void jsonRemoveAllNulls(JsonNode *pNode){
++  int i, n;
++  assert( pNode->eType==JSON_OBJECT );
++  n = pNode->n;
++  for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
++    switch( pNode[i].eType ){
++      case JSON_NULL:
++        pNode[i].jnFlags |= JNODE_REMOVE;
++        break;
++      case JSON_OBJECT:
++        jsonRemoveAllNulls(&pNode[i]);
++        break;
++    }
++  }
++}
++
++
++/****************************************************************************
++** SQL functions used for testing and debugging
++****************************************************************************/
++
++#ifdef SQLITE_DEBUG
++/*
++** The json_parse(JSON) function returns a string which describes
++** a parse of the JSON provided.  Or it returns NULL if JSON is not
++** well-formed.
++*/
++static void jsonParseFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonString s;       /* Output string - not real JSON */
++  JsonParse x;        /* The parse */
++  u32 i;
++
++  assert( argc==1 );
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  jsonParseFindParents(&x);
++  jsonInit(&s, ctx);
++  for(i=0; i<x.nNode; i++){
++    const char *zType;
++    if( x.aNode[i].jnFlags & JNODE_LABEL ){
++      assert( x.aNode[i].eType==JSON_STRING );
++      zType = "label";
++    }else{
++      zType = jsonType[x.aNode[i].eType];
++    }
++    jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
++               i, zType, x.aNode[i].n, x.aUp[i]);
++    if( x.aNode[i].u.zJContent!=0 ){
++      jsonAppendRaw(&s, " ", 1);
++      jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
++    }
++    jsonAppendRaw(&s, "\n", 1);
++  }
++  jsonParseReset(&x);
++  jsonResult(&s);
++}
++
++/*
++** The json_test1(JSON) function return true (1) if the input is JSON
++** text generated by another json function.  It returns (0) if the input
++** is not known to be JSON.
++*/
++static void jsonTest1Func(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  UNUSED_PARAM(argc);
++  sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
++}
++#endif /* SQLITE_DEBUG */
++
++/****************************************************************************
++** Scalar SQL function implementations
++****************************************************************************/
++
++/*
++** Implementation of the json_QUOTE(VALUE) function.  Return a JSON value
++** corresponding to the SQL value input.  Mostly this means putting 
++** double-quotes around strings and returning the unquoted string "null"
++** when given a NULL input.
++*/
++static void jsonQuoteFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonString jx;
++  UNUSED_PARAM(argc);
++
++  jsonInit(&jx, ctx);
++  jsonAppendValue(&jx, argv[0]);
++  jsonResult(&jx);
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++
++/*
++** Implementation of the json_array(VALUE,...) function.  Return a JSON
++** array that contains all values given in arguments.  Or if any argument
++** is a BLOB, throw an error.
++*/
++static void jsonArrayFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  int i;
++  JsonString jx;
++
++  jsonInit(&jx, ctx);
++  jsonAppendChar(&jx, '[');
++  for(i=0; i<argc; i++){
++    jsonAppendSeparator(&jx);
++    jsonAppendValue(&jx, argv[i]);
++  }
++  jsonAppendChar(&jx, ']');
++  jsonResult(&jx);
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++
++
++/*
++** json_array_length(JSON)
++** json_array_length(JSON, PATH)
++**
++** Return the number of elements in the top-level JSON array.  
++** Return 0 if the input is not a well-formed JSON array.
++*/
++static void jsonArrayLengthFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse *p;          /* The parse */
++  sqlite3_int64 n = 0;
++  u32 i;
++  JsonNode *pNode;
++
++  p = jsonParseCached(ctx, argv);
++  if( p==0 ) return;
++  assert( p->nNode );
++  if( argc==2 ){
++    const char *zPath = (const char*)sqlite3_value_text(argv[1]);
++    pNode = jsonLookup(p, zPath, 0, ctx);
++  }else{
++    pNode = p->aNode;
++  }
++  if( pNode==0 ){
++    return;
++  }
++  if( pNode->eType==JSON_ARRAY ){
++    assert( (pNode->jnFlags & JNODE_APPEND)==0 );
++    for(i=1; i<=pNode->n; n++){
++      i += jsonNodeSize(&pNode[i]);
++    }
++  }
++  sqlite3_result_int64(ctx, n);
++}
++
++/*
++** json_extract(JSON, PATH, ...)
++**
++** Return the element described by PATH.  Return NULL if there is no
++** PATH element.  If there are multiple PATHs, then return a JSON array
++** with the result from each path.  Throw an error if the JSON or any PATH
++** is malformed.
++*/
++static void jsonExtractFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse *p;          /* The parse */
++  JsonNode *pNode;
++  const char *zPath;
++  JsonString jx;
++  int i;
++
++  if( argc<2 ) return;
++  p = jsonParseCached(ctx, argv);
++  if( p==0 ) return;
++  jsonInit(&jx, ctx);
++  jsonAppendChar(&jx, '[');
++  for(i=1; i<argc; i++){
++    zPath = (const char*)sqlite3_value_text(argv[i]);
++    pNode = jsonLookup(p, zPath, 0, ctx);
++    if( p->nErr ) break;
++    if( argc>2 ){
++      jsonAppendSeparator(&jx);
++      if( pNode ){
++        jsonRenderNode(pNode, &jx, 0);
++      }else{
++        jsonAppendRaw(&jx, "null", 4);
++      }
++    }else if( pNode ){
++      jsonReturn(pNode, ctx, 0);
++    }
++  }
++  if( argc>2 && i==argc ){
++    jsonAppendChar(&jx, ']');
++    jsonResult(&jx);
++    sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++  }
++  jsonReset(&jx);
++}
++
++/* This is the RFC 7396 MergePatch algorithm.
++*/
++static JsonNode *jsonMergePatch(
++  JsonParse *pParse,   /* The JSON parser that contains the TARGET */
++  u32 iTarget,         /* Node of the TARGET in pParse */
++  JsonNode *pPatch     /* The PATCH */
++){
++  u32 i, j;
++  u32 iRoot;
++  JsonNode *pTarget;
++  if( pPatch->eType!=JSON_OBJECT ){
++    return pPatch;
++  }
++  assert( iTarget>=0 && iTarget<pParse->nNode );
++  pTarget = &pParse->aNode[iTarget];
++  assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
++  if( pTarget->eType!=JSON_OBJECT ){
++    jsonRemoveAllNulls(pPatch);
++    return pPatch;
++  }
++  iRoot = iTarget;
++  for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
++    u32 nKey;
++    const char *zKey;
++    assert( pPatch[i].eType==JSON_STRING );
++    assert( pPatch[i].jnFlags & JNODE_LABEL );
++    nKey = pPatch[i].n;
++    zKey = pPatch[i].u.zJContent;
++    assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
++    for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
++      assert( pTarget[j].eType==JSON_STRING );
++      assert( pTarget[j].jnFlags & JNODE_LABEL );
++      assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
++      if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){
++        if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
++        if( pPatch[i+1].eType==JSON_NULL ){
++          pTarget[j+1].jnFlags |= JNODE_REMOVE;
++        }else{
++          JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
++          if( pNew==0 ) return 0;
++          pTarget = &pParse->aNode[iTarget];
++          if( pNew!=&pTarget[j+1] ){
++            pTarget[j+1].u.pPatch = pNew;
++            pTarget[j+1].jnFlags |= JNODE_PATCH;
++          }
++        }
++        break;
++      }
++    }
++    if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
++      int iStart, iPatch;
++      iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
++      jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
++      iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
++      if( pParse->oom ) return 0;
++      jsonRemoveAllNulls(pPatch);
++      pTarget = &pParse->aNode[iTarget];
++      pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
++      pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
++      iRoot = iStart;
++      pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
++      pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
++    }
++  }
++  return pTarget;
++}
++
++/*
++** Implementation of the json_mergepatch(JSON1,JSON2) function.  Return a JSON
++** object that is the result of running the RFC 7396 MergePatch() algorithm
++** on the two arguments.
++*/
++static void jsonPatchFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;     /* The JSON that is being patched */
++  JsonParse y;     /* The patch */
++  JsonNode *pResult;   /* The result of the merge */
++
++  UNUSED_PARAM(argc);
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
++    jsonParseReset(&x);
++    return;
++  }
++  pResult = jsonMergePatch(&x, 0, y.aNode);
++  assert( pResult!=0 || x.oom );
++  if( pResult ){
++    jsonReturnJson(pResult, ctx, 0);
++  }else{
++    sqlite3_result_error_nomem(ctx);
++  }
++  jsonParseReset(&x);
++  jsonParseReset(&y);
++}
++
++
++/*
++** Implementation of the json_object(NAME,VALUE,...) function.  Return a JSON
++** object that contains all name/value given in arguments.  Or if any name
++** is not a string or if any value is a BLOB, throw an error.
++*/
++static void jsonObjectFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  int i;
++  JsonString jx;
++  const char *z;
++  u32 n;
++
++  if( argc&1 ){
++    sqlite3_result_error(ctx, "json_object() requires an even number "
++                                  "of arguments", -1);
++    return;
++  }
++  jsonInit(&jx, ctx);
++  jsonAppendChar(&jx, '{');
++  for(i=0; i<argc; i+=2){
++    if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
++      sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
++      jsonReset(&jx);
++      return;
++    }
++    jsonAppendSeparator(&jx);
++    z = (const char*)sqlite3_value_text(argv[i]);
++    n = (u32)sqlite3_value_bytes(argv[i]);
++    jsonAppendString(&jx, z, n);
++    jsonAppendChar(&jx, ':');
++    jsonAppendValue(&jx, argv[i+1]);
++  }
++  jsonAppendChar(&jx, '}');
++  jsonResult(&jx);
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++
++
++/*
++** json_remove(JSON, PATH, ...)
++**
++** Remove the named elements from JSON and return the result.  malformed
++** JSON or PATH arguments result in an error.
++*/
++static void jsonRemoveFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;          /* The parse */
++  JsonNode *pNode;
++  const char *zPath;
++  u32 i;
++
++  if( argc<1 ) return;
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  assert( x.nNode );
++  for(i=1; i<(u32)argc; i++){
++    zPath = (const char*)sqlite3_value_text(argv[i]);
++    if( zPath==0 ) goto remove_done;
++    pNode = jsonLookup(&x, zPath, 0, ctx);
++    if( x.nErr ) goto remove_done;
++    if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
++  }
++  if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
++    jsonReturnJson(x.aNode, ctx, 0);
++  }
++remove_done:
++  jsonParseReset(&x);
++}
++
++/*
++** json_replace(JSON, PATH, VALUE, ...)
++**
++** Replace the value at PATH with VALUE.  If PATH does not already exist,
++** this routine is a no-op.  If JSON or PATH is malformed, throw an error.
++*/
++static void jsonReplaceFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;          /* The parse */
++  JsonNode *pNode;
++  const char *zPath;
++  u32 i;
++
++  if( argc<1 ) return;
++  if( (argc&1)==0 ) {
++    jsonWrongNumArgs(ctx, "replace");
++    return;
++  }
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  assert( x.nNode );
++  for(i=1; i<(u32)argc; i+=2){
++    zPath = (const char*)sqlite3_value_text(argv[i]);
++    pNode = jsonLookup(&x, zPath, 0, ctx);
++    if( x.nErr ) goto replace_err;
++    if( pNode ){
++      pNode->jnFlags |= (u8)JNODE_REPLACE;
++      pNode->u.iReplace = i + 1;
++    }
++  }
++  if( x.aNode[0].jnFlags & JNODE_REPLACE ){
++    sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
++  }else{
++    jsonReturnJson(x.aNode, ctx, argv);
++  }
++replace_err:
++  jsonParseReset(&x);
++}
++
++/*
++** json_set(JSON, PATH, VALUE, ...)
++**
++** Set the value at PATH to VALUE.  Create the PATH if it does not already
++** exist.  Overwrite existing values that do exist.
++** If JSON or PATH is malformed, throw an error.
++**
++** json_insert(JSON, PATH, VALUE, ...)
++**
++** Create PATH and initialize it to VALUE.  If PATH already exists, this
++** routine is a no-op.  If JSON or PATH is malformed, throw an error.
++*/
++static void jsonSetFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;          /* The parse */
++  JsonNode *pNode;
++  const char *zPath;
++  u32 i;
++  int bApnd;
++  int bIsSet = *(int*)sqlite3_user_data(ctx);
++
++  if( argc<1 ) return;
++  if( (argc&1)==0 ) {
++    jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
++    return;
++  }
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  assert( x.nNode );
++  for(i=1; i<(u32)argc; i+=2){
++    zPath = (const char*)sqlite3_value_text(argv[i]);
++    bApnd = 0;
++    pNode = jsonLookup(&x, zPath, &bApnd, ctx);
++    if( x.oom ){
++      sqlite3_result_error_nomem(ctx);
++      goto jsonSetDone;
++    }else if( x.nErr ){
++      goto jsonSetDone;
++    }else if( pNode && (bApnd || bIsSet) ){
++      pNode->jnFlags |= (u8)JNODE_REPLACE;
++      pNode->u.iReplace = i + 1;
++    }
++  }
++  if( x.aNode[0].jnFlags & JNODE_REPLACE ){
++    sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
++  }else{
++    jsonReturnJson(x.aNode, ctx, argv);
++  }
++jsonSetDone:
++  jsonParseReset(&x);
++}
++
++/*
++** json_type(JSON)
++** json_type(JSON, PATH)
++**
++** Return the top-level "type" of a JSON string.  Throw an error if
++** either the JSON or PATH inputs are not well-formed.
++*/
++static void jsonTypeFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;          /* The parse */
++  const char *zPath;
++  JsonNode *pNode;
++
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  assert( x.nNode );
++  if( argc==2 ){
++    zPath = (const char*)sqlite3_value_text(argv[1]);
++    pNode = jsonLookup(&x, zPath, 0, ctx);
++  }else{
++    pNode = x.aNode;
++  }
++  if( pNode ){
++    sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
++  }
++  jsonParseReset(&x);
++}
++
++/*
++** json_valid(JSON)
++**
++** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
++** Return 0 otherwise.
++*/
++static void jsonValidFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;          /* The parse */
++  int rc = 0;
++
++  UNUSED_PARAM(argc);
++  if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){
++    rc = 1;
++  }
++  jsonParseReset(&x);
++  sqlite3_result_int(ctx, rc);
++}
++
++
++/****************************************************************************
++** Aggregate SQL function implementations
++****************************************************************************/
++/*
++** json_group_array(VALUE)
++**
++** Return a JSON array composed of all values in the aggregate.
++*/
++static void jsonArrayStep(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonString *pStr;
++  UNUSED_PARAM(argc);
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
++  if( pStr ){
++    if( pStr->zBuf==0 ){
++      jsonInit(pStr, ctx);
++      jsonAppendChar(pStr, '[');
++    }else{
++      jsonAppendChar(pStr, ',');
++      pStr->pCtx = ctx;
++    }
++    jsonAppendValue(pStr, argv[0]);
++  }
++}
++static void jsonArrayFinal(sqlite3_context *ctx){
++  JsonString *pStr;
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
++  if( pStr ){
++    pStr->pCtx = ctx;
++    jsonAppendChar(pStr, ']');
++    if( pStr->bErr ){
++      if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
++      assert( pStr->bStatic );
++    }else{
++      sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
++                          pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
++      pStr->bStatic = 1;
++    }
++  }else{
++    sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
++  }
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++
++/*
++** json_group_obj(NAME,VALUE)
++**
++** Return a JSON object composed of all names and values in the aggregate.
++*/
++static void jsonObjectStep(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonString *pStr;
++  const char *z;
++  u32 n;
++  UNUSED_PARAM(argc);
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
++  if( pStr ){
++    if( pStr->zBuf==0 ){
++      jsonInit(pStr, ctx);
++      jsonAppendChar(pStr, '{');
++    }else{
++      jsonAppendChar(pStr, ',');
++      pStr->pCtx = ctx;
++    }
++    z = (const char*)sqlite3_value_text(argv[0]);
++    n = (u32)sqlite3_value_bytes(argv[0]);
++    jsonAppendString(pStr, z, n);
++    jsonAppendChar(pStr, ':');
++    jsonAppendValue(pStr, argv[1]);
++  }
++}
++static void jsonObjectFinal(sqlite3_context *ctx){
++  JsonString *pStr;
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
++  if( pStr ){
++    jsonAppendChar(pStr, '}');
++    if( pStr->bErr ){
++      if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
++      assert( pStr->bStatic );
++    }else{
++      sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
++                          pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
++      pStr->bStatic = 1;
++    }
++  }else{
++    sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
++  }
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++
++
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++/****************************************************************************
++** The json_each virtual table
++****************************************************************************/
++typedef struct JsonEachCursor JsonEachCursor;
++struct JsonEachCursor {
++  sqlite3_vtab_cursor base;  /* Base class - must be first */
++  u32 iRowid;                /* The rowid */
++  u32 iBegin;                /* The first node of the scan */
++  u32 i;                     /* Index in sParse.aNode[] of current row */
++  u32 iEnd;                  /* EOF when i equals or exceeds this value */
++  u8 eType;                  /* Type of top-level element */
++  u8 bRecursive;             /* True for json_tree().  False for json_each() */
++  char *zJson;               /* Input JSON */
++  char *zRoot;               /* Path by which to filter zJson */
++  JsonParse sParse;          /* Parse of the input JSON */
++};
++
++/* Constructor for the json_each virtual table */
++static int jsonEachConnect(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  sqlite3_vtab *pNew;
++  int rc;
++
++/* Column numbers */
++#define JEACH_KEY     0
++#define JEACH_VALUE   1
++#define JEACH_TYPE    2
++#define JEACH_ATOM    3
++#define JEACH_ID      4
++#define JEACH_PARENT  5
++#define JEACH_FULLKEY 6
++#define JEACH_PATH    7
++#define JEACH_JSON    8
++#define JEACH_ROOT    9
++
++  UNUSED_PARAM(pzErr);
++  UNUSED_PARAM(argv);
++  UNUSED_PARAM(argc);
++  UNUSED_PARAM(pAux);
++  rc = sqlite3_declare_vtab(db, 
++     "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
++                    "json HIDDEN,root HIDDEN)");
++  if( rc==SQLITE_OK ){
++    pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
++    if( pNew==0 ) return SQLITE_NOMEM;
++    memset(pNew, 0, sizeof(*pNew));
++  }
++  return rc;
++}
++
++/* destructor for json_each virtual table */
++static int jsonEachDisconnect(sqlite3_vtab *pVtab){
++  sqlite3_free(pVtab);
++  return SQLITE_OK;
++}
++
++/* constructor for a JsonEachCursor object for json_each(). */
++static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
++  JsonEachCursor *pCur;
++
++  UNUSED_PARAM(p);
++  pCur = sqlite3_malloc( sizeof(*pCur) );
++  if( pCur==0 ) return SQLITE_NOMEM;
++  memset(pCur, 0, sizeof(*pCur));
++  *ppCursor = &pCur->base;
++  return SQLITE_OK;
++}
++
++/* constructor for a JsonEachCursor object for json_tree(). */
++static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
++  int rc = jsonEachOpenEach(p, ppCursor);
++  if( rc==SQLITE_OK ){
++    JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
++    pCur->bRecursive = 1;
++  }
++  return rc;
++}
++
++/* Reset a JsonEachCursor back to its original state.  Free any memory
++** held. */
++static void jsonEachCursorReset(JsonEachCursor *p){
++  sqlite3_free(p->zJson);
++  sqlite3_free(p->zRoot);
++  jsonParseReset(&p->sParse);
++  p->iRowid = 0;
++  p->i = 0;
++  p->iEnd = 0;
++  p->eType = 0;
++  p->zJson = 0;
++  p->zRoot = 0;
++}
++
++/* Destructor for a jsonEachCursor object */
++static int jsonEachClose(sqlite3_vtab_cursor *cur){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  jsonEachCursorReset(p);
++  sqlite3_free(cur);
++  return SQLITE_OK;
++}
++
++/* Return TRUE if the jsonEachCursor object has been advanced off the end
++** of the JSON object */
++static int jsonEachEof(sqlite3_vtab_cursor *cur){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  return p->i >= p->iEnd;
++}
++
++/* Advance the cursor to the next element for json_tree() */
++static int jsonEachNext(sqlite3_vtab_cursor *cur){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  if( p->bRecursive ){
++    if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
++    p->i++;
++    p->iRowid++;
++    if( p->i<p->iEnd ){
++      u32 iUp = p->sParse.aUp[p->i];
++      JsonNode *pUp = &p->sParse.aNode[iUp];
++      p->eType = pUp->eType;
++      if( pUp->eType==JSON_ARRAY ){
++        if( iUp==p->i-1 ){
++          pUp->u.iKey = 0;
++        }else{
++          pUp->u.iKey++;
++        }
++      }
++    }
++  }else{
++    switch( p->eType ){
++      case JSON_ARRAY: {
++        p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
++        p->iRowid++;
++        break;
++      }
++      case JSON_OBJECT: {
++        p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
++        p->iRowid++;
++        break;
++      }
++      default: {
++        p->i = p->iEnd;
++        break;
++      }
++    }
++  }
++  return SQLITE_OK;
++}
++
++/* Append the name of the path for element i to pStr
++*/
++static void jsonEachComputePath(
++  JsonEachCursor *p,       /* The cursor */
++  JsonString *pStr,        /* Write the path here */
++  u32 i                    /* Path to this element */
++){
++  JsonNode *pNode, *pUp;
++  u32 iUp;
++  if( i==0 ){
++    jsonAppendChar(pStr, '$');
++    return;
++  }
++  iUp = p->sParse.aUp[i];
++  jsonEachComputePath(p, pStr, iUp);
++  pNode = &p->sParse.aNode[i];
++  pUp = &p->sParse.aNode[iUp];
++  if( pUp->eType==JSON_ARRAY ){
++    jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
++  }else{
++    assert( pUp->eType==JSON_OBJECT );
++    if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
++    assert( pNode->eType==JSON_STRING );
++    assert( pNode->jnFlags & JNODE_LABEL );
++    jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
++  }
++}
++
++/* Return the value of a column */
++static int jsonEachColumn(
++  sqlite3_vtab_cursor *cur,   /* The cursor */
++  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
++  int i                       /* Which column to return */
++){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  JsonNode *pThis = &p->sParse.aNode[p->i];
++  switch( i ){
++    case JEACH_KEY: {
++      if( p->i==0 ) break;
++      if( p->eType==JSON_OBJECT ){
++        jsonReturn(pThis, ctx, 0);
++      }else if( p->eType==JSON_ARRAY ){
++        u32 iKey;
++        if( p->bRecursive ){
++          if( p->iRowid==0 ) break;
++          iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
++        }else{
++          iKey = p->iRowid;
++        }
++        sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
++      }
++      break;
++    }
++    case JEACH_VALUE: {
++      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
++      jsonReturn(pThis, ctx, 0);
++      break;
++    }
++    case JEACH_TYPE: {
++      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
++      sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
++      break;
++    }
++    case JEACH_ATOM: {
++      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
++      if( pThis->eType>=JSON_ARRAY ) break;
++      jsonReturn(pThis, ctx, 0);
++      break;
++    }
++    case JEACH_ID: {
++      sqlite3_result_int64(ctx, 
++         (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
++      break;
++    }
++    case JEACH_PARENT: {
++      if( p->i>p->iBegin && p->bRecursive ){
++        sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
++      }
++      break;
++    }
++    case JEACH_FULLKEY: {
++      JsonString x;
++      jsonInit(&x, ctx);
++      if( p->bRecursive ){
++        jsonEachComputePath(p, &x, p->i);
++      }else{
++        if( p->zRoot ){
++          jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
++        }else{
++          jsonAppendChar(&x, '$');
++        }
++        if( p->eType==JSON_ARRAY ){
++          jsonPrintf(30, &x, "[%d]", p->iRowid);
++        }else{
++          jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
++        }
++      }
++      jsonResult(&x);
++      break;
++    }
++    case JEACH_PATH: {
++      if( p->bRecursive ){
++        JsonString x;
++        jsonInit(&x, ctx);
++        jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
++        jsonResult(&x);
++        break;
++      }
++      /* For json_each() path and root are the same so fall through
++      ** into the root case */
++    }
++    default: {
++      const char *zRoot = p->zRoot;
++      if( zRoot==0 ) zRoot = "$";
++      sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
++      break;
++    }
++    case JEACH_JSON: {
++      assert( i==JEACH_JSON );
++      sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
++      break;
++    }
++  }
++  return SQLITE_OK;
++}
++
++/* Return the current rowid value */
++static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  *pRowid = p->iRowid;
++  return SQLITE_OK;
++}
++
++/* The query strategy is to look for an equality constraint on the json
++** column.  Without such a constraint, the table cannot operate.  idxNum is
++** 1 if the constraint is found, 3 if the constraint and zRoot are found,
++** and 0 otherwise.
++*/
++static int jsonEachBestIndex(
++  sqlite3_vtab *tab,
++  sqlite3_index_info *pIdxInfo
++){
++  int i;
++  int jsonIdx = -1;
++  int rootIdx = -1;
++  const struct sqlite3_index_constraint *pConstraint;
++
++  UNUSED_PARAM(tab);
++  pConstraint = pIdxInfo->aConstraint;
++  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
++    if( pConstraint->usable==0 ) continue;
++    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
++    switch( pConstraint->iColumn ){
++      case JEACH_JSON:   jsonIdx = i;    break;
++      case JEACH_ROOT:   rootIdx = i;    break;
++      default:           /* no-op */     break;
++    }
++  }
++  if( jsonIdx<0 ){
++    pIdxInfo->idxNum = 0;
++    pIdxInfo->estimatedCost = 1e99;
++  }else{
++    pIdxInfo->estimatedCost = 1.0;
++    pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
++    pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
++    if( rootIdx<0 ){
++      pIdxInfo->idxNum = 1;
++    }else{
++      pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
++      pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
++      pIdxInfo->idxNum = 3;
++    }
++  }
++  return SQLITE_OK;
++}
++
++/* Start a search on a new JSON string */
++static int jsonEachFilter(
++  sqlite3_vtab_cursor *cur,
++  int idxNum, const char *idxStr,
++  int argc, sqlite3_value **argv
++){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  const char *z;
++  const char *zRoot = 0;
++  sqlite3_int64 n;
++
++  UNUSED_PARAM(idxStr);
++  UNUSED_PARAM(argc);
++  jsonEachCursorReset(p);
++  if( idxNum==0 ) return SQLITE_OK;
++  z = (const char*)sqlite3_value_text(argv[0]);
++  if( z==0 ) return SQLITE_OK;
++  n = sqlite3_value_bytes(argv[0]);
++  p->zJson = sqlite3_malloc64( n+1 );
++  if( p->zJson==0 ) return SQLITE_NOMEM;
++  memcpy(p->zJson, z, (size_t)n+1);
++  if( jsonParse(&p->sParse, 0, p->zJson) ){
++    int rc = SQLITE_NOMEM;
++    if( p->sParse.oom==0 ){
++      sqlite3_free(cur->pVtab->zErrMsg);
++      cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
++      if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
++    }
++    jsonEachCursorReset(p);
++    return rc;
++  }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
++    jsonEachCursorReset(p);
++    return SQLITE_NOMEM;
++  }else{
++    JsonNode *pNode = 0;
++    if( idxNum==3 ){
++      const char *zErr = 0;
++      zRoot = (const char*)sqlite3_value_text(argv[1]);
++      if( zRoot==0 ) return SQLITE_OK;
++      n = sqlite3_value_bytes(argv[1]);
++      p->zRoot = sqlite3_malloc64( n+1 );
++      if( p->zRoot==0 ) return SQLITE_NOMEM;
++      memcpy(p->zRoot, zRoot, (size_t)n+1);
++      if( zRoot[0]!='$' ){
++        zErr = zRoot;
++      }else{
++        pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
++      }
++      if( zErr ){
++        sqlite3_free(cur->pVtab->zErrMsg);
++        cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
++        jsonEachCursorReset(p);
++        return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
++      }else if( pNode==0 ){
++        return SQLITE_OK;
++      }
++    }else{
++      pNode = p->sParse.aNode;
++    }
++    p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
++    p->eType = pNode->eType;
++    if( p->eType>=JSON_ARRAY ){
++      pNode->u.iKey = 0;
++      p->iEnd = p->i + pNode->n + 1;
++      if( p->bRecursive ){
++        p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
++        if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
++          p->i--;
++        }
++      }else{
++        p->i++;
++      }
++    }else{
++      p->iEnd = p->i+1;
++    }
++  }
++  return SQLITE_OK;
++}
++
++/* The methods of the json_each virtual table */
++static sqlite3_module jsonEachModule = {
++  0,                         /* iVersion */
++  0,                         /* xCreate */
++  jsonEachConnect,           /* xConnect */
++  jsonEachBestIndex,         /* xBestIndex */
++  jsonEachDisconnect,        /* xDisconnect */
++  0,                         /* xDestroy */
++  jsonEachOpenEach,          /* xOpen - open a cursor */
++  jsonEachClose,             /* xClose - close a cursor */
++  jsonEachFilter,            /* xFilter - configure scan constraints */
++  jsonEachNext,              /* xNext - advance a cursor */
++  jsonEachEof,               /* xEof - check for end of scan */
++  jsonEachColumn,            /* xColumn - read data */
++  jsonEachRowid,             /* xRowid - read data */
++  0,                         /* xUpdate */
++  0,                         /* xBegin */
++  0,                         /* xSync */
++  0,                         /* xCommit */
++  0,                         /* xRollback */
++  0,                         /* xFindMethod */
++  0,                         /* xRename */
++  0,                         /* xSavepoint */
++  0,                         /* xRelease */
++  0                          /* xRollbackTo */
++};
++
++/* The methods of the json_tree virtual table. */
++static sqlite3_module jsonTreeModule = {
++  0,                         /* iVersion */
++  0,                         /* xCreate */
++  jsonEachConnect,           /* xConnect */
++  jsonEachBestIndex,         /* xBestIndex */
++  jsonEachDisconnect,        /* xDisconnect */
++  0,                         /* xDestroy */
++  jsonEachOpenTree,          /* xOpen - open a cursor */
++  jsonEachClose,             /* xClose - close a cursor */
++  jsonEachFilter,            /* xFilter - configure scan constraints */
++  jsonEachNext,              /* xNext - advance a cursor */
++  jsonEachEof,               /* xEof - check for end of scan */
++  jsonEachColumn,            /* xColumn - read data */
++  jsonEachRowid,             /* xRowid - read data */
++  0,                         /* xUpdate */
++  0,                         /* xBegin */
++  0,                         /* xSync */
++  0,                         /* xCommit */
++  0,                         /* xRollback */
++  0,                         /* xFindMethod */
++  0,                         /* xRename */
++  0,                         /* xSavepoint */
++  0,                         /* xRelease */
++  0                          /* xRollbackTo */
++};
++#endif /* SQLITE_OMIT_VIRTUALTABLE */
++
++/****************************************************************************
++** The following routines are the only publically visible identifiers in this
++** file.  Call the following routines in order to register the various SQL
++** functions and the virtual table implemented by this file.
++****************************************************************************/
++
++SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){
++  int rc = SQLITE_OK;
++  unsigned int i;
++  static const struct {
++     const char *zName;
++     int nArg;
++     int flag;
++     void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
++  } aFunc[] = {
++    { "json",                 1, 0,   jsonRemoveFunc        },
++    { "json_array",          -1, 0,   jsonArrayFunc         },
++    { "json_array_length",    1, 0,   jsonArrayLengthFunc   },
++    { "json_array_length",    2, 0,   jsonArrayLengthFunc   },
++    { "json_extract",        -1, 0,   jsonExtractFunc       },
++    { "json_insert",         -1, 0,   jsonSetFunc           },
++    { "json_object",         -1, 0,   jsonObjectFunc        },
++    { "json_patch",           2, 0,   jsonPatchFunc         },
++    { "json_quote",           1, 0,   jsonQuoteFunc         },
++    { "json_remove",         -1, 0,   jsonRemoveFunc        },
++    { "json_replace",        -1, 0,   jsonReplaceFunc       },
++    { "json_set",            -1, 1,   jsonSetFunc           },
++    { "json_type",            1, 0,   jsonTypeFunc          },
++    { "json_type",            2, 0,   jsonTypeFunc          },
++    { "json_valid",           1, 0,   jsonValidFunc         },
++
++#if SQLITE_DEBUG
++    /* DEBUG and TESTING functions */
++    { "json_parse",           1, 0,   jsonParseFunc         },
++    { "json_test1",           1, 0,   jsonTest1Func         },
++#endif
++  };
++  static const struct {
++     const char *zName;
++     int nArg;
++     void (*xStep)(sqlite3_context*,int,sqlite3_value**);
++     void (*xFinal)(sqlite3_context*);
++  } aAgg[] = {
++    { "json_group_array",     1,   jsonArrayStep,   jsonArrayFinal  },
++    { "json_group_object",    2,   jsonObjectStep,  jsonObjectFinal },
++  };
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  static const struct {
++     const char *zName;
++     sqlite3_module *pModule;
++  } aMod[] = {
++    { "json_each",            &jsonEachModule               },
++    { "json_tree",            &jsonTreeModule               },
++  };
++#endif
++  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
++    rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
++                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 
++                                 (void*)&aFunc[i].flag,
++                                 aFunc[i].xFunc, 0, 0);
++  }
++  for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
++    rc = sqlite3_create_function(db, aAgg[i].zName, aAgg[i].nArg,
++                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
++                                 0, aAgg[i].xStep, aAgg[i].xFinal);
++  }
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
++    rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
++  }
++#endif
++  return rc;
++}
++
++
++#ifndef SQLITE_CORE
++#ifdef _WIN32
++__declspec(dllexport)
++#endif
++SQLITE_API int sqlite3_json_init(
++  sqlite3 *db, 
++  char **pzErrMsg, 
++  const sqlite3_api_routines *pApi
++){
++  SQLITE_EXTENSION_INIT2(pApi);
++  (void)pzErrMsg;  /* Unused parameter */
++  return sqlite3Json1Init(db);
++}
++#endif
++#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */
++
++/************** End of json1.c ***********************************************/
++/************** Begin file fts5.c ********************************************/
++
++
++#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) 
++
++#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) 
++# define NDEBUG 1
++#endif
++#if defined(NDEBUG) && defined(SQLITE_DEBUG)
++# undef NDEBUG
++#endif
++
++/*
++** 2014 May 31
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** Interfaces to extend FTS5. Using the interfaces defined in this file, 
++** FTS5 may be extended with:
++**
++**     * custom tokenizers, and
++**     * custom auxiliary functions.
++*/
++
++
++#ifndef _FTS5_H
++#define _FTS5_H
++
++/* #include "sqlite3.h" */
++
++#if 0
++extern "C" {
++#endif
++
++/*************************************************************************
++** CUSTOM AUXILIARY FUNCTIONS
++**
++** Virtual table implementations may overload SQL functions by implementing
++** the sqlite3_module.xFindFunction() method.
++*/
++
++typedef struct Fts5ExtensionApi Fts5ExtensionApi;
++typedef struct Fts5Context Fts5Context;
++typedef struct Fts5PhraseIter Fts5PhraseIter;
++
++typedef void (*fts5_extension_function)(
++  const Fts5ExtensionApi *pApi,   /* API offered by current FTS version */
++  Fts5Context *pFts,              /* First arg to pass to pApi functions */
++  sqlite3_context *pCtx,          /* Context for returning result/error */
++  int nVal,                       /* Number of values in apVal[] array */
++  sqlite3_value **apVal           /* Array of trailing arguments */
++);
++
++struct Fts5PhraseIter {
++  const unsigned char *a;
++  const unsigned char *b;
++};
++
++/*
++** EXTENSION API FUNCTIONS
++**
++** xUserData(pFts):
++**   Return a copy of the context pointer the extension function was 
++**   registered with.
++**
++** xColumnTotalSize(pFts, iCol, pnToken):
++**   If parameter iCol is less than zero, set output variable *pnToken
++**   to the total number of tokens in the FTS5 table. Or, if iCol is
++**   non-negative but less than the number of columns in the table, return
++**   the total number of tokens in column iCol, considering all rows in 
++**   the FTS5 table.
++**
++**   If parameter iCol is greater than or equal to the number of columns
++**   in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
++**   an OOM condition or IO error), an appropriate SQLite error code is 
++**   returned.
++**
++** xColumnCount(pFts):
++**   Return the number of columns in the table.
++**
++** xColumnSize(pFts, iCol, pnToken):
++**   If parameter iCol is less than zero, set output variable *pnToken
++**   to the total number of tokens in the current row. Or, if iCol is
++**   non-negative but less than the number of columns in the table, set
++**   *pnToken to the number of tokens in column iCol of the current row.
++**
++**   If parameter iCol is greater than or equal to the number of columns
++**   in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
++**   an OOM condition or IO error), an appropriate SQLite error code is 
++**   returned.
++**
++**   This function may be quite inefficient if used with an FTS5 table
++**   created with the "columnsize=0" option.
++**
++** xColumnText:
++**   This function attempts to retrieve the text of column iCol of the
++**   current document. If successful, (*pz) is set to point to a buffer
++**   containing the text in utf-8 encoding, (*pn) is set to the size in bytes
++**   (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
++**   if an error occurs, an SQLite error code is returned and the final values
++**   of (*pz) and (*pn) are undefined.
++**
++** xPhraseCount:
++**   Returns the number of phrases in the current query expression.
++**
++** xPhraseSize:
++**   Returns the number of tokens in phrase iPhrase of the query. Phrases
++**   are numbered starting from zero.
++**
++** xInstCount:
++**   Set *pnInst to the total number of occurrences of all phrases within
++**   the query within the current row. Return SQLITE_OK if successful, or
++**   an error code (i.e. SQLITE_NOMEM) if an error occurs.
++**
++**   This API can be quite slow if used with an FTS5 table created with the
++**   "detail=none" or "detail=column" option. If the FTS5 table is created 
++**   with either "detail=none" or "detail=column" and "content=" option 
++**   (i.e. if it is a contentless table), then this API always returns 0.
++**
++** xInst:
++**   Query for the details of phrase match iIdx within the current row.
++**   Phrase matches are numbered starting from zero, so the iIdx argument
++**   should be greater than or equal to zero and smaller than the value
++**   output by xInstCount().
++**
++**   Usually, output parameter *piPhrase is set to the phrase number, *piCol
++**   to the column in which it occurs and *piOff the token offset of the
++**   first token of the phrase. The exception is if the table was created
++**   with the offsets=0 option specified. In this case *piOff is always
++**   set to -1.
++**
++**   Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM) 
++**   if an error occurs.
++**
++**   This API can be quite slow if used with an FTS5 table created with the
++**   "detail=none" or "detail=column" option. 
++**
++** xRowid:
++**   Returns the rowid of the current row.
++**
++** xTokenize:
++**   Tokenize text using the tokenizer belonging to the FTS5 table.
++**
++** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
++**   This API function is used to query the FTS table for phrase iPhrase
++**   of the current query. Specifically, a query equivalent to:
++**
++**       ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
++**
++**   with $p set to a phrase equivalent to the phrase iPhrase of the
++**   current query is executed. Any column filter that applies to
++**   phrase iPhrase of the current query is included in $p. For each 
++**   row visited, the callback function passed as the fourth argument 
++**   is invoked. The context and API objects passed to the callback 
++**   function may be used to access the properties of each matched row.
++**   Invoking Api.xUserData() returns a copy of the pointer passed as 
++**   the third argument to pUserData.
++**
++**   If the callback function returns any value other than SQLITE_OK, the
++**   query is abandoned and the xQueryPhrase function returns immediately.
++**   If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
++**   Otherwise, the error code is propagated upwards.
++**
++**   If the query runs to completion without incident, SQLITE_OK is returned.
++**   Or, if some error occurs before the query completes or is aborted by
++**   the callback, an SQLite error code is returned.
++**
++**
++** xSetAuxdata(pFts5, pAux, xDelete)
++**
++**   Save the pointer passed as the second argument as the extension functions 
++**   "auxiliary data". The pointer may then be retrieved by the current or any
++**   future invocation of the same fts5 extension function made as part of
++**   of the same MATCH query using the xGetAuxdata() API.
++**
++**   Each extension function is allocated a single auxiliary data slot for
++**   each FTS query (MATCH expression). If the extension function is invoked 
++**   more than once for a single FTS query, then all invocations share a 
++**   single auxiliary data context.
++**
++**   If there is already an auxiliary data pointer when this function is
++**   invoked, then it is replaced by the new pointer. If an xDelete callback
++**   was specified along with the original pointer, it is invoked at this
++**   point.
++**
++**   The xDelete callback, if one is specified, is also invoked on the
++**   auxiliary data pointer after the FTS5 query has finished.
++**
++**   If an error (e.g. an OOM condition) occurs within this function, an
++**   the auxiliary data is set to NULL and an error code returned. If the
++**   xDelete parameter was not NULL, it is invoked on the auxiliary data
++**   pointer before returning.
++**
++**
++** xGetAuxdata(pFts5, bClear)
++**
++**   Returns the current auxiliary data pointer for the fts5 extension 
++**   function. See the xSetAuxdata() method for details.
++**
++**   If the bClear argument is non-zero, then the auxiliary data is cleared
++**   (set to NULL) before this function returns. In this case the xDelete,
++**   if any, is not invoked.
++**
++**
++** xRowCount(pFts5, pnRow)
++**
++**   This function is used to retrieve the total number of rows in the table.
++**   In other words, the same value that would be returned by:
++**
++**        SELECT count(*) FROM ftstable;
++**
++** xPhraseFirst()
++**   This function is used, along with type Fts5PhraseIter and the xPhraseNext
++**   method, to iterate through all instances of a single query phrase within
++**   the current row. This is the same information as is accessible via the
++**   xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
++**   to use, this API may be faster under some circumstances. To iterate 
++**   through instances of phrase iPhrase, use the following code:
++**
++**       Fts5PhraseIter iter;
++**       int iCol, iOff;
++**       for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
++**           iCol>=0;
++**           pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
++**       ){
++**         // An instance of phrase iPhrase at offset iOff of column iCol
++**       }
++**
++**   The Fts5PhraseIter structure is defined above. Applications should not
++**   modify this structure directly - it should only be used as shown above
++**   with the xPhraseFirst() and xPhraseNext() API methods (and by
++**   xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
++**
++**   This API can be quite slow if used with an FTS5 table created with the
++**   "detail=none" or "detail=column" option. If the FTS5 table is created 
++**   with either "detail=none" or "detail=column" and "content=" option 
++**   (i.e. if it is a contentless table), then this API always iterates
++**   through an empty set (all calls to xPhraseFirst() set iCol to -1).
++**
++** xPhraseNext()
++**   See xPhraseFirst above.
++**
++** xPhraseFirstColumn()
++**   This function and xPhraseNextColumn() are similar to the xPhraseFirst()
++**   and xPhraseNext() APIs described above. The difference is that instead
++**   of iterating through all instances of a phrase in the current row, these
++**   APIs are used to iterate through the set of columns in the current row
++**   that contain one or more instances of a specified phrase. For example:
++**
++**       Fts5PhraseIter iter;
++**       int iCol;
++**       for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
++**           iCol>=0;
++**           pApi->xPhraseNextColumn(pFts, &iter, &iCol)
++**       ){
++**         // Column iCol contains at least one instance of phrase iPhrase
++**       }
++**
++**   This API can be quite slow if used with an FTS5 table created with the
++**   "detail=none" option. If the FTS5 table is created with either 
++**   "detail=none" "content=" option (i.e. if it is a contentless table), 
++**   then this API always iterates through an empty set (all calls to 
++**   xPhraseFirstColumn() set iCol to -1).
++**
++**   The information accessed using this API and its companion
++**   xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
++**   (or xInst/xInstCount). The chief advantage of this API is that it is
++**   significantly more efficient than those alternatives when used with
++**   "detail=column" tables.  
++**
++** xPhraseNextColumn()
++**   See xPhraseFirstColumn above.
++*/
++struct Fts5ExtensionApi {
++  int iVersion;                   /* Currently always set to 3 */
++
++  void *(*xUserData)(Fts5Context*);
++
++  int (*xColumnCount)(Fts5Context*);
++  int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
++  int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
++
++  int (*xTokenize)(Fts5Context*, 
++    const char *pText, int nText, /* Text to tokenize */
++    void *pCtx,                   /* Context passed to xToken() */
++    int (*xToken)(void*, int, const char*, int, int, int)       /* Callback */
++  );
++
++  int (*xPhraseCount)(Fts5Context*);
++  int (*xPhraseSize)(Fts5Context*, int iPhrase);
++
++  int (*xInstCount)(Fts5Context*, int *pnInst);
++  int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
++
++  sqlite3_int64 (*xRowid)(Fts5Context*);
++  int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
++  int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
++
++  int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
++    int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
++  );
++  int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
++  void *(*xGetAuxdata)(Fts5Context*, int bClear);
++
++  int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
++  void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
++
++  int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
++  void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
++};
++
++/* 
++** CUSTOM AUXILIARY FUNCTIONS
++*************************************************************************/
++
++/*************************************************************************
++** CUSTOM TOKENIZERS
++**
++** Applications may also register custom tokenizer types. A tokenizer 
++** is registered by providing fts5 with a populated instance of the 
++** following structure. All structure methods must be defined, setting
++** any member of the fts5_tokenizer struct to NULL leads to undefined
++** behaviour. The structure methods are expected to function as follows:
++**
++** xCreate:
++**   This function is used to allocate and initialize a tokenizer instance.
++**   A tokenizer instance is required to actually tokenize text.
++**
++**   The first argument passed to this function is a copy of the (void*)
++**   pointer provided by the application when the fts5_tokenizer object
++**   was registered with FTS5 (the third argument to xCreateTokenizer()). 
++**   The second and third arguments are an array of nul-terminated strings
++**   containing the tokenizer arguments, if any, specified following the
++**   tokenizer name as part of the CREATE VIRTUAL TABLE statement used
++**   to create the FTS5 table.
++**
++**   The final argument is an output variable. If successful, (*ppOut) 
++**   should be set to point to the new tokenizer handle and SQLITE_OK
++**   returned. If an error occurs, some value other than SQLITE_OK should
++**   be returned. In this case, fts5 assumes that the final value of *ppOut 
++**   is undefined.
++**
++** xDelete:
++**   This function is invoked to delete a tokenizer handle previously
++**   allocated using xCreate(). Fts5 guarantees that this function will
++**   be invoked exactly once for each successful call to xCreate().
++**
++** xTokenize:
++**   This function is expected to tokenize the nText byte string indicated 
++**   by argument pText. pText may or may not be nul-terminated. The first
++**   argument passed to this function is a pointer to an Fts5Tokenizer object
++**   returned by an earlier call to xCreate().
++**
++**   The second argument indicates the reason that FTS5 is requesting
++**   tokenization of the supplied text. This is always one of the following
++**   four values:
++**
++**   <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
++**            or removed from the FTS table. The tokenizer is being invoked to
++**            determine the set of tokens to add to (or delete from) the
++**            FTS index.
++**
++**       <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed 
++**            against the FTS index. The tokenizer is being called to tokenize 
++**            a bareword or quoted string specified as part of the query.
++**
++**       <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
++**            FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
++**            followed by a "*" character, indicating that the last token
++**            returned by the tokenizer will be treated as a token prefix.
++**
++**       <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to 
++**            satisfy an fts5_api.xTokenize() request made by an auxiliary
++**            function. Or an fts5_api.xColumnSize() request made by the same
++**            on a columnsize=0 database.  
++**   </ul>
++**
++**   For each token in the input string, the supplied callback xToken() must
++**   be invoked. The first argument to it should be a copy of the pointer
++**   passed as the second argument to xTokenize(). The third and fourth
++**   arguments are a pointer to a buffer containing the token text, and the
++**   size of the token in bytes. The 4th and 5th arguments are the byte offsets
++**   of the first byte of and first byte immediately following the text from
++**   which the token is derived within the input.
++**
++**   The second argument passed to the xToken() callback ("tflags") should
++**   normally be set to 0. The exception is if the tokenizer supports 
++**   synonyms. In this case see the discussion below for details.
++**
++**   FTS5 assumes the xToken() callback is invoked for each token in the 
++**   order that they occur within the input text.
++**
++**   If an xToken() callback returns any value other than SQLITE_OK, then
++**   the tokenization should be abandoned and the xTokenize() method should
++**   immediately return a copy of the xToken() return value. Or, if the
++**   input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
++**   if an error occurs with the xTokenize() implementation itself, it
++**   may abandon the tokenization and return any error code other than
++**   SQLITE_OK or SQLITE_DONE.
++**
++** SYNONYM SUPPORT
++**
++**   Custom tokenizers may also support synonyms. Consider a case in which a
++**   user wishes to query for a phrase such as "first place". Using the 
++**   built-in tokenizers, the FTS5 query 'first + place' will match instances
++**   of "first place" within the document set, but not alternative forms
++**   such as "1st place". In some applications, it would be better to match
++**   all instances of "first place" or "1st place" regardless of which form
++**   the user specified in the MATCH query text.
++**
++**   There are several ways to approach this in FTS5:
++**
++**   <ol><li> By mapping all synonyms to a single token. In this case, the 
++**            In the above example, this means that the tokenizer returns the
++**            same token for inputs "first" and "1st". Say that token is in
++**            fact "first", so that when the user inserts the document "I won
++**            1st place" entries are added to the index for tokens "i", "won",
++**            "first" and "place". If the user then queries for '1st + place',
++**            the tokenizer substitutes "first" for "1st" and the query works
++**            as expected.
++**
++**       <li> By adding multiple synonyms for a single term to the FTS index.
++**            In this case, when tokenizing query text, the tokenizer may 
++**            provide multiple synonyms for a single term within the document.
++**            FTS5 then queries the index for each synonym individually. For
++**            example, faced with the query:
++**
++**   <codeblock>
++**     ... MATCH 'first place'</codeblock>
++**
++**            the tokenizer offers both "1st" and "first" as synonyms for the
++**            first token in the MATCH query and FTS5 effectively runs a query 
++**            similar to:
++**
++**   <codeblock>
++**     ... MATCH '(first OR 1st) place'</codeblock>
++**
++**            except that, for the purposes of auxiliary functions, the query
++**            still appears to contain just two phrases - "(first OR 1st)" 
++**            being treated as a single phrase.
++**
++**       <li> By adding multiple synonyms for a single term to the FTS index.
++**            Using this method, when tokenizing document text, the tokenizer
++**            provides multiple synonyms for each token. So that when a 
++**            document such as "I won first place" is tokenized, entries are
++**            added to the FTS index for "i", "won", "first", "1st" and
++**            "place".
++**
++**            This way, even if the tokenizer does not provide synonyms
++**            when tokenizing query text (it should not - to do would be
++**            inefficient), it doesn't matter if the user queries for 
++**            'first + place' or '1st + place', as there are entires in the
++**            FTS index corresponding to both forms of the first token.
++**   </ol>
++**
++**   Whether it is parsing document or query text, any call to xToken that
++**   specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
++**   is considered to supply a synonym for the previous token. For example,
++**   when parsing the document "I won first place", a tokenizer that supports
++**   synonyms would call xToken() 5 times, as follows:
++**
++**   <codeblock>
++**       xToken(pCtx, 0, "i",                      1,  0,  1);
++**       xToken(pCtx, 0, "won",                    3,  2,  5);
++**       xToken(pCtx, 0, "first",                  5,  6, 11);
++**       xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3,  6, 11);
++**       xToken(pCtx, 0, "place",                  5, 12, 17);
++**</codeblock>
++**
++**   It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
++**   xToken() is called. Multiple synonyms may be specified for a single token
++**   by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence. 
++**   There is no limit to the number of synonyms that may be provided for a
++**   single token.
++**
++**   In many cases, method (1) above is the best approach. It does not add 
++**   extra data to the FTS index or require FTS5 to query for multiple terms,
++**   so it is efficient in terms of disk space and query speed. However, it
++**   does not support prefix queries very well. If, as suggested above, the
++**   token "first" is subsituted for "1st" by the tokenizer, then the query:
++**
++**   <codeblock>
++**     ... MATCH '1s*'</codeblock>
++**
++**   will not match documents that contain the token "1st" (as the tokenizer
++**   will probably not map "1s" to any prefix of "first").
++**
++**   For full prefix support, method (3) may be preferred. In this case, 
++**   because the index contains entries for both "first" and "1st", prefix
++**   queries such as 'fi*' or '1s*' will match correctly. However, because
++**   extra entries are added to the FTS index, this method uses more space
++**   within the database.
++**
++**   Method (2) offers a midpoint between (1) and (3). Using this method,
++**   a query such as '1s*' will match documents that contain the literal 
++**   token "1st", but not "first" (assuming the tokenizer is not able to
++**   provide synonyms for prefixes). However, a non-prefix query like '1st'
++**   will match against "1st" and "first". This method does not require
++**   extra disk space, as no extra entries are added to the FTS index. 
++**   On the other hand, it may require more CPU cycles to run MATCH queries,
++**   as separate queries of the FTS index are required for each synonym.
++**
++**   When using methods (2) or (3), it is important that the tokenizer only
++**   provide synonyms when tokenizing document text (method (2)) or query
++**   text (method (3)), not both. Doing so will not cause any errors, but is
++**   inefficient.
++*/
++typedef struct Fts5Tokenizer Fts5Tokenizer;
++typedef struct fts5_tokenizer fts5_tokenizer;
++struct fts5_tokenizer {
++  int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
++  void (*xDelete)(Fts5Tokenizer*);
++  int (*xTokenize)(Fts5Tokenizer*, 
++      void *pCtx,
++      int flags,            /* Mask of FTS5_TOKENIZE_* flags */
++      const char *pText, int nText, 
++      int (*xToken)(
++        void *pCtx,         /* Copy of 2nd argument to xTokenize() */
++        int tflags,         /* Mask of FTS5_TOKEN_* flags */
++        const char *pToken, /* Pointer to buffer containing token */
++        int nToken,         /* Size of token in bytes */
++        int iStart,         /* Byte offset of token within input text */
++        int iEnd            /* Byte offset of end of token within input text */
++      )
++  );
++};
++
++/* Flags that may be passed as the third argument to xTokenize() */
++#define FTS5_TOKENIZE_QUERY     0x0001
++#define FTS5_TOKENIZE_PREFIX    0x0002
++#define FTS5_TOKENIZE_DOCUMENT  0x0004
++#define FTS5_TOKENIZE_AUX       0x0008
++
++/* Flags that may be passed by the tokenizer implementation back to FTS5
++** as the third argument to the supplied xToken callback. */
++#define FTS5_TOKEN_COLOCATED    0x0001      /* Same position as prev. token */
++
++/*
++** END OF CUSTOM TOKENIZERS
++*************************************************************************/
++
++/*************************************************************************
++** FTS5 EXTENSION REGISTRATION API
++*/
++typedef struct fts5_api fts5_api;
++struct fts5_api {
++  int iVersion;                   /* Currently always set to 2 */
++
++  /* Create a new tokenizer */
++  int (*xCreateTokenizer)(
++    fts5_api *pApi,
++    const char *zName,
++    void *pContext,
++    fts5_tokenizer *pTokenizer,
++    void (*xDestroy)(void*)
++  );
++
++  /* Find an existing tokenizer */
++  int (*xFindTokenizer)(
++    fts5_api *pApi,
++    const char *zName,
++    void **ppContext,
++    fts5_tokenizer *pTokenizer
++  );
++
++  /* Create a new auxiliary function */
++  int (*xCreateFunction)(
++    fts5_api *pApi,
++    const char *zName,
++    void *pContext,
++    fts5_extension_function xFunction,
++    void (*xDestroy)(void*)
++  );
++};
++
++/*
++** END OF REGISTRATION API
++*************************************************************************/
++
++#if 0
++}  /* end of the 'extern "C"' block */
 +#endif
- 
--#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \
--        SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent)
--#endif /* defined(InterlockedCompareExchange) */
-+#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
-+        LPVOID))aSyscall[22].pCurrent)
- 
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
--  { "UuidCreate",               (SYSCALL)UuidCreate,             0 },
-+#if !SQLITE_OS_WINRT
-+  { "GetFileSize",             (SYSCALL)GetFileSize,             0 },
- #else
--  { "UuidCreate",               (SYSCALL)0,                      0 },
-+  { "GetFileSize",             (SYSCALL)0,                       0 },
- #endif
- 
--#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent)
-+#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent)
- 
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
--  { "UuidCreateSequential",     (SYSCALL)UuidCreateSequential,   0 },
-+#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
-+  { "GetFullPathNameA",        (SYSCALL)GetFullPathNameA,        0 },
- #else
--  { "UuidCreateSequential",     (SYSCALL)0,                      0 },
-+  { "GetFullPathNameA",        (SYSCALL)0,                       0 },
- #endif
- 
--#define osUuidCreateSequential \
--        ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent)
-+#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
-+        LPSTR*))aSyscall[24].pCurrent)
- 
--#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0
--  { "FlushViewOfFile",          (SYSCALL)FlushViewOfFile,        0 },
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "GetFullPathNameW",        (SYSCALL)GetFullPathNameW,        0 },
- #else
--  { "FlushViewOfFile",          (SYSCALL)0,                      0 },
-+  { "GetFullPathNameW",        (SYSCALL)0,                       0 },
- #endif
- 
--#define osFlushViewOfFile \
--        ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent)
-+#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
-+        LPWSTR*))aSyscall[25].pCurrent)
- 
--}; /* End of the overrideable system calls */
-+  { "GetLastError",            (SYSCALL)GetLastError,            0 },
- 
--/*
--** This is the xSetSystemCall() method of sqlite3_vfs for all of the
--** "win32" VFSes.  Return SQLITE_OK opon successfully updating the
--** system call pointer, or SQLITE_NOTFOUND if there is no configurable
--** system call named zName.
--*/
--static int winSetSystemCall(
--  sqlite3_vfs *pNotUsed,        /* The VFS pointer.  Not used */
--  const char *zName,            /* Name of system call to override */
--  sqlite3_syscall_ptr pNewFunc  /* Pointer to new system call value */
--){
--  unsigned int i;
--  int rc = SQLITE_NOTFOUND;
-+#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
- 
--  UNUSED_PARAMETER(pNotUsed);
--  if( zName==0 ){
--    /* If no zName is given, restore all system calls to their default
--    ** settings and return NULL
--    */
--    rc = SQLITE_OK;
--    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
--      if( aSyscall[i].pDefault ){
--        aSyscall[i].pCurrent = aSyscall[i].pDefault;
--      }
--    }
--  }else{
--    /* If zName is specified, operate on only the one system call
--    ** specified.
--    */
--    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
--      if( strcmp(zName, aSyscall[i].zName)==0 ){
--        if( aSyscall[i].pDefault==0 ){
--          aSyscall[i].pDefault = aSyscall[i].pCurrent;
--        }
--        rc = SQLITE_OK;
--        if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault;
--        aSyscall[i].pCurrent = pNewFunc;
--        break;
--      }
--    }
--  }
--  return rc;
--}
-+#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
-+#if SQLITE_OS_WINCE
-+  /* The GetProcAddressA() routine is only available on Windows CE. */
-+  { "GetProcAddressA",         (SYSCALL)GetProcAddressA,         0 },
-+#else
-+  /* All other Windows platforms expect GetProcAddress() to take
-+  ** an ANSI string regardless of the _UNICODE setting */
-+  { "GetProcAddressA",         (SYSCALL)GetProcAddress,          0 },
++
++#endif /* _FTS5_H */
++
++/*
++** 2014 May 31
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++*/
++#ifndef _FTS5INT_H
++#define _FTS5INT_H
++
++/* #include "fts5.h" */
++/* #include "sqlite3ext.h" */
++SQLITE_EXTENSION_INIT1
++
++/* #include <string.h> */
++/* #include <assert.h> */
++
++#ifndef SQLITE_AMALGAMATION
++
++typedef unsigned char  u8;
++typedef unsigned int   u32;
++typedef unsigned short u16;
++typedef short i16;
++typedef sqlite3_int64 i64;
++typedef sqlite3_uint64 u64;
++
++#ifndef ArraySize
++# define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
++#endif
++
++#define testcase(x)
++#define ALWAYS(x) 1
++#define NEVER(x) 0
++
++#define MIN(x,y) (((x) < (y)) ? (x) : (y))
++#define MAX(x,y) (((x) > (y)) ? (x) : (y))
++
++/*
++** Constants for the largest and smallest possible 64-bit signed integers.
++*/
++# define LARGEST_INT64  (0xffffffff|(((i64)0x7fffffff)<<32))
++# define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
++
 +#endif
++
++/* Truncate very long tokens to this many bytes. Hard limit is 
++** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset
++** field that occurs at the start of each leaf page (see fts5_index.c). */
++#define FTS5_MAX_TOKEN_SIZE 32768
++
++/*
++** Maximum number of prefix indexes on single FTS5 table. This must be
++** less than 32. If it is set to anything large than that, an #error
++** directive in fts5_index.c will cause the build to fail.
++*/
++#define FTS5_MAX_PREFIX_INDEXES 31
++
++#define FTS5_DEFAULT_NEARDIST 10
++#define FTS5_DEFAULT_RANK     "bm25"
++
++/* Name of rank and rowid columns */
++#define FTS5_RANK_NAME "rank"
++#define FTS5_ROWID_NAME "rowid"
++
++#ifdef SQLITE_DEBUG
++# define FTS5_CORRUPT sqlite3Fts5Corrupt()
++static int sqlite3Fts5Corrupt(void);
 +#else
-+  { "GetProcAddressA",         (SYSCALL)0,                       0 },
++# define FTS5_CORRUPT SQLITE_CORRUPT_VTAB
 +#endif
- 
--/*
--** Return the value of a system call.  Return NULL if zName is not a
--** recognized system call name.  NULL is also returned if the system call
--** is currently undefined.
--*/
--static sqlite3_syscall_ptr winGetSystemCall(
--  sqlite3_vfs *pNotUsed,
--  const char *zName
--){
--  unsigned int i;
-+#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
-+        LPCSTR))aSyscall[27].pCurrent)
- 
--  UNUSED_PARAMETER(pNotUsed);
--  for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
--    if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
--  }
--  return 0;
--}
-+#if !SQLITE_OS_WINRT
-+  { "GetSystemInfo",           (SYSCALL)GetSystemInfo,           0 },
++
++/*
++** The assert_nc() macro is similar to the assert() macro, except that it
++** is used for assert() conditions that are true only if it can be 
++** guranteed that the database is not corrupt.
++*/
++#ifdef SQLITE_DEBUG
++SQLITE_API extern int sqlite3_fts5_may_be_corrupt;
++# define assert_nc(x) assert(sqlite3_fts5_may_be_corrupt || (x))
 +#else
-+  { "GetSystemInfo",           (SYSCALL)0,                       0 },
++# define assert_nc(x) assert(x)
 +#endif
- 
--/*
--** Return the name of the first system call after zName.  If zName==NULL
--** then return the name of the first system call.  Return NULL if zName
--** is the last system call or if zName is not the name of a valid
--** system call.
--*/
--static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
--  int i = -1;
-+#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent)
- 
--  UNUSED_PARAMETER(p);
--  if( zName ){
--    for(i=0; i<ArraySize(aSyscall)-1; i++){
--      if( strcmp(zName, aSyscall[i].zName)==0 ) break;
--    }
--  }
--  for(i++; i<ArraySize(aSyscall); i++){
--    if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
--  }
--  return 0;
--}
-+  { "GetSystemTime",           (SYSCALL)GetSystemTime,           0 },
- 
--#ifdef SQLITE_WIN32_MALLOC
--/*
--** If a Win32 native heap has been configured, this function will attempt to
--** compact it.  Upon success, SQLITE_OK will be returned.  Upon failure, one
--** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned.  The
--** "pnLargest" argument, if non-zero, will be used to return the size of the
--** largest committed free block in the heap, in bytes.
--*/
--SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
--  int rc = SQLITE_OK;
--  UINT nLargest = 0;
--  HANDLE hHeap;
-+#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent)
- 
--  winMemAssertMagic();
--  hHeap = winMemGetHeap();
--  assert( hHeap!=0 );
--  assert( hHeap!=INVALID_HANDLE_VALUE );
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
--  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
--#endif
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
--  if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){
--    DWORD lastErrno = osGetLastError();
--    if( lastErrno==NO_ERROR ){
--      sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
--                  (void*)hHeap);
--      rc = SQLITE_NOMEM;
--    }else{
--      sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
--                  osGetLastError(), (void*)hHeap);
--      rc = SQLITE_ERROR;
--    }
--  }
-+#if !SQLITE_OS_WINCE
-+  { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
- #else
--  sqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p",
--              (void*)hHeap);
--  rc = SQLITE_NOTFOUND;
-+  { "GetSystemTimeAsFileTime", (SYSCALL)0,                       0 },
- #endif
--  if( pnLargest ) *pnLargest = nLargest;
--  return rc;
--}
--
--/*
--** If a Win32 native heap has been configured, this function will attempt to
--** destroy and recreate it.  If the Win32 native heap is not isolated and/or
--** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
--** be returned and no changes will be made to the Win32 native heap.
--*/
--SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
--  int rc;
--  MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
--  MUTEX_LOGIC( sqlite3_mutex *pMem; )    /* The memsys static mutex */
--  MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
--  MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
--  sqlite3_mutex_enter(pMaster);
--  sqlite3_mutex_enter(pMem);
--  winMemAssertMagic();
--  if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
--    /*
--    ** At this point, there should be no outstanding memory allocations on
--    ** the heap.  Also, since both the master and memsys locks are currently
--    ** being held by us, no other function (i.e. from another thread) should
--    ** be able to even access the heap.  Attempt to destroy and recreate our
--    ** isolated Win32 native heap now.
--    */
--    assert( winMemGetHeap()!=NULL );
--    assert( winMemGetOwned() );
--    assert( sqlite3_memory_used()==0 );
--    winMemShutdown(winMemGetDataPtr());
--    assert( winMemGetHeap()==NULL );
--    assert( !winMemGetOwned() );
--    assert( sqlite3_memory_used()==0 );
--    rc = winMemInit(winMemGetDataPtr());
--    assert( rc!=SQLITE_OK || winMemGetHeap()!=NULL );
--    assert( rc!=SQLITE_OK || winMemGetOwned() );
--    assert( rc!=SQLITE_OK || sqlite3_memory_used()==0 );
--  }else{
--    /*
--    ** The Win32 native heap cannot be modified because it may be in use.
--    */
--    rc = SQLITE_BUSY;
--  }
--  sqlite3_mutex_leave(pMem);
--  sqlite3_mutex_leave(pMaster);
--  return rc;
--}
--#endif /* SQLITE_WIN32_MALLOC */
- 
--/*
--** This function outputs the specified (ANSI) string to the Win32 debugger
--** (if available).
--*/
-+#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
-+        LPFILETIME))aSyscall[30].pCurrent)
- 
--SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int nBuf){
--  char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
--  int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
--  if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
--  assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
- #if defined(SQLITE_WIN32_HAS_ANSI)
--  if( nMin>0 ){
--    memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
--    memcpy(zDbgBuf, zBuf, nMin);
--    osOutputDebugStringA(zDbgBuf);
--  }else{
--    osOutputDebugStringA(zBuf);
--  }
--#elif defined(SQLITE_WIN32_HAS_WIDE)
--  memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
--  if ( osMultiByteToWideChar(
--          osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf,
--          nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){
--    return;
--  }
--  osOutputDebugStringW((LPCWSTR)zDbgBuf);
-+  { "GetTempPathA",            (SYSCALL)GetTempPathA,            0 },
- #else
--  if( nMin>0 ){
--    memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
--    memcpy(zDbgBuf, zBuf, nMin);
--    fprintf(stderr, "%s", zDbgBuf);
--  }else{
--    fprintf(stderr, "%s", zBuf);
--  }
-+  { "GetTempPathA",            (SYSCALL)0,                       0 },
++
++/* Mark a function parameter as unused, to suppress nuisance compiler
++** warnings. */
++#ifndef UNUSED_PARAM
++# define UNUSED_PARAM(X)  (void)(X)
++#endif
++
++#ifndef UNUSED_PARAM2
++# define UNUSED_PARAM2(X, Y)  (void)(X), (void)(Y)
++#endif
++
++typedef struct Fts5Global Fts5Global;
++typedef struct Fts5Colset Fts5Colset;
++
++/* If a NEAR() clump or phrase may only match a specific set of columns, 
++** then an object of the following type is used to record the set of columns.
++** Each entry in the aiCol[] array is a column that may be matched.
++**
++** This object is used by fts5_expr.c and fts5_index.c.
++*/
++struct Fts5Colset {
++  int nCol;
++  int aiCol[1];
++};
++
++
++
++/**************************************************************************
++** Interface to code in fts5_config.c. fts5_config.c contains contains code
++** to parse the arguments passed to the CREATE VIRTUAL TABLE statement.
++*/
++
++typedef struct Fts5Config Fts5Config;
++
++/*
++** An instance of the following structure encodes all information that can
++** be gleaned from the CREATE VIRTUAL TABLE statement.
++**
++** And all information loaded from the %_config table.
++**
++** nAutomerge:
++**   The minimum number of segments that an auto-merge operation should
++**   attempt to merge together. A value of 1 sets the object to use the 
++**   compile time default. Zero disables auto-merge altogether.
++**
++** zContent:
++**
++** zContentRowid:
++**   The value of the content_rowid= option, if one was specified. Or 
++**   the string "rowid" otherwise. This text is not quoted - if it is
++**   used as part of an SQL statement it needs to be quoted appropriately.
++**
++** zContentExprlist:
++**
++** pzErrmsg:
++**   This exists in order to allow the fts5_index.c module to return a 
++**   decent error message if it encounters a file-format version it does
++**   not understand.
++**
++** bColumnsize:
++**   True if the %_docsize table is created.
++**
++** bPrefixIndex:
++**   This is only used for debugging. If set to false, any prefix indexes
++**   are ignored. This value is configured using:
++**
++**       INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex);
++**
++*/
++struct Fts5Config {
++  sqlite3 *db;                    /* Database handle */
++  char *zDb;                      /* Database holding FTS index (e.g. "main") */
++  char *zName;                    /* Name of FTS index */
++  int nCol;                       /* Number of columns */
++  char **azCol;                   /* Column names */
++  u8 *abUnindexed;                /* True for unindexed columns */
++  int nPrefix;                    /* Number of prefix indexes */
++  int *aPrefix;                   /* Sizes in bytes of nPrefix prefix indexes */
++  int eContent;                   /* An FTS5_CONTENT value */
++  char *zContent;                 /* content table */ 
++  char *zContentRowid;            /* "content_rowid=" option value */ 
++  int bColumnsize;                /* "columnsize=" option value (dflt==1) */
++  int eDetail;                    /* FTS5_DETAIL_XXX value */
++  char *zContentExprlist;
++  Fts5Tokenizer *pTok;
++  fts5_tokenizer *pTokApi;
++
++  /* Values loaded from the %_config table */
++  int iCookie;                    /* Incremented when %_config is modified */
++  int pgsz;                       /* Approximate page size used in %_data */
++  int nAutomerge;                 /* 'automerge' setting */
++  int nCrisisMerge;               /* Maximum allowed segments per level */
++  int nUsermerge;                 /* 'usermerge' setting */
++  int nHashSize;                  /* Bytes of memory for in-memory hash */
++  char *zRank;                    /* Name of rank function */
++  char *zRankArgs;                /* Arguments to rank function */
++
++  /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
++  char **pzErrmsg;
++
++#ifdef SQLITE_DEBUG
++  int bPrefixIndex;               /* True to use prefix-indexes */
 +#endif
++};
++
++/* Current expected value of %_config table 'version' field */
++#define FTS5_CURRENT_VERSION 4
++
++#define FTS5_CONTENT_NORMAL   0
++#define FTS5_CONTENT_NONE     1
++#define FTS5_CONTENT_EXTERNAL 2
++
++#define FTS5_DETAIL_FULL    0
++#define FTS5_DETAIL_NONE    1
++#define FTS5_DETAIL_COLUMNS 2
++
++
++
++static int sqlite3Fts5ConfigParse(
++    Fts5Global*, sqlite3*, int, const char **, Fts5Config**, char**
++);
++static void sqlite3Fts5ConfigFree(Fts5Config*);
++
++static int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig);
++
++static int sqlite3Fts5Tokenize(
++  Fts5Config *pConfig,            /* FTS5 Configuration object */
++  int flags,                      /* FTS5_TOKENIZE_* flags */
++  const char *pText, int nText,   /* Text to tokenize */
++  void *pCtx,                     /* Context passed to xToken() */
++  int (*xToken)(void*, int, const char*, int, int, int)    /* Callback */
++);
++
++static void sqlite3Fts5Dequote(char *z);
++
++/* Load the contents of the %_config table */
++static int sqlite3Fts5ConfigLoad(Fts5Config*, int);
++
++/* Set the value of a single config attribute */
++static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, int*);
++
++static int sqlite3Fts5ConfigParseRank(const char*, char**, char**);
++
++/*
++** End of interface to code in fts5_config.c.
++**************************************************************************/
++
++/**************************************************************************
++** Interface to code in fts5_buffer.c.
++*/
++
++/*
++** Buffer object for the incremental building of string data.
++*/
++typedef struct Fts5Buffer Fts5Buffer;
++struct Fts5Buffer {
++  u8 *p;
++  int n;
++  int nSpace;
++};
++
++static int sqlite3Fts5BufferSize(int*, Fts5Buffer*, u32);
++static void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64);
++static void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, u32, const u8*);
++static void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*);
++static void sqlite3Fts5BufferFree(Fts5Buffer*);
++static void sqlite3Fts5BufferZero(Fts5Buffer*);
++static void sqlite3Fts5BufferSet(int*, Fts5Buffer*, int, const u8*);
++static void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...);
++
++static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
++
++#define fts5BufferZero(x)             sqlite3Fts5BufferZero(x)
++#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c)
++#define fts5BufferFree(a)             sqlite3Fts5BufferFree(a)
++#define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d)
++#define fts5BufferSet(a,b,c,d)        sqlite3Fts5BufferSet(a,b,c,d)
++
++#define fts5BufferGrow(pRc,pBuf,nn) ( \
++  (u32)((pBuf)->n) + (u32)(nn) <= (u32)((pBuf)->nSpace) ? 0 : \
++    sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \
++)
++
++/* Write and decode big-endian 32-bit integer values */
++static void sqlite3Fts5Put32(u8*, int);
++static int sqlite3Fts5Get32(const u8*);
++
++#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
++#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0xFFFFFFFF)
++
++typedef struct Fts5PoslistReader Fts5PoslistReader;
++struct Fts5PoslistReader {
++  /* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */
++  const u8 *a;                    /* Position list to iterate through */
++  int n;                          /* Size of buffer at a[] in bytes */
++  int i;                          /* Current offset in a[] */
++
++  u8 bFlag;                       /* For client use (any custom purpose) */
++
++  /* Output variables */
++  u8 bEof;                        /* Set to true at EOF */
++  i64 iPos;                       /* (iCol<<32) + iPos */
++};
++static int sqlite3Fts5PoslistReaderInit(
++  const u8 *a, int n,             /* Poslist buffer to iterate through */
++  Fts5PoslistReader *pIter        /* Iterator object to initialize */
++);
++static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader*);
 +
-+#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent)
++typedef struct Fts5PoslistWriter Fts5PoslistWriter;
++struct Fts5PoslistWriter {
++  i64 iPrev;
++};
++static int sqlite3Fts5PoslistWriterAppend(Fts5Buffer*, Fts5PoslistWriter*, i64);
++static void sqlite3Fts5PoslistSafeAppend(Fts5Buffer*, i64*, i64);
 +
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "GetTempPathW",            (SYSCALL)GetTempPathW,            0 },
-+#else
-+  { "GetTempPathW",            (SYSCALL)0,                       0 },
- #endif
--}
- 
--/*
--** The following routine suspends the current thread for at least ms
--** milliseconds.  This is equivalent to the Win32 Sleep() interface.
--*/
--#if SQLITE_OS_WINRT
--static HANDLE sleepObj = NULL;
-+#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent)
++static int sqlite3Fts5PoslistNext64(
++  const u8 *a, int n,             /* Buffer containing poslist */
++  int *pi,                        /* IN/OUT: Offset within a[] */
++  i64 *piOff                      /* IN/OUT: Current offset */
++);
 +
-+#if !SQLITE_OS_WINRT
-+  { "GetTickCount",            (SYSCALL)GetTickCount,            0 },
-+#else
-+  { "GetTickCount",            (SYSCALL)0,                       0 },
- #endif
- 
--SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds){
--#if SQLITE_OS_WINRT
--  if ( sleepObj==NULL ){
--    sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
--                                SYNCHRONIZE);
--  }
--  assert( sleepObj!=NULL );
--  osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
-+#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
++/* Malloc utility */
++static void *sqlite3Fts5MallocZero(int *pRc, int nByte);
++static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn);
 +
-+#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \
-+        SQLITE_WIN32_GETVERSIONEX
-+  { "GetVersionExA",           (SYSCALL)GetVersionExA,           0 },
- #else
--  osSleep(milliseconds);
-+  { "GetVersionExA",           (SYSCALL)0,                       0 },
- #endif
--}
- 
--#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
--        SQLITE_THREADSAFE>0
--SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
--  DWORD rc;
--  while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
--                                       TRUE))==WAIT_IO_COMPLETION ){}
--  return rc;
--}
-+#define osGetVersionExA ((BOOL(WINAPI*)( \
-+        LPOSVERSIONINFOA))aSyscall[34].pCurrent)
++/* Character set tests (like isspace(), isalpha() etc.) */
++static int sqlite3Fts5IsBareword(char t);
 +
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
-+        defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
-+  { "GetVersionExW",           (SYSCALL)GetVersionExW,           0 },
-+#else
-+  { "GetVersionExW",           (SYSCALL)0,                       0 },
- #endif
- 
--/*
--** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
--** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
--**
--** Here is an interesting observation:  Win95, Win98, and WinME lack
--** the LockFileEx() API.  But we can still statically link against that
--** API as long as we don't call it when running Win95/98/ME.  A call to
--** this routine is used to determine if the host is Win95/98/ME or
--** WinNT/2K/XP so that we will know whether or not we can safely call
--** the LockFileEx() API.
--*/
-+#define osGetVersionExW ((BOOL(WINAPI*)( \
-+        LPOSVERSIONINFOW))aSyscall[35].pCurrent)
- 
--#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX
--# define osIsNT()  (1)
--#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
--# define osIsNT()  (1)
--#elif !defined(SQLITE_WIN32_HAS_WIDE)
--# define osIsNT()  (0)
-+  { "HeapAlloc",               (SYSCALL)HeapAlloc,               0 },
-+
-+#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
-+        SIZE_T))aSyscall[36].pCurrent)
-+
-+#if !SQLITE_OS_WINRT
-+  { "HeapCreate",              (SYSCALL)HeapCreate,              0 },
- #else
--# define osIsNT()  ((sqlite3_os_type==2) || sqlite3_win32_is_nt())
-+  { "HeapCreate",              (SYSCALL)0,                       0 },
- #endif
- 
--/*
--** This function determines if the machine is running a version of Windows
--** based on the NT kernel.
--*/
--SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){
--#if SQLITE_OS_WINRT
--  /*
--  ** NOTE: The WinRT sub-platform is always assumed to be based on the NT
--  **       kernel.
--  */
--  return 1;
--#elif defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
--  if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){
--#if defined(SQLITE_WIN32_HAS_ANSI)
--    OSVERSIONINFOA sInfo;
--    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
--    osGetVersionExA(&sInfo);
--    osInterlockedCompareExchange(&sqlite3_os_type,
--        (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
--#elif defined(SQLITE_WIN32_HAS_WIDE)
--    OSVERSIONINFOW sInfo;
--    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
--    osGetVersionExW(&sInfo);
--    osInterlockedCompareExchange(&sqlite3_os_type,
--        (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
-+#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
-+        SIZE_T))aSyscall[37].pCurrent)
-+
-+#if !SQLITE_OS_WINRT
-+  { "HeapDestroy",             (SYSCALL)HeapDestroy,             0 },
-+#else
-+  { "HeapDestroy",             (SYSCALL)0,                       0 },
- #endif
--  }
--  return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
--#elif SQLITE_TEST
--  return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
 +
-+#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent)
++/* Bucket of terms object used by the integrity-check in offsets=0 mode. */
++typedef struct Fts5Termset Fts5Termset;
++static int sqlite3Fts5TermsetNew(Fts5Termset**);
++static int sqlite3Fts5TermsetAdd(Fts5Termset*, int, const char*, int, int *pbPresent);
++static void sqlite3Fts5TermsetFree(Fts5Termset*);
 +
-+  { "HeapFree",                (SYSCALL)HeapFree,                0 },
++/*
++** End of interface to code in fts5_buffer.c.
++**************************************************************************/
 +
-+#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent)
++/**************************************************************************
++** Interface to code in fts5_index.c. fts5_index.c contains contains code
++** to access the data stored in the %_data table.
++*/
 +
-+  { "HeapReAlloc",             (SYSCALL)HeapReAlloc,             0 },
++typedef struct Fts5Index Fts5Index;
++typedef struct Fts5IndexIter Fts5IndexIter;
 +
-+#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
-+        SIZE_T))aSyscall[40].pCurrent)
++struct Fts5IndexIter {
++  i64 iRowid;
++  const u8 *pData;
++  int nData;
++  u8 bEof;
++};
 +
-+  { "HeapSize",                (SYSCALL)HeapSize,                0 },
++#define sqlite3Fts5IterEof(x) ((x)->bEof)
 +
-+#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
-+        LPCVOID))aSyscall[41].pCurrent)
++/*
++** Values used as part of the flags argument passed to IndexQuery().
++*/
++#define FTS5INDEX_QUERY_PREFIX     0x0001   /* Prefix query */
++#define FTS5INDEX_QUERY_DESC       0x0002   /* Docs in descending rowid order */
++#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004   /* Do not use prefix index */
++#define FTS5INDEX_QUERY_SCAN       0x0008   /* Scan query (fts5vocab) */
 +
-+#if !SQLITE_OS_WINRT
-+  { "HeapValidate",            (SYSCALL)HeapValidate,            0 },
- #else
--  /*
--  ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are
--  **       deprecated are always assumed to be based on the NT kernel.
--  */
--  return 1;
-+  { "HeapValidate",            (SYSCALL)0,                       0 },
- #endif
--}
- 
--#ifdef SQLITE_WIN32_MALLOC
--/*
--** Allocate nBytes of memory.
--*/
--static void *winMemMalloc(int nBytes){
--  HANDLE hHeap;
--  void *p;
-+#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
-+        LPCVOID))aSyscall[42].pCurrent)
- 
--  winMemAssertMagic();
--  hHeap = winMemGetHeap();
--  assert( hHeap!=0 );
--  assert( hHeap!=INVALID_HANDLE_VALUE );
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
--  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-+  { "HeapCompact",             (SYSCALL)HeapCompact,             0 },
-+#else
-+  { "HeapCompact",             (SYSCALL)0,                       0 },
- #endif
--  assert( nBytes>=0 );
--  p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
--  if( !p ){
--    sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p",
--                nBytes, osGetLastError(), (void*)hHeap);
--  }
--  return p;
--}
- 
--/*
--** Free memory.
--*/
--static void winMemFree(void *pPrior){
--  HANDLE hHeap;
-+#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent)
- 
--  winMemAssertMagic();
--  hHeap = winMemGetHeap();
--  assert( hHeap!=0 );
--  assert( hHeap!=INVALID_HANDLE_VALUE );
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
--  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
-+#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
-+  { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
-+#else
-+  { "LoadLibraryA",            (SYSCALL)0,                       0 },
- #endif
--  if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
--  if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
--    sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p",
--                pPrior, osGetLastError(), (void*)hHeap);
--  }
--}
- 
--/*
--** Change the size of an existing memory allocation
--*/
--static void *winMemRealloc(void *pPrior, int nBytes){
--  HANDLE hHeap;
--  void *p;
-+#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent)
- 
--  winMemAssertMagic();
--  hHeap = winMemGetHeap();
--  assert( hHeap!=0 );
--  assert( hHeap!=INVALID_HANDLE_VALUE );
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
--  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
-+        !defined(SQLITE_OMIT_LOAD_EXTENSION)
-+  { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
-+#else
-+  { "LoadLibraryW",            (SYSCALL)0,                       0 },
- #endif
--  assert( nBytes>=0 );
--  if( !pPrior ){
--    p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
--  }else{
--    p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
--  }
--  if( !p ){
--    sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p",
--                pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(),
--                (void*)hHeap);
--  }
--  return p;
--}
- 
--/*
--** Return the size of an outstanding allocation, in bytes.
--*/
--static int winMemSize(void *p){
--  HANDLE hHeap;
--  SIZE_T n;
-+#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent)
- 
--  winMemAssertMagic();
--  hHeap = winMemGetHeap();
--  assert( hHeap!=0 );
--  assert( hHeap!=INVALID_HANDLE_VALUE );
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
--  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) );
-+#if !SQLITE_OS_WINRT
-+  { "LocalFree",               (SYSCALL)LocalFree,               0 },
-+#else
-+  { "LocalFree",               (SYSCALL)0,                       0 },
- #endif
--  if( !p ) return 0;
--  n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
--  if( n==(SIZE_T)-1 ){
--    sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p",
--                p, osGetLastError(), (void*)hHeap);
--    return 0;
--  }
--  return (int)n;
--}
- 
--/*
--** Round up a request size to the next valid allocation size.
--*/
--static int winMemRoundup(int n){
--  return n;
--}
-+#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent)
- 
--/*
--** Initialize this module.
--*/
--static int winMemInit(void *pAppData){
--  winMemData *pWinMemData = (winMemData *)pAppData;
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-+  { "LockFile",                (SYSCALL)LockFile,                0 },
-+#else
-+  { "LockFile",                (SYSCALL)0,                       0 },
-+#endif
- 
--  if( !pWinMemData ) return SQLITE_ERROR;
--  assert( pWinMemData->magic1==WINMEM_MAGIC1 );
--  assert( pWinMemData->magic2==WINMEM_MAGIC2 );
-+#ifndef osLockFile
-+#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
-+        DWORD))aSyscall[47].pCurrent)
-+#endif
- 
--#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
--  if( !pWinMemData->hHeap ){
--    DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE;
--    DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap;
--    if( dwMaximumSize==0 ){
--      dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE;
--    }else if( dwInitialSize>dwMaximumSize ){
--      dwInitialSize = dwMaximumSize;
--    }
--    pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
--                                      dwInitialSize, dwMaximumSize);
--    if( !pWinMemData->hHeap ){
--      sqlite3_log(SQLITE_NOMEM,
--          "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
--          osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
--          dwMaximumSize);
--      return SQLITE_NOMEM;
--    }
--    pWinMemData->bOwned = TRUE;
--    assert( pWinMemData->bOwned );
--  }
-+#if !SQLITE_OS_WINCE
-+  { "LockFileEx",              (SYSCALL)LockFileEx,              0 },
- #else
--  pWinMemData->hHeap = osGetProcessHeap();
--  if( !pWinMemData->hHeap ){
--    sqlite3_log(SQLITE_NOMEM,
--        "failed to GetProcessHeap (%lu)", osGetLastError());
--    return SQLITE_NOMEM;
--  }
--  pWinMemData->bOwned = FALSE;
--  assert( !pWinMemData->bOwned );
-+  { "LockFileEx",              (SYSCALL)0,                       0 },
- #endif
--  assert( pWinMemData->hHeap!=0 );
--  assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
--  assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
++/* The following are used internally by the fts5_index.c module. They are
++** defined here only to make it easier to avoid clashes with the flags
++** above. */
++#define FTS5INDEX_QUERY_SKIPEMPTY  0x0010
++#define FTS5INDEX_QUERY_NOOUTPUT   0x0020
 +
-+#ifndef osLockFileEx
-+#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
-+        LPOVERLAPPED))aSyscall[48].pCurrent)
- #endif
--  return SQLITE_OK;
--}
- 
--/*
--** Deinitialize this module.
--*/
--static void winMemShutdown(void *pAppData){
--  winMemData *pWinMemData = (winMemData *)pAppData;
-+#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \
-+        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
-+  { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
-+#else
-+  { "MapViewOfFile",           (SYSCALL)0,                       0 },
-+#endif
- 
--  if( !pWinMemData ) return;
--  assert( pWinMemData->magic1==WINMEM_MAGIC1 );
--  assert( pWinMemData->magic2==WINMEM_MAGIC2 );
-+#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
-+        SIZE_T))aSyscall[49].pCurrent)
- 
--  if( pWinMemData->hHeap ){
--    assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
--    assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
-+  { "MultiByteToWideChar",     (SYSCALL)MultiByteToWideChar,     0 },
++/*
++** Create/destroy an Fts5Index object.
++*/
++static int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**);
++static int sqlite3Fts5IndexClose(Fts5Index *p);
++
++/*
++** Return a simple checksum value based on the arguments.
++*/
++static u64 sqlite3Fts5IndexEntryCksum(
++  i64 iRowid, 
++  int iCol, 
++  int iPos, 
++  int iIdx,
++  const char *pTerm,
++  int nTerm
++);
++
++/*
++** Argument p points to a buffer containing utf-8 text that is n bytes in 
++** size. Return the number of bytes in the nChar character prefix of the
++** buffer, or 0 if there are less than nChar characters in total.
++*/
++static int sqlite3Fts5IndexCharlenToBytelen(
++  const char *p, 
++  int nByte, 
++  int nChar
++);
++
++/*
++** Open a new iterator to iterate though all rowids that match the 
++** specified token or token prefix.
++*/
++static int sqlite3Fts5IndexQuery(
++  Fts5Index *p,                   /* FTS index to query */
++  const char *pToken, int nToken, /* Token (or prefix) to query for */
++  int flags,                      /* Mask of FTS5INDEX_QUERY_X flags */
++  Fts5Colset *pColset,            /* Match these columns only */
++  Fts5IndexIter **ppIter          /* OUT: New iterator object */
++);
++
++/*
++** The various operations on open token or token prefix iterators opened
++** using sqlite3Fts5IndexQuery().
++*/
++static int sqlite3Fts5IterNext(Fts5IndexIter*);
++static int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
++
++/*
++** Close an iterator opened by sqlite3Fts5IndexQuery().
++*/
++static void sqlite3Fts5IterClose(Fts5IndexIter*);
++
++/*
++** This interface is used by the fts5vocab module.
++*/
++static const char *sqlite3Fts5IterTerm(Fts5IndexIter*, int*);
++static int sqlite3Fts5IterNextScan(Fts5IndexIter*);
++
++
++/*
++** Insert or remove data to or from the index. Each time a document is 
++** added to or removed from the index, this function is called one or more
++** times.
++**
++** For an insert, it must be called once for each token in the new document.
++** If the operation is a delete, it must be called (at least) once for each
++** unique token in the document with an iCol value less than zero. The iPos
++** argument is ignored for a delete.
++*/
++static int sqlite3Fts5IndexWrite(
++  Fts5Index *p,                   /* Index to write to */
++  int iCol,                       /* Column token appears in (-ve -> delete) */
++  int iPos,                       /* Position of token within column */
++  const char *pToken, int nToken  /* Token to add or remove to or from index */
++);
++
++/*
++** Indicate that subsequent calls to sqlite3Fts5IndexWrite() pertain to
++** document iDocid.
++*/
++static int sqlite3Fts5IndexBeginWrite(
++  Fts5Index *p,                   /* Index to write to */
++  int bDelete,                    /* True if current operation is a delete */
++  i64 iDocid                      /* Docid to add or remove data from */
++);
++
++/*
++** Flush any data stored in the in-memory hash tables to the database.
++** Also close any open blob handles.
++*/
++static int sqlite3Fts5IndexSync(Fts5Index *p);
++
++/*
++** Discard any data stored in the in-memory hash tables. Do not write it
++** to the database. Additionally, assume that the contents of the %_data
++** table may have changed on disk. So any in-memory caches of %_data 
++** records must be invalidated.
++*/
++static int sqlite3Fts5IndexRollback(Fts5Index *p);
++
++/*
++** Get or set the "averages" values.
++*/
++static int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize);
++static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int);
++
++/*
++** Functions called by the storage module as part of integrity-check.
++*/
++static int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum);
++
++/* 
++** Called during virtual module initialization to register UDF 
++** fts5_decode() with SQLite 
++*/
++static int sqlite3Fts5IndexInit(sqlite3*);
++
++static int sqlite3Fts5IndexSetCookie(Fts5Index*, int);
++
++/*
++** Return the total number of entries read from the %_data table by 
++** this connection since it was created.
++*/
++static int sqlite3Fts5IndexReads(Fts5Index *p);
++
++static int sqlite3Fts5IndexReinit(Fts5Index *p);
++static int sqlite3Fts5IndexOptimize(Fts5Index *p);
++static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
++static int sqlite3Fts5IndexReset(Fts5Index *p);
++
++static int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
++
++/*
++** End of interface to code in fts5_index.c.
++**************************************************************************/
++
++/**************************************************************************
++** Interface to code in fts5_varint.c. 
++*/
++static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v);
++static int sqlite3Fts5GetVarintLen(u32 iVal);
++static u8 sqlite3Fts5GetVarint(const unsigned char*, u64*);
++static int sqlite3Fts5PutVarint(unsigned char *p, u64 v);
++
++#define fts5GetVarint32(a,b) sqlite3Fts5GetVarint32(a,(u32*)&b)
++#define fts5GetVarint    sqlite3Fts5GetVarint
++
++#define fts5FastGetVarint32(a, iOff, nVal) {      \
++  nVal = (a)[iOff++];                             \
++  if( nVal & 0x80 ){                              \
++    iOff--;                                       \
++    iOff += fts5GetVarint32(&(a)[iOff], nVal);    \
++  }                                               \
++}
++
++
++/*
++** End of interface to code in fts5_varint.c.
++**************************************************************************/
++
++
++/**************************************************************************
++** Interface to code in fts5.c. 
++*/
++
++static int sqlite3Fts5GetTokenizer(
++  Fts5Global*, 
++  const char **azArg,
++  int nArg,
++  Fts5Tokenizer**,
++  fts5_tokenizer**,
++  char **pzErr
++);
++
++static Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, Fts5Config **);
++
++/*
++** End of interface to code in fts5.c.
++**************************************************************************/
++
++/**************************************************************************
++** Interface to code in fts5_hash.c. 
++*/
++typedef struct Fts5Hash Fts5Hash;
++
++/*
++** Create a hash table, free a hash table.
++*/
++static int sqlite3Fts5HashNew(Fts5Config*, Fts5Hash**, int *pnSize);
++static void sqlite3Fts5HashFree(Fts5Hash*);
++
++static int sqlite3Fts5HashWrite(
++  Fts5Hash*,
++  i64 iRowid,                     /* Rowid for this entry */
++  int iCol,                       /* Column token appears in (-ve -> delete) */
++  int iPos,                       /* Position of token within column */
++  char bByte,
++  const char *pToken, int nToken  /* Token to add or remove to or from index */
++);
++
++/*
++** Empty (but do not delete) a hash table.
++*/
++static void sqlite3Fts5HashClear(Fts5Hash*);
++
++static int sqlite3Fts5HashQuery(
++  Fts5Hash*,                      /* Hash table to query */
++  const char *pTerm, int nTerm,   /* Query term */
++  const u8 **ppDoclist,           /* OUT: Pointer to doclist for pTerm */
++  int *pnDoclist                  /* OUT: Size of doclist in bytes */
++);
++
++static int sqlite3Fts5HashScanInit(
++  Fts5Hash*,                      /* Hash table to query */
++  const char *pTerm, int nTerm    /* Query prefix */
++);
++static void sqlite3Fts5HashScanNext(Fts5Hash*);
++static int sqlite3Fts5HashScanEof(Fts5Hash*);
++static void sqlite3Fts5HashScanEntry(Fts5Hash *,
++  const char **pzTerm,            /* OUT: term (nul-terminated) */
++  const u8 **ppDoclist,           /* OUT: pointer to doclist */
++  int *pnDoclist                  /* OUT: size of doclist in bytes */
++);
++
++
++/*
++** End of interface to code in fts5_hash.c.
++**************************************************************************/
++
++/**************************************************************************
++** Interface to code in fts5_storage.c. fts5_storage.c contains contains 
++** code to access the data stored in the %_content and %_docsize tables.
++*/
++
++#define FTS5_STMT_SCAN_ASC  0     /* SELECT rowid, * FROM ... ORDER BY 1 ASC */
++#define FTS5_STMT_SCAN_DESC 1     /* SELECT rowid, * FROM ... ORDER BY 1 DESC */
++#define FTS5_STMT_LOOKUP    2     /* SELECT rowid, * FROM ... WHERE rowid=? */
++
++typedef struct Fts5Storage Fts5Storage;
++
++static int sqlite3Fts5StorageOpen(Fts5Config*, Fts5Index*, int, Fts5Storage**, char**);
++static int sqlite3Fts5StorageClose(Fts5Storage *p);
++static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName);
++
++static int sqlite3Fts5DropAll(Fts5Config*);
++static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **);
++
++static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**);
++static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
++static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
++
++static int sqlite3Fts5StorageIntegrity(Fts5Storage *p);
++
++static int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**);
++static void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*);
++
++static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol);
++static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg);
++static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow);
++
++static int sqlite3Fts5StorageSync(Fts5Storage *p);
++static int sqlite3Fts5StorageRollback(Fts5Storage *p);
++
++static int sqlite3Fts5StorageConfigValue(
++    Fts5Storage *p, const char*, sqlite3_value*, int
++);
++
++static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p);
++static int sqlite3Fts5StorageRebuild(Fts5Storage *p);
++static int sqlite3Fts5StorageOptimize(Fts5Storage *p);
++static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge);
++static int sqlite3Fts5StorageReset(Fts5Storage *p);
++
++/*
++** End of interface to code in fts5_storage.c.
++**************************************************************************/
++
++
++/**************************************************************************
++** Interface to code in fts5_expr.c. 
++*/
++typedef struct Fts5Expr Fts5Expr;
++typedef struct Fts5ExprNode Fts5ExprNode;
++typedef struct Fts5Parse Fts5Parse;
++typedef struct Fts5Token Fts5Token;
++typedef struct Fts5ExprPhrase Fts5ExprPhrase;
++typedef struct Fts5ExprNearset Fts5ExprNearset;
++
++struct Fts5Token {
++  const char *p;                  /* Token text (not NULL terminated) */
++  int n;                          /* Size of buffer p in bytes */
++};
++
++/* Parse a MATCH expression. */
++static int sqlite3Fts5ExprNew(
++  Fts5Config *pConfig, 
++  int iCol,                       /* Column on LHS of MATCH operator */
++  const char *zExpr,
++  Fts5Expr **ppNew, 
++  char **pzErr
++);
++
++/*
++** for(rc = sqlite3Fts5ExprFirst(pExpr, pIdx, bDesc);
++**     rc==SQLITE_OK && 0==sqlite3Fts5ExprEof(pExpr);
++**     rc = sqlite3Fts5ExprNext(pExpr)
++** ){
++**   // The document with rowid iRowid matches the expression!
++**   i64 iRowid = sqlite3Fts5ExprRowid(pExpr);
++** }
++*/
++static int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, int bDesc);
++static int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax);
++static int sqlite3Fts5ExprEof(Fts5Expr*);
++static i64 sqlite3Fts5ExprRowid(Fts5Expr*);
++
++static void sqlite3Fts5ExprFree(Fts5Expr*);
++
++/* Called during startup to register a UDF with SQLite */
++static int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*);
++
++static int sqlite3Fts5ExprPhraseCount(Fts5Expr*);
++static int sqlite3Fts5ExprPhraseSize(Fts5Expr*, int iPhrase);
++static int sqlite3Fts5ExprPoslist(Fts5Expr*, int, const u8 **);
++
++typedef struct Fts5PoslistPopulator Fts5PoslistPopulator;
++static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr*, int);
++static int sqlite3Fts5ExprPopulatePoslists(
++    Fts5Config*, Fts5Expr*, Fts5PoslistPopulator*, int, const char*, int
++);
++static void sqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64);
++
++static int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**);
++
++static int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *);
++
++/*******************************************
++** The fts5_expr.c API above this point is used by the other hand-written
++** C code in this module. The interfaces below this point are called by
++** the parser code in fts5parse.y.  */
++
++static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...);
++
++static Fts5ExprNode *sqlite3Fts5ParseNode(
++  Fts5Parse *pParse,
++  int eType,
++  Fts5ExprNode *pLeft,
++  Fts5ExprNode *pRight,
++  Fts5ExprNearset *pNear
++);
++
++static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
++  Fts5Parse *pParse,
++  Fts5ExprNode *pLeft,
++  Fts5ExprNode *pRight
++);
++
++static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
++  Fts5Parse *pParse, 
++  Fts5ExprPhrase *pPhrase, 
++  Fts5Token *pToken,
++  int bPrefix
++);
++
++static Fts5ExprNearset *sqlite3Fts5ParseNearset(
++  Fts5Parse*, 
++  Fts5ExprNearset*,
++  Fts5ExprPhrase* 
++);
++
++static Fts5Colset *sqlite3Fts5ParseColset(
++  Fts5Parse*, 
++  Fts5Colset*, 
++  Fts5Token *
++);
++
++static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase*);
++static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*);
++static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*);
++
++static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*);
++static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNode*, Fts5Colset*);
++static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*);
++static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p);
++static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*);
++
++/*
++** End of interface to code in fts5_expr.c.
++**************************************************************************/
++
++
++
++/**************************************************************************
++** Interface to code in fts5_aux.c. 
++*/
++
++static int sqlite3Fts5AuxInit(fts5_api*);
++/*
++** End of interface to code in fts5_aux.c.
++**************************************************************************/
 +
-+#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
-+        int))aSyscall[50].pCurrent)
++/**************************************************************************
++** Interface to code in fts5_tokenizer.c. 
++*/
 +
-+  { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
++static int sqlite3Fts5TokenizerInit(fts5_api*);
++/*
++** End of interface to code in fts5_tokenizer.c.
++**************************************************************************/
 +
-+#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
-+        LARGE_INTEGER*))aSyscall[51].pCurrent)
++/**************************************************************************
++** Interface to code in fts5_vocab.c. 
++*/
 +
-+  { "ReadFile",                (SYSCALL)ReadFile,                0 },
++static int sqlite3Fts5VocabInit(Fts5Global*, sqlite3*);
 +
-+#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
-+        LPOVERLAPPED))aSyscall[52].pCurrent)
++/*
++** End of interface to code in fts5_vocab.c.
++**************************************************************************/
 +
-+  { "SetEndOfFile",            (SYSCALL)SetEndOfFile,            0 },
 +
-+#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent)
++/**************************************************************************
++** Interface to automatically generated code in fts5_unicode2.c. 
++*/
++static int sqlite3Fts5UnicodeIsalnum(int c);
++static int sqlite3Fts5UnicodeIsdiacritic(int c);
++static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
++/*
++** End of interface to code in fts5_unicode2.c.
++**************************************************************************/
 +
-+#if !SQLITE_OS_WINRT
-+  { "SetFilePointer",          (SYSCALL)SetFilePointer,          0 },
-+#else
-+  { "SetFilePointer",          (SYSCALL)0,                       0 },
- #endif
--    if( pWinMemData->bOwned ){
--      if( !osHeapDestroy(pWinMemData->hHeap) ){
--        sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p",
--                    osGetLastError(), (void*)pWinMemData->hHeap);
--      }
--      pWinMemData->bOwned = FALSE;
--    }
--    pWinMemData->hHeap = NULL;
--  }
--}
- 
--/*
--** Populate the low-level memory allocation function pointers in
--** sqlite3GlobalConfig.m with pointers to the routines in this file. The
--** arguments specify the block of memory to manage.
--**
--** This routine is only called by sqlite3_config(), and therefore
--** is not required to be threadsafe (it is not).
--*/
--SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void){
--  static const sqlite3_mem_methods winMemMethods = {
--    winMemMalloc,
--    winMemFree,
--    winMemRealloc,
--    winMemSize,
--    winMemRoundup,
--    winMemInit,
--    winMemShutdown,
--    &win_mem_data
--  };
--  return &winMemMethods;
--}
-+#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
-+        DWORD))aSyscall[54].pCurrent)
- 
--SQLITE_PRIVATE void sqlite3MemSetDefault(void){
--  sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32());
--}
--#endif /* SQLITE_WIN32_MALLOC */
-+#if !SQLITE_OS_WINRT
-+  { "Sleep",                   (SYSCALL)Sleep,                   0 },
-+#else
-+  { "Sleep",                   (SYSCALL)0,                       0 },
-+#endif
- 
--/*
--** Convert a UTF-8 string to Microsoft Unicode (UTF-16?).
--**
--** Space to hold the returned string is obtained from malloc.
--*/
--static LPWSTR winUtf8ToUnicode(const char *zFilename){
--  int nChar;
--  LPWSTR zWideFilename;
-+#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent)
- 
--  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
--  if( nChar==0 ){
--    return 0;
--  }
--  zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
--  if( zWideFilename==0 ){
--    return 0;
--  }
--  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
--                                nChar);
--  if( nChar==0 ){
--    sqlite3_free(zWideFilename);
--    zWideFilename = 0;
--  }
--  return zWideFilename;
--}
-+  { "SystemTimeToFileTime",    (SYSCALL)SystemTimeToFileTime,    0 },
- 
--/*
--** Convert Microsoft Unicode to UTF-8.  Space to hold the returned string is
--** obtained from sqlite3_malloc().
--*/
--static char *winUnicodeToUtf8(LPCWSTR zWideFilename){
--  int nByte;
--  char *zFilename;
-+#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
-+        LPFILETIME))aSyscall[56].pCurrent)
- 
--  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
--  if( nByte == 0 ){
--    return 0;
--  }
--  zFilename = sqlite3MallocZero( nByte );
--  if( zFilename==0 ){
--    return 0;
--  }
--  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
--                                0, 0);
--  if( nByte == 0 ){
--    sqlite3_free(zFilename);
--    zFilename = 0;
--  }
--  return zFilename;
--}
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-+  { "UnlockFile",              (SYSCALL)UnlockFile,              0 },
-+#else
-+  { "UnlockFile",              (SYSCALL)0,                       0 },
-+#endif
- 
--/*
--** Convert an ANSI string to Microsoft Unicode, based on the
--** current codepage settings for file apis.
--**
--** Space to hold the returned string is obtained
--** from sqlite3_malloc.
--*/
--static LPWSTR winMbcsToUnicode(const char *zFilename){
--  int nByte;
--  LPWSTR zMbcsFilename;
--  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
-+#ifndef osUnlockFile
-+#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
-+        DWORD))aSyscall[57].pCurrent)
-+#endif
- 
--  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
--                                0)*sizeof(WCHAR);
--  if( nByte==0 ){
--    return 0;
--  }
--  zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
--  if( zMbcsFilename==0 ){
--    return 0;
--  }
--  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
--                                nByte);
--  if( nByte==0 ){
--    sqlite3_free(zMbcsFilename);
--    zMbcsFilename = 0;
--  }
--  return zMbcsFilename;
--}
-+#if !SQLITE_OS_WINCE
-+  { "UnlockFileEx",            (SYSCALL)UnlockFileEx,            0 },
-+#else
-+  { "UnlockFileEx",            (SYSCALL)0,                       0 },
 +#endif
- 
--/*
--** Convert Microsoft Unicode to multi-byte character string, based on the
--** user's ANSI codepage.
--**
--** Space to hold the returned string is obtained from
--** sqlite3_malloc().
--*/
--static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
--  int nByte;
--  char *zFilename;
--  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
-+#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
-+        LPOVERLAPPED))aSyscall[58].pCurrent)
 +
-+#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
-+  { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
-+#else
-+  { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
-+#endif
++#define FTS5_OR                               1
++#define FTS5_AND                              2
++#define FTS5_NOT                              3
++#define FTS5_TERM                             4
++#define FTS5_COLON                            5
++#define FTS5_MINUS                            6
++#define FTS5_LCP                              7
++#define FTS5_RCP                              8
++#define FTS5_STRING                           9
++#define FTS5_LP                              10
++#define FTS5_RP                              11
++#define FTS5_COMMA                           12
++#define FTS5_PLUS                            13
++#define FTS5_STAR                            14
 +
-+#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)
++/*
++** 2000-05-29
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** Driver template for the LEMON parser generator.
++**
++** The "lemon" program processes an LALR(1) input grammar file, then uses
++** this template to construct a parser.  The "lemon" program inserts text
++** at each "%%" line.  Also, any "P-a-r-s-e" identifer prefix (without the
++** interstitial "-" characters) contained in this template is changed into
++** the value of the %name directive from the grammar.  Otherwise, the content
++** of this template is copied straight through into the generate parser
++** source file.
++**
++** The following is the concatenation of all %include directives from the
++** input grammar file:
++*/
++/* #include <stdio.h> */
++/************ Begin %include sections from the grammar ************************/
 +
-+  { "WideCharToMultiByte",     (SYSCALL)WideCharToMultiByte,     0 },
- 
--  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
--  if( nByte == 0 ){
--    return 0;
--  }
--  zFilename = sqlite3MallocZero( nByte );
--  if( zFilename==0 ){
--    return 0;
--  }
--  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename,
--                                nByte, 0, 0);
--  if( nByte == 0 ){
--    sqlite3_free(zFilename);
--    zFilename = 0;
--  }
--  return zFilename;
--}
-+#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
-+        LPCSTR,LPBOOL))aSyscall[60].pCurrent)
- 
--/*
--** Convert multibyte character string to UTF-8.  Space to hold the
--** returned string is obtained from sqlite3_malloc().
--*/
--SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename){
--  char *zFilenameUtf8;
--  LPWSTR zTmpWide;
-+  { "WriteFile",               (SYSCALL)WriteFile,               0 },
- 
--  zTmpWide = winMbcsToUnicode(zFilename);
--  if( zTmpWide==0 ){
--    return 0;
--  }
--  zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
--  sqlite3_free(zTmpWide);
--  return zFilenameUtf8;
--}
-+#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
-+        LPOVERLAPPED))aSyscall[61].pCurrent)
- 
--/*
--** Convert UTF-8 to multibyte character string.  Space to hold the
--** returned string is obtained from sqlite3_malloc().
--*/
--SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename){
--  char *zFilenameMbcs;
--  LPWSTR zTmpWide;
-+#if SQLITE_OS_WINRT
-+  { "CreateEventExW",          (SYSCALL)CreateEventExW,          0 },
-+#else
-+  { "CreateEventExW",          (SYSCALL)0,                       0 },
-+#endif
- 
--  zTmpWide = winUtf8ToUnicode(zFilename);
--  if( zTmpWide==0 ){
--    return 0;
--  }
--  zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
--  sqlite3_free(zTmpWide);
--  return zFilenameMbcs;
--}
-+#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
-+        DWORD,DWORD))aSyscall[62].pCurrent)
- 
--/*
--** This function sets the data directory or the temporary directory based on
--** the provided arguments.  The type argument must be 1 in order to set the
--** data directory or 2 in order to set the temporary directory.  The zValue
--** argument is the name of the directory to use.  The return value will be
--** SQLITE_OK if successful.
--*/
--SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
--  char **ppDirectory = 0;
--#ifndef SQLITE_OMIT_AUTOINIT
--  int rc = sqlite3_initialize();
--  if( rc ) return rc;
-+#if !SQLITE_OS_WINRT
-+  { "WaitForSingleObject",     (SYSCALL)WaitForSingleObject,     0 },
-+#else
-+  { "WaitForSingleObject",     (SYSCALL)0,                       0 },
- #endif
--  if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
--    ppDirectory = &sqlite3_data_directory;
--  }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){
--    ppDirectory = &sqlite3_temp_directory;
--  }
--  assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE
--          || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE
--  );
--  assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
--  if( ppDirectory ){
--    char *zValueUtf8 = 0;
--    if( zValue && zValue[0] ){
--      zValueUtf8 = winUnicodeToUtf8(zValue);
--      if ( zValueUtf8==0 ){
--        return SQLITE_NOMEM;
--      }
--    }
--    sqlite3_free(*ppDirectory);
--    *ppDirectory = zValueUtf8;
--    return SQLITE_OK;
--  }
--  return SQLITE_ERROR;
--}
- 
--/*
--** The return value of winGetLastErrorMsg
--** is zero if the error message fits in the buffer, or non-zero
--** otherwise (if the message was truncated).
--*/
--static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
--  /* FormatMessage returns 0 on failure.  Otherwise it
--  ** returns the number of TCHARs written to the output
--  ** buffer, excluding the terminating null char.
--  */
--  DWORD dwLen = 0;
--  char *zOut = 0;
-+#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
-+        DWORD))aSyscall[63].pCurrent)
++/* #include "fts5Int.h" */
++/* #include "fts5parse.h" */
 +
-+#if !SQLITE_OS_WINCE
-+  { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
-+#else
-+  { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
++/*
++** Disable all error recovery processing in the parser push-down
++** automaton.
++*/
++#define fts5YYNOERRORRECOVERY 1
++
++/*
++** Make fts5yytestcase() the same as testcase()
++*/
++#define fts5yytestcase(X) testcase(X)
++
++/*
++** Indicate that sqlite3ParserFree() will never be called with a null
++** pointer.
++*/
++#define fts5YYPARSEFREENOTNULL 1
++
++/*
++** Alternative datatype for the argument to the malloc() routine passed
++** into sqlite3ParserAlloc().  The default is size_t.
++*/
++#define fts5YYMALLOCARGTYPE  u64
++
++/**************** End of %include directives **********************************/
++/* These constants specify the various numeric values for terminal symbols
++** in a format understandable to "makeheaders".  This section is blank unless
++** "lemon" is run with the "-m" command-line option.
++***************** Begin makeheaders token definitions *************************/
++/**************** End makeheaders token definitions ***************************/
++
++/* The next sections is a series of control #defines.
++** various aspects of the generated parser.
++**    fts5YYCODETYPE         is the data type used to store the integer codes
++**                       that represent terminal and non-terminal symbols.
++**                       "unsigned char" is used if there are fewer than
++**                       256 symbols.  Larger types otherwise.
++**    fts5YYNOCODE           is a number of type fts5YYCODETYPE that is not used for
++**                       any terminal or nonterminal symbol.
++**    fts5YYFALLBACK         If defined, this indicates that one or more tokens
++**                       (also known as: "terminal symbols") have fall-back
++**                       values which should be used if the original symbol
++**                       would not parse.  This permits keywords to sometimes
++**                       be used as identifiers, for example.
++**    fts5YYACTIONTYPE       is the data type used for "action codes" - numbers
++**                       that indicate what to do in response to the next
++**                       token.
++**    sqlite3Fts5ParserFTS5TOKENTYPE     is the data type used for minor type for terminal
++**                       symbols.  Background: A "minor type" is a semantic
++**                       value associated with a terminal or non-terminal
++**                       symbols.  For example, for an "ID" terminal symbol,
++**                       the minor type might be the name of the identifier.
++**                       Each non-terminal can have a different minor type.
++**                       Terminal symbols all have the same minor type, though.
++**                       This macros defines the minor type for terminal 
++**                       symbols.
++**    fts5YYMINORTYPE        is the data type used for all minor types.
++**                       This is typically a union of many types, one of
++**                       which is sqlite3Fts5ParserFTS5TOKENTYPE.  The entry in the union
++**                       for terminal symbols is called "fts5yy0".
++**    fts5YYSTACKDEPTH       is the maximum depth of the parser's stack.  If
++**                       zero the stack is dynamically sized using realloc()
++**    sqlite3Fts5ParserARG_SDECL     A static variable declaration for the %extra_argument
++**    sqlite3Fts5ParserARG_PDECL     A parameter declaration for the %extra_argument
++**    sqlite3Fts5ParserARG_STORE     Code to store %extra_argument into fts5yypParser
++**    sqlite3Fts5ParserARG_FETCH     Code to extract %extra_argument from fts5yypParser
++**    fts5YYERRORSYMBOL      is the code number of the error symbol.  If not
++**                       defined, then do no error processing.
++**    fts5YYNSTATE           the combined number of states.
++**    fts5YYNRULE            the number of rules in the grammar
++**    fts5YY_MAX_SHIFT       Maximum value for shift actions
++**    fts5YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
++**    fts5YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
++**    fts5YY_MIN_REDUCE      Maximum value for reduce actions
++**    fts5YY_ERROR_ACTION    The fts5yy_action[] code for syntax error
++**    fts5YY_ACCEPT_ACTION   The fts5yy_action[] code for accept
++**    fts5YY_NO_ACTION       The fts5yy_action[] code for no-op
++*/
++#ifndef INTERFACE
++# define INTERFACE 1
++#endif
++/************* Begin control #defines *****************************************/
++#define fts5YYCODETYPE unsigned char
++#define fts5YYNOCODE 28
++#define fts5YYACTIONTYPE unsigned char
++#define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token
++typedef union {
++  int fts5yyinit;
++  sqlite3Fts5ParserFTS5TOKENTYPE fts5yy0;
++  int fts5yy4;
++  Fts5Colset* fts5yy11;
++  Fts5ExprNode* fts5yy24;
++  Fts5ExprNearset* fts5yy46;
++  Fts5ExprPhrase* fts5yy53;
++} fts5YYMINORTYPE;
++#ifndef fts5YYSTACKDEPTH
++#define fts5YYSTACKDEPTH 100
++#endif
++#define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse;
++#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
++#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse
++#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse
++#define fts5YYNSTATE             33
++#define fts5YYNRULE              27
++#define fts5YY_MAX_SHIFT         32
++#define fts5YY_MIN_SHIFTREDUCE   50
++#define fts5YY_MAX_SHIFTREDUCE   76
++#define fts5YY_MIN_REDUCE        77
++#define fts5YY_MAX_REDUCE        103
++#define fts5YY_ERROR_ACTION      104
++#define fts5YY_ACCEPT_ACTION     105
++#define fts5YY_NO_ACTION         106
++/************* End control #defines *******************************************/
++
++/* Define the fts5yytestcase() macro to be a no-op if is not already defined
++** otherwise.
++**
++** Applications can choose to define fts5yytestcase() in the %include section
++** to a macro that can assist in verifying code coverage.  For production
++** code the fts5yytestcase() macro should be turned off.  But it is useful
++** for testing.
++*/
++#ifndef fts5yytestcase
++# define fts5yytestcase(X)
 +#endif
 +
-+#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
-+        BOOL))aSyscall[64].pCurrent)
- 
--  if( osIsNT() ){
- #if SQLITE_OS_WINRT
--    WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1];
--    dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
--                             FORMAT_MESSAGE_IGNORE_INSERTS,
--                             NULL,
--                             lastErrno,
--                             0,
--                             zTempWide,
--                             SQLITE_WIN32_MAX_ERRMSG_CHARS,
--                             0);
-+  { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
- #else
--    LPWSTR zTempWide = NULL;
--    dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
--                             FORMAT_MESSAGE_FROM_SYSTEM |
--                             FORMAT_MESSAGE_IGNORE_INSERTS,
--                             NULL,
--                             lastErrno,
--                             0,
--                             (LPWSTR) &zTempWide,
--                             0,
--                             0);
-+  { "SetFilePointerEx",        (SYSCALL)0,                       0 },
- #endif
--    if( dwLen > 0 ){
--      /* allocate a buffer and convert to UTF8 */
--      sqlite3BeginBenignMalloc();
--      zOut = winUnicodeToUtf8(zTempWide);
--      sqlite3EndBenignMalloc();
--#if !SQLITE_OS_WINRT
--      /* free the system buffer allocated by FormatMessage */
--      osLocalFree(zTempWide);
-+
-+#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
-+        PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent)
-+
-+#if SQLITE_OS_WINRT
-+  { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
-+#else
-+  { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
- #endif
--    }
--  }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    char *zTemp = NULL;
--    dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
--                             FORMAT_MESSAGE_FROM_SYSTEM |
--                             FORMAT_MESSAGE_IGNORE_INSERTS,
--                             NULL,
--                             lastErrno,
--                             0,
--                             (LPSTR) &zTemp,
--                             0,
--                             0);
--    if( dwLen > 0 ){
--      /* allocate a buffer and convert to UTF8 */
--      sqlite3BeginBenignMalloc();
--      zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
--      sqlite3EndBenignMalloc();
--      /* free the system buffer allocated by FormatMessage */
--      osLocalFree(zTemp);
--    }
--  }
 +
-+#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
-+        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
++/* Next are the tables used to determine what action to take based on the
++** current state and lookahead token.  These tables are used to implement
++** functions that take a state number and lookahead value and return an
++** action integer.  
++**
++** Suppose the action integer is N.  Then the action is determined as
++** follows
++**
++**   0 <= N <= fts5YY_MAX_SHIFT             Shift N.  That is, push the lookahead
++**                                      token onto the stack and goto state N.
++**
++**   N between fts5YY_MIN_SHIFTREDUCE       Shift to an arbitrary state then
++**     and fts5YY_MAX_SHIFTREDUCE           reduce by rule N-fts5YY_MIN_SHIFTREDUCE.
++**
++**   N between fts5YY_MIN_REDUCE            Reduce by rule N-fts5YY_MIN_REDUCE
++**     and fts5YY_MAX_REDUCE
++**
++**   N == fts5YY_ERROR_ACTION               A syntax error has occurred.
++**
++**   N == fts5YY_ACCEPT_ACTION              The parser accepts its input.
++**
++**   N == fts5YY_NO_ACTION                  No such action.  Denotes unused
++**                                      slots in the fts5yy_action[] table.
++**
++** The action table is constructed as a single large table named fts5yy_action[].
++** Given state S and lookahead X, the action is computed as either:
++**
++**    (A)   N = fts5yy_action[ fts5yy_shift_ofst[S] + X ]
++**    (B)   N = fts5yy_default[S]
++**
++** The (A) formula is preferred.  The B formula is used instead if:
++**    (1)  The fts5yy_shift_ofst[S]+X value is out of range, or
++**    (2)  fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X, or
++**    (3)  fts5yy_shift_ofst[S] equal fts5YY_SHIFT_USE_DFLT.
++** (Implementation note: fts5YY_SHIFT_USE_DFLT is chosen so that
++** fts5YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X.
++** Hence only tests (1) and (2) need to be evaluated.)
++**
++** The formulas above are for computing the action when the lookahead is
++** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
++** a reduce action) then the fts5yy_reduce_ofst[] array is used in place of
++** the fts5yy_shift_ofst[] array and fts5YY_REDUCE_USE_DFLT is used in place of
++** fts5YY_SHIFT_USE_DFLT.
++**
++** The following are the tables generated in this section:
++**
++**  fts5yy_action[]        A single table containing all actions.
++**  fts5yy_lookahead[]     A table containing the lookahead for each entry in
++**                     fts5yy_action.  Used to detect hash collisions.
++**  fts5yy_shift_ofst[]    For each state, the offset into fts5yy_action for
++**                     shifting terminals.
++**  fts5yy_reduce_ofst[]   For each state, the offset into fts5yy_action for
++**                     shifting non-terminals after a reduce.
++**  fts5yy_default[]       Default action for each state.
++**
++*********** Begin parsing tables **********************************************/
++#define fts5YY_ACTTAB_COUNT (98)
++static const fts5YYACTIONTYPE fts5yy_action[] = {
++ /*     0 */   105,   19,   90,    6,   26,   93,   92,   24,   24,   17,
++ /*    10 */    90,    6,   26,   16,   92,   54,   24,   18,   90,    6,
++ /*    20 */    26,   10,   92,   12,   24,   75,   86,   90,    6,   26,
++ /*    30 */    13,   92,   75,   24,   20,   90,    6,   26,  101,   92,
++ /*    40 */    56,   24,   27,   90,    6,   26,  100,   92,   21,   24,
++ /*    50 */    23,   15,   30,   11,    1,   91,   22,   25,    9,   92,
++ /*    60 */     7,   24,    3,    4,    5,    3,    4,    5,    3,   77,
++ /*    70 */     4,    5,    3,   61,   23,   15,   60,   11,   80,   12,
++ /*    80 */     2,   13,   68,   10,   29,   52,   55,   75,   31,   32,
++ /*    90 */     8,   28,    5,    3,   51,   55,   72,   14,
++};
++static const fts5YYCODETYPE fts5yy_lookahead[] = {
++ /*     0 */    16,   17,   18,   19,   20,   22,   22,   24,   24,   17,
++ /*    10 */    18,   19,   20,    7,   22,    9,   24,   17,   18,   19,
++ /*    20 */    20,   10,   22,    9,   24,   14,   17,   18,   19,   20,
++ /*    30 */     9,   22,   14,   24,   17,   18,   19,   20,   26,   22,
++ /*    40 */     9,   24,   17,   18,   19,   20,   26,   22,   21,   24,
++ /*    50 */     6,    7,   13,    9,   10,   18,   21,   20,    5,   22,
++ /*    60 */     5,   24,    3,    1,    2,    3,    1,    2,    3,    0,
++ /*    70 */     1,    2,    3,   11,    6,    7,   11,    9,    5,    9,
++ /*    80 */    10,    9,   11,   10,   12,    8,    9,   14,   24,   25,
++ /*    90 */    23,   24,    2,    3,    8,    9,    9,    9,
++};
++#define fts5YY_SHIFT_USE_DFLT (98)
++#define fts5YY_SHIFT_COUNT    (32)
++#define fts5YY_SHIFT_MIN      (0)
++#define fts5YY_SHIFT_MAX      (90)
++static const unsigned char fts5yy_shift_ofst[] = {
++ /*     0 */    44,   44,   44,   44,   44,   44,   68,   70,   72,   14,
++ /*    10 */    21,   73,   11,   18,   18,   31,   31,   62,   65,   69,
++ /*    20 */    90,   77,   86,    6,   39,   53,   55,   59,   39,   87,
++ /*    30 */    88,   39,   71,
++};
++#define fts5YY_REDUCE_USE_DFLT (-18)
++#define fts5YY_REDUCE_COUNT (16)
++#define fts5YY_REDUCE_MIN   (-17)
++#define fts5YY_REDUCE_MAX   (67)
++static const signed char fts5yy_reduce_ofst[] = {
++ /*     0 */   -16,   -8,    0,    9,   17,   25,   37,  -17,   64,  -17,
++ /*    10 */    67,   12,   12,   12,   20,   27,   35,
++};
++static const fts5YYACTIONTYPE fts5yy_default[] = {
++ /*     0 */   104,  104,  104,  104,  104,  104,   89,  104,   98,  104,
++ /*    10 */   104,  103,  103,  103,  103,  104,  104,  104,  104,  104,
++ /*    20 */    85,  104,  104,  104,   94,  104,  104,   84,   96,  104,
++ /*    30 */   104,   97,  104,
++};
++/********** End of lemon-generated parsing tables *****************************/
++
++/* The next table maps tokens (terminal symbols) into fallback tokens.  
++** If a construct like the following:
++** 
++**      %fallback ID X Y Z.
++**
++** appears in the grammar, then ID becomes a fallback token for X, Y,
++** and Z.  Whenever one of the tokens X, Y, or Z is input to the parser
++** but it does not parse, the type of the token is changed to ID and
++** the parse is retried before an error is thrown.
++**
++** This feature can be used, for example, to cause some keywords in a language
++** to revert to identifiers if they keyword does not apply in the context where
++** it appears.
++*/
++#ifdef fts5YYFALLBACK
++static const fts5YYCODETYPE fts5yyFallback[] = {
++};
++#endif /* fts5YYFALLBACK */
 +
-+#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
-+  { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
-+#else
-+  { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
- #endif
--  if( 0 == dwLen ){
--    sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno);
--  }else{
--    /* copy a maximum of nBuf chars to output buffer */
--    sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
--    /* free the UTF8 buffer */
--    sqlite3_free(zOut);
--  }
--  return 0;
--}
- 
--/*
--**
--** This function - winLogErrorAtLine() - is only ever called via the macro
--** winLogError().
--**
--** This routine is invoked after an error occurs in an OS function.
--** It logs a message using sqlite3_log() containing the current value of
--** error code and, if possible, the human-readable equivalent from
--** FormatMessage.
--**
--** The first argument passed to the macro should be the error code that
--** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN).
--** The two subsequent arguments should be the name of the OS function that
--** failed and the associated file-system path, if any.
--*/
--#define winLogError(a,b,c,d)   winLogErrorAtLine(a,b,c,d,__LINE__)
--static int winLogErrorAtLine(
--  int errcode,                    /* SQLite error code */
--  DWORD lastErrno,                /* Win32 last error */
--  const char *zFunc,              /* Name of OS function that failed */
--  const char *zPath,              /* File path associated with error */
--  int iLine                       /* Source line number where error occurred */
--){
--  char zMsg[500];                 /* Human readable error text */
--  int i;                          /* Loop counter */
-+#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
-+        SIZE_T))aSyscall[67].pCurrent)
- 
--  zMsg[0] = 0;
--  winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
--  assert( errcode!=SQLITE_OK );
--  if( zPath==0 ) zPath = "";
--  for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
--  zMsg[i] = 0;
--  sqlite3_log(errcode,
--      "os_win.c:%d: (%lu) %s(%s) - %s",
--      iLine, lastErrno, zFunc, zPath, zMsg
--  );
-+#if SQLITE_OS_WINRT
-+  { "CreateFile2",             (SYSCALL)CreateFile2,             0 },
-+#else
-+  { "CreateFile2",             (SYSCALL)0,                       0 },
++/* The following structure represents a single element of the
++** parser's stack.  Information stored includes:
++**
++**   +  The state number for the parser at this level of the stack.
++**
++**   +  The value of the token stored at this level of the stack.
++**      (In other words, the "major" token.)
++**
++**   +  The semantic value stored at this level of the stack.  This is
++**      the information used by the action routines in the grammar.
++**      It is sometimes called the "minor" token.
++**
++** After the "shift" half of a SHIFTREDUCE action, the stateno field
++** actually contains the reduce action for the second half of the
++** SHIFTREDUCE.
++*/
++struct fts5yyStackEntry {
++  fts5YYACTIONTYPE stateno;  /* The state-number, or reduce action in SHIFTREDUCE */
++  fts5YYCODETYPE major;      /* The major token value.  This is the code
++                         ** number for the token at this stack level */
++  fts5YYMINORTYPE minor;     /* The user-supplied minor token value.  This
++                         ** is the value of the token  */
++};
++typedef struct fts5yyStackEntry fts5yyStackEntry;
++
++/* The state of the parser is completely contained in an instance of
++** the following structure */
++struct fts5yyParser {
++  fts5yyStackEntry *fts5yytos;          /* Pointer to top element of the stack */
++#ifdef fts5YYTRACKMAXSTACKDEPTH
++  int fts5yyhwm;                    /* High-water mark of the stack */
 +#endif
- 
--  return errcode;
--}
-+#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
-+        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent)
- 
--/*
--** The number of times that a ReadFile(), WriteFile(), and DeleteFile()
--** will be retried following a locking error - probably caused by
--** antivirus software.  Also the initial delay before the first retry.
--** The delay increases linearly with each retry.
--*/
--#ifndef SQLITE_WIN32_IOERR_RETRY
--# define SQLITE_WIN32_IOERR_RETRY 10
-+#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
-+  { "LoadPackagedLibrary",     (SYSCALL)LoadPackagedLibrary,     0 },
++#ifndef fts5YYNOERRORRECOVERY
++  int fts5yyerrcnt;                 /* Shifts left before out of the error */
++#endif
++  sqlite3Fts5ParserARG_SDECL                /* A place to hold %extra_argument */
++#if fts5YYSTACKDEPTH<=0
++  int fts5yystksz;                  /* Current side of the stack */
++  fts5yyStackEntry *fts5yystack;        /* The parser's stack */
++  fts5yyStackEntry fts5yystk0;          /* First stack entry */
 +#else
-+  { "LoadPackagedLibrary",     (SYSCALL)0,                       0 },
- #endif
--#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
--# define SQLITE_WIN32_IOERR_RETRY_DELAY 25
++  fts5yyStackEntry fts5yystack[fts5YYSTACKDEPTH];  /* The parser's stack */
++  fts5yyStackEntry *fts5yystackEnd;            /* Last entry in the stack */
++#endif
++};
++typedef struct fts5yyParser fts5yyParser;
 +
-+#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
-+        DWORD))aSyscall[69].pCurrent)
++#ifndef NDEBUG
++/* #include <stdio.h> */
++static FILE *fts5yyTraceFILE = 0;
++static char *fts5yyTracePrompt = 0;
++#endif /* NDEBUG */
 +
-+#if SQLITE_OS_WINRT
-+  { "GetTickCount64",          (SYSCALL)GetTickCount64,          0 },
-+#else
-+  { "GetTickCount64",          (SYSCALL)0,                       0 },
- #endif
--static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY;
--static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
- 
--/*
--** The "winIoerrCanRetry1" macro is used to determine if a particular I/O
--** error code obtained via GetLastError() is eligible to be retried.  It
--** must accept the error code DWORD as its only argument and should return
--** non-zero if the error code is transient in nature and the operation
--** responsible for generating the original error might succeed upon being
--** retried.  The argument to this macro should be a variable.
--**
--** Additionally, a macro named "winIoerrCanRetry2" may be defined.  If it
--** is defined, it will be consulted only when the macro "winIoerrCanRetry1"
--** returns zero.  The "winIoerrCanRetry2" macro is completely optional and
--** may be used to include additional error codes in the set that should
--** result in the failing I/O operation being retried by the caller.  If
--** defined, the "winIoerrCanRetry2" macro must exhibit external semantics
--** identical to those of the "winIoerrCanRetry1" macro.
--*/
--#if !defined(winIoerrCanRetry1)
--#define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED)        || \
--                              ((a)==ERROR_SHARING_VIOLATION)    || \
--                              ((a)==ERROR_LOCK_VIOLATION)       || \
--                              ((a)==ERROR_DEV_NOT_EXIST)        || \
--                              ((a)==ERROR_NETNAME_DELETED)      || \
--                              ((a)==ERROR_SEM_TIMEOUT)          || \
--                              ((a)==ERROR_NETWORK_UNREACHABLE))
-+#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent)
-+
-+#if SQLITE_OS_WINRT
-+  { "GetNativeSystemInfo",     (SYSCALL)GetNativeSystemInfo,     0 },
-+#else
-+  { "GetNativeSystemInfo",     (SYSCALL)0,                       0 },
- #endif
- 
--/*
--** If a ReadFile() or WriteFile() error occurs, invoke this routine
--** to see if it should be retried.  Return TRUE to retry.  Return FALSE
--** to give up with an error.
--*/
--static int winRetryIoerr(int *pnRetry, DWORD *pError){
--  DWORD e = osGetLastError();
--  if( *pnRetry>=winIoerrRetry ){
--    if( pError ){
--      *pError = e;
--    }
--    return 0;
--  }
--  if( winIoerrCanRetry1(e) ){
--    sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
--    ++*pnRetry;
--    return 1;
--  }
--#if defined(winIoerrCanRetry2)
--  else if( winIoerrCanRetry2(e) ){
--    sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
--    ++*pnRetry;
--    return 1;
--  }
-+#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
-+        LPSYSTEM_INFO))aSyscall[71].pCurrent)
++#ifndef NDEBUG
++/* 
++** Turn parser tracing on by giving a stream to which to write the trace
++** and a prompt to preface each trace message.  Tracing is turned off
++** by making either argument NULL 
++**
++** Inputs:
++** <ul>
++** <li> A FILE* to which trace output should be written.
++**      If NULL, then tracing is turned off.
++** <li> A prefix string written at the beginning of every
++**      line of trace output.  If NULL, then tracing is
++**      turned off.
++** </ul>
++**
++** Outputs:
++** None.
++*/
++static void sqlite3Fts5ParserTrace(FILE *TraceFILE, char *zTracePrompt){
++  fts5yyTraceFILE = TraceFILE;
++  fts5yyTracePrompt = zTracePrompt;
++  if( fts5yyTraceFILE==0 ) fts5yyTracePrompt = 0;
++  else if( fts5yyTracePrompt==0 ) fts5yyTraceFILE = 0;
++}
++#endif /* NDEBUG */
 +
-+#if defined(SQLITE_WIN32_HAS_ANSI)
-+  { "OutputDebugStringA",      (SYSCALL)OutputDebugStringA,      0 },
-+#else
-+  { "OutputDebugStringA",      (SYSCALL)0,                       0 },
- #endif
--  if( pError ){
--    *pError = e;
--  }
--  return 0;
--}
- 
--/*
--** Log a I/O error retry episode.
--*/
--static void winLogIoerr(int nRetry, int lineno){
--  if( nRetry ){
--    sqlite3_log(SQLITE_NOTICE,
--      "delayed %dms for lock/sharing conflict at line %d",
--      winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno
--    );
--  }
--}
-+#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent)
- 
--#if SQLITE_OS_WINCE
--/*************************************************************************
--** This section contains code for WinCE only.
--*/
--#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API
--/*
--** The MSVC CRT on Windows CE may not have a localtime() function.  So
--** create a substitute.
--*/
--/* #include <time.h> */
--struct tm *__cdecl localtime(const time_t *t)
--{
--  static struct tm y;
--  FILETIME uTm, lTm;
--  SYSTEMTIME pTm;
--  sqlite3_int64 t64;
--  t64 = *t;
--  t64 = (t64 + 11644473600)*10000000;
--  uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
--  uTm.dwHighDateTime= (DWORD)(t64 >> 32);
--  osFileTimeToLocalFileTime(&uTm,&lTm);
--  osFileTimeToSystemTime(&lTm,&pTm);
--  y.tm_year = pTm.wYear - 1900;
--  y.tm_mon = pTm.wMonth - 1;
--  y.tm_wday = pTm.wDayOfWeek;
--  y.tm_mday = pTm.wDay;
--  y.tm_hour = pTm.wHour;
--  y.tm_min = pTm.wMinute;
--  y.tm_sec = pTm.wSecond;
--  return &y;
--}
-+#if defined(SQLITE_WIN32_HAS_WIDE)
-+  { "OutputDebugStringW",      (SYSCALL)OutputDebugStringW,      0 },
-+#else
-+  { "OutputDebugStringW",      (SYSCALL)0,                       0 },
- #endif
- 
--#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
-+#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)
- 
--/*
--** Acquire a lock on the handle h
--*/
--static void winceMutexAcquire(HANDLE h){
--   DWORD dwErr;
--   do {
--     dwErr = osWaitForSingleObject(h, INFINITE);
--   } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
--}
--/*
--** Release a lock acquired by winceMutexAcquire()
--*/
--#define winceMutexRelease(h) ReleaseMutex(h)
-+  { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },
- 
--/*
--** Create the mutex and shared memory used for locking in the file
--** descriptor pFile
--*/
--static int winceCreateLock(const char *zFilename, winFile *pFile){
--  LPWSTR zTok;
--  LPWSTR zName;
--  DWORD lastErrno;
--  BOOL bLogged = FALSE;
--  BOOL bInit = TRUE;
-+#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
- 
--  zName = winUtf8ToUnicode(zFilename);
--  if( zName==0 ){
--    /* out of memory */
--    return SQLITE_IOERR_NOMEM;
--  }
-+#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
-+  { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
-+#else
-+  { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
-+#endif
- 
--  /* Initialize the local lockdata */
--  memset(&pFile->local, 0, sizeof(pFile->local));
-+#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
-+        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
- 
--  /* Replace the backslashes from the filename and lowercase it
--  ** to derive a mutex name. */
--  zTok = osCharLowerW(zName);
--  for (;*zTok;zTok++){
--    if (*zTok == '\\') *zTok = '_';
--  }
++#ifndef NDEBUG
++/* For tracing shifts, the names of all terminals and nonterminals
++** are required.  The following table supplies these names */
++static const char *const fts5yyTokenName[] = { 
++  "$",             "OR",            "AND",           "NOT",         
++  "TERM",          "COLON",         "MINUS",         "LCP",         
++  "RCP",           "STRING",        "LP",            "RP",          
++  "COMMA",         "PLUS",          "STAR",          "error",       
++  "input",         "expr",          "cnearset",      "exprlist",    
++  "colset",        "colsetlist",    "nearset",       "nearphrases", 
++  "phrase",        "neardist_opt",  "star_opt",    
++};
++#endif /* NDEBUG */
++
++#ifndef NDEBUG
++/* For tracing reduce actions, the names of all rules are required.
++*/
++static const char *const fts5yyRuleName[] = {
++ /*   0 */ "input ::= expr",
++ /*   1 */ "colset ::= MINUS LCP colsetlist RCP",
++ /*   2 */ "colset ::= LCP colsetlist RCP",
++ /*   3 */ "colset ::= STRING",
++ /*   4 */ "colset ::= MINUS STRING",
++ /*   5 */ "colsetlist ::= colsetlist STRING",
++ /*   6 */ "colsetlist ::= STRING",
++ /*   7 */ "expr ::= expr AND expr",
++ /*   8 */ "expr ::= expr OR expr",
++ /*   9 */ "expr ::= expr NOT expr",
++ /*  10 */ "expr ::= colset COLON LP expr RP",
++ /*  11 */ "expr ::= LP expr RP",
++ /*  12 */ "expr ::= exprlist",
++ /*  13 */ "exprlist ::= cnearset",
++ /*  14 */ "exprlist ::= exprlist cnearset",
++ /*  15 */ "cnearset ::= nearset",
++ /*  16 */ "cnearset ::= colset COLON nearset",
++ /*  17 */ "nearset ::= phrase",
++ /*  18 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
++ /*  19 */ "nearphrases ::= phrase",
++ /*  20 */ "nearphrases ::= nearphrases phrase",
++ /*  21 */ "neardist_opt ::=",
++ /*  22 */ "neardist_opt ::= COMMA STRING",
++ /*  23 */ "phrase ::= phrase PLUS STRING star_opt",
++ /*  24 */ "phrase ::= STRING star_opt",
++ /*  25 */ "star_opt ::= STAR",
++ /*  26 */ "star_opt ::=",
++};
++#endif /* NDEBUG */
++
++
++#if fts5YYSTACKDEPTH<=0
 +/*
-+** NOTE: On some sub-platforms, the InterlockedCompareExchange "function"
-+**       is really just a macro that uses a compiler intrinsic (e.g. x64).
-+**       So do not try to make this is into a redefinable interface.
++** Try to increase the size of the parser stack.  Return the number
++** of errors.  Return 0 on success.
 +*/
-+#if defined(InterlockedCompareExchange)
-+  { "InterlockedCompareExchange", (SYSCALL)0,                    0 },
- 
--  /* Create/open the named mutex */
--  pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
--  if (!pFile->hMutex){
--    pFile->lastErrno = osGetLastError();
--    sqlite3_free(zName);
--    return winLogError(SQLITE_IOERR, pFile->lastErrno,
--                       "winceCreateLock1", zFilename);
--  }
-+#define osInterlockedCompareExchange InterlockedCompareExchange
-+#else
-+  { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 },
- 
--  /* Acquire the mutex before continuing */
--  winceMutexAcquire(pFile->hMutex);
-+#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \
-+        SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent)
-+#endif /* defined(InterlockedCompareExchange) */
- 
--  /* Since the names of named mutexes, semaphores, file mappings etc are
--  ** case-sensitive, take advantage of that by uppercasing the mutex name
--  ** and using that as the shared filemapping name.
--  */
--  osCharUpperW(zName);
--  pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
--                                        PAGE_READWRITE, 0, sizeof(winceLock),
--                                        zName);
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
-+  { "UuidCreate",               (SYSCALL)UuidCreate,             0 },
-+#else
-+  { "UuidCreate",               (SYSCALL)0,                      0 },
++static int fts5yyGrowStack(fts5yyParser *p){
++  int newSize;
++  int idx;
++  fts5yyStackEntry *pNew;
++
++  newSize = p->fts5yystksz*2 + 100;
++  idx = p->fts5yytos ? (int)(p->fts5yytos - p->fts5yystack) : 0;
++  if( p->fts5yystack==&p->fts5yystk0 ){
++    pNew = malloc(newSize*sizeof(pNew[0]));
++    if( pNew ) pNew[0] = p->fts5yystk0;
++  }else{
++    pNew = realloc(p->fts5yystack, newSize*sizeof(pNew[0]));
++  }
++  if( pNew ){
++    p->fts5yystack = pNew;
++    p->fts5yytos = &p->fts5yystack[idx];
++#ifndef NDEBUG
++    if( fts5yyTraceFILE ){
++      fprintf(fts5yyTraceFILE,"%sStack grows from %d to %d entries.\n",
++              fts5yyTracePrompt, p->fts5yystksz, newSize);
++    }
 +#endif
- 
--  /* Set a flag that indicates we're the first to create the memory so it
--  ** must be zero-initialized */
--  lastErrno = osGetLastError();
--  if (lastErrno == ERROR_ALREADY_EXISTS){
--    bInit = FALSE;
--  }
-+#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent)
- 
--  sqlite3_free(zName);
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
-+  { "UuidCreateSequential",     (SYSCALL)UuidCreateSequential,   0 },
-+#else
-+  { "UuidCreateSequential",     (SYSCALL)0,                      0 },
-+#endif
- 
--  /* If we succeeded in making the shared memory handle, map it. */
--  if( pFile->hShared ){
--    pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared,
--             FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
--    /* If mapping failed, close the shared memory handle and erase it */
--    if( !pFile->shared ){
--      pFile->lastErrno = osGetLastError();
--      winLogError(SQLITE_IOERR, pFile->lastErrno,
--                  "winceCreateLock2", zFilename);
--      bLogged = TRUE;
--      osCloseHandle(pFile->hShared);
--      pFile->hShared = NULL;
--    }
--  }
-+#define osUuidCreateSequential \
-+        ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent)
- 
--  /* If shared memory could not be created, then close the mutex and fail */
--  if( pFile->hShared==NULL ){
--    if( !bLogged ){
--      pFile->lastErrno = lastErrno;
--      winLogError(SQLITE_IOERR, pFile->lastErrno,
--                  "winceCreateLock3", zFilename);
--      bLogged = TRUE;
--    }
--    winceMutexRelease(pFile->hMutex);
--    osCloseHandle(pFile->hMutex);
--    pFile->hMutex = NULL;
--    return SQLITE_IOERR;
--  }
-+#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0
-+  { "FlushViewOfFile",          (SYSCALL)FlushViewOfFile,        0 },
-+#else
-+  { "FlushViewOfFile",          (SYSCALL)0,                      0 },
++    p->fts5yystksz = newSize;
++  }
++  return pNew==0; 
++}
 +#endif
- 
--  /* Initialize the shared memory if we're supposed to */
--  if( bInit ){
--    memset(pFile->shared, 0, sizeof(winceLock));
--  }
-+#define osFlushViewOfFile \
-+        ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent)
- 
--  winceMutexRelease(pFile->hMutex);
--  return SQLITE_OK;
--}
-+}; /* End of the overrideable system calls */
- 
- /*
--** Destroy the part of winFile that deals with wince locks
-+** This is the xSetSystemCall() method of sqlite3_vfs for all of the
-+** "win32" VFSes.  Return SQLITE_OK opon successfully updating the
-+** system call pointer, or SQLITE_NOTFOUND if there is no configurable
-+** system call named zName.
- */
--static void winceDestroyLock(winFile *pFile){
--  if (pFile->hMutex){
--    /* Acquire the mutex */
--    winceMutexAcquire(pFile->hMutex);
-+static int winSetSystemCall(
-+  sqlite3_vfs *pNotUsed,        /* The VFS pointer.  Not used */
-+  const char *zName,            /* Name of system call to override */
-+  sqlite3_syscall_ptr pNewFunc  /* Pointer to new system call value */
++
++/* Datatype of the argument to the memory allocated passed as the
++** second argument to sqlite3Fts5ParserAlloc() below.  This can be changed by
++** putting an appropriate #define in the %include section of the input
++** grammar.
++*/
++#ifndef fts5YYMALLOCARGTYPE
++# define fts5YYMALLOCARGTYPE size_t
++#endif
++
++/* Initialize a new parser that has already been allocated.
++*/
++static void sqlite3Fts5ParserInit(void *fts5yypParser){
++  fts5yyParser *pParser = (fts5yyParser*)fts5yypParser;
++#ifdef fts5YYTRACKMAXSTACKDEPTH
++  pParser->fts5yyhwm = 0;
++#endif
++#if fts5YYSTACKDEPTH<=0
++  pParser->fts5yytos = NULL;
++  pParser->fts5yystack = NULL;
++  pParser->fts5yystksz = 0;
++  if( fts5yyGrowStack(pParser) ){
++    pParser->fts5yystack = &pParser->fts5yystk0;
++    pParser->fts5yystksz = 1;
++  }
++#endif
++#ifndef fts5YYNOERRORRECOVERY
++  pParser->fts5yyerrcnt = -1;
++#endif
++  pParser->fts5yytos = pParser->fts5yystack;
++  pParser->fts5yystack[0].stateno = 0;
++  pParser->fts5yystack[0].major = 0;
++#if fts5YYSTACKDEPTH>0
++  pParser->fts5yystackEnd = &pParser->fts5yystack[fts5YYSTACKDEPTH-1];
++#endif
++}
++
++#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
++/* 
++** This function allocates a new parser.
++** The only argument is a pointer to a function which works like
++** malloc.
++**
++** Inputs:
++** A pointer to the function used to allocate memory.
++**
++** Outputs:
++** A pointer to a parser.  This pointer is used in subsequent calls
++** to sqlite3Fts5Parser and sqlite3Fts5ParserFree.
++*/
++static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE)){
++  fts5yyParser *pParser;
++  pParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) );
++  if( pParser ) sqlite3Fts5ParserInit(pParser);
++  return pParser;
++}
++#endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */
++
++
++/* The following function deletes the "minor type" or semantic value
++** associated with a symbol.  The symbol can be either a terminal
++** or nonterminal. "fts5yymajor" is the symbol code, and "fts5yypminor" is
++** a pointer to the value to be deleted.  The code used to do the 
++** deletions is derived from the %destructor and/or %token_destructor
++** directives of the input grammar.
++*/
++static void fts5yy_destructor(
++  fts5yyParser *fts5yypParser,    /* The parser */
++  fts5YYCODETYPE fts5yymajor,     /* Type code for object to destroy */
++  fts5YYMINORTYPE *fts5yypminor   /* The object to be destroyed */
 +){
-+  unsigned int i;
-+  int rc = SQLITE_NOTFOUND;
- 
--    /* The following blocks should probably assert in debug mode, but they
--       are to cleanup in case any locks remained open */
--    if (pFile->local.nReaders){
--      pFile->shared->nReaders --;
--    }
--    if (pFile->local.bReserved){
--      pFile->shared->bReserved = FALSE;
--    }
--    if (pFile->local.bPending){
--      pFile->shared->bPending = FALSE;
-+  UNUSED_PARAMETER(pNotUsed);
-+  if( zName==0 ){
-+    /* If no zName is given, restore all system calls to their default
-+    ** settings and return NULL
-+    */
-+    rc = SQLITE_OK;
-+    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
-+      if( aSyscall[i].pDefault ){
-+        aSyscall[i].pCurrent = aSyscall[i].pDefault;
-+      }
-     }
--    if (pFile->local.bExclusive){
--      pFile->shared->bExclusive = FALSE;
-+  }else{
-+    /* If zName is specified, operate on only the one system call
-+    ** specified.
++  sqlite3Fts5ParserARG_FETCH;
++  switch( fts5yymajor ){
++    /* Here is inserted the actions which take place when a
++    ** terminal or non-terminal is destroyed.  This can happen
++    ** when the symbol is popped from the stack during a
++    ** reduce or during error processing or when a parser is 
++    ** being destroyed before it is finished parsing.
++    **
++    ** Note: during a reduce, the only symbols destroyed are those
++    ** which appear on the RHS of the rule, but which are *not* used
++    ** inside the C code.
 +    */
-+    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
-+      if( strcmp(zName, aSyscall[i].zName)==0 ){
-+        if( aSyscall[i].pDefault==0 ){
-+          aSyscall[i].pDefault = aSyscall[i].pCurrent;
-+        }
-+        rc = SQLITE_OK;
-+        if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault;
-+        aSyscall[i].pCurrent = pNewFunc;
-+        break;
-+      }
-     }
--
--    /* De-reference and close our copy of the shared memory handle */
--    osUnmapViewOfFile(pFile->shared);
--    osCloseHandle(pFile->hShared);
--
--    /* Done with the mutex */
--    winceMutexRelease(pFile->hMutex);
--    osCloseHandle(pFile->hMutex);
--    pFile->hMutex = NULL;
-   }
-+  return rc;
- }
- 
- /*
--** An implementation of the LockFile() API of Windows for CE
-+** Return the value of a system call.  Return NULL if zName is not a
-+** recognized system call name.  NULL is also returned if the system call
-+** is currently undefined.
- */
--static BOOL winceLockFile(
--  LPHANDLE phFile,
--  DWORD dwFileOffsetLow,
--  DWORD dwFileOffsetHigh,
--  DWORD nNumberOfBytesToLockLow,
--  DWORD nNumberOfBytesToLockHigh
-+static sqlite3_syscall_ptr winGetSystemCall(
-+  sqlite3_vfs *pNotUsed,
-+  const char *zName
- ){
--  winFile *pFile = HANDLE_TO_WINFILE(phFile);
--  BOOL bReturn = FALSE;
-+  unsigned int i;
- 
--  UNUSED_PARAMETER(dwFileOffsetHigh);
--  UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
-+  UNUSED_PARAMETER(pNotUsed);
-+  for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
-+    if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
++/********* Begin destructor definitions ***************************************/
++    case 16: /* input */
++{
++ (void)pParse; 
++}
++      break;
++    case 17: /* expr */
++    case 18: /* cnearset */
++    case 19: /* exprlist */
++{
++ sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24)); 
++}
++      break;
++    case 20: /* colset */
++    case 21: /* colsetlist */
++{
++ sqlite3_free((fts5yypminor->fts5yy11)); 
++}
++      break;
++    case 22: /* nearset */
++    case 23: /* nearphrases */
++{
++ sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46)); 
++}
++      break;
++    case 24: /* phrase */
++{
++ sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53)); 
++}
++      break;
++/********* End destructor definitions *****************************************/
++    default:  break;   /* If no destructor action specified: do nothing */
 +  }
-+  return 0;
 +}
- 
--  if (!pFile->hMutex) return TRUE;
--  winceMutexAcquire(pFile->hMutex);
++
 +/*
-+** Return the name of the first system call after zName.  If zName==NULL
-+** then return the name of the first system call.  Return NULL if zName
-+** is the last system call or if zName is not the name of a valid
-+** system call.
++** Pop the parser's stack once.
++**
++** If there is a destructor routine associated with the token which
++** is popped from the stack, then call it.
 +*/
-+static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
-+  int i = -1;
- 
--  /* Wanting an exclusive lock? */
--  if (dwFileOffsetLow == (DWORD)SHARED_FIRST
--       && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
--    if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
--       pFile->shared->bExclusive = TRUE;
--       pFile->local.bExclusive = TRUE;
--       bReturn = TRUE;
-+  UNUSED_PARAMETER(p);
-+  if( zName ){
-+    for(i=0; i<ArraySize(aSyscall)-1; i++){
-+      if( strcmp(zName, aSyscall[i].zName)==0 ) break;
-     }
-   }
--
--  /* Want a read-only lock? */
--  else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
--           nNumberOfBytesToLockLow == 1){
--    if (pFile->shared->bExclusive == 0){
--      pFile->local.nReaders ++;
--      if (pFile->local.nReaders == 1){
--        pFile->shared->nReaders ++;
--      }
--      bReturn = TRUE;
--    }
-+  for(i++; i<ArraySize(aSyscall); i++){
-+    if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
-   }
-+  return 0;
++static void fts5yy_pop_parser_stack(fts5yyParser *pParser){
++  fts5yyStackEntry *fts5yytos;
++  assert( pParser->fts5yytos!=0 );
++  assert( pParser->fts5yytos > pParser->fts5yystack );
++  fts5yytos = pParser->fts5yytos--;
++#ifndef NDEBUG
++  if( fts5yyTraceFILE ){
++    fprintf(fts5yyTraceFILE,"%sPopping %s\n",
++      fts5yyTracePrompt,
++      fts5yyTokenName[fts5yytos->major]);
++  }
++#endif
++  fts5yy_destructor(pParser, fts5yytos->major, &fts5yytos->minor);
 +}
- 
--  /* Want a pending lock? */
--  else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
--           && nNumberOfBytesToLockLow == 1){
--    /* If no pending lock has been acquired, then acquire it */
--    if (pFile->shared->bPending == 0) {
--      pFile->shared->bPending = TRUE;
--      pFile->local.bPending = TRUE;
--      bReturn = TRUE;
--    }
--  }
-+#ifdef SQLITE_WIN32_MALLOC
++
 +/*
-+** If a Win32 native heap has been configured, this function will attempt to
-+** compact it.  Upon success, SQLITE_OK will be returned.  Upon failure, one
-+** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned.  The
-+** "pnLargest" argument, if non-zero, will be used to return the size of the
-+** largest committed free block in the heap, in bytes.
++** Clear all secondary memory allocations from the parser
 +*/
-+SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
-+  int rc = SQLITE_OK;
-+  UINT nLargest = 0;
-+  HANDLE hHeap;
- 
--  /* Want a reserved lock? */
--  else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
--           && nNumberOfBytesToLockLow == 1){
--    if (pFile->shared->bReserved == 0) {
--      pFile->shared->bReserved = TRUE;
--      pFile->local.bReserved = TRUE;
--      bReturn = TRUE;
-+  winMemAssertMagic();
-+  hHeap = winMemGetHeap();
-+  assert( hHeap!=0 );
-+  assert( hHeap!=INVALID_HANDLE_VALUE );
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
-+  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
-+#endif
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-+  if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){
-+    DWORD lastErrno = osGetLastError();
-+    if( lastErrno==NO_ERROR ){
-+      sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
-+                  (void*)hHeap);
-+      rc = SQLITE_NOMEM;
-+    }else{
-+      sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
-+                  osGetLastError(), (void*)hHeap);
-+      rc = SQLITE_ERROR;
-     }
-   }
--
--  winceMutexRelease(pFile->hMutex);
--  return bReturn;
-+#else
-+  sqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p",
-+              (void*)hHeap);
-+  rc = SQLITE_NOTFOUND;
++static void sqlite3Fts5ParserFinalize(void *p){
++  fts5yyParser *pParser = (fts5yyParser*)p;
++  while( pParser->fts5yytos>pParser->fts5yystack ) fts5yy_pop_parser_stack(pParser);
++#if fts5YYSTACKDEPTH<=0
++  if( pParser->fts5yystack!=&pParser->fts5yystk0 ) free(pParser->fts5yystack);
 +#endif
-+  if( pnLargest ) *pnLargest = nLargest;
-+  return rc;
- }
- 
- /*
--** An implementation of the UnlockFile API of Windows for CE
-+** If a Win32 native heap has been configured, this function will attempt to
-+** destroy and recreate it.  If the Win32 native heap is not isolated and/or
-+** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
-+** be returned and no changes will be made to the Win32 native heap.
- */
--static BOOL winceUnlockFile(
--  LPHANDLE phFile,
--  DWORD dwFileOffsetLow,
--  DWORD dwFileOffsetHigh,
--  DWORD nNumberOfBytesToUnlockLow,
--  DWORD nNumberOfBytesToUnlockHigh
--){
--  winFile *pFile = HANDLE_TO_WINFILE(phFile);
--  BOOL bReturn = FALSE;
--
--  UNUSED_PARAMETER(dwFileOffsetHigh);
--  UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);
--
--  if (!pFile->hMutex) return TRUE;
--  winceMutexAcquire(pFile->hMutex);
-+SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
-+  int rc;
-+  MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
-+  MUTEX_LOGIC( sqlite3_mutex *pMem; )    /* The memsys static mutex */
-+  MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
-+  MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
-+  sqlite3_mutex_enter(pMaster);
-+  sqlite3_mutex_enter(pMem);
-+  winMemAssertMagic();
-+  if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
-+    /*
-+    ** At this point, there should be no outstanding memory allocations on
-+    ** the heap.  Also, since both the master and memsys locks are currently
-+    ** being held by us, no other function (i.e. from another thread) should
-+    ** be able to even access the heap.  Attempt to destroy and recreate our
-+    ** isolated Win32 native heap now.
-+    */
-+    assert( winMemGetHeap()!=NULL );
-+    assert( winMemGetOwned() );
-+    assert( sqlite3_memory_used()==0 );
-+    winMemShutdown(winMemGetDataPtr());
-+    assert( winMemGetHeap()==NULL );
-+    assert( !winMemGetOwned() );
-+    assert( sqlite3_memory_used()==0 );
-+    rc = winMemInit(winMemGetDataPtr());
-+    assert( rc!=SQLITE_OK || winMemGetHeap()!=NULL );
-+    assert( rc!=SQLITE_OK || winMemGetOwned() );
-+    assert( rc!=SQLITE_OK || sqlite3_memory_used()==0 );
-+  }else{
-+    /*
-+    ** The Win32 native heap cannot be modified because it may be in use.
-+    */
-+    rc = SQLITE_BUSY;
-+  }
-+  sqlite3_mutex_leave(pMem);
-+  sqlite3_mutex_leave(pMaster);
-+  return rc;
 +}
-+#endif /* SQLITE_WIN32_MALLOC */
- 
--  /* Releasing a reader lock or an exclusive lock */
--  if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
--    /* Did we have an exclusive lock? */
--    if (pFile->local.bExclusive){
--      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
--      pFile->local.bExclusive = FALSE;
--      pFile->shared->bExclusive = FALSE;
--      bReturn = TRUE;
--    }
++
++#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
++/* 
++** Deallocate and destroy a parser.  Destructors are called for
++** all stack elements before shutting the parser down.
++**
++** If the fts5YYPARSEFREENEVERNULL macro exists (for example because it
++** is defined in a %include section of the input grammar) then it is
++** assumed that the input pointer is never NULL.
++*/
++static void sqlite3Fts5ParserFree(
++  void *p,                    /* The parser to be deleted */
++  void (*freeProc)(void*)     /* Function used to reclaim memory */
++){
++#ifndef fts5YYPARSEFREENEVERNULL
++  if( p==0 ) return;
++#endif
++  sqlite3Fts5ParserFinalize(p);
++  (*freeProc)(p);
++}
++#endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */
++
++/*
++** Return the peak depth of the stack for a parser.
++*/
++#ifdef fts5YYTRACKMAXSTACKDEPTH
++static int sqlite3Fts5ParserStackPeak(void *p){
++  fts5yyParser *pParser = (fts5yyParser*)p;
++  return pParser->fts5yyhwm;
++}
++#endif
++
++/*
++** Find the appropriate action for a parser given the terminal
++** look-ahead token iLookAhead.
++*/
++static unsigned int fts5yy_find_shift_action(
++  fts5yyParser *pParser,        /* The parser */
++  fts5YYCODETYPE iLookAhead     /* The look-ahead token */
++){
++  int i;
++  int stateno = pParser->fts5yytos->stateno;
++ 
++  if( stateno>=fts5YY_MIN_REDUCE ) return stateno;
++  assert( stateno <= fts5YY_SHIFT_COUNT );
++  do{
++    i = fts5yy_shift_ofst[stateno];
++    assert( iLookAhead!=fts5YYNOCODE );
++    i += iLookAhead;
++    if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){
++#ifdef fts5YYFALLBACK
++      fts5YYCODETYPE iFallback;            /* Fallback token */
++      if( iLookAhead<sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])
++             && (iFallback = fts5yyFallback[iLookAhead])!=0 ){
++#ifndef NDEBUG
++        if( fts5yyTraceFILE ){
++          fprintf(fts5yyTraceFILE, "%sFALLBACK %s => %s\n",
++             fts5yyTracePrompt, fts5yyTokenName[iLookAhead], fts5yyTokenName[iFallback]);
++        }
++#endif
++        assert( fts5yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
++        iLookAhead = iFallback;
++        continue;
++      }
++#endif
++#ifdef fts5YYWILDCARD
++      {
++        int j = i - iLookAhead + fts5YYWILDCARD;
++        if( 
++#if fts5YY_SHIFT_MIN+fts5YYWILDCARD<0
++          j>=0 &&
++#endif
++#if fts5YY_SHIFT_MAX+fts5YYWILDCARD>=fts5YY_ACTTAB_COUNT
++          j<fts5YY_ACTTAB_COUNT &&
++#endif
++          fts5yy_lookahead[j]==fts5YYWILDCARD && iLookAhead>0
++        ){
++#ifndef NDEBUG
++          if( fts5yyTraceFILE ){
++            fprintf(fts5yyTraceFILE, "%sWILDCARD %s => %s\n",
++               fts5yyTracePrompt, fts5yyTokenName[iLookAhead],
++               fts5yyTokenName[fts5YYWILDCARD]);
++          }
++#endif /* NDEBUG */
++          return fts5yy_action[j];
++        }
++      }
++#endif /* fts5YYWILDCARD */
++      return fts5yy_default[stateno];
++    }else{
++      return fts5yy_action[i];
++    }
++  }while(1);
++}
++
 +/*
-+** This function outputs the specified (ANSI) string to the Win32 debugger
-+** (if available).
++** Find the appropriate action for a parser given the non-terminal
++** look-ahead token iLookAhead.
 +*/
- 
--    /* Did we just have a reader lock? */
--    else if (pFile->local.nReaders){
--      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE
--             || nNumberOfBytesToUnlockLow == 1);
--      pFile->local.nReaders --;
--      if (pFile->local.nReaders == 0)
--      {
--        pFile->shared->nReaders --;
--      }
--      bReturn = TRUE;
--    }
-+SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int nBuf){
-+  char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
-+  int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
-+  if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
-+  assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
-+#if defined(SQLITE_WIN32_HAS_ANSI)
-+  if( nMin>0 ){
-+    memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
-+    memcpy(zDbgBuf, zBuf, nMin);
-+    osOutputDebugStringA(zDbgBuf);
-+  }else{
-+    osOutputDebugStringA(zBuf);
-   }
--
--  /* Releasing a pending lock */
--  else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
--           && nNumberOfBytesToUnlockLow == 1){
--    if (pFile->local.bPending){
--      pFile->local.bPending = FALSE;
--      pFile->shared->bPending = FALSE;
--      bReturn = TRUE;
--    }
-+#elif defined(SQLITE_WIN32_HAS_WIDE)
-+  memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
-+  if ( osMultiByteToWideChar(
-+          osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf,
-+          nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){
-+    return;
-   }
--  /* Releasing a reserved lock */
--  else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
--           && nNumberOfBytesToUnlockLow == 1){
--    if (pFile->local.bReserved) {
--      pFile->local.bReserved = FALSE;
--      pFile->shared->bReserved = FALSE;
--      bReturn = TRUE;
--    }
-+  osOutputDebugStringW((LPCWSTR)zDbgBuf);
++static int fts5yy_find_reduce_action(
++  int stateno,              /* Current state number */
++  fts5YYCODETYPE iLookAhead     /* The look-ahead token */
++){
++  int i;
++#ifdef fts5YYERRORSYMBOL
++  if( stateno>fts5YY_REDUCE_COUNT ){
++    return fts5yy_default[stateno];
++  }
 +#else
-+  if( nMin>0 ){
-+    memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
-+    memcpy(zDbgBuf, zBuf, nMin);
-+    fprintf(stderr, "%s", zDbgBuf);
-+  }else{
-+    fprintf(stderr, "%s", zBuf);
-   }
++  assert( stateno<=fts5YY_REDUCE_COUNT );
++#endif
++  i = fts5yy_reduce_ofst[stateno];
++  assert( i!=fts5YY_REDUCE_USE_DFLT );
++  assert( iLookAhead!=fts5YYNOCODE );
++  i += iLookAhead;
++#ifdef fts5YYERRORSYMBOL
++  if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){
++    return fts5yy_default[stateno];
++  }
++#else
++  assert( i>=0 && i<fts5YY_ACTTAB_COUNT );
++  assert( fts5yy_lookahead[i]==iLookAhead );
 +#endif
++  return fts5yy_action[i];
 +}
- 
--  winceMutexRelease(pFile->hMutex);
--  return bReturn;
++
 +/*
-+** The following routine suspends the current thread for at least ms
-+** milliseconds.  This is equivalent to the Win32 Sleep() interface.
++** The following routine is called if the stack overflows.
 +*/
-+#if SQLITE_OS_WINRT
-+static HANDLE sleepObj = NULL;
++static void fts5yyStackOverflow(fts5yyParser *fts5yypParser){
++   sqlite3Fts5ParserARG_FETCH;
++#ifndef NDEBUG
++   if( fts5yyTraceFILE ){
++     fprintf(fts5yyTraceFILE,"%sStack Overflow!\n",fts5yyTracePrompt);
++   }
 +#endif
++   while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ) fts5yy_pop_parser_stack(fts5yypParser);
++   /* Here code is inserted which will execute if the parser
++   ** stack every overflows */
++/******** Begin %stack_overflow code ******************************************/
++
++  sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
++/******** End %stack_overflow code ********************************************/
++   sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
++}
 +
-+SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds){
-+#if SQLITE_OS_WINRT
-+  if ( sleepObj==NULL ){
-+    sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
-+                                SYNCHRONIZE);
++/*
++** Print tracing information for a SHIFT action
++*/
++#ifndef NDEBUG
++static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState){
++  if( fts5yyTraceFILE ){
++    if( fts5yyNewState<fts5YYNSTATE ){
++      fprintf(fts5yyTraceFILE,"%sShift '%s', go to state %d\n",
++         fts5yyTracePrompt,fts5yyTokenName[fts5yypParser->fts5yytos->major],
++         fts5yyNewState);
++    }else{
++      fprintf(fts5yyTraceFILE,"%sShift '%s'\n",
++         fts5yyTracePrompt,fts5yyTokenName[fts5yypParser->fts5yytos->major]);
++    }
 +  }
-+  assert( sleepObj!=NULL );
-+  osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
-+#else
-+  osSleep(milliseconds);
-+#endif
 +}
-+
-+#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
-+        SQLITE_THREADSAFE>0
-+SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
-+  DWORD rc;
-+  while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
-+                                       TRUE))==WAIT_IO_COMPLETION ){}
-+  return rc;
- }
++#else
++# define fts5yyTraceShift(X,Y)
 +#endif
 +
- /*
--** End of the special code for wince
--*****************************************************************************/
--#endif /* SQLITE_OS_WINCE */
-+** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
-+** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
-+**
-+** Here is an interesting observation:  Win95, Win98, and WinME lack
-+** the LockFileEx() API.  But we can still statically link against that
-+** API as long as we don't call it when running Win95/98/ME.  A call to
-+** this routine is used to determine if the host is Win95/98/ME or
-+** WinNT/2K/XP so that we will know whether or not we can safely call
-+** the LockFileEx() API.
++/*
++** Perform a shift action.
 +*/
-+
-+#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX
-+# define osIsNT()  (1)
-+#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
-+# define osIsNT()  (1)
-+#elif !defined(SQLITE_WIN32_HAS_WIDE)
-+# define osIsNT()  (0)
-+#else
-+# define osIsNT()  ((sqlite3_os_type==2) || sqlite3_win32_is_nt())
++static void fts5yy_shift(
++  fts5yyParser *fts5yypParser,          /* The parser to be shifted */
++  int fts5yyNewState,               /* The new state to shift in */
++  int fts5yyMajor,                  /* The major token to shift in */
++  sqlite3Fts5ParserFTS5TOKENTYPE fts5yyMinor        /* The minor token to shift in */
++){
++  fts5yyStackEntry *fts5yytos;
++  fts5yypParser->fts5yytos++;
++#ifdef fts5YYTRACKMAXSTACKDEPTH
++  if( (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)>fts5yypParser->fts5yyhwm ){
++    fts5yypParser->fts5yyhwm++;
++    assert( fts5yypParser->fts5yyhwm == (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack) );
++  }
 +#endif
- 
- /*
--** Lock a file region.
-+** This function determines if the machine is running a version of Windows
-+** based on the NT kernel.
- */
--static BOOL winLockFile(
--  LPHANDLE phFile,
--  DWORD flags,
--  DWORD offsetLow,
--  DWORD offsetHigh,
--  DWORD numBytesLow,
--  DWORD numBytesHigh
--){
--#if SQLITE_OS_WINCE
-+SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){
-+#if SQLITE_OS_WINRT
-   /*
--  ** NOTE: Windows CE is handled differently here due its lack of the Win32
--  **       API LockFile.
-+  ** NOTE: The WinRT sub-platform is always assumed to be based on the NT
-+  **       kernel.
-   */
--  return winceLockFile(phFile, offsetLow, offsetHigh,
--                       numBytesLow, numBytesHigh);
-+  return 1;
-+#elif defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
-+  if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){
-+#if defined(SQLITE_WIN32_HAS_ANSI)
-+    OSVERSIONINFOA sInfo;
-+    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
-+    osGetVersionExA(&sInfo);
-+    osInterlockedCompareExchange(&sqlite3_os_type,
-+        (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
-+#elif defined(SQLITE_WIN32_HAS_WIDE)
-+    OSVERSIONINFOW sInfo;
-+    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
-+    osGetVersionExW(&sInfo);
-+    osInterlockedCompareExchange(&sqlite3_os_type,
-+        (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
-+#endif
-+  }
-+  return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
-+#elif SQLITE_TEST
-+  return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
- #else
--  if( osIsNT() ){
--    OVERLAPPED ovlp;
--    memset(&ovlp, 0, sizeof(OVERLAPPED));
--    ovlp.Offset = offsetLow;
--    ovlp.OffsetHigh = offsetHigh;
--    return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp);
--  }else{
--    return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
--                      numBytesHigh);
-+  /*
-+  ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are
-+  **       deprecated are always assumed to be based on the NT kernel.
-+  */
-+  return 1;
++#if fts5YYSTACKDEPTH>0 
++  if( fts5yypParser->fts5yytos>fts5yypParser->fts5yystackEnd ){
++    fts5yypParser->fts5yytos--;
++    fts5yyStackOverflow(fts5yypParser);
++    return;
++  }
++#else
++  if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz] ){
++    if( fts5yyGrowStack(fts5yypParser) ){
++      fts5yypParser->fts5yytos--;
++      fts5yyStackOverflow(fts5yypParser);
++      return;
++    }
++  }
 +#endif
++  if( fts5yyNewState > fts5YY_MAX_SHIFT ){
++    fts5yyNewState += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
++  }
++  fts5yytos = fts5yypParser->fts5yytos;
++  fts5yytos->stateno = (fts5YYACTIONTYPE)fts5yyNewState;
++  fts5yytos->major = (fts5YYCODETYPE)fts5yyMajor;
++  fts5yytos->minor.fts5yy0 = fts5yyMinor;
++  fts5yyTraceShift(fts5yypParser, fts5yyNewState);
 +}
 +
-+#ifdef SQLITE_WIN32_MALLOC
-+/*
-+** Allocate nBytes of memory.
++/* The following table contains information about every rule that
++** is used during the reduce.
 +*/
-+static void *winMemMalloc(int nBytes){
-+  HANDLE hHeap;
-+  void *p;
++static const struct {
++  fts5YYCODETYPE lhs;       /* Symbol on the left-hand side of the rule */
++  signed char nrhs;     /* Negative of the number of RHS symbols in the rule */
++} fts5yyRuleInfo[] = {
++  { 16, -1 },
++  { 20, -4 },
++  { 20, -3 },
++  { 20, -1 },
++  { 20, -2 },
++  { 21, -2 },
++  { 21, -1 },
++  { 17, -3 },
++  { 17, -3 },
++  { 17, -3 },
++  { 17, -5 },
++  { 17, -3 },
++  { 17, -1 },
++  { 19, -1 },
++  { 19, -2 },
++  { 18, -1 },
++  { 18, -3 },
++  { 22, -1 },
++  { 22, -5 },
++  { 23, -1 },
++  { 23, -2 },
++  { 25, 0 },
++  { 25, -2 },
++  { 24, -4 },
++  { 24, -2 },
++  { 26, -1 },
++  { 26, 0 },
++};
 +
-+  winMemAssertMagic();
-+  hHeap = winMemGetHeap();
-+  assert( hHeap!=0 );
-+  assert( hHeap!=INVALID_HANDLE_VALUE );
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
-+  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
-+#endif
-+  assert( nBytes>=0 );
-+  p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
-+  if( !p ){
-+    sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p",
-+                nBytes, osGetLastError(), (void*)hHeap);
-   }
-+  return p;
-+}
++static void fts5yy_accept(fts5yyParser*);  /* Forward Declaration */
 +
 +/*
-+** Free memory.
++** Perform a reduce action and the shift that must immediately
++** follow the reduce.
 +*/
-+static void winMemFree(void *pPrior){
-+  HANDLE hHeap;
-+
-+  winMemAssertMagic();
-+  hHeap = winMemGetHeap();
-+  assert( hHeap!=0 );
-+  assert( hHeap!=INVALID_HANDLE_VALUE );
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
-+  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
- #endif
-+  if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
-+  if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
-+    sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p",
-+                pPrior, osGetLastError(), (void*)hHeap);
++static void fts5yy_reduce(
++  fts5yyParser *fts5yypParser,         /* The parser */
++  unsigned int fts5yyruleno        /* Number of the rule by which to reduce */
++){
++  int fts5yygoto;                     /* The next state */
++  int fts5yyact;                      /* The next action */
++  fts5yyStackEntry *fts5yymsp;            /* The top of the parser's stack */
++  int fts5yysize;                     /* Amount to pop the stack */
++  sqlite3Fts5ParserARG_FETCH;
++  fts5yymsp = fts5yypParser->fts5yytos;
++#ifndef NDEBUG
++  if( fts5yyTraceFILE && fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){
++    fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
++    fprintf(fts5yyTraceFILE, "%sReduce [%s], go to state %d.\n", fts5yyTracePrompt,
++      fts5yyRuleName[fts5yyruleno], fts5yymsp[fts5yysize].stateno);
 +  }
- }
- 
- /*
--** Unlock a file region.
-- */
--static BOOL winUnlockFile(
--  LPHANDLE phFile,
--  DWORD offsetLow,
--  DWORD offsetHigh,
--  DWORD numBytesLow,
--  DWORD numBytesHigh
--){
--#if SQLITE_OS_WINCE
--  /*
--  ** NOTE: Windows CE is handled differently here due its lack of the Win32
--  **       API UnlockFile.
--  */
--  return winceUnlockFile(phFile, offsetLow, offsetHigh,
--                         numBytesLow, numBytesHigh);
--#else
--  if( osIsNT() ){
--    OVERLAPPED ovlp;
--    memset(&ovlp, 0, sizeof(OVERLAPPED));
--    ovlp.Offset = offsetLow;
--    ovlp.OffsetHigh = offsetHigh;
--    return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp);
--  }else{
--    return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
--                        numBytesHigh);
-+** Change the size of an existing memory allocation
-+*/
-+static void *winMemRealloc(void *pPrior, int nBytes){
-+  HANDLE hHeap;
-+  void *p;
-+
-+  winMemAssertMagic();
-+  hHeap = winMemGetHeap();
-+  assert( hHeap!=0 );
-+  assert( hHeap!=INVALID_HANDLE_VALUE );
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
-+  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
++#endif /* NDEBUG */
++
++  /* Check that the stack is large enough to grow by a single entry
++  ** if the RHS of the rule is empty.  This ensures that there is room
++  ** enough on the stack to push the LHS value */
++  if( fts5yyRuleInfo[fts5yyruleno].nrhs==0 ){
++#ifdef fts5YYTRACKMAXSTACKDEPTH
++    if( (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)>fts5yypParser->fts5yyhwm ){
++      fts5yypParser->fts5yyhwm++;
++      assert( fts5yypParser->fts5yyhwm == (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack));
++    }
++#endif
++#if fts5YYSTACKDEPTH>0 
++    if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){
++      fts5yyStackOverflow(fts5yypParser);
++      return;
++    }
++#else
++    if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz-1] ){
++      if( fts5yyGrowStack(fts5yypParser) ){
++        fts5yyStackOverflow(fts5yypParser);
++        return;
++      }
++      fts5yymsp = fts5yypParser->fts5yytos;
++    }
 +#endif
-+  assert( nBytes>=0 );
-+  if( !pPrior ){
-+    p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
-+  }else{
-+    p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
-   }
--#endif
-+  if( !p ){
-+    sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p",
-+                pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(),
-+                (void*)hHeap);
 +  }
-+  return p;
- }
- 
--/*****************************************************************************
--** The next group of routines implement the I/O methods specified
--** by the sqlite3_io_methods object.
--******************************************************************************/
--
- /*
--** Some Microsoft compilers lack this definition.
-+** Return the size of an outstanding allocation, in bytes.
- */
--#ifndef INVALID_SET_FILE_POINTER
--# define INVALID_SET_FILE_POINTER ((DWORD)-1)
-+static int winMemSize(void *p){
-+  HANDLE hHeap;
-+  SIZE_T n;
 +
-+  winMemAssertMagic();
-+  hHeap = winMemGetHeap();
-+  assert( hHeap!=0 );
-+  assert( hHeap!=INVALID_HANDLE_VALUE );
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
-+  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) );
- #endif
-+  if( !p ) return 0;
-+  n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
-+  if( n==(SIZE_T)-1 ){
-+    sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p",
-+                p, osGetLastError(), (void*)hHeap);
-+    return 0;
-+  }
-+  return (int)n;
++  switch( fts5yyruleno ){
++  /* Beginning here are the reduction cases.  A typical example
++  ** follows:
++  **   case 0:
++  **  #line <lineno> <grammarfile>
++  **     { ... }           // User supplied code
++  **  #line <lineno> <thisfile>
++  **     break;
++  */
++/********** Begin reduce actions **********************************************/
++        fts5YYMINORTYPE fts5yylhsminor;
++      case 0: /* input ::= expr */
++{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); }
++        break;
++      case 1: /* colset ::= MINUS LCP colsetlist RCP */
++{ 
++    fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
 +}
- 
- /*
--** Move the current position of the file handle passed as the first
--** argument to offset iOffset within the file. If successful, return 0.
--** Otherwise, set pFile->lastErrno and return non-zero.
-+** Round up a request size to the next valid allocation size.
- */
--static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){
--#if !SQLITE_OS_WINRT
--  LONG upperBits;                 /* Most sig. 32 bits of new offset */
--  LONG lowerBits;                 /* Least sig. 32 bits of new offset */
--  DWORD dwRet;                    /* Value returned by SetFilePointer() */
--  DWORD lastErrno;                /* Value returned by GetLastError() */
--
--  OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset));
-+static int winMemRoundup(int n){
-+  return n;
++        break;
++      case 2: /* colset ::= LCP colsetlist RCP */
++{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
++        break;
++      case 3: /* colset ::= STRING */
++{
++  fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
 +}
- 
--  upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
--  lowerBits = (LONG)(iOffset & 0xffffffff);
-+/*
-+** Initialize this module.
-+*/
-+static int winMemInit(void *pAppData){
-+  winMemData *pWinMemData = (winMemData *)pAppData;
- 
--  /* API oddity: If successful, SetFilePointer() returns a dword
--  ** containing the lower 32-bits of the new file-offset. Or, if it fails,
--  ** it returns INVALID_SET_FILE_POINTER. However according to MSDN,
--  ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine
--  ** whether an error has actually occurred, it is also necessary to call
--  ** GetLastError().
--  */
--  dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
-+  if( !pWinMemData ) return SQLITE_ERROR;
-+  assert( pWinMemData->magic1==WINMEM_MAGIC1 );
-+  assert( pWinMemData->magic2==WINMEM_MAGIC2 );
- 
--  if( (dwRet==INVALID_SET_FILE_POINTER
--      && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
--    pFile->lastErrno = lastErrno;
--    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
--                "winSeekFile", pFile->zPath);
--    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
--    return 1;
-+#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
-+  if( !pWinMemData->hHeap ){
-+    DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE;
-+    DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap;
-+    if( dwMaximumSize==0 ){
-+      dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE;
-+    }else if( dwInitialSize>dwMaximumSize ){
-+      dwInitialSize = dwMaximumSize;
-+    }
-+    pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
-+                                      dwInitialSize, dwMaximumSize);
-+    if( !pWinMemData->hHeap ){
-+      sqlite3_log(SQLITE_NOMEM,
-+          "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
-+          osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
-+          dwMaximumSize);
-+      return SQLITE_NOMEM;
-+    }
-+    pWinMemData->bOwned = TRUE;
-+    assert( pWinMemData->bOwned );
-   }
--
--  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
--  return 0;
- #else
--  /*
--  ** Same as above, except that this implementation works for WinRT.
--  */
--
--  LARGE_INTEGER x;                /* The new offset */
--  BOOL bRet;                      /* Value returned by SetFilePointerEx() */
--
--  x.QuadPart = iOffset;
--  bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);
--
--  if(!bRet){
--    pFile->lastErrno = osGetLastError();
--    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
--                "winSeekFile", pFile->zPath);
--    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
--    return 1;
-+  pWinMemData->hHeap = osGetProcessHeap();
-+  if( !pWinMemData->hHeap ){
-+    sqlite3_log(SQLITE_NOMEM,
-+        "failed to GetProcessHeap (%lu)", osGetLastError());
-+    return SQLITE_NOMEM;
-   }
--
--  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
--  return 0;
-+  pWinMemData->bOwned = FALSE;
-+  assert( !pWinMemData->bOwned );
- #endif
--}
--
--#if SQLITE_MAX_MMAP_SIZE>0
--/* Forward references to VFS helper methods used for memory mapped files */
--static int winMapfile(winFile*, sqlite3_int64);
--static int winUnmapfile(winFile*);
-+  assert( pWinMemData->hHeap!=0 );
-+  assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
-+  assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
- #endif
-+  return SQLITE_OK;
++  fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
++        break;
++      case 4: /* colset ::= MINUS STRING */
++{
++  fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
++  fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
 +}
- 
- /*
--** Close a file.
--**
--** It is reported that an attempt to close a handle might sometimes
--** fail.  This is a very unreasonable result, but Windows is notorious
--** for being unreasonable so I do not doubt that it might happen.  If
--** the close fails, we pause for 100 milliseconds and try again.  As
--** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
--** giving up and returning an error.
-+** Deinitialize this module.
- */
--#define MX_CLOSE_ATTEMPT 3
--static int winClose(sqlite3_file *id){
--  int rc, cnt = 0;
--  winFile *pFile = (winFile*)id;
-+static void winMemShutdown(void *pAppData){
-+  winMemData *pWinMemData = (winMemData *)pAppData;
- 
--  assert( id!=0 );
--#ifndef SQLITE_OMIT_WAL
--  assert( pFile->pShm==0 );
--#endif
--  assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
--  OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n",
--           osGetCurrentProcessId(), pFile, pFile->h));
-+  if( !pWinMemData ) return;
-+  assert( pWinMemData->magic1==WINMEM_MAGIC1 );
-+  assert( pWinMemData->magic2==WINMEM_MAGIC2 );
- 
--#if SQLITE_MAX_MMAP_SIZE>0
--  winUnmapfile(pFile);
-+  if( pWinMemData->hHeap ){
-+    assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
-+    assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
- #endif
--
--  do{
--    rc = osCloseHandle(pFile->h);
--    /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
--  }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
--#if SQLITE_OS_WINCE
--#define WINCE_DELETION_ATTEMPTS 3
--  winceDestroyLock(pFile);
--  if( pFile->zDeleteOnClose ){
--    int cnt = 0;
--    while(
--           osDeleteFileW(pFile->zDeleteOnClose)==0
--        && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
--        && cnt++ < WINCE_DELETION_ATTEMPTS
--    ){
--       sqlite3_win32_sleep(100);  /* Wait a little before trying again */
-+    if( pWinMemData->bOwned ){
-+      if( !osHeapDestroy(pWinMemData->hHeap) ){
-+        sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p",
-+                    osGetLastError(), (void*)pWinMemData->hHeap);
-+      }
-+      pWinMemData->bOwned = FALSE;
-     }
--    sqlite3_free(pFile->zDeleteOnClose);
--  }
--#endif
--  if( rc ){
--    pFile->h = NULL;
-+    pWinMemData->hHeap = NULL;
-   }
--  OpenCounter(-1);
--  OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n",
--           osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed"));
--  return rc ? SQLITE_OK
--            : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
--                          "winClose", pFile->zPath);
- }
- 
- /*
--** Read data from a file into a buffer.  Return SQLITE_OK if all
--** bytes were read successfully and SQLITE_IOERR if anything goes
--** wrong.
-+** Populate the low-level memory allocation function pointers in
-+** sqlite3GlobalConfig.m with pointers to the routines in this file. The
-+** arguments specify the block of memory to manage.
-+**
-+** This routine is only called by sqlite3_config(), and therefore
-+** is not required to be threadsafe (it is not).
- */
--static int winRead(
--  sqlite3_file *id,          /* File to read from */
--  void *pBuf,                /* Write content into this buffer */
--  int amt,                   /* Number of bytes to read */
--  sqlite3_int64 offset       /* Begin reading at this offset */
--){
--#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
--  OVERLAPPED overlapped;          /* The offset for ReadFile. */
--#endif
--  winFile *pFile = (winFile*)id;  /* file handle */
--  DWORD nRead;                    /* Number of bytes actually read from file */
--  int nRetry = 0;                 /* Number of retrys */
-+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void){
-+  static const sqlite3_mem_methods winMemMethods = {
-+    winMemMalloc,
-+    winMemFree,
-+    winMemRealloc,
-+    winMemSize,
-+    winMemRoundup,
-+    winMemInit,
-+    winMemShutdown,
-+    &win_mem_data
-+  };
-+  return &winMemMethods;
++        break;
++      case 5: /* colsetlist ::= colsetlist STRING */
++{ 
++  fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, 
&fts5yymsp[0].minor.fts5yy0); }
++  fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
++        break;
++      case 6: /* colsetlist ::= STRING */
++{ 
++  fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); 
 +}
- 
--  assert( id!=0 );
--  assert( amt>0 );
--  assert( offset>=0 );
--  SimulateIOError(return SQLITE_IOERR_READ);
--  OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
--           "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
--           pFile->h, pBuf, amt, offset, pFile->locktype));
-+SQLITE_PRIVATE void sqlite3MemSetDefault(void){
-+  sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32());
++  fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
++        break;
++      case 7: /* expr ::= expr AND expr */
++{
++  fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, 
fts5yymsp[0].minor.fts5yy24, 0);
 +}
-+#endif /* SQLITE_WIN32_MALLOC */
- 
--#if SQLITE_MAX_MMAP_SIZE>0
--  /* Deal with as much of this read request as possible by transfering
--  ** data from the memory mapping using memcpy().  */
--  if( offset<pFile->mmapSize ){
--    if( offset+amt <= pFile->mmapSize ){
--      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
--      OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
--               osGetCurrentProcessId(), pFile, pFile->h));
--      return SQLITE_OK;
--    }else{
--      int nCopy = (int)(pFile->mmapSize - offset);
--      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
--      pBuf = &((u8 *)pBuf)[nCopy];
--      amt -= nCopy;
--      offset += nCopy;
--    }
--  }
--#endif
-+/*
-+** Convert a UTF-8 string to Microsoft Unicode (UTF-16?).
-+**
-+** Space to hold the returned string is obtained from malloc.
-+*/
-+static LPWSTR winUtf8ToUnicode(const char *zFilename){
-+  int nChar;
-+  LPWSTR zWideFilename;
- 
--#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
--  if( winSeekFile(pFile, offset) ){
--    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
--             osGetCurrentProcessId(), pFile, pFile->h));
--    return SQLITE_FULL;
-+  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
-+  if( nChar==0 ){
-+    return 0;
-   }
--  while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
--#else
--  memset(&overlapped, 0, sizeof(OVERLAPPED));
--  overlapped.Offset = (LONG)(offset & 0xffffffff);
--  overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
--  while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) &&
--         osGetLastError()!=ERROR_HANDLE_EOF ){
--#endif
--    DWORD lastErrno;
--    if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
--    pFile->lastErrno = lastErrno;
--    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n",
--             osGetCurrentProcessId(), pFile, pFile->h));
--    return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
--                       "winRead", pFile->zPath);
-+  zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
-+  if( zWideFilename==0 ){
-+    return 0;
-   }
--  winLogIoerr(nRetry, __LINE__);
--  if( nRead<(DWORD)amt ){
--    /* Unread parts of the buffer must be zero-filled */
--    memset(&((char*)pBuf)[nRead], 0, amt-nRead);
--    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n",
--             osGetCurrentProcessId(), pFile, pFile->h));
--    return SQLITE_IOERR_SHORT_READ;
-+  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
-+                                nChar);
-+  if( nChar==0 ){
-+    sqlite3_free(zWideFilename);
-+    zWideFilename = 0;
-   }
--
--  OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
--           osGetCurrentProcessId(), pFile, pFile->h));
--  return SQLITE_OK;
-+  return zWideFilename;
- }
- 
- /*
--** Write data from a buffer into a file.  Return SQLITE_OK on success
--** or some other error code on failure.
-+** Convert Microsoft Unicode to UTF-8.  Space to hold the returned string is
-+** obtained from sqlite3_malloc().
- */
--static int winWrite(
--  sqlite3_file *id,               /* File to write into */
--  const void *pBuf,               /* The bytes to be written */
--  int amt,                        /* Number of bytes to write */
--  sqlite3_int64 offset            /* Offset into the file to begin writing at */
--){
--  int rc = 0;                     /* True if error has occurred, else false */
--  winFile *pFile = (winFile*)id;  /* File handle */
--  int nRetry = 0;                 /* Number of retries */
--
--  assert( amt>0 );
--  assert( pFile );
--  SimulateIOError(return SQLITE_IOERR_WRITE);
--  SimulateDiskfullError(return SQLITE_FULL);
--
--  OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
--           "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
--           pFile->h, pBuf, amt, offset, pFile->locktype));
-+static char *winUnicodeToUtf8(LPCWSTR zWideFilename){
-+  int nByte;
-+  char *zFilename;
- 
--#if SQLITE_MAX_MMAP_SIZE>0
--  /* Deal with as much of this write request as possible by transfering
--  ** data from the memory mapping using memcpy().  */
--  if( offset<pFile->mmapSize ){
--    if( offset+amt <= pFile->mmapSize ){
--      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
--      OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
--               osGetCurrentProcessId(), pFile, pFile->h));
--      return SQLITE_OK;
--    }else{
--      int nCopy = (int)(pFile->mmapSize - offset);
--      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
--      pBuf = &((u8 *)pBuf)[nCopy];
--      amt -= nCopy;
--      offset += nCopy;
--    }
-+  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
-+  if( nByte == 0 ){
-+    return 0;
-   }
--#endif
--
--#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
--  rc = winSeekFile(pFile, offset);
--  if( rc==0 ){
--#else
--  {
--#endif
--#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
--    OVERLAPPED overlapped;        /* The offset for WriteFile. */
--#endif
--    u8 *aRem = (u8 *)pBuf;        /* Data yet to be written */
--    int nRem = amt;               /* Number of bytes yet to be written */
--    DWORD nWrite;                 /* Bytes written by each WriteFile() call */
--    DWORD lastErrno = NO_ERROR;   /* Value returned by GetLastError() */
-+  zFilename = sqlite3MallocZero( nByte );
-+  if( zFilename==0 ){
-+    return 0;
-+  }
-+  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
-+                                0, 0);
-+  if( nByte == 0 ){
-+    sqlite3_free(zFilename);
-+    zFilename = 0;
++  fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
++        break;
++      case 8: /* expr ::= expr OR expr */
++{
++  fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, 
fts5yymsp[0].minor.fts5yy24, 0);
++}
++  fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
++        break;
++      case 9: /* expr ::= expr NOT expr */
++{
++  fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, 
fts5yymsp[0].minor.fts5yy24, 0);
++}
++  fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
++        break;
++      case 10: /* expr ::= colset COLON LP expr RP */
++{
++  sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11);
++  fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;
++}
++  fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
++        break;
++      case 11: /* expr ::= LP expr RP */
++{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;}
++        break;
++      case 12: /* expr ::= exprlist */
++      case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13);
++{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;}
++  fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
++        break;
++      case 14: /* exprlist ::= exprlist cnearset */
++{
++  fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, 
fts5yymsp[0].minor.fts5yy24);
++}
++  fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
++        break;
++      case 15: /* cnearset ::= nearset */
++{ 
++  fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); 
++}
++  fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
++        break;
++      case 16: /* cnearset ::= colset COLON nearset */
++{ 
++  fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); 
++  sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11);
++}
++  fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
++        break;
++      case 17: /* nearset ::= phrase */
++{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
++  fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
++        break;
++      case 18: /* nearset ::= STRING LP nearphrases neardist_opt RP */
++{
++  sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
++  sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
++  fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46;
++}
++  fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
++        break;
++      case 19: /* nearphrases ::= phrase */
++{ 
++  fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); 
++}
++  fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
++        break;
++      case 20: /* nearphrases ::= nearphrases phrase */
++{
++  fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, 
fts5yymsp[0].minor.fts5yy53);
++}
++  fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
++        break;
++      case 21: /* neardist_opt ::= */
++{ fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
++        break;
++      case 22: /* neardist_opt ::= COMMA STRING */
++{ fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
++        break;
++      case 23: /* phrase ::= phrase PLUS STRING star_opt */
++{ 
++  fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, 
&fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
++}
++  fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
++        break;
++      case 24: /* phrase ::= STRING star_opt */
++{ 
++  fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, 
fts5yymsp[0].minor.fts5yy4);
++}
++  fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
++        break;
++      case 25: /* star_opt ::= STAR */
++{ fts5yymsp[0].minor.fts5yy4 = 1; }
++        break;
++      case 26: /* star_opt ::= */
++{ fts5yymsp[1].minor.fts5yy4 = 0; }
++        break;
++      default:
++        break;
++/********** End reduce actions ************************************************/
++  };
++  assert( fts5yyruleno<sizeof(fts5yyRuleInfo)/sizeof(fts5yyRuleInfo[0]) );
++  fts5yygoto = fts5yyRuleInfo[fts5yyruleno].lhs;
++  fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
++  fts5yyact = fts5yy_find_reduce_action(fts5yymsp[fts5yysize].stateno,(fts5YYCODETYPE)fts5yygoto);
++
++  /* There are no SHIFTREDUCE actions on nonterminals because the table
++  ** generator has simplified them to pure REDUCE actions. */
++  assert( !(fts5yyact>fts5YY_MAX_SHIFT && fts5yyact<=fts5YY_MAX_SHIFTREDUCE) );
++
++  /* It is not possible for a REDUCE to be followed by an error */
++  assert( fts5yyact!=fts5YY_ERROR_ACTION );
++
++  if( fts5yyact==fts5YY_ACCEPT_ACTION ){
++    fts5yypParser->fts5yytos += fts5yysize;
++    fts5yy_accept(fts5yypParser);
++  }else{
++    fts5yymsp += fts5yysize+1;
++    fts5yypParser->fts5yytos = fts5yymsp;
++    fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
++    fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
++    fts5yyTraceShift(fts5yypParser, fts5yyact);
 +  }
-+  return zFilename;
 +}
- 
--#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
--    memset(&overlapped, 0, sizeof(OVERLAPPED));
--    overlapped.Offset = (LONG)(offset & 0xffffffff);
--    overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
--#endif
++
 +/*
-+** Convert an ANSI string to Microsoft Unicode, based on the
-+** current codepage settings for file apis.
-+**
-+** Space to hold the returned string is obtained
-+** from sqlite3_malloc.
++** The following code executes when the parse fails
 +*/
-+static LPWSTR winMbcsToUnicode(const char *zFilename){
-+  int nByte;
-+  LPWSTR zMbcsFilename;
-+  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
- 
--    while( nRem>0 ){
--#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
--      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
--#else
--      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
--#endif
--        if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
--        break;
--      }
--      assert( nWrite==0 || nWrite<=(DWORD)nRem );
--      if( nWrite==0 || nWrite>(DWORD)nRem ){
--        lastErrno = osGetLastError();
--        break;
--      }
--#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
--      offset += nWrite;
--      overlapped.Offset = (LONG)(offset & 0xffffffff);
--      overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
--#endif
--      aRem += nWrite;
--      nRem -= nWrite;
--    }
--    if( nRem>0 ){
--      pFile->lastErrno = lastErrno;
--      rc = 1;
--    }
-+  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
-+                                0)*sizeof(WCHAR);
-+  if( nByte==0 ){
-+    return 0;
-   }
--
--  if( rc ){
--    if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
--       || ( pFile->lastErrno==ERROR_DISK_FULL )){
--      OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
--               osGetCurrentProcessId(), pFile, pFile->h));
--      return winLogError(SQLITE_FULL, pFile->lastErrno,
--                         "winWrite1", pFile->zPath);
--    }
--    OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n",
--             osGetCurrentProcessId(), pFile, pFile->h));
--    return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
--                       "winWrite2", pFile->zPath);
--  }else{
--    winLogIoerr(nRetry, __LINE__);
-+  zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
-+  if( zMbcsFilename==0 ){
-+    return 0;
-   }
--  OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
--           osGetCurrentProcessId(), pFile, pFile->h));
--  return SQLITE_OK;
-+  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
-+                                nByte);
-+  if( nByte==0 ){
-+    sqlite3_free(zMbcsFilename);
-+    zMbcsFilename = 0;
-+  }
-+  return zMbcsFilename;
- }
- 
- /*
--** Truncate an open file to a specified size
-+** Convert Microsoft Unicode to multi-byte character string, based on the
-+** user's ANSI codepage.
-+**
-+** Space to hold the returned string is obtained from
-+** sqlite3_malloc().
- */
--static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
--  winFile *pFile = (winFile*)id;  /* File handle object */
--  int rc = SQLITE_OK;             /* Return code for this function */
--  DWORD lastErrno;
--
--  assert( pFile );
--  SimulateIOError(return SQLITE_IOERR_TRUNCATE);
--  OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
--           osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype));
-+static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
-+  int nByte;
-+  char *zFilename;
-+  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
- 
--  /* If the user has configured a chunk-size for this file, truncate the
--  ** file so that it consists of an integer number of chunks (i.e. the
--  ** actual file size after the operation may be larger than the requested
--  ** size).
--  */
--  if( pFile->szChunk>0 ){
--    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
-+  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
-+  if( nByte == 0 ){
-+    return 0;
-   }
--
--  /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
--  if( winSeekFile(pFile, nByte) ){
--    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
--                     "winTruncate1", pFile->zPath);
--  }else if( 0==osSetEndOfFile(pFile->h) &&
--            ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){
--    pFile->lastErrno = lastErrno;
--    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
--                     "winTruncate2", pFile->zPath);
-+  zFilename = sqlite3MallocZero( nByte );
-+  if( zFilename==0 ){
-+    return 0;
-   }
--
--#if SQLITE_MAX_MMAP_SIZE>0
--  /* If the file was truncated to a size smaller than the currently
--  ** mapped region, reduce the effective mapping size as well. SQLite will
--  ** use read() and write() to access data beyond this point from now on.
--  */
--  if( pFile->pMapRegion && nByte<pFile->mmapSize ){
--    pFile->mmapSize = nByte;
-+  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename,
-+                                nByte, 0, 0);
-+  if( nByte == 0 ){
-+    sqlite3_free(zFilename);
-+    zFilename = 0;
-   }
--#endif
--
--  OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n",
--           osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc)));
--  return rc;
-+  return zFilename;
- }
- 
--#ifdef SQLITE_TEST
- /*
--** Count the number of fullsyncs and normal syncs.  This is used to test
--** that syncs and fullsyncs are occuring at the right times.
-+** Convert multibyte character string to UTF-8.  Space to hold the
-+** returned string is obtained from sqlite3_malloc().
- */
--SQLITE_API int sqlite3_sync_count = 0;
--SQLITE_API int sqlite3_fullsync_count = 0;
--#endif
-+SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename){
-+  char *zFilenameUtf8;
-+  LPWSTR zTmpWide;
-+
-+  zTmpWide = winMbcsToUnicode(zFilename);
-+  if( zTmpWide==0 ){
-+    return 0;
++#ifndef fts5YYNOERRORRECOVERY
++static void fts5yy_parse_failed(
++  fts5yyParser *fts5yypParser           /* The parser */
++){
++  sqlite3Fts5ParserARG_FETCH;
++#ifndef NDEBUG
++  if( fts5yyTraceFILE ){
++    fprintf(fts5yyTraceFILE,"%sFail!\n",fts5yyTracePrompt);
 +  }
-+  zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
-+  sqlite3_free(zTmpWide);
-+  return zFilenameUtf8;
-+}
- 
- /*
--** Make sure all writes to a particular file are committed to disk.
-+** Convert UTF-8 to multibyte character string.  Space to hold the
-+** returned string is obtained from sqlite3_malloc().
- */
--static int winSync(sqlite3_file *id, int flags){
--#ifndef SQLITE_NO_SYNC
--  /*
--  ** Used only when SQLITE_NO_SYNC is not defined.
--   */
--  BOOL rc;
--#endif
--#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
--    defined(SQLITE_HAVE_OS_TRACE)
--  /*
--  ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
--  ** OSTRACE() macros.
--   */
--  winFile *pFile = (winFile*)id;
--#else
--  UNUSED_PARAMETER(id);
--#endif
--
--  assert( pFile );
--  /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
--  assert((flags&0x0F)==SQLITE_SYNC_NORMAL
--      || (flags&0x0F)==SQLITE_SYNC_FULL
--  );
--
--  /* Unix cannot, but some systems may return SQLITE_FULL from here. This
--  ** line is to test that doing so does not cause any problems.
--  */
--  SimulateDiskfullError( return SQLITE_FULL );
--
--  OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n",
--           osGetCurrentProcessId(), pFile, pFile->h, flags,
--           pFile->locktype));
-+SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename){
-+  char *zFilenameMbcs;
-+  LPWSTR zTmpWide;
- 
--#ifndef SQLITE_TEST
--  UNUSED_PARAMETER(flags);
--#else
--  if( (flags&0x0F)==SQLITE_SYNC_FULL ){
--    sqlite3_fullsync_count++;
-+  zTmpWide = winUtf8ToUnicode(zFilename);
-+  if( zTmpWide==0 ){
-+    return 0;
-   }
--  sqlite3_sync_count++;
--#endif
-+  zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
-+  sqlite3_free(zTmpWide);
-+  return zFilenameMbcs;
++#endif
++  while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ) fts5yy_pop_parser_stack(fts5yypParser);
++  /* Here code is inserted which will be executed whenever the
++  ** parser fails */
++/************ Begin %parse_failure code ***************************************/
++/************ End %parse_failure code *****************************************/
++  sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
 +}
- 
--  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
--  ** no-op
--  */
--#ifdef SQLITE_NO_SYNC
--  OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
--           osGetCurrentProcessId(), pFile, pFile->h));
--  return SQLITE_OK;
--#else
--#if SQLITE_MAX_MMAP_SIZE>0
--  if( pFile->pMapRegion ){
--    if( osFlushViewOfFile(pFile->pMapRegion, 0) ){
--      OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
--               "rc=SQLITE_OK\n", osGetCurrentProcessId(),
--               pFile, pFile->pMapRegion));
--    }else{
--      pFile->lastErrno = osGetLastError();
--      OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
--               "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(),
--               pFile, pFile->pMapRegion));
--      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
--                         "winSync1", pFile->zPath);
--    }
--  }
++#endif /* fts5YYNOERRORRECOVERY */
++
 +/*
-+** 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.
++** The following code executes when a syntax error first occurs.
 +*/
-+SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
-+  char **ppDirectory = 0;
-+#ifndef SQLITE_OMIT_AUTOINIT
-+  int rc = sqlite3_initialize();
-+  if( rc ) return rc;
- #endif
--  rc = osFlushFileBuffers(pFile->h);
--  SimulateIOError( rc=FALSE );
--  if( rc ){
--    OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
--             osGetCurrentProcessId(), pFile, pFile->h));
-+  if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
-+    ppDirectory = &sqlite3_data_directory;
-+  }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){
-+    ppDirectory = &sqlite3_temp_directory;
-+  }
-+  assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE
-+          || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE
++static void fts5yy_syntax_error(
++  fts5yyParser *fts5yypParser,           /* The parser */
++  int fts5yymajor,                   /* The major type of the error token */
++  sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor         /* The minor type of the error token */
++){
++  sqlite3Fts5ParserARG_FETCH;
++#define FTS5TOKEN fts5yyminor
++/************ Begin %syntax_error code ****************************************/
++
++  UNUSED_PARAM(fts5yymajor); /* Silence a compiler warning */
++  sqlite3Fts5ParseError(
++    pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p
 +  );
-+  assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
-+  if( ppDirectory ){
-+    char *zValueUtf8 = 0;
-+    if( zValue && zValue[0] ){
-+      zValueUtf8 = winUnicodeToUtf8(zValue);
-+      if ( zValueUtf8==0 ){
-+        return SQLITE_NOMEM;
++/************ End %syntax_error code ******************************************/
++  sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++}
++
++/*
++** The following is executed when the parser accepts
++*/
++static void fts5yy_accept(
++  fts5yyParser *fts5yypParser           /* The parser */
++){
++  sqlite3Fts5ParserARG_FETCH;
++#ifndef NDEBUG
++  if( fts5yyTraceFILE ){
++    fprintf(fts5yyTraceFILE,"%sAccept!\n",fts5yyTracePrompt);
++  }
++#endif
++#ifndef fts5YYNOERRORRECOVERY
++  fts5yypParser->fts5yyerrcnt = -1;
++#endif
++  assert( fts5yypParser->fts5yytos==fts5yypParser->fts5yystack );
++  /* Here code is inserted which will be executed whenever the
++  ** parser accepts */
++/*********** Begin %parse_accept code *****************************************/
++/*********** End %parse_accept code *******************************************/
++  sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++}
++
++/* The main parser program.
++** The first argument is a pointer to a structure obtained from
++** "sqlite3Fts5ParserAlloc" which describes the current state of the parser.
++** The second argument is the major token number.  The third is
++** the minor token.  The fourth optional argument is whatever the
++** user wants (and specified in the grammar) and is available for
++** use by the action routines.
++**
++** Inputs:
++** <ul>
++** <li> A pointer to the parser (an opaque structure.)
++** <li> The major token number.
++** <li> The minor token number.
++** <li> An option argument of a grammar-specified type.
++** </ul>
++**
++** Outputs:
++** None.
++*/
++static void sqlite3Fts5Parser(
++  void *fts5yyp,                   /* The parser */
++  int fts5yymajor,                 /* The major token code number */
++  sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor       /* The value for the token */
++  sqlite3Fts5ParserARG_PDECL               /* Optional %extra_argument parameter */
++){
++  fts5YYMINORTYPE fts5yyminorunion;
++  unsigned int fts5yyact;   /* The parser action. */
++#if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
++  int fts5yyendofinput;     /* True if we are at the end of input */
++#endif
++#ifdef fts5YYERRORSYMBOL
++  int fts5yyerrorhit = 0;   /* True if fts5yymajor has invoked an error */
++#endif
++  fts5yyParser *fts5yypParser;  /* The parser */
++
++  fts5yypParser = (fts5yyParser*)fts5yyp;
++  assert( fts5yypParser->fts5yytos!=0 );
++#if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
++  fts5yyendofinput = (fts5yymajor==0);
++#endif
++  sqlite3Fts5ParserARG_STORE;
++
++#ifndef NDEBUG
++  if( fts5yyTraceFILE ){
++    fprintf(fts5yyTraceFILE,"%sInput '%s'\n",fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]);
++  }
++#endif
++
++  do{
++    fts5yyact = fts5yy_find_shift_action(fts5yypParser,(fts5YYCODETYPE)fts5yymajor);
++    if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
++      fts5yy_shift(fts5yypParser,fts5yyact,fts5yymajor,fts5yyminor);
++#ifndef fts5YYNOERRORRECOVERY
++      fts5yypParser->fts5yyerrcnt--;
++#endif
++      fts5yymajor = fts5YYNOCODE;
++    }else if( fts5yyact <= fts5YY_MAX_REDUCE ){
++      fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE);
++    }else{
++      assert( fts5yyact == fts5YY_ERROR_ACTION );
++      fts5yyminorunion.fts5yy0 = fts5yyminor;
++#ifdef fts5YYERRORSYMBOL
++      int fts5yymx;
++#endif
++#ifndef NDEBUG
++      if( fts5yyTraceFILE ){
++        fprintf(fts5yyTraceFILE,"%sSyntax Error!\n",fts5yyTracePrompt);
 +      }
-+    }
-+    sqlite3_free(*ppDirectory);
-+    *ppDirectory = zValueUtf8;
-     return SQLITE_OK;
--  }else{
--    pFile->lastErrno = osGetLastError();
--    OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n",
--             osGetCurrentProcessId(), pFile, pFile->h));
--    return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
--                       "winSync2", pFile->zPath);
-   }
--#endif
-+  return SQLITE_ERROR;
- }
- 
- /*
--** Determine the current size of a file in bytes
-+** The return value of winGetLastErrorMsg
-+** is zero if the error message fits in the buffer, or non-zero
-+** otherwise (if the message was truncated).
- */
--static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
--  winFile *pFile = (winFile*)id;
--  int rc = SQLITE_OK;
--
--  assert( id!=0 );
--  assert( pSize!=0 );
--  SimulateIOError(return SQLITE_IOERR_FSTAT);
--  OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize));
-+static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
-+  /* FormatMessage returns 0 on failure.  Otherwise it
-+  ** returns the number of TCHARs written to the output
-+  ** buffer, excluding the terminating null char.
-+  */
-+  DWORD dwLen = 0;
-+  char *zOut = 0;
- 
-+  if( osIsNT() ){
- #if SQLITE_OS_WINRT
--  {
--    FILE_STANDARD_INFO info;
--    if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo,
--                                     &info, sizeof(info)) ){
--      *pSize = info.EndOfFile.QuadPart;
--    }else{
--      pFile->lastErrno = osGetLastError();
--      rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
--                       "winFileSize", pFile->zPath);
-+    WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1];
-+    dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
-+                             FORMAT_MESSAGE_IGNORE_INSERTS,
-+                             NULL,
-+                             lastErrno,
-+                             0,
-+                             zTempWide,
-+                             SQLITE_WIN32_MAX_ERRMSG_CHARS,
-+                             0);
-+#else
-+    LPWSTR zTempWide = NULL;
-+    dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-+                             FORMAT_MESSAGE_FROM_SYSTEM |
-+                             FORMAT_MESSAGE_IGNORE_INSERTS,
-+                             NULL,
-+                             lastErrno,
-+                             0,
-+                             (LPWSTR) &zTempWide,
-+                             0,
-+                             0);
-+#endif
-+    if( dwLen > 0 ){
-+      /* allocate a buffer and convert to UTF8 */
-+      sqlite3BeginBenignMalloc();
-+      zOut = winUnicodeToUtf8(zTempWide);
-+      sqlite3EndBenignMalloc();
-+#if !SQLITE_OS_WINRT
-+      /* free the system buffer allocated by FormatMessage */
-+      osLocalFree(zTempWide);
 +#endif
-     }
-   }
--#else
--  {
--    DWORD upperBits;
--    DWORD lowerBits;
--    DWORD lastErrno;
--
--    lowerBits = osGetFileSize(pFile->h, &upperBits);
--    *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
--    if(   (lowerBits == INVALID_FILE_SIZE)
--       && ((lastErrno = osGetLastError())!=NO_ERROR) ){
--      pFile->lastErrno = lastErrno;
--      rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
--                       "winFileSize", pFile->zPath);
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    char *zTemp = NULL;
-+    dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-+                             FORMAT_MESSAGE_FROM_SYSTEM |
-+                             FORMAT_MESSAGE_IGNORE_INSERTS,
-+                             NULL,
-+                             lastErrno,
-+                             0,
-+                             (LPSTR) &zTemp,
-+                             0,
-+                             0);
-+    if( dwLen > 0 ){
-+      /* allocate a buffer and convert to UTF8 */
-+      sqlite3BeginBenignMalloc();
-+      zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
-+      sqlite3EndBenignMalloc();
-+      /* free the system buffer allocated by FormatMessage */
-+      osLocalFree(zTemp);
-     }
-   }
- #endif
--  OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n",
--           pFile->h, pSize, *pSize, sqlite3ErrName(rc)));
--  return rc;
-+  if( 0 == dwLen ){
-+    sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno);
-+  }else{
-+    /* copy a maximum of nBuf chars to output buffer */
-+    sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
-+    /* free the UTF8 buffer */
-+    sqlite3_free(zOut);
++#ifdef fts5YYERRORSYMBOL
++      /* A syntax error has occurred.
++      ** The response to an error depends upon whether or not the
++      ** grammar defines an error token "ERROR".  
++      **
++      ** This is what we do if the grammar does define ERROR:
++      **
++      **  * Call the %syntax_error function.
++      **
++      **  * Begin popping the stack until we enter a state where
++      **    it is legal to shift the error symbol, then shift
++      **    the error symbol.
++      **
++      **  * Set the error count to three.
++      **
++      **  * Begin accepting and shifting new tokens.  No new error
++      **    processing will occur until three tokens have been
++      **    shifted successfully.
++      **
++      */
++      if( fts5yypParser->fts5yyerrcnt<0 ){
++        fts5yy_syntax_error(fts5yypParser,fts5yymajor,fts5yyminor);
++      }
++      fts5yymx = fts5yypParser->fts5yytos->major;
++      if( fts5yymx==fts5YYERRORSYMBOL || fts5yyerrorhit ){
++#ifndef NDEBUG
++        if( fts5yyTraceFILE ){
++          fprintf(fts5yyTraceFILE,"%sDiscard input token %s\n",
++             fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]);
++        }
++#endif
++        fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
++        fts5yymajor = fts5YYNOCODE;
++      }else{
++        while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack
++            && fts5yymx != fts5YYERRORSYMBOL
++            && (fts5yyact = fts5yy_find_reduce_action(
++                        fts5yypParser->fts5yytos->stateno,
++                        fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
++        ){
++          fts5yy_pop_parser_stack(fts5yypParser);
++        }
++        if( fts5yypParser->fts5yytos < fts5yypParser->fts5yystack || fts5yymajor==0 ){
++          fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
++          fts5yy_parse_failed(fts5yypParser);
++#ifndef fts5YYNOERRORRECOVERY
++          fts5yypParser->fts5yyerrcnt = -1;
++#endif
++          fts5yymajor = fts5YYNOCODE;
++        }else if( fts5yymx!=fts5YYERRORSYMBOL ){
++          fts5yy_shift(fts5yypParser,fts5yyact,fts5YYERRORSYMBOL,fts5yyminor);
++        }
++      }
++      fts5yypParser->fts5yyerrcnt = 3;
++      fts5yyerrorhit = 1;
++#elif defined(fts5YYNOERRORRECOVERY)
++      /* If the fts5YYNOERRORRECOVERY macro is defined, then do not attempt to
++      ** do any kind of error recovery.  Instead, simply invoke the syntax
++      ** error routine and continue going as if nothing had happened.
++      **
++      ** Applications can set this macro (for example inside %include) if
++      ** they intend to abandon the parse upon the first syntax error seen.
++      */
++      fts5yy_syntax_error(fts5yypParser,fts5yymajor, fts5yyminor);
++      fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
++      fts5yymajor = fts5YYNOCODE;
++      
++#else  /* fts5YYERRORSYMBOL is not defined */
++      /* This is what we do if the grammar does not define ERROR:
++      **
++      **  * Report an error message, and throw away the input token.
++      **
++      **  * If the input token is $, then fail the parse.
++      **
++      ** As before, subsequent error messages are suppressed until
++      ** three input tokens have been successfully shifted.
++      */
++      if( fts5yypParser->fts5yyerrcnt<=0 ){
++        fts5yy_syntax_error(fts5yypParser,fts5yymajor, fts5yyminor);
++      }
++      fts5yypParser->fts5yyerrcnt = 3;
++      fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
++      if( fts5yyendofinput ){
++        fts5yy_parse_failed(fts5yypParser);
++#ifndef fts5YYNOERRORRECOVERY
++        fts5yypParser->fts5yyerrcnt = -1;
++#endif
++      }
++      fts5yymajor = fts5YYNOCODE;
++#endif
++    }
++  }while( fts5yymajor!=fts5YYNOCODE && fts5yypParser->fts5yytos>fts5yypParser->fts5yystack );
++#ifndef NDEBUG
++  if( fts5yyTraceFILE ){
++    fts5yyStackEntry *i;
++    char cDiv = '[';
++    fprintf(fts5yyTraceFILE,"%sReturn. Stack=",fts5yyTracePrompt);
++    for(i=&fts5yypParser->fts5yystack[1]; i<=fts5yypParser->fts5yytos; i++){
++      fprintf(fts5yyTraceFILE,"%c%s", cDiv, fts5yyTokenName[i->major]);
++      cDiv = ' ';
++    }
++    fprintf(fts5yyTraceFILE,"]\n");
 +  }
-+  return 0;
- }
- 
- /*
--** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
++#endif
++  return;
++}
++
++/*
++** 2014 May 31
 +**
-+** This function - winLogErrorAtLine() - is only ever called via the macro
-+** winLogError().
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
 +**
-+** This routine is invoked after an error occurs in an OS function.
-+** It logs a message using sqlite3_log() containing the current value of
-+** error code and, if possible, the human-readable equivalent from
-+** FormatMessage.
++**    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.
 +**
-+** The first argument passed to the macro should be the error code that
-+** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN).
-+** The two subsequent arguments should be the name of the OS function that
-+** failed and the associated file-system path, if any.
- */
--#ifndef LOCKFILE_FAIL_IMMEDIATELY
--# define LOCKFILE_FAIL_IMMEDIATELY 1
--#endif
-+#define winLogError(a,b,c,d)   winLogErrorAtLine(a,b,c,d,__LINE__)
-+static int winLogErrorAtLine(
-+  int errcode,                    /* SQLite error code */
-+  DWORD lastErrno,                /* Win32 last error */
-+  const char *zFunc,              /* Name of OS function that failed */
-+  const char *zPath,              /* File path associated with error */
-+  int iLine                       /* Source line number where error occurred */
-+){
-+  char zMsg[500];                 /* Human readable error text */
-+  int i;                          /* Loop counter */
- 
--#ifndef LOCKFILE_EXCLUSIVE_LOCK
--# define LOCKFILE_EXCLUSIVE_LOCK 2
--#endif
-+  zMsg[0] = 0;
-+  winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
-+  assert( errcode!=SQLITE_OK );
-+  if( zPath==0 ) zPath = "";
-+  for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
-+  zMsg[i] = 0;
-+  sqlite3_log(errcode,
-+      "os_win.c:%d: (%lu) %s(%s) - %s",
-+      iLine, lastErrno, zFunc, zPath, zMsg
-+  );
++******************************************************************************
++*/
 +
-+  return errcode;
-+}
- 
- /*
--** Historically, SQLite has used both the LockFile and LockFileEx functions.
--** When the LockFile function was used, it was always expected to fail
--** immediately if the lock could not be obtained.  Also, it always expected to
--** obtain an exclusive lock.  These flags are used with the LockFileEx function
--** and reflect those expectations; therefore, they should not be changed.
-+** The number of times that a ReadFile(), WriteFile(), and DeleteFile()
-+** will be retried following a locking error - probably caused by
-+** antivirus software.  Also the initial delay before the first retry.
-+** The delay increases linearly with each retry.
- */
--#ifndef SQLITE_LOCKFILE_FLAGS
--# define SQLITE_LOCKFILE_FLAGS   (LOCKFILE_FAIL_IMMEDIATELY | \
--                                  LOCKFILE_EXCLUSIVE_LOCK)
-+#ifndef SQLITE_WIN32_IOERR_RETRY
-+# define SQLITE_WIN32_IOERR_RETRY 10
-+#endif
-+#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
-+# define SQLITE_WIN32_IOERR_RETRY_DELAY 25
- #endif
-+static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY;
-+static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
- 
- /*
--** Currently, SQLite never calls the LockFileEx function without wanting the
--** call to fail immediately if the lock cannot be obtained.
-+** The "winIoerrCanRetry1" macro is used to determine if a particular I/O
-+** error code obtained via GetLastError() is eligible to be retried.  It
-+** must accept the error code DWORD as its only argument and should return
-+** non-zero if the error code is transient in nature and the operation
-+** responsible for generating the original error might succeed upon being
-+** retried.  The argument to this macro should be a variable.
-+**
-+** Additionally, a macro named "winIoerrCanRetry2" may be defined.  If it
-+** is defined, it will be consulted only when the macro "winIoerrCanRetry1"
-+** returns zero.  The "winIoerrCanRetry2" macro is completely optional and
-+** may be used to include additional error codes in the set that should
-+** result in the failing I/O operation being retried by the caller.  If
-+** defined, the "winIoerrCanRetry2" macro must exhibit external semantics
-+** identical to those of the "winIoerrCanRetry1" macro.
- */
--#ifndef SQLITE_LOCKFILEEX_FLAGS
--# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY)
-+#if !defined(winIoerrCanRetry1)
-+#define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED)        || \
-+                              ((a)==ERROR_SHARING_VIOLATION)    || \
-+                              ((a)==ERROR_LOCK_VIOLATION)       || \
-+                              ((a)==ERROR_DEV_NOT_EXIST)        || \
-+                              ((a)==ERROR_NETNAME_DELETED)      || \
-+                              ((a)==ERROR_SEM_TIMEOUT)          || \
-+                              ((a)==ERROR_NETWORK_UNREACHABLE))
- #endif
- 
- /*
--** Acquire a reader lock.
--** Different API routines are called depending on whether or not this
--** is Win9x or WinNT.
-+** If a ReadFile() or WriteFile() error occurs, invoke this routine
-+** to see if it should be retried.  Return TRUE to retry.  Return FALSE
-+** to give up with an error.
- */
--static int winGetReadLock(winFile *pFile){
--  int res;
--  OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
--  if( osIsNT() ){
--#if SQLITE_OS_WINCE
--    /*
--    ** NOTE: Windows CE is handled differently here due its lack of the Win32
--    **       API LockFileEx.
--    */
--    res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0);
--#else
--    res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0,
--                      SHARED_SIZE, 0);
--#endif
-+static int winRetryIoerr(int *pnRetry, DWORD *pError){
-+  DWORD e = osGetLastError();
-+  if( *pnRetry>=winIoerrRetry ){
-+    if( pError ){
-+      *pError = e;
++
++/* #include "fts5Int.h" */
++#include <math.h>                 /* amalgamator: keep */
++
++/*
++** Object used to iterate through all "coalesced phrase instances" in 
++** a single column of the current row. If the phrase instances in the
++** column being considered do not overlap, this object simply iterates
++** through them. Or, if they do overlap (share one or more tokens in
++** common), each set of overlapping instances is treated as a single
++** match. See documentation for the highlight() auxiliary function for
++** details.
++**
++** Usage is:
++**
++**   for(rc = fts5CInstIterNext(pApi, pFts, iCol, &iter);
++**      (rc==SQLITE_OK && 0==fts5CInstIterEof(&iter);
++**      rc = fts5CInstIterNext(&iter)
++**   ){
++**     printf("instance starts at %d, ends at %d\n", iter.iStart, iter.iEnd);
++**   }
++**
++*/
++typedef struct CInstIter CInstIter;
++struct CInstIter {
++  const Fts5ExtensionApi *pApi;   /* API offered by current FTS version */
++  Fts5Context *pFts;              /* First arg to pass to pApi functions */
++  int iCol;                       /* Column to search */
++  int iInst;                      /* Next phrase instance index */
++  int nInst;                      /* Total number of phrase instances */
++
++  /* Output variables */
++  int iStart;                     /* First token in coalesced phrase instance */
++  int iEnd;                       /* Last token in coalesced phrase instance */
++};
++
++/*
++** Advance the iterator to the next coalesced phrase instance. Return
++** an SQLite error code if an error occurs, or SQLITE_OK otherwise.
++*/
++static int fts5CInstIterNext(CInstIter *pIter){
++  int rc = SQLITE_OK;
++  pIter->iStart = -1;
++  pIter->iEnd = -1;
++
++  while( rc==SQLITE_OK && pIter->iInst<pIter->nInst ){
++    int ip; int ic; int io;
++    rc = pIter->pApi->xInst(pIter->pFts, pIter->iInst, &ip, &ic, &io);
++    if( rc==SQLITE_OK ){
++      if( ic==pIter->iCol ){
++        int iEnd = io - 1 + pIter->pApi->xPhraseSize(pIter->pFts, ip);
++        if( pIter->iStart<0 ){
++          pIter->iStart = io;
++          pIter->iEnd = iEnd;
++        }else if( io<=pIter->iEnd ){
++          if( iEnd>pIter->iEnd ) pIter->iEnd = iEnd;
++        }else{
++          break;
++        }
++      }
++      pIter->iInst++;
 +    }
-+    return 0;
-   }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    int lk;
--    sqlite3_randomness(sizeof(lk), &lk);
--    pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
--    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
--                      SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
-+  if( winIoerrCanRetry1(e) ){
-+    sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
-+    ++*pnRetry;
-+    return 1;
 +  }
-+#if defined(winIoerrCanRetry2)
-+  else if( winIoerrCanRetry2(e) ){
-+    sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
-+    ++*pnRetry;
-+    return 1;
-   }
- #endif
--  if( res == 0 ){
--    pFile->lastErrno = osGetLastError();
--    /* No need to log a failure to lock */
-+  if( pError ){
-+    *pError = e;
-   }
--  OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res));
--  return res;
-+  return 0;
- }
- 
- /*
--** Undo a readlock
-+** Log a I/O error retry episode.
- */
--static int winUnlockReadLock(winFile *pFile){
--  int res;
--  DWORD lastErrno;
--  OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
--  if( osIsNT() ){
--    res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
--  }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
--  }
--#endif
--  if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
--    pFile->lastErrno = lastErrno;
--    winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
--                "winUnlockReadLock", pFile->zPath);
-+static void winLogIoerr(int nRetry, int lineno){
-+  if( nRetry ){
-+    sqlite3_log(SQLITE_NOTICE,
-+      "delayed %dms for lock/sharing conflict at line %d",
-+      winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno
-+    );
-   }
--  OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res));
--  return res;
- }
- 
-+#if SQLITE_OS_WINCE
++
++  return rc;
++}
++
++/*
++** Initialize the iterator object indicated by the final parameter to 
++** iterate through coalesced phrase instances in column iCol.
++*/
++static int fts5CInstIterInit(
++  const Fts5ExtensionApi *pApi,
++  Fts5Context *pFts,
++  int iCol,
++  CInstIter *pIter
++){
++  int rc;
++
++  memset(pIter, 0, sizeof(CInstIter));
++  pIter->pApi = pApi;
++  pIter->pFts = pFts;
++  pIter->iCol = iCol;
++  rc = pApi->xInstCount(pFts, &pIter->nInst);
++
++  if( rc==SQLITE_OK ){
++    rc = fts5CInstIterNext(pIter);
++  }
++
++  return rc;
++}
++
++
++
 +/*************************************************************************
-+** This section contains code for WinCE only.
++** Start of highlight() implementation.
 +*/
-+#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API
- /*
--** Lock the file with the lock specified by parameter locktype - one
--** of the following:
--**
--**     (1) SHARED_LOCK
--**     (2) RESERVED_LOCK
--**     (3) PENDING_LOCK
--**     (4) EXCLUSIVE_LOCK
--**
--** Sometimes when requesting one lock state, additional lock states
--** are inserted in between.  The locking might fail on one of the later
--** transitions leaving the lock state different from what it started but
--** still short of its goal.  The following chart shows the allowed
--** transitions and the inserted intermediate states:
--**
--**    UNLOCKED -> SHARED
--**    SHARED -> RESERVED
--**    SHARED -> (PENDING) -> EXCLUSIVE
--**    RESERVED -> (PENDING) -> EXCLUSIVE
--**    PENDING -> EXCLUSIVE
--**
--** This routine will only increase a lock.  The winUnlock() routine
--** erases all locks at once and returns us immediately to locking level 0.
--** It is not possible to lower the locking level one step at a time.  You
--** must go straight to locking level 0.
-+** The MSVC CRT on Windows CE may not have a localtime() function.  So
-+** create a substitute.
- */
--static int winLock(sqlite3_file *id, int locktype){
--  int rc = SQLITE_OK;    /* Return code from subroutines */
--  int res = 1;           /* Result of a Windows lock call */
--  int newLocktype;       /* Set pFile->locktype to this value before exiting */
--  int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
--  winFile *pFile = (winFile*)id;
--  DWORD lastErrno = NO_ERROR;
-+/* #include <time.h> */
-+struct tm *__cdecl localtime(const time_t *t)
-+{
-+  static struct tm y;
-+  FILETIME uTm, lTm;
-+  SYSTEMTIME pTm;
-+  sqlite3_int64 t64;
-+  t64 = *t;
-+  t64 = (t64 + 11644473600)*10000000;
-+  uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
-+  uTm.dwHighDateTime= (DWORD)(t64 >> 32);
-+  osFileTimeToLocalFileTime(&uTm,&lTm);
-+  osFileTimeToSystemTime(&lTm,&pTm);
-+  y.tm_year = pTm.wYear - 1900;
-+  y.tm_mon = pTm.wMonth - 1;
-+  y.tm_wday = pTm.wDayOfWeek;
-+  y.tm_mday = pTm.wDay;
-+  y.tm_hour = pTm.wHour;
-+  y.tm_min = pTm.wMinute;
-+  y.tm_sec = pTm.wSecond;
-+  return &y;
-+}
-+#endif
- 
--  assert( id!=0 );
--  OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n",
--           pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
-+#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
- 
--  /* If there is already a lock of this type or more restrictive on the
--  ** OsFile, do nothing. Don't use the end_lock: exit path, as
--  ** sqlite3OsEnterMutex() hasn't been called yet.
--  */
--  if( pFile->locktype>=locktype ){
--    OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h));
--    return SQLITE_OK;
++typedef struct HighlightContext HighlightContext;
++struct HighlightContext {
++  CInstIter iter;                 /* Coalesced Instance Iterator */
++  int iPos;                       /* Current token offset in zIn[] */
++  int iRangeStart;                /* First token to include */
++  int iRangeEnd;                  /* If non-zero, last token to include */
++  const char *zOpen;              /* Opening highlight */
++  const char *zClose;             /* Closing highlight */
++  const char *zIn;                /* Input text */
++  int nIn;                        /* Size of input text in bytes */
++  int iOff;                       /* Current offset within zIn[] */
++  char *zOut;                     /* Output value */
++};
++
 +/*
-+** Acquire a lock on the handle h
++** Append text to the HighlightContext output string - p->zOut. Argument
++** z points to a buffer containing n bytes of text to append. If n is 
++** negative, everything up until the first '\0' is appended to the output.
++**
++** If *pRc is set to any value other than SQLITE_OK when this function is 
++** called, it is a no-op. If an error (i.e. an OOM condition) is encountered, 
++** *pRc is set to an error code before returning. 
 +*/
-+static void winceMutexAcquire(HANDLE h){
-+   DWORD dwErr;
-+   do {
-+     dwErr = osWaitForSingleObject(h, INFINITE);
-+   } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
++static void fts5HighlightAppend(
++  int *pRc, 
++  HighlightContext *p, 
++  const char *z, int n
++){
++  if( *pRc==SQLITE_OK ){
++    if( n<0 ) n = (int)strlen(z);
++    p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z);
++    if( p->zOut==0 ) *pRc = SQLITE_NOMEM;
++  }
 +}
++
 +/*
-+** Release a lock acquired by winceMutexAcquire()
++** Tokenizer callback used by implementation of highlight() function.
 +*/
-+#define winceMutexRelease(h) ReleaseMutex(h)
++static int fts5HighlightCb(
++  void *pContext,                 /* Pointer to HighlightContext object */
++  int tflags,                     /* Mask of FTS5_TOKEN_* flags */
++  const char *pToken,             /* Buffer containing token */
++  int nToken,                     /* Size of token in bytes */
++  int iStartOff,                  /* Start offset of token */
++  int iEndOff                     /* End offset of token */
++){
++  HighlightContext *p = (HighlightContext*)pContext;
++  int rc = SQLITE_OK;
++  int iPos;
++
++  UNUSED_PARAM2(pToken, nToken);
++
++  if( tflags & FTS5_TOKEN_COLOCATED ) return SQLITE_OK;
++  iPos = p->iPos++;
++
++  if( p->iRangeEnd>0 ){
++    if( iPos<p->iRangeStart || iPos>p->iRangeEnd ) return SQLITE_OK;
++    if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff;
++  }
++
++  if( iPos==p->iter.iStart ){
++    fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iStartOff - p->iOff);
++    fts5HighlightAppend(&rc, p, p->zOpen, -1);
++    p->iOff = iStartOff;
++  }
++
++  if( iPos==p->iter.iEnd ){
++    if( p->iRangeEnd && p->iter.iStart<p->iRangeStart ){
++      fts5HighlightAppend(&rc, p, p->zOpen, -1);
++    }
++    fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
++    fts5HighlightAppend(&rc, p, p->zClose, -1);
++    p->iOff = iEndOff;
++    if( rc==SQLITE_OK ){
++      rc = fts5CInstIterNext(&p->iter);
++    }
++  }
++
++  if( p->iRangeEnd>0 && iPos==p->iRangeEnd ){
++    fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
++    p->iOff = iEndOff;
++    if( iPos>=p->iter.iStart && iPos<p->iter.iEnd ){
++      fts5HighlightAppend(&rc, p, p->zClose, -1);
++    }
++  }
++
++  return rc;
++}
 +
 +/*
-+** Create the mutex and shared memory used for locking in the file
-+** descriptor pFile
++** Implementation of highlight() function.
 +*/
-+static int winceCreateLock(const char *zFilename, winFile *pFile){
-+  LPWSTR zTok;
-+  LPWSTR zName;
-+  DWORD lastErrno;
-+  BOOL bLogged = FALSE;
-+  BOOL bInit = TRUE;
++static void fts5HighlightFunction(
++  const Fts5ExtensionApi *pApi,   /* API offered by current FTS version */
++  Fts5Context *pFts,              /* First arg to pass to pApi functions */
++  sqlite3_context *pCtx,          /* Context for returning result/error */
++  int nVal,                       /* Number of values in apVal[] array */
++  sqlite3_value **apVal           /* Array of trailing arguments */
++){
++  HighlightContext ctx;
++  int rc;
++  int iCol;
 +
-+  zName = winUtf8ToUnicode(zFilename);
-+  if( zName==0 ){
-+    /* out of memory */
-+    return SQLITE_IOERR_NOMEM;
-   }
- 
--  /* Make sure the locking sequence is correct
--  */
--  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
--  assert( locktype!=PENDING_LOCK );
--  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
-+  /* Initialize the local lockdata */
-+  memset(&pFile->local, 0, sizeof(pFile->local));
- 
--  /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
--  ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
--  ** the PENDING_LOCK byte is temporary.
--  */
--  newLocktype = pFile->locktype;
--  if(   (pFile->locktype==NO_LOCK)
--     || (   (locktype==EXCLUSIVE_LOCK)
--         && (pFile->locktype==RESERVED_LOCK))
--  ){
--    int cnt = 3;
--    while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
--                                         PENDING_BYTE, 0, 1, 0))==0 ){
--      /* Try 3 times to get the pending lock.  This is needed to work
--      ** around problems caused by indexing and/or anti-virus software on
--      ** Windows systems.
--      ** If you are using this code as a model for alternative VFSes, do not
--      ** copy this retry logic.  It is a hack intended for Windows only.
--      */
--      lastErrno = osGetLastError();
--      OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n",
--               pFile->h, cnt, res));
--      if( lastErrno==ERROR_INVALID_HANDLE ){
--        pFile->lastErrno = lastErrno;
--        rc = SQLITE_IOERR_LOCK;
--        OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n",
--                 pFile->h, cnt, sqlite3ErrName(rc)));
--        return rc;
--      }
--      if( cnt ) sqlite3_win32_sleep(1);
--    }
--    gotPendingLock = res;
--    if( !res ){
--      lastErrno = osGetLastError();
--    }
-+  /* Replace the backslashes from the filename and lowercase it
-+  ** to derive a mutex name. */
-+  zTok = osCharLowerW(zName);
-+  for (;*zTok;zTok++){
-+    if (*zTok == '\\') *zTok = '_';
-   }
- 
--  /* Acquire a shared lock
--  */
--  if( locktype==SHARED_LOCK && res ){
--    assert( pFile->locktype==NO_LOCK );
--    res = winGetReadLock(pFile);
--    if( res ){
--      newLocktype = SHARED_LOCK;
--    }else{
--      lastErrno = osGetLastError();
--    }
-+  /* Create/open the named mutex */
-+  pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
-+  if (!pFile->hMutex){
-+    pFile->lastErrno = osGetLastError();
-+    sqlite3_free(zName);
-+    return winLogError(SQLITE_IOERR, pFile->lastErrno,
-+                       "winceCreateLock1", zFilename);
-   }
- 
--  /* Acquire a RESERVED lock
--  */
--  if( locktype==RESERVED_LOCK && res ){
--    assert( pFile->locktype==SHARED_LOCK );
--    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
--    if( res ){
--      newLocktype = RESERVED_LOCK;
--    }else{
--      lastErrno = osGetLastError();
--    }
--  }
-+  /* Acquire the mutex before continuing */
-+  winceMutexAcquire(pFile->hMutex);
- 
--  /* Acquire a PENDING lock
-+  /* Since the names of named mutexes, semaphores, file mappings etc are
-+  ** case-sensitive, take advantage of that by uppercasing the mutex name
-+  ** and using that as the shared filemapping name.
-   */
--  if( locktype==EXCLUSIVE_LOCK && res ){
--    newLocktype = PENDING_LOCK;
--    gotPendingLock = 0;
-+  osCharUpperW(zName);
-+  pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
-+                                        PAGE_READWRITE, 0, sizeof(winceLock),
-+                                        zName);
-+
-+  /* Set a flag that indicates we're the first to create the memory so it
-+  ** must be zero-initialized */
-+  lastErrno = osGetLastError();
-+  if (lastErrno == ERROR_ALREADY_EXISTS){
-+    bInit = FALSE;
-   }
- 
--  /* Acquire an EXCLUSIVE lock
--  */
--  if( locktype==EXCLUSIVE_LOCK && res ){
--    assert( pFile->locktype>=SHARED_LOCK );
--    res = winUnlockReadLock(pFile);
--    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
--                      SHARED_SIZE, 0);
--    if( res ){
--      newLocktype = EXCLUSIVE_LOCK;
--    }else{
--      lastErrno = osGetLastError();
--      winGetReadLock(pFile);
-+  sqlite3_free(zName);
-+
-+  /* If we succeeded in making the shared memory handle, map it. */
-+  if( pFile->hShared ){
-+    pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared,
-+             FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
-+    /* If mapping failed, close the shared memory handle and erase it */
-+    if( !pFile->shared ){
-+      pFile->lastErrno = osGetLastError();
-+      winLogError(SQLITE_IOERR, pFile->lastErrno,
-+                  "winceCreateLock2", zFilename);
-+      bLogged = TRUE;
-+      osCloseHandle(pFile->hShared);
-+      pFile->hShared = NULL;
-     }
-   }
- 
--  /* If we are holding a PENDING lock that ought to be released, then
--  ** release it now.
--  */
--  if( gotPendingLock && locktype==SHARED_LOCK ){
--    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
-+  /* If shared memory could not be created, then close the mutex and fail */
-+  if( pFile->hShared==NULL ){
-+    if( !bLogged ){
-+      pFile->lastErrno = lastErrno;
-+      winLogError(SQLITE_IOERR, pFile->lastErrno,
-+                  "winceCreateLock3", zFilename);
-+      bLogged = TRUE;
-+    }
-+    winceMutexRelease(pFile->hMutex);
-+    osCloseHandle(pFile->hMutex);
-+    pFile->hMutex = NULL;
-+    return SQLITE_IOERR;
-   }
- 
--  /* Update the state of the lock has held in the file descriptor then
--  ** return the appropriate result code.
--  */
--  if( res ){
--    rc = SQLITE_OK;
--  }else{
--    pFile->lastErrno = lastErrno;
--    rc = SQLITE_BUSY;
--    OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
--             pFile->h, locktype, newLocktype));
-+  /* Initialize the shared memory if we're supposed to */
-+  if( bInit ){
-+    memset(pFile->shared, 0, sizeof(winceLock));
-   }
--  pFile->locktype = (u8)newLocktype;
--  OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n",
--           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
--  return rc;
++  if( nVal!=3 ){
++    const char *zErr = "wrong number of arguments to function highlight()";
++    sqlite3_result_error(pCtx, zErr, -1);
++    return;
++  }
++
++  iCol = sqlite3_value_int(apVal[0]);
++  memset(&ctx, 0, sizeof(HighlightContext));
++  ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
++  ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
++  rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn);
++
++  if( ctx.zIn ){
++    if( rc==SQLITE_OK ){
++      rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter);
++    }
++
++    if( rc==SQLITE_OK ){
++      rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
++    }
++    fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
 +
-+  winceMutexRelease(pFile->hMutex);
++    if( rc==SQLITE_OK ){
++      sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT);
++    }
++    sqlite3_free(ctx.zOut);
++  }
++  if( rc!=SQLITE_OK ){
++    sqlite3_result_error_code(pCtx, rc);
++  }
++}
++/*
++** End of highlight() implementation.
++**************************************************************************/
++
++/*
++** Context object passed to the fts5SentenceFinderCb() function.
++*/
++typedef struct Fts5SFinder Fts5SFinder;
++struct Fts5SFinder {
++  int iPos;                       /* Current token position */
++  int nFirstAlloc;                /* Allocated size of aFirst[] */
++  int nFirst;                     /* Number of entries in aFirst[] */
++  int *aFirst;                    /* Array of first token in each sentence */
++  const char *zDoc;               /* Document being tokenized */
++};
++
++/*
++** Add an entry to the Fts5SFinder.aFirst[] array. Grow the array if
++** necessary. Return SQLITE_OK if successful, or SQLITE_NOMEM if an
++** error occurs.
++*/
++static int fts5SentenceFinderAdd(Fts5SFinder *p, int iAdd){
++  if( p->nFirstAlloc==p->nFirst ){
++    int nNew = p->nFirstAlloc ? p->nFirstAlloc*2 : 64;
++    int *aNew;
++
++    aNew = (int*)sqlite3_realloc(p->aFirst, nNew*sizeof(int));
++    if( aNew==0 ) return SQLITE_NOMEM;
++    p->aFirst = aNew;
++    p->nFirstAlloc = nNew;
++  }
++  p->aFirst[p->nFirst++] = iAdd;
 +  return SQLITE_OK;
- }
- 
- /*
--** This routine checks if there is a RESERVED lock held on the specified
--** file by this or any other process. If such a lock is held, return
--** non-zero, otherwise zero.
-+** Destroy the part of winFile that deals with wince locks
- */
--static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
--  int res;
--  winFile *pFile = (winFile*)id;
--
--  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
--  OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut));
-+static void winceDestroyLock(winFile *pFile){
-+  if (pFile->hMutex){
-+    /* Acquire the mutex */
-+    winceMutexAcquire(pFile->hMutex);
- 
--  assert( id!=0 );
--  if( pFile->locktype>=RESERVED_LOCK ){
--    res = 1;
--    OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res));
--  }else{
--    res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0);
--    if( res ){
--      winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
-+    /* The following blocks should probably assert in debug mode, but they
-+       are to cleanup in case any locks remained open */
-+    if (pFile->local.nReaders){
-+      pFile->shared->nReaders --;
-     }
--    res = !res;
--    OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res));
-+    if (pFile->local.bReserved){
-+      pFile->shared->bReserved = FALSE;
++}
++
++/*
++** This function is an xTokenize() callback used by the auxiliary snippet()
++** function. Its job is to identify tokens that are the first in a sentence.
++** For each such token, an entry is added to the SFinder.aFirst[] array.
++*/
++static int fts5SentenceFinderCb(
++  void *pContext,                 /* Pointer to HighlightContext object */
++  int tflags,                     /* Mask of FTS5_TOKEN_* flags */
++  const char *pToken,             /* Buffer containing token */
++  int nToken,                     /* Size of token in bytes */
++  int iStartOff,                  /* Start offset of token */
++  int iEndOff                     /* End offset of token */
++){
++  int rc = SQLITE_OK;
++
++  UNUSED_PARAM2(pToken, nToken);
++  UNUSED_PARAM(iEndOff);
++
++  if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
++    Fts5SFinder *p = (Fts5SFinder*)pContext;
++    if( p->iPos>0 ){
++      int i;
++      char c = 0;
++      for(i=iStartOff-1; i>=0; i--){
++        c = p->zDoc[i];
++        if( c!=' ' && c!='\t' && c!='\n' && c!='\r' ) break;
++      }
++      if( i!=iStartOff-1 && (c=='.' || c==':') ){
++        rc = fts5SentenceFinderAdd(p, p->iPos);
++      }
++    }else{
++      rc = fts5SentenceFinderAdd(p, 0);
++    }
++    p->iPos++;
++  }
++  return rc;
++}
++
++static int fts5SnippetScore(
++  const Fts5ExtensionApi *pApi,   /* API offered by current FTS version */
++  Fts5Context *pFts,              /* First arg to pass to pApi functions */
++  int nDocsize,                   /* Size of column in tokens */
++  unsigned char *aSeen,           /* Array with one element per query phrase */
++  int iCol,                       /* Column to score */
++  int iPos,                       /* Starting offset to score */
++  int nToken,                     /* Max tokens per snippet */
++  int *pnScore,                   /* OUT: Score */
++  int *piPos                      /* OUT: Adjusted offset */
++){
++  int rc;
++  int i;
++  int ip = 0;
++  int ic = 0;
++  int iOff = 0;
++  int iFirst = -1;
++  int nInst;
++  int nScore = 0;
++  int iLast = 0;
++
++  rc = pApi->xInstCount(pFts, &nInst);
++  for(i=0; i<nInst && rc==SQLITE_OK; i++){
++    rc = pApi->xInst(pFts, i, &ip, &ic, &iOff);
++    if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<(iPos+nToken) ){
++      nScore += (aSeen[ip] ? 1 : 1000);
++      aSeen[ip] = 1;
++      if( iFirst<0 ) iFirst = iOff;
++      iLast = iOff + pApi->xPhraseSize(pFts, ip);
 +    }
-+    if (pFile->local.bPending){
-+      pFile->shared->bPending = FALSE;
++  }
++
++  *pnScore = nScore;
++  if( piPos ){
++    int iAdj = iFirst - (nToken - (iLast-iFirst)) / 2;
++    if( (iAdj+nToken)>nDocsize ) iAdj = nDocsize - nToken;
++    if( iAdj<0 ) iAdj = 0;
++    *piPos = iAdj;
++  }
++
++  return rc;
++}
++
++/*
++** Implementation of snippet() function.
++*/
++static void fts5SnippetFunction(
++  const Fts5ExtensionApi *pApi,   /* API offered by current FTS version */
++  Fts5Context *pFts,              /* First arg to pass to pApi functions */
++  sqlite3_context *pCtx,          /* Context for returning result/error */
++  int nVal,                       /* Number of values in apVal[] array */
++  sqlite3_value **apVal           /* Array of trailing arguments */
++){
++  HighlightContext ctx;
++  int rc = SQLITE_OK;             /* Return code */
++  int iCol;                       /* 1st argument to snippet() */
++  const char *zEllips;            /* 4th argument to snippet() */
++  int nToken;                     /* 5th argument to snippet() */
++  int nInst = 0;                  /* Number of instance matches this row */
++  int i;                          /* Used to iterate through instances */
++  int nPhrase;                    /* Number of phrases in query */
++  unsigned char *aSeen;           /* Array of "seen instance" flags */
++  int iBestCol;                   /* Column containing best snippet */
++  int iBestStart = 0;             /* First token of best snippet */
++  int nBestScore = 0;             /* Score of best snippet */
++  int nColSize = 0;               /* Total size of iBestCol in tokens */
++  Fts5SFinder sFinder;            /* Used to find the beginnings of sentences */
++  int nCol;
++
++  if( nVal!=5 ){
++    const char *zErr = "wrong number of arguments to function snippet()";
++    sqlite3_result_error(pCtx, zErr, -1);
++    return;
++  }
++
++  nCol = pApi->xColumnCount(pFts);
++  memset(&ctx, 0, sizeof(HighlightContext));
++  iCol = sqlite3_value_int(apVal[0]);
++  ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
++  ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
++  zEllips = (const char*)sqlite3_value_text(apVal[3]);
++  nToken = sqlite3_value_int(apVal[4]);
++
++  iBestCol = (iCol>=0 ? iCol : 0);
++  nPhrase = pApi->xPhraseCount(pFts);
++  aSeen = sqlite3_malloc(nPhrase);
++  if( aSeen==0 ){
++    rc = SQLITE_NOMEM;
++  }
++  if( rc==SQLITE_OK ){
++    rc = pApi->xInstCount(pFts, &nInst);
++  }
++
++  memset(&sFinder, 0, sizeof(Fts5SFinder));
++  for(i=0; i<nCol; i++){
++    if( iCol<0 || iCol==i ){
++      int nDoc;
++      int nDocsize;
++      int ii;
++      sFinder.iPos = 0;
++      sFinder.nFirst = 0;
++      rc = pApi->xColumnText(pFts, i, &sFinder.zDoc, &nDoc);
++      if( rc!=SQLITE_OK ) break;
++      rc = pApi->xTokenize(pFts, 
++          sFinder.zDoc, nDoc, (void*)&sFinder,fts5SentenceFinderCb
++      );
++      if( rc!=SQLITE_OK ) break;
++      rc = pApi->xColumnSize(pFts, i, &nDocsize);
++      if( rc!=SQLITE_OK ) break;
++
++      for(ii=0; rc==SQLITE_OK && ii<nInst; ii++){
++        int ip, ic, io;
++        int iAdj;
++        int nScore;
++        int jj;
++
++        rc = pApi->xInst(pFts, ii, &ip, &ic, &io);
++        if( ic!=i || rc!=SQLITE_OK ) continue;
++        memset(aSeen, 0, nPhrase);
++        rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
++            io, nToken, &nScore, &iAdj
++        );
++        if( rc==SQLITE_OK && nScore>nBestScore ){
++          nBestScore = nScore;
++          iBestCol = i;
++          iBestStart = iAdj;
++          nColSize = nDocsize;
++        }
++
++        if( rc==SQLITE_OK && sFinder.nFirst && nDocsize>nToken ){
++          for(jj=0; jj<(sFinder.nFirst-1); jj++){
++            if( sFinder.aFirst[jj+1]>io ) break;
++          }
++
++          if( sFinder.aFirst[jj]<io ){
++            memset(aSeen, 0, nPhrase);
++            rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i, 
++              sFinder.aFirst[jj], nToken, &nScore, 0
++            );
++
++            nScore += (sFinder.aFirst[jj]==0 ? 120 : 100);
++            if( rc==SQLITE_OK && nScore>nBestScore ){
++              nBestScore = nScore;
++              iBestCol = i;
++              iBestStart = sFinder.aFirst[jj];
++              nColSize = nDocsize;
++            }
++          }
++        }
++      }
 +    }
-+    if (pFile->local.bExclusive){
-+      pFile->shared->bExclusive = FALSE;
++  }
++
++  if( rc==SQLITE_OK ){
++    rc = pApi->xColumnText(pFts, iBestCol, &ctx.zIn, &ctx.nIn);
++  }
++  if( rc==SQLITE_OK && nColSize==0 ){
++    rc = pApi->xColumnSize(pFts, iBestCol, &nColSize);
++  }
++  if( ctx.zIn ){
++    if( rc==SQLITE_OK ){
++      rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter);
 +    }
 +
-+    /* De-reference and close our copy of the shared memory handle */
-+    osUnmapViewOfFile(pFile->shared);
-+    osCloseHandle(pFile->hShared);
++    ctx.iRangeStart = iBestStart;
++    ctx.iRangeEnd = iBestStart + nToken - 1;
 +
-+    /* Done with the mutex */
-+    winceMutexRelease(pFile->hMutex);
-+    osCloseHandle(pFile->hMutex);
-+    pFile->hMutex = NULL;
-   }
--  *pResOut = res;
--  OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
--           pFile->h, pResOut, *pResOut));
--  return SQLITE_OK;
- }
- 
- /*
--** Lower the locking level on file descriptor id to locktype.  locktype
--** must be either NO_LOCK or SHARED_LOCK.
--**
--** If the locking level of the file descriptor is already at or below
--** the requested locking level, this routine is a no-op.
--**
--** It is not possible for this routine to fail if the second argument
--** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
--** might return SQLITE_IOERR;
-+** An implementation of the LockFile() API of Windows for CE
- */
--static int winUnlock(sqlite3_file *id, int locktype){
--  int type;
--  winFile *pFile = (winFile*)id;
--  int rc = SQLITE_OK;
--  assert( pFile!=0 );
--  assert( locktype<=SHARED_LOCK );
--  OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n",
--           pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
--  type = pFile->locktype;
--  if( type>=EXCLUSIVE_LOCK ){
--    winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
--    if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){
--      /* This should never happen.  We should always be able to
--      ** reacquire the read lock */
--      rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
--                       "winUnlock", pFile->zPath);
-+static BOOL winceLockFile(
-+  LPHANDLE phFile,
-+  DWORD dwFileOffsetLow,
-+  DWORD dwFileOffsetHigh,
-+  DWORD nNumberOfBytesToLockLow,
-+  DWORD nNumberOfBytesToLockHigh
-+){
-+  winFile *pFile = HANDLE_TO_WINFILE(phFile);
-+  BOOL bReturn = FALSE;
-+
-+  UNUSED_PARAMETER(dwFileOffsetHigh);
-+  UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
-+
-+  if (!pFile->hMutex) return TRUE;
-+  winceMutexAcquire(pFile->hMutex);
-+
-+  /* Wanting an exclusive lock? */
-+  if (dwFileOffsetLow == (DWORD)SHARED_FIRST
-+       && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
-+    if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
-+       pFile->shared->bExclusive = TRUE;
-+       pFile->local.bExclusive = TRUE;
-+       bReturn = TRUE;
-     }
-   }
--  if( type>=RESERVED_LOCK ){
--    winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
-+
-+  /* Want a read-only lock? */
-+  else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
-+           nNumberOfBytesToLockLow == 1){
-+    if (pFile->shared->bExclusive == 0){
-+      pFile->local.nReaders ++;
-+      if (pFile->local.nReaders == 1){
-+        pFile->shared->nReaders ++;
-+      }
-+      bReturn = TRUE;
-+    }
-   }
--  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
--    winUnlockReadLock(pFile);
-+
-+  /* Want a pending lock? */
-+  else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
-+           && nNumberOfBytesToLockLow == 1){
-+    /* If no pending lock has been acquired, then acquire it */
-+    if (pFile->shared->bPending == 0) {
-+      pFile->shared->bPending = TRUE;
-+      pFile->local.bPending = TRUE;
-+      bReturn = TRUE;
-+    }
-   }
--  if( type>=PENDING_LOCK ){
--    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
-+
-+  /* Want a reserved lock? */
-+  else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
-+           && nNumberOfBytesToLockLow == 1){
-+    if (pFile->shared->bReserved == 0) {
-+      pFile->shared->bReserved = TRUE;
-+      pFile->local.bReserved = TRUE;
-+      bReturn = TRUE;
-+    }
-   }
--  pFile->locktype = (u8)locktype;
--  OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n",
--           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
--  return rc;
++    if( iBestStart>0 ){
++      fts5HighlightAppend(&rc, &ctx, zEllips, -1);
++    }
 +
-+  winceMutexRelease(pFile->hMutex);
-+  return bReturn;
- }
- 
- /*
--** If *pArg is initially negative then this is a query.  Set *pArg to
--** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
--**
--** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
-+** An implementation of the UnlockFile API of Windows for CE
- */
--static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
--  if( *pArg<0 ){
--    *pArg = (pFile->ctrlFlags & mask)!=0;
--  }else if( (*pArg)==0 ){
--    pFile->ctrlFlags &= ~mask;
--  }else{
--    pFile->ctrlFlags |= mask;
--  }
--}
-+static BOOL winceUnlockFile(
-+  LPHANDLE phFile,
-+  DWORD dwFileOffsetLow,
-+  DWORD dwFileOffsetHigh,
-+  DWORD nNumberOfBytesToUnlockLow,
-+  DWORD nNumberOfBytesToUnlockHigh
-+){
-+  winFile *pFile = HANDLE_TO_WINFILE(phFile);
-+  BOOL bReturn = FALSE;
- 
--/* Forward references to VFS helper methods used for temporary files */
--static int winGetTempname(sqlite3_vfs *, char **);
--static int winIsDir(const void *);
--static BOOL winIsDriveLetterAndColon(const char *);
-+  UNUSED_PARAMETER(dwFileOffsetHigh);
-+  UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);
- 
--/*
--** Control and query of the open file handle.
--*/
--static int winFileControl(sqlite3_file *id, int op, void *pArg){
--  winFile *pFile = (winFile*)id;
--  OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg));
--  switch( op ){
--    case SQLITE_FCNTL_LOCKSTATE: {
--      *(int*)pArg = pFile->locktype;
--      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
--      return SQLITE_OK;
--    }
--    case SQLITE_LAST_ERRNO: {
--      *(int*)pArg = (int)pFile->lastErrno;
--      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
--      return SQLITE_OK;
--    }
--    case SQLITE_FCNTL_CHUNK_SIZE: {
--      pFile->szChunk = *(int *)pArg;
--      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
--      return SQLITE_OK;
--    }
--    case SQLITE_FCNTL_SIZE_HINT: {
--      if( pFile->szChunk>0 ){
--        sqlite3_int64 oldSz;
--        int rc = winFileSize(id, &oldSz);
--        if( rc==SQLITE_OK ){
--          sqlite3_int64 newSz = *(sqlite3_int64*)pArg;
--          if( newSz>oldSz ){
--            SimulateIOErrorBenign(1);
--            rc = winTruncate(id, newSz);
--            SimulateIOErrorBenign(0);
--          }
--        }
--        OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
--        return rc;
--      }
--      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
--      return SQLITE_OK;
--    }
--    case SQLITE_FCNTL_PERSIST_WAL: {
--      winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg);
--      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
--      return SQLITE_OK;
--    }
--    case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
--      winModeBit(pFile, WINFILE_PSOW, (int*)pArg);
--      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
--      return SQLITE_OK;
--    }
--    case SQLITE_FCNTL_VFSNAME: {
--      *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
--      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
--      return SQLITE_OK;
-+  if (!pFile->hMutex) return TRUE;
-+  winceMutexAcquire(pFile->hMutex);
-+
-+  /* Releasing a reader lock or an exclusive lock */
-+  if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
-+    /* Did we have an exclusive lock? */
-+    if (pFile->local.bExclusive){
-+      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
-+      pFile->local.bExclusive = FALSE;
-+      pFile->shared->bExclusive = FALSE;
-+      bReturn = TRUE;
-     }
--    case SQLITE_FCNTL_WIN32_AV_RETRY: {
--      int *a = (int*)pArg;
--      if( a[0]>0 ){
--        winIoerrRetry = a[0];
--      }else{
--        a[0] = winIoerrRetry;
--      }
--      if( a[1]>0 ){
--        winIoerrRetryDelay = a[1];
--      }else{
--        a[1] = winIoerrRetryDelay;
-+
-+    /* Did we just have a reader lock? */
-+    else if (pFile->local.nReaders){
-+      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE
-+             || nNumberOfBytesToUnlockLow == 1);
-+      pFile->local.nReaders --;
-+      if (pFile->local.nReaders == 0)
-+      {
-+        pFile->shared->nReaders --;
-       }
--      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
--      return SQLITE_OK;
--    }
--#ifdef SQLITE_TEST
--    case SQLITE_FCNTL_WIN32_SET_HANDLE: {
--      LPHANDLE phFile = (LPHANDLE)pArg;
--      HANDLE hOldFile = pFile->h;
--      pFile->h = *phFile;
--      *phFile = hOldFile;
--      OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n",
--               hOldFile, pFile->h));
--      return SQLITE_OK;
-+      bReturn = TRUE;
-     }
--#endif
--    case SQLITE_FCNTL_TEMPFILENAME: {
--      char *zTFile = 0;
--      int rc = winGetTempname(pFile->pVfs, &zTFile);
--      if( rc==SQLITE_OK ){
--        *(char**)pArg = zTFile;
--      }
--      OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
--      return rc;
++    /* Advance iterator ctx.iter so that it points to the first coalesced
++    ** phrase instance at or following position iBestStart. */
++    while( ctx.iter.iStart>=0 && ctx.iter.iStart<iBestStart && rc==SQLITE_OK ){
++      rc = fts5CInstIterNext(&ctx.iter);
++    }
++
++    if( rc==SQLITE_OK ){
++      rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
++    }
++    if( ctx.iRangeEnd>=(nColSize-1) ){
++      fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
++    }else{
++      fts5HighlightAppend(&rc, &ctx, zEllips, -1);
++    }
++  }
++  if( rc==SQLITE_OK ){
++    sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT);
++  }else{
++    sqlite3_result_error_code(pCtx, rc);
 +  }
++  sqlite3_free(ctx.zOut);
++  sqlite3_free(aSeen);
++  sqlite3_free(sFinder.aFirst);
++}
 +
-+  /* Releasing a pending lock */
-+  else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
-+           && nNumberOfBytesToUnlockLow == 1){
-+    if (pFile->local.bPending){
-+      pFile->local.bPending = FALSE;
-+      pFile->shared->bPending = FALSE;
-+      bReturn = TRUE;
-     }
--#if SQLITE_MAX_MMAP_SIZE>0
--    case SQLITE_FCNTL_MMAP_SIZE: {
--      i64 newLimit = *(i64*)pArg;
--      int rc = SQLITE_OK;
--      if( newLimit>sqlite3GlobalConfig.mxMmap ){
--        newLimit = sqlite3GlobalConfig.mxMmap;
--      }
--      *(i64*)pArg = pFile->mmapSizeMax;
--      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
--        pFile->mmapSizeMax = newLimit;
--        if( pFile->mmapSize>0 ){
--          winUnmapfile(pFile);
--          rc = winMapfile(pFile, -1);
--        }
--      }
--      OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
--      return rc;
-+  }
-+  /* Releasing a reserved lock */
-+  else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
-+           && nNumberOfBytesToUnlockLow == 1){
-+    if (pFile->local.bReserved) {
-+      pFile->local.bReserved = FALSE;
-+      pFile->shared->bReserved = FALSE;
-+      bReturn = TRUE;
-     }
--#endif
-   }
--  OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
--  return SQLITE_NOTFOUND;
++/************************************************************************/
 +
-+  winceMutexRelease(pFile->hMutex);
-+  return bReturn;
-+}
 +/*
-+** End of the special code for wince
-+*****************************************************************************/
-+#endif /* SQLITE_OS_WINCE */
++** The first time the bm25() function is called for a query, an instance
++** of the following structure is allocated and populated.
++*/
++typedef struct Fts5Bm25Data Fts5Bm25Data;
++struct Fts5Bm25Data {
++  int nPhrase;                    /* Number of phrases in query */
++  double avgdl;                   /* Average number of tokens in each row */
++  double *aIDF;                   /* IDF for each phrase */
++  double *aFreq;                  /* Array used to calculate phrase freq. */
++};
 +
 +/*
-+** Lock a file region.
++** Callback used by fts5Bm25GetData() to count the number of rows in the
++** table matched by each individual phrase within the query.
 +*/
-+static BOOL winLockFile(
-+  LPHANDLE phFile,
-+  DWORD flags,
-+  DWORD offsetLow,
-+  DWORD offsetHigh,
-+  DWORD numBytesLow,
-+  DWORD numBytesHigh
++static int fts5CountCb(
++  const Fts5ExtensionApi *pApi, 
++  Fts5Context *pFts,
++  void *pUserData                 /* Pointer to sqlite3_int64 variable */
 +){
-+#if SQLITE_OS_WINCE
-+  /*
-+  ** NOTE: Windows CE is handled differently here due its lack of the Win32
-+  **       API LockFile.
-+  */
-+  return winceLockFile(phFile, offsetLow, offsetHigh,
-+                       numBytesLow, numBytesHigh);
-+#else
-+  if( osIsNT() ){
-+    OVERLAPPED ovlp;
-+    memset(&ovlp, 0, sizeof(OVERLAPPED));
-+    ovlp.Offset = offsetLow;
-+    ovlp.OffsetHigh = offsetHigh;
-+    return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp);
-+  }else{
-+    return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
-+                      numBytesHigh);
-+  }
-+#endif
- }
- 
- /*
--** Return the sector size in bytes of the underlying block device for
--** the specified file. This is almost always 512 bytes, but may be
--** larger for some devices.
--**
--** SQLite code assumes this function cannot fail. It also assumes that
--** if two files are created in the same file-system directory (i.e.
--** a database and its journal file) that the sector size will be the
--** same for both.
--*/
--static int winSectorSize(sqlite3_file *id){
--  (void)id;
--  return SQLITE_DEFAULT_SECTOR_SIZE;
-+** Unlock a file region.
-+ */
-+static BOOL winUnlockFile(
-+  LPHANDLE phFile,
-+  DWORD offsetLow,
-+  DWORD offsetHigh,
-+  DWORD numBytesLow,
-+  DWORD numBytesHigh
++  sqlite3_int64 *pn = (sqlite3_int64*)pUserData;
++  UNUSED_PARAM2(pApi, pFts);
++  (*pn)++;
++  return SQLITE_OK;
++}
++
++/*
++** Set *ppData to point to the Fts5Bm25Data object for the current query. 
++** If the object has not already been allocated, allocate and populate it
++** now.
++*/
++static int fts5Bm25GetData(
++  const Fts5ExtensionApi *pApi, 
++  Fts5Context *pFts,
++  Fts5Bm25Data **ppData           /* OUT: bm25-data object for this query */
 +){
-+#if SQLITE_OS_WINCE
-+  /*
-+  ** NOTE: Windows CE is handled differently here due its lack of the Win32
-+  **       API UnlockFile.
-+  */
-+  return winceUnlockFile(phFile, offsetLow, offsetHigh,
-+                         numBytesLow, numBytesHigh);
-+#else
-+  if( osIsNT() ){
-+    OVERLAPPED ovlp;
-+    memset(&ovlp, 0, sizeof(OVERLAPPED));
-+    ovlp.Offset = offsetLow;
-+    ovlp.OffsetHigh = offsetHigh;
-+    return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp);
-+  }else{
-+    return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
-+                        numBytesHigh);
-+  }
-+#endif
- }
- 
-+/*****************************************************************************
-+** The next group of routines implement the I/O methods specified
-+** by the sqlite3_io_methods object.
-+******************************************************************************/
++  int rc = SQLITE_OK;             /* Return code */
++  Fts5Bm25Data *p;                /* Object to return */
 +
- /*
--** Return a vector of device characteristics.
-+** Some Microsoft compilers lack this definition.
- */
--static int winDeviceCharacteristics(sqlite3_file *id){
--  winFile *p = (winFile*)id;
--  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
--         ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
--}
-+#ifndef INVALID_SET_FILE_POINTER
-+# define INVALID_SET_FILE_POINTER ((DWORD)-1)
-+#endif
- 
- /*
--** Windows will only let you create file view mappings
--** on allocation size granularity boundaries.
--** During sqlite3_os_init() we do a GetSystemInfo()
--** to get the granularity size.
-+** Move the current position of the file handle passed as the first
-+** argument to offset iOffset within the file. If successful, return 0.
-+** Otherwise, set pFile->lastErrno and return non-zero.
- */
--static SYSTEM_INFO winSysInfo;
-+static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){
-+#if !SQLITE_OS_WINRT
-+  LONG upperBits;                 /* Most sig. 32 bits of new offset */
-+  LONG lowerBits;                 /* Least sig. 32 bits of new offset */
-+  DWORD dwRet;                    /* Value returned by SetFilePointer() */
-+  DWORD lastErrno;                /* Value returned by GetLastError() */
- 
--#ifndef SQLITE_OMIT_WAL
-+  OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset));
- 
--/*
--** Helper functions to obtain and relinquish the global mutex. The
--** global mutex is used to protect the winLockInfo objects used by
--** this file, all of which may be shared by multiple threads.
--**
--** Function winShmMutexHeld() is used to assert() that the global mutex
--** is held when required. This function is only used as part of assert()
--** statements. e.g.
--**
--**   winShmEnterMutex()
--**     assert( winShmMutexHeld() );
--**   winShmLeaveMutex()
--*/
--static void winShmEnterMutex(void){
--  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
--}
--static void winShmLeaveMutex(void){
--  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
--}
--#ifndef NDEBUG
--static int winShmMutexHeld(void) {
--  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-+  upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
-+  lowerBits = (LONG)(iOffset & 0xffffffff);
-+
-+  /* API oddity: If successful, SetFilePointer() returns a dword
-+  ** containing the lower 32-bits of the new file-offset. Or, if it fails,
-+  ** it returns INVALID_SET_FILE_POINTER. However according to MSDN,
-+  ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine
-+  ** whether an error has actually occurred, it is also necessary to call
-+  ** GetLastError().
-+  */
-+  dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
-+
-+  if( (dwRet==INVALID_SET_FILE_POINTER
-+      && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
-+    pFile->lastErrno = lastErrno;
-+    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
-+                "winSeekFile", pFile->zPath);
-+    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
-+    return 1;
-+  }
++  p = pApi->xGetAuxdata(pFts, 0);
++  if( p==0 ){
++    int nPhrase;                  /* Number of phrases in query */
++    sqlite3_int64 nRow = 0;       /* Number of rows in table */
++    sqlite3_int64 nToken = 0;     /* Number of tokens in table */
++    int nByte;                    /* Bytes of space to allocate */
++    int i;
 +
-+  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
-+  return 0;
-+#else
-+  /*
-+  ** Same as above, except that this implementation works for WinRT.
-+  */
++    /* Allocate the Fts5Bm25Data object */
++    nPhrase = pApi->xPhraseCount(pFts);
++    nByte = sizeof(Fts5Bm25Data) + nPhrase*2*sizeof(double);
++    p = (Fts5Bm25Data*)sqlite3_malloc(nByte);
++    if( p==0 ){
++      rc = SQLITE_NOMEM;
++    }else{
++      memset(p, 0, nByte);
++      p->nPhrase = nPhrase;
++      p->aIDF = (double*)&p[1];
++      p->aFreq = &p->aIDF[nPhrase];
++    }
 +
-+  LARGE_INTEGER x;                /* The new offset */
-+  BOOL bRet;                      /* Value returned by SetFilePointerEx() */
++    /* Calculate the average document length for this FTS5 table */
++    if( rc==SQLITE_OK ) rc = pApi->xRowCount(pFts, &nRow);
++    if( rc==SQLITE_OK ) rc = pApi->xColumnTotalSize(pFts, -1, &nToken);
++    if( rc==SQLITE_OK ) p->avgdl = (double)nToken  / (double)nRow;
 +
-+  x.QuadPart = iOffset;
-+  bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);
++    /* Calculate an IDF for each phrase in the query */
++    for(i=0; rc==SQLITE_OK && i<nPhrase; i++){
++      sqlite3_int64 nHit = 0;
++      rc = pApi->xQueryPhrase(pFts, i, (void*)&nHit, fts5CountCb);
++      if( rc==SQLITE_OK ){
++        /* Calculate the IDF (Inverse Document Frequency) for phrase i.
++        ** This is done using the standard BM25 formula as found on wikipedia:
++        **
++        **   IDF = log( (N - nHit + 0.5) / (nHit + 0.5) )
++        **
++        ** where "N" is the total number of documents in the set and nHit
++        ** is the number that contain at least one instance of the phrase
++        ** under consideration.
++        **
++        ** The problem with this is that if (N < 2*nHit), the IDF is 
++        ** negative. Which is undesirable. So the mimimum allowable IDF is
++        ** (1e-6) - roughly the same as a term that appears in just over
++        ** half of set of 5,000,000 documents.  */
++        double idf = log( (nRow - nHit + 0.5) / (nHit + 0.5) );
++        if( idf<=0.0 ) idf = 1e-6;
++        p->aIDF[i] = idf;
++      }
++    }
 +
-+  if(!bRet){
-+    pFile->lastErrno = osGetLastError();
-+    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
-+                "winSeekFile", pFile->zPath);
-+    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
-+    return 1;
++    if( rc!=SQLITE_OK ){
++      sqlite3_free(p);
++    }else{
++      rc = pApi->xSetAuxdata(pFts, p, sqlite3_free);
++    }
++    if( rc!=SQLITE_OK ) p = 0;
 +  }
++  *ppData = p;
++  return rc;
++}
 +
-+  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
-+  return 0;
-+#endif
- }
++/*
++** Implementation of bm25() function.
++*/
++static void fts5Bm25Function(
++  const Fts5ExtensionApi *pApi,   /* API offered by current FTS version */
++  Fts5Context *pFts,              /* First arg to pass to pApi functions */
++  sqlite3_context *pCtx,          /* Context for returning result/error */
++  int nVal,                       /* Number of values in apVal[] array */
++  sqlite3_value **apVal           /* Array of trailing arguments */
++){
++  const double k1 = 1.2;          /* Constant "k1" from BM25 formula */
++  const double b = 0.75;          /* Constant "b" from BM25 formula */
++  int rc = SQLITE_OK;             /* Error code */
++  double score = 0.0;             /* SQL function return value */
++  Fts5Bm25Data *pData;            /* Values allocated/calculated once only */
++  int i;                          /* Iterator variable */
++  int nInst = 0;                  /* Value returned by xInstCount() */
++  double D = 0.0;                 /* Total number of tokens in row */
++  double *aFreq = 0;              /* Array of phrase freq. for current row */
 +
-+#if SQLITE_MAX_MMAP_SIZE>0
-+/* Forward references to VFS helper methods used for memory mapped files */
-+static int winMapfile(winFile*, sqlite3_int64);
-+static int winUnmapfile(winFile*);
- #endif
- 
- /*
--** Object used to represent a single file opened and mmapped to provide
--** shared memory.  When multiple threads all reference the same
--** log-summary, each thread has its own winFile object, but they all
--** point to a single instance of this object.  In other words, each
--** log-summary is opened only once per process.
--**
--** winShmMutexHeld() must be true when creating or destroying
--** this object or while reading or writing the following fields:
--**
--**      nRef
--**      pNext
--**
--** The following fields are read-only after the object is created:
--**
--**      fid
--**      zFilename
--**
--** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
--** winShmMutexHeld() is true when reading or writing any other field
--** in this structure.
-+** Close a file.
- **
-+** It is reported that an attempt to close a handle might sometimes
-+** fail.  This is a very unreasonable result, but Windows is notorious
-+** for being unreasonable so I do not doubt that it might happen.  If
-+** the close fails, we pause for 100 milliseconds and try again.  As
-+** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
-+** giving up and returning an error.
- */
--struct winShmNode {
--  sqlite3_mutex *mutex;      /* Mutex to access this object */
--  char *zFilename;           /* Name of the file */
--  winFile hFile;             /* File handle from winOpen */
-+#define MX_CLOSE_ATTEMPT 3
-+static int winClose(sqlite3_file *id){
-+  int rc, cnt = 0;
-+  winFile *pFile = (winFile*)id;
- 
--  int szRegion;              /* Size of shared-memory regions */
--  int nRegion;               /* Size of array apRegion */
--  struct ShmRegion {
--    HANDLE hMap;             /* File handle from CreateFileMapping */
--    void *pMap;
--  } *aRegion;
--  DWORD lastErrno;           /* The Windows errno from the last I/O error */
-+  assert( id!=0 );
-+#ifndef SQLITE_OMIT_WAL
-+  assert( pFile->pShm==0 );
-+#endif
-+  assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
-+  OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n",
-+           osGetCurrentProcessId(), pFile, pFile->h));
- 
--  int nRef;                  /* Number of winShm objects pointing to this */
--  winShm *pFirst;            /* All winShm objects pointing to this */
--  winShmNode *pNext;         /* Next in list of all winShmNode objects */
--#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
--  u8 nextShmId;              /* Next available winShm.id value */
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  winUnmapfile(pFile);
- #endif
--};
- 
--/*
--** A global array of all winShmNode objects.
--**
--** The winShmMutexHeld() must be true while reading or writing this list.
--*/
--static winShmNode *winShmNodeList = 0;
-+  do{
-+    rc = osCloseHandle(pFile->h);
-+    /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
-+  }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
-+#if SQLITE_OS_WINCE
-+#define WINCE_DELETION_ATTEMPTS 3
-+  winceDestroyLock(pFile);
-+  if( pFile->zDeleteOnClose ){
-+    int cnt = 0;
-+    while(
-+           osDeleteFileW(pFile->zDeleteOnClose)==0
-+        && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
-+        && cnt++ < WINCE_DELETION_ATTEMPTS
-+    ){
-+       sqlite3_win32_sleep(100);  /* Wait a little before trying again */
++  /* Calculate the phrase frequency (symbol "f(qi,D)" in the documentation)
++  ** for each phrase in the query for the current row. */
++  rc = fts5Bm25GetData(pApi, pFts, &pData);
++  if( rc==SQLITE_OK ){
++    aFreq = pData->aFreq;
++    memset(aFreq, 0, sizeof(double) * pData->nPhrase);
++    rc = pApi->xInstCount(pFts, &nInst);
++  }
++  for(i=0; rc==SQLITE_OK && i<nInst; i++){
++    int ip; int ic; int io;
++    rc = pApi->xInst(pFts, i, &ip, &ic, &io);
++    if( rc==SQLITE_OK ){
++      double w = (nVal > ic) ? sqlite3_value_double(apVal[ic]) : 1.0;
++      aFreq[ip] += w;
 +    }
-+    sqlite3_free(pFile->zDeleteOnClose);
 +  }
-+#endif
-+  if( rc ){
-+    pFile->h = NULL;
++
++  /* Figure out the total size of the current row in tokens. */
++  if( rc==SQLITE_OK ){
++    int nTok;
++    rc = pApi->xColumnSize(pFts, -1, &nTok);
++    D = (double)nTok;
++  }
++
++  /* Determine the BM25 score for the current row. */
++  for(i=0; rc==SQLITE_OK && i<pData->nPhrase; i++){
++    score += pData->aIDF[i] * (
++      ( aFreq[i] * (k1 + 1.0) ) / 
++      ( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) )
++    );
++  }
++  
++  /* If no error has occurred, return the calculated score. Otherwise,
++  ** throw an SQL exception.  */
++  if( rc==SQLITE_OK ){
++    sqlite3_result_double(pCtx, -1.0 * score);
++  }else{
++    sqlite3_result_error_code(pCtx, rc);
 +  }
-+  OpenCounter(-1);
-+  OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n",
-+           osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed"));
-+  return rc ? SQLITE_OK
-+            : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
-+                          "winClose", pFile->zPath);
 +}
- 
- /*
--** Structure used internally by this VFS to record the state of an
--** open shared memory connection.
--**
--** The following fields are initialized when this object is created and
--** are read-only thereafter:
--**
--**    winShm.pShmNode
--**    winShm.id
--**
--** All other fields are read/write.  The winShm.pShmNode->mutex must be held
--** while accessing any read/write fields.
-+** Read data from a file into a buffer.  Return SQLITE_OK if all
-+** bytes were read successfully and SQLITE_IOERR if anything goes
-+** wrong.
- */
--struct winShm {
--  winShmNode *pShmNode;      /* The underlying winShmNode object */
--  winShm *pNext;             /* Next winShm with the same winShmNode */
--  u8 hasMutex;               /* True if holding the winShmNode mutex */
--  u16 sharedMask;            /* Mask of shared locks held */
--  u16 exclMask;              /* Mask of exclusive locks held */
--#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
--  u8 id;                     /* Id of this connection with its winShmNode */
-+static int winRead(
-+  sqlite3_file *id,          /* File to read from */
-+  void *pBuf,                /* Write content into this buffer */
-+  int amt,                   /* Number of bytes to read */
-+  sqlite3_int64 offset       /* Begin reading at this offset */
-+){
-+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
-+  OVERLAPPED overlapped;          /* The offset for ReadFile. */
- #endif
--};
-+  winFile *pFile = (winFile*)id;  /* file handle */
-+  DWORD nRead;                    /* Number of bytes actually read from file */
-+  int nRetry = 0;                 /* Number of retrys */
- 
--/*
--** Constants used for locking
--*/
--#define WIN_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
--#define WIN_SHM_DMS    (WIN_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
-+  assert( id!=0 );
-+  assert( amt>0 );
-+  assert( offset>=0 );
-+  SimulateIOError(return SQLITE_IOERR_READ);
-+  OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
-+           "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
-+           pFile->h, pBuf, amt, offset, pFile->locktype));
 +
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  /* Deal with as much of this read request as possible by transfering
-+  ** data from the memory mapping using memcpy().  */
-+  if( offset<pFile->mmapSize ){
-+    if( offset+amt <= pFile->mmapSize ){
-+      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
-+      OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
-+               osGetCurrentProcessId(), pFile, pFile->h));
-+      return SQLITE_OK;
++static int sqlite3Fts5AuxInit(fts5_api *pApi){
++  struct Builtin {
++    const char *zFunc;            /* Function name (nul-terminated) */
++    void *pUserData;              /* User-data pointer */
++    fts5_extension_function xFunc;/* Callback function */
++    void (*xDestroy)(void*);      /* Destructor function */
++  } aBuiltin [] = {
++    { "snippet",   0, fts5SnippetFunction, 0 },
++    { "highlight", 0, fts5HighlightFunction, 0 },
++    { "bm25",      0, fts5Bm25Function,    0 },
++  };
++  int rc = SQLITE_OK;             /* Return code */
++  int i;                          /* To iterate through builtin functions */
++
++  for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
++    rc = pApi->xCreateFunction(pApi,
++        aBuiltin[i].zFunc,
++        aBuiltin[i].pUserData,
++        aBuiltin[i].xFunc,
++        aBuiltin[i].xDestroy
++    );
++  }
++
++  return rc;
++}
++
++
++
++/*
++** 2014 May 31
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++*/
++
++
++
++/* #include "fts5Int.h" */
++
++static int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){
++  if( (u32)pBuf->nSpace<nByte ){
++    u32 nNew = pBuf->nSpace ? pBuf->nSpace : 64;
++    u8 *pNew;
++    while( nNew<nByte ){
++      nNew = nNew * 2;
++    }
++    pNew = sqlite3_realloc(pBuf->p, nNew);
++    if( pNew==0 ){
++      *pRc = SQLITE_NOMEM;
++      return 1;
 +    }else{
-+      int nCopy = (int)(pFile->mmapSize - offset);
-+      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
-+      pBuf = &((u8 *)pBuf)[nCopy];
-+      amt -= nCopy;
-+      offset += nCopy;
++      pBuf->nSpace = nNew;
++      pBuf->p = pNew;
 +    }
 +  }
-+#endif
++  return 0;
++}
 +
-+#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
-+  if( winSeekFile(pFile, offset) ){
-+    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
-+             osGetCurrentProcessId(), pFile, pFile->h));
-+    return SQLITE_FULL;
-+  }
-+  while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
-+#else
-+  memset(&overlapped, 0, sizeof(OVERLAPPED));
-+  overlapped.Offset = (LONG)(offset & 0xffffffff);
-+  overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
-+  while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) &&
-+         osGetLastError()!=ERROR_HANDLE_EOF ){
-+#endif
-+    DWORD lastErrno;
-+    if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
-+    pFile->lastErrno = lastErrno;
-+    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n",
-+             osGetCurrentProcessId(), pFile, pFile->h));
-+    return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
-+                       "winRead", pFile->zPath);
-+  }
-+  winLogIoerr(nRetry, __LINE__);
-+  if( nRead<(DWORD)amt ){
-+    /* Unread parts of the buffer must be zero-filled */
-+    memset(&((char*)pBuf)[nRead], 0, amt-nRead);
-+    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n",
-+             osGetCurrentProcessId(), pFile, pFile->h));
-+    return SQLITE_IOERR_SHORT_READ;
++
++/*
++** Encode value iVal as an SQLite varint and append it to the buffer object
++** pBuf. If an OOM error occurs, set the error code in p.
++*/
++static void sqlite3Fts5BufferAppendVarint(int *pRc, Fts5Buffer *pBuf, i64 iVal){
++  if( fts5BufferGrow(pRc, pBuf, 9) ) return;
++  pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iVal);
++}
++
++static void sqlite3Fts5Put32(u8 *aBuf, int iVal){
++  aBuf[0] = (iVal>>24) & 0x00FF;
++  aBuf[1] = (iVal>>16) & 0x00FF;
++  aBuf[2] = (iVal>> 8) & 0x00FF;
++  aBuf[3] = (iVal>> 0) & 0x00FF;
++}
++
++static int sqlite3Fts5Get32(const u8 *aBuf){
++  return (aBuf[0] << 24) + (aBuf[1] << 16) + (aBuf[2] << 8) + aBuf[3];
++}
++
++/*
++** Append buffer nData/pData to buffer pBuf. If an OOM error occurs, set 
++** the error code in p. If an error has already occurred when this function
++** is called, it is a no-op.
++*/
++static void sqlite3Fts5BufferAppendBlob(
++  int *pRc,
++  Fts5Buffer *pBuf, 
++  u32 nData, 
++  const u8 *pData
++){
++  assert_nc( *pRc || nData>=0 );
++  if( nData ){
++    if( fts5BufferGrow(pRc, pBuf, nData) ) return;
++    memcpy(&pBuf->p[pBuf->n], pData, nData);
++    pBuf->n += nData;
 +  }
++}
 +
-+  OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
-+           osGetCurrentProcessId(), pFile, pFile->h));
-+  return SQLITE_OK;
++/*
++** Append the nul-terminated string zStr to the buffer pBuf. This function
++** ensures that the byte following the buffer data is set to 0x00, even 
++** though this byte is not included in the pBuf->n count.
++*/
++static void sqlite3Fts5BufferAppendString(
++  int *pRc,
++  Fts5Buffer *pBuf, 
++  const char *zStr
++){
++  int nStr = (int)strlen(zStr);
++  sqlite3Fts5BufferAppendBlob(pRc, pBuf, nStr+1, (const u8*)zStr);
++  pBuf->n--;
 +}
- 
- /*
--** Apply advisory locks for all n bytes beginning at ofst.
-+** Write data from a buffer into a file.  Return SQLITE_OK on success
-+** or some other error code on failure.
- */
--#define _SHM_UNLCK  1
--#define _SHM_RDLCK  2
--#define _SHM_WRLCK  3
--static int winShmSystemLock(
--  winShmNode *pFile,    /* Apply locks to this open shared-memory segment */
--  int lockType,         /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
--  int ofst,             /* Offset to first byte to be locked/unlocked */
--  int nByte             /* Number of bytes to lock or unlock */
-+static int winWrite(
-+  sqlite3_file *id,               /* File to write into */
-+  const void *pBuf,               /* The bytes to be written */
-+  int amt,                        /* Number of bytes to write */
-+  sqlite3_int64 offset            /* Offset into the file to begin writing at */
- ){
--  int rc = 0;           /* Result code form Lock/UnlockFileEx() */
--
--  /* Access to the winShmNode object is serialized by the caller */
--  assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
-+  int rc = 0;                     /* True if error has occurred, else false */
-+  winFile *pFile = (winFile*)id;  /* File handle */
-+  int nRetry = 0;                 /* Number of retries */
- 
--  OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n",
--           pFile->hFile.h, lockType, ofst, nByte));
-+  assert( amt>0 );
-+  assert( pFile );
-+  SimulateIOError(return SQLITE_IOERR_WRITE);
-+  SimulateDiskfullError(return SQLITE_FULL);
- 
--  /* Release/Acquire the system-level lock */
--  if( lockType==_SHM_UNLCK ){
--    rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
--  }else{
--    /* Initialize the locking parameters */
--    DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
--    if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
--    rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
--  }
-+  OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
-+           "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
-+           pFile->h, pBuf, amt, offset, pFile->locktype));
- 
--  if( rc!= 0 ){
--    rc = SQLITE_OK;
--  }else{
--    pFile->lastErrno =  osGetLastError();
--    rc = SQLITE_BUSY;
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  /* Deal with as much of this write request as possible by transfering
-+  ** data from the memory mapping using memcpy().  */
-+  if( offset<pFile->mmapSize ){
-+    if( offset+amt <= pFile->mmapSize ){
-+      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
-+      OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
-+               osGetCurrentProcessId(), pFile, pFile->h));
-+      return SQLITE_OK;
++
++/*
++** Argument zFmt is a printf() style format string. This function performs
++** the printf() style processing, then appends the results to buffer pBuf.
++**
++** Like sqlite3Fts5BufferAppendString(), this function ensures that the byte 
++** following the buffer data is set to 0x00, even though this byte is not
++** included in the pBuf->n count.
++*/ 
++static void sqlite3Fts5BufferAppendPrintf(
++  int *pRc,
++  Fts5Buffer *pBuf, 
++  char *zFmt, ...
++){
++  if( *pRc==SQLITE_OK ){
++    char *zTmp;
++    va_list ap;
++    va_start(ap, zFmt);
++    zTmp = sqlite3_vmprintf(zFmt, ap);
++    va_end(ap);
++
++    if( zTmp==0 ){
++      *pRc = SQLITE_NOMEM;
 +    }else{
-+      int nCopy = (int)(pFile->mmapSize - offset);
-+      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
-+      pBuf = &((u8 *)pBuf)[nCopy];
-+      amt -= nCopy;
-+      offset += nCopy;
++      sqlite3Fts5BufferAppendString(pRc, pBuf, zTmp);
++      sqlite3_free(zTmp);
 +    }
-   }
-+#endif
- 
--  OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n",
--           pFile->hFile.h, (lockType == _SHM_UNLCK) ? "winUnlockFile" :
--           "winLockFile", pFile->lastErrno, sqlite3ErrName(rc)));
--
--  return rc;
--}
-+#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
-+  rc = winSeekFile(pFile, offset);
-+  if( rc==0 ){
-+#else
-+  {
-+#endif
-+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
-+    OVERLAPPED overlapped;        /* The offset for WriteFile. */
-+#endif
-+    u8 *aRem = (u8 *)pBuf;        /* Data yet to be written */
-+    int nRem = amt;               /* Number of bytes yet to be written */
-+    DWORD nWrite;                 /* Bytes written by each WriteFile() call */
-+    DWORD lastErrno = NO_ERROR;   /* Value returned by GetLastError() */
- 
--/* Forward references to VFS methods */
--static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
--static int winDelete(sqlite3_vfs *,const char*,int);
-+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
-+    memset(&overlapped, 0, sizeof(OVERLAPPED));
-+    overlapped.Offset = (LONG)(offset & 0xffffffff);
-+    overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
-+#endif
- 
--/*
--** Purge the winShmNodeList list of all entries with winShmNode.nRef==0.
--**
--** This is not a VFS shared-memory method; it is a utility function called
--** by VFS shared-memory methods.
--*/
--static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
--  winShmNode **pp;
--  winShmNode *p;
--  assert( winShmMutexHeld() );
--  OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n",
--           osGetCurrentProcessId(), deleteFlag));
--  pp = &winShmNodeList;
--  while( (p = *pp)!=0 ){
--    if( p->nRef==0 ){
--      int i;
--      if( p->mutex ){ sqlite3_mutex_free(p->mutex); }
--      for(i=0; i<p->nRegion; i++){
--        BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
--        OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
--                 osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
--        UNUSED_VARIABLE_VALUE(bRc);
--        bRc = osCloseHandle(p->aRegion[i].hMap);
--        OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n",
--                 osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
--        UNUSED_VARIABLE_VALUE(bRc);
--      }
--      if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){
--        SimulateIOErrorBenign(1);
--        winClose((sqlite3_file *)&p->hFile);
--        SimulateIOErrorBenign(0);
-+    while( nRem>0 ){
-+#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
-+      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
-+#else
-+      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
-+#endif
-+        if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
-+        break;
-       }
--      if( deleteFlag ){
--        SimulateIOErrorBenign(1);
--        sqlite3BeginBenignMalloc();
--        winDelete(pVfs, p->zFilename, 0);
--        sqlite3EndBenignMalloc();
--        SimulateIOErrorBenign(0);
-+      assert( nWrite==0 || nWrite<=(DWORD)nRem );
-+      if( nWrite==0 || nWrite>(DWORD)nRem ){
-+        lastErrno = osGetLastError();
-+        break;
-       }
--      *pp = p->pNext;
--      sqlite3_free(p->aRegion);
--      sqlite3_free(p);
--    }else{
--      pp = &p->pNext;
-+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
-+      offset += nWrite;
-+      overlapped.Offset = (LONG)(offset & 0xffffffff);
-+      overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
-+#endif
-+      aRem += nWrite;
-+      nRem -= nWrite;
++  }
++}
++
++static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...){
++  char *zRet = 0;
++  if( *pRc==SQLITE_OK ){
++    va_list ap;
++    va_start(ap, zFmt);
++    zRet = sqlite3_vmprintf(zFmt, ap);
++    va_end(ap);
++    if( zRet==0 ){
++      *pRc = SQLITE_NOMEM; 
 +    }
-+    if( nRem>0 ){
-+      pFile->lastErrno = lastErrno;
-+      rc = 1;
++  }
++  return zRet;
++}
++ 
++
++/*
++** Free any buffer allocated by pBuf. Zero the structure before returning.
++*/
++static void sqlite3Fts5BufferFree(Fts5Buffer *pBuf){
++  sqlite3_free(pBuf->p);
++  memset(pBuf, 0, sizeof(Fts5Buffer));
++}
++
++/*
++** Zero the contents of the buffer object. But do not free the associated 
++** memory allocation.
++*/
++static void sqlite3Fts5BufferZero(Fts5Buffer *pBuf){
++  pBuf->n = 0;
++}
++
++/*
++** Set the buffer to contain nData/pData. If an OOM error occurs, leave an
++** the error code in p. If an error has already occurred when this function
++** is called, it is a no-op.
++*/
++static void sqlite3Fts5BufferSet(
++  int *pRc,
++  Fts5Buffer *pBuf, 
++  int nData, 
++  const u8 *pData
++){
++  pBuf->n = 0;
++  sqlite3Fts5BufferAppendBlob(pRc, pBuf, nData, pData);
++}
++
++static int sqlite3Fts5PoslistNext64(
++  const u8 *a, int n,             /* Buffer containing poslist */
++  int *pi,                        /* IN/OUT: Offset within a[] */
++  i64 *piOff                      /* IN/OUT: Current offset */
++){
++  int i = *pi;
++  if( i>=n ){
++    /* EOF */
++    *piOff = -1;
++    return 1;  
++  }else{
++    i64 iOff = *piOff;
++    int iVal;
++    fts5FastGetVarint32(a, i, iVal);
++    if( iVal==1 ){
++      fts5FastGetVarint32(a, i, iVal);
++      iOff = ((i64)iVal) << 32;
++      fts5FastGetVarint32(a, i, iVal);
 +    }
++    *piOff = iOff + (iVal-2);
++    *pi = i;
++    return 0;
 +  }
++}
++
 +
-+  if( rc ){
-+    if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
-+       || ( pFile->lastErrno==ERROR_DISK_FULL )){
-+      OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
-+               osGetCurrentProcessId(), pFile, pFile->h));
-+      return winLogError(SQLITE_FULL, pFile->lastErrno,
-+                         "winWrite1", pFile->zPath);
-     }
-+    OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n",
-+             osGetCurrentProcessId(), pFile, pFile->h));
-+    return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
-+                       "winWrite2", pFile->zPath);
-+  }else{
-+    winLogIoerr(nRetry, __LINE__);
-   }
-+  OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
-+           osGetCurrentProcessId(), pFile, pFile->h));
-+  return SQLITE_OK;
- }
- 
- /*
--** Open the shared-memory area associated with database file pDbFd.
--**
--** When opening a new shared-memory file, if no other instances of that
--** file are currently open, in this process or in other processes, then
--** the file must be truncated to zero length or have its header cleared.
-+** Truncate an open file to a specified size
- */
--static int winOpenSharedMemory(winFile *pDbFd){
--  struct winShm *p;                  /* The connection to be opened */
--  struct winShmNode *pShmNode = 0;   /* The underlying mmapped file */
--  int rc;                            /* Result code */
--  struct winShmNode *pNew;           /* Newly allocated winShmNode */
--  int nName;                         /* Size of zName in bytes */
-+static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
-+  winFile *pFile = (winFile*)id;  /* File handle object */
-+  int rc = SQLITE_OK;             /* Return code for this function */
-+  DWORD lastErrno;
- 
--  assert( pDbFd->pShm==0 );    /* Not previously opened */
-+  assert( pFile );
-+  SimulateIOError(return SQLITE_IOERR_TRUNCATE);
-+  OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
-+           osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype));
- 
--  /* Allocate space for the new sqlite3_shm object.  Also speculatively
--  ** allocate space for a new winShmNode and filename.
-+  /* If the user has configured a chunk-size for this file, truncate the
-+  ** file so that it consists of an integer number of chunks (i.e. the
-+  ** actual file size after the operation may be larger than the requested
-+  ** size).
-   */
--  p = sqlite3MallocZero( sizeof(*p) );
--  if( p==0 ) return SQLITE_IOERR_NOMEM;
--  nName = sqlite3Strlen30(pDbFd->zPath);
--  pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
--  if( pNew==0 ){
--    sqlite3_free(p);
--    return SQLITE_IOERR_NOMEM;
-+  if( pFile->szChunk>0 ){
-+    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
-   }
--  pNew->zFilename = (char*)&pNew[1];
--  sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
--  sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
- 
--  /* Look to see if there is an existing winShmNode that can be used.
--  ** If no matching winShmNode currently exists, create a new one.
--  */
--  winShmEnterMutex();
--  for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
--    /* TBD need to come up with better match here.  Perhaps
--    ** use FILE_ID_BOTH_DIR_INFO Structure.
--    */
--    if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break;
-+  /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
-+  if( winSeekFile(pFile, nByte) ){
-+    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
-+                     "winTruncate1", pFile->zPath);
-+  }else if( 0==osSetEndOfFile(pFile->h) &&
-+            ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){
-+    pFile->lastErrno = lastErrno;
-+    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
-+                     "winTruncate2", pFile->zPath);
-   }
--  if( pShmNode ){
--    sqlite3_free(pNew);
--  }else{
--    pShmNode = pNew;
--    pNew = 0;
--    ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
--    pShmNode->pNext = winShmNodeList;
--    winShmNodeList = pShmNode;
--
--    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
--    if( pShmNode->mutex==0 ){
--      rc = SQLITE_IOERR_NOMEM;
--      goto shm_open_err;
--    }
--
--    rc = winOpen(pDbFd->pVfs,
--                 pShmNode->zFilename,             /* Name of the file (UTF-8) */
--                 (sqlite3_file*)&pShmNode->hFile,  /* File handle here */
--                 SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
--                 0);
--    if( SQLITE_OK!=rc ){
--      goto shm_open_err;
--    }
- 
--    /* Check to see if another process is holding the dead-man switch.
--    ** If not, truncate the file to zero length.
--    */
--    if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
--      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
--      if( rc!=SQLITE_OK ){
--        rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
--                         "winOpenShm", pDbFd->zPath);
--      }
--    }
--    if( rc==SQLITE_OK ){
--      winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
--      rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
--    }
--    if( rc ) goto shm_open_err;
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  /* If the file was truncated to a size smaller than the currently
-+  ** mapped region, reduce the effective mapping size as well. SQLite will
-+  ** use read() and write() to access data beyond this point from now on.
-+  */
-+  if( pFile->pMapRegion && nByte<pFile->mmapSize ){
-+    pFile->mmapSize = nByte;
-   }
--
--  /* Make the new connection a child of the winShmNode */
--  p->pShmNode = pShmNode;
--#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
--  p->id = pShmNode->nextShmId++;
- #endif
--  pShmNode->nRef++;
--  pDbFd->pShm = p;
--  winShmLeaveMutex();
--
--  /* The reference count on pShmNode has already been incremented under
--  ** the cover of the winShmEnterMutex() mutex and the pointer from the
--  ** new (struct winShm) object to the pShmNode has been set. All that is
--  ** left to do is to link the new object into the linked list starting
--  ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
--  ** mutex.
--  */
--  sqlite3_mutex_enter(pShmNode->mutex);
--  p->pNext = pShmNode->pFirst;
--  pShmNode->pFirst = p;
--  sqlite3_mutex_leave(pShmNode->mutex);
--  return SQLITE_OK;
- 
--  /* Jump here on any error */
--shm_open_err:
--  winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
--  winShmPurge(pDbFd->pVfs, 0);      /* This call frees pShmNode if required */
--  sqlite3_free(p);
--  sqlite3_free(pNew);
--  winShmLeaveMutex();
-+  OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n",
-+           osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc)));
-   return rc;
- }
- 
-+#ifdef SQLITE_TEST
- /*
--** Close a connection to shared-memory.  Delete the underlying
--** storage if deleteFlag is true.
-+** Count the number of fullsyncs and normal syncs.  This is used to test
-+** that syncs and fullsyncs are occuring at the right times.
- */
--static int winShmUnmap(
--  sqlite3_file *fd,          /* Database holding shared memory */
--  int deleteFlag             /* Delete after closing if true */
--){
--  winFile *pDbFd;       /* Database holding shared-memory */
--  winShm *p;            /* The connection to be closed */
--  winShmNode *pShmNode; /* The underlying shared-memory file */
--  winShm **pp;          /* For looping over sibling connections */
-+SQLITE_API int sqlite3_sync_count = 0;
-+SQLITE_API int sqlite3_fullsync_count = 0;
-+#endif
- 
--  pDbFd = (winFile*)fd;
--  p = pDbFd->pShm;
--  if( p==0 ) return SQLITE_OK;
--  pShmNode = p->pShmNode;
 +/*
-+** Make sure all writes to a particular file are committed to disk.
++** Advance the iterator object passed as the only argument. Return true
++** if the iterator reaches EOF, or false otherwise.
 +*/
-+static int winSync(sqlite3_file *id, int flags){
-+#ifndef SQLITE_NO_SYNC
-+  /*
-+  ** Used only when SQLITE_NO_SYNC is not defined.
-+   */
-+  BOOL rc;
-+#endif
-+#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
-+    defined(SQLITE_HAVE_OS_TRACE)
-+  /*
-+  ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
-+  ** OSTRACE() macros.
-+   */
-+  winFile *pFile = (winFile*)id;
-+#else
-+  UNUSED_PARAMETER(id);
-+#endif
- 
--  /* Remove connection p from the set of connections associated
--  ** with pShmNode */
--  sqlite3_mutex_enter(pShmNode->mutex);
--  for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
--  *pp = p->pNext;
-+  assert( pFile );
-+  /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
-+  assert((flags&0x0F)==SQLITE_SYNC_NORMAL
-+      || (flags&0x0F)==SQLITE_SYNC_FULL
-+  );
- 
--  /* Free the connection p */
--  sqlite3_free(p);
--  pDbFd->pShm = 0;
--  sqlite3_mutex_leave(pShmNode->mutex);
-+  /* Unix cannot, but some systems may return SQLITE_FULL from here. This
-+  ** line is to test that doing so does not cause any problems.
-+  */
-+  SimulateDiskfullError( return SQLITE_FULL );
- 
--  /* If pShmNode->nRef has reached 0, then close the underlying
--  ** shared-memory file, too */
--  winShmEnterMutex();
--  assert( pShmNode->nRef>0 );
--  pShmNode->nRef--;
--  if( pShmNode->nRef==0 ){
--    winShmPurge(pDbFd->pVfs, deleteFlag);
-+  OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n",
-+           osGetCurrentProcessId(), pFile, pFile->h, flags,
-+           pFile->locktype));
-+
-+#ifndef SQLITE_TEST
-+  UNUSED_PARAMETER(flags);
-+#else
-+  if( (flags&0x0F)==SQLITE_SYNC_FULL ){
-+    sqlite3_fullsync_count++;
-   }
--  winShmLeaveMutex();
-+  sqlite3_sync_count++;
-+#endif
- 
-+  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
-+  ** no-op
-+  */
-+#ifdef SQLITE_NO_SYNC
-+  OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
-+           osGetCurrentProcessId(), pFile, pFile->h));
-   return SQLITE_OK;
-+#else
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  if( pFile->pMapRegion ){
-+    if( osFlushViewOfFile(pFile->pMapRegion, 0) ){
-+      OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
-+               "rc=SQLITE_OK\n", osGetCurrentProcessId(),
-+               pFile, pFile->pMapRegion));
++static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader *pIter){
++  if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos) ){
++    pIter->bEof = 1;
++  }
++  return pIter->bEof;
++}
++
++static int sqlite3Fts5PoslistReaderInit(
++  const u8 *a, int n,             /* Poslist buffer to iterate through */
++  Fts5PoslistReader *pIter        /* Iterator object to initialize */
++){
++  memset(pIter, 0, sizeof(*pIter));
++  pIter->a = a;
++  pIter->n = n;
++  sqlite3Fts5PoslistReaderNext(pIter);
++  return pIter->bEof;
++}
++
++/*
++** Append position iPos to the position list being accumulated in buffer
++** pBuf, which must be already be large enough to hold the new data.
++** The previous position written to this list is *piPrev. *piPrev is set
++** to iPos before returning.
++*/
++static void sqlite3Fts5PoslistSafeAppend(
++  Fts5Buffer *pBuf, 
++  i64 *piPrev, 
++  i64 iPos
++){
++  static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
++  if( (iPos & colmask) != (*piPrev & colmask) ){
++    pBuf->p[pBuf->n++] = 1;
++    pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32));
++    *piPrev = (iPos & colmask);
++  }
++  pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2);
++  *piPrev = iPos;
++}
++
++static int sqlite3Fts5PoslistWriterAppend(
++  Fts5Buffer *pBuf, 
++  Fts5PoslistWriter *pWriter,
++  i64 iPos
++){
++  int rc = 0;   /* Initialized only to suppress erroneous warning from Clang */
++  if( fts5BufferGrow(&rc, pBuf, 5+5+5) ) return rc;
++  sqlite3Fts5PoslistSafeAppend(pBuf, &pWriter->iPrev, iPos);
++  return SQLITE_OK;
++}
++
++static void *sqlite3Fts5MallocZero(int *pRc, int nByte){
++  void *pRet = 0;
++  if( *pRc==SQLITE_OK ){
++    pRet = sqlite3_malloc(nByte);
++    if( pRet==0 ){
++      if( nByte>0 ) *pRc = SQLITE_NOMEM;
 +    }else{
-+      pFile->lastErrno = osGetLastError();
-+      OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
-+               "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(),
-+               pFile, pFile->pMapRegion));
-+      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
-+                         "winSync1", pFile->zPath);
++      memset(pRet, 0, nByte);
 +    }
 +  }
-+#endif
-+  rc = osFlushFileBuffers(pFile->h);
-+  SimulateIOError( rc=FALSE );
-+  if( rc ){
-+    OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
-+             osGetCurrentProcessId(), pFile, pFile->h));
-+    return SQLITE_OK;
-+  }else{
-+    pFile->lastErrno = osGetLastError();
-+    OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n",
-+             osGetCurrentProcessId(), pFile, pFile->h));
-+    return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
-+                       "winSync2", pFile->zPath);
++  return pRet;
++}
++
++/*
++** Return a nul-terminated copy of the string indicated by pIn. If nIn
++** is non-negative, then it is the length of the string in bytes. Otherwise,
++** the length of the string is determined using strlen().
++**
++** It is the responsibility of the caller to eventually free the returned
++** buffer using sqlite3_free(). If an OOM error occurs, NULL is returned. 
++*/
++static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){
++  char *zRet = 0;
++  if( *pRc==SQLITE_OK ){
++    if( nIn<0 ){
++      nIn = (int)strlen(pIn);
++    }
++    zRet = (char*)sqlite3_malloc(nIn+1);
++    if( zRet ){
++      memcpy(zRet, pIn, nIn);
++      zRet[nIn] = '\0';
++    }else{
++      *pRc = SQLITE_NOMEM;
++    }
 +  }
-+#endif
- }
- 
- /*
--** Change the lock state for a shared-memory segment.
-+** Determine the current size of a file in bytes
- */
--static int winShmLock(
--  sqlite3_file *fd,          /* Database file holding the shared memory */
--  int ofst,                  /* First lock to acquire or release */
--  int n,                     /* Number of locks to acquire or release */
--  int flags                  /* What to do with the lock */
--){
--  winFile *pDbFd = (winFile*)fd;        /* Connection holding shared memory */
--  winShm *p = pDbFd->pShm;              /* The shared memory being locked */
--  winShm *pX;                           /* For looping over all siblings */
--  winShmNode *pShmNode = p->pShmNode;
--  int rc = SQLITE_OK;                   /* Result code */
--  u16 mask;                             /* Mask of locks to take or release */
--
--  assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
--  assert( n>=1 );
--  assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
--       || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
--       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
--       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
--  assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
--
--  mask = (u16)((1U<<(ofst+n)) - (1U<<ofst));
--  assert( n>1 || mask==(1<<ofst) );
--  sqlite3_mutex_enter(pShmNode->mutex);
--  if( flags & SQLITE_SHM_UNLOCK ){
--    u16 allMask = 0; /* Mask of locks held by siblings */
-+static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
-+  winFile *pFile = (winFile*)id;
++  return zRet;
++}
++
++
++/*
++** Return true if character 't' may be part of an FTS5 bareword, or false
++** otherwise. Characters that may be part of barewords:
++**
++**   * All non-ASCII characters,
++**   * The 52 upper and lower case ASCII characters, and
++**   * The 10 integer ASCII characters.
++**   * The underscore character "_" (0x5F).
++**   * The unicode "subsitute" character (0x1A).
++*/
++static int sqlite3Fts5IsBareword(char t){
++  u8 aBareword[128] = {
++    0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0,   /* 0x00 .. 0x0F */
++    0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 1, 0, 0, 0, 0, 0,   /* 0x10 .. 0x1F */
++    0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0,   /* 0x20 .. 0x2F */
++    1, 1, 1, 1, 1, 1, 1, 1,    1, 1, 0, 0, 0, 0, 0, 0,   /* 0x30 .. 0x3F */
++    0, 1, 1, 1, 1, 1, 1, 1,    1, 1, 1, 1, 1, 1, 1, 1,   /* 0x40 .. 0x4F */
++    1, 1, 1, 1, 1, 1, 1, 1,    1, 1, 1, 0, 0, 0, 0, 1,   /* 0x50 .. 0x5F */
++    0, 1, 1, 1, 1, 1, 1, 1,    1, 1, 1, 1, 1, 1, 1, 1,   /* 0x60 .. 0x6F */
++    1, 1, 1, 1, 1, 1, 1, 1,    1, 1, 1, 0, 0, 0, 0, 0    /* 0x70 .. 0x7F */
++  };
++
++  return (t & 0x80) || aBareword[(int)t];
++}
++
++
++/*************************************************************************
++*/
++typedef struct Fts5TermsetEntry Fts5TermsetEntry;
++struct Fts5TermsetEntry {
++  char *pTerm;
++  int nTerm;
++  int iIdx;                       /* Index (main or aPrefix[] entry) */
++  Fts5TermsetEntry *pNext;
++};
++
++struct Fts5Termset {
++  Fts5TermsetEntry *apHash[512];
++};
++
++static int sqlite3Fts5TermsetNew(Fts5Termset **pp){
 +  int rc = SQLITE_OK;
- 
--    /* See if any siblings hold this same lock */
--    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
--      if( pX==p ) continue;
--      assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
--      allMask |= pX->sharedMask;
--    }
-+  assert( id!=0 );
-+  assert( pSize!=0 );
-+  SimulateIOError(return SQLITE_IOERR_FSTAT);
-+  OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize));
- 
--    /* Unlock the system-level locks */
--    if( (mask & allMask)==0 ){
--      rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
-+#if SQLITE_OS_WINRT
-+  {
-+    FILE_STANDARD_INFO info;
-+    if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo,
-+                                     &info, sizeof(info)) ){
-+      *pSize = info.EndOfFile.QuadPart;
-     }else{
--      rc = SQLITE_OK;
-+      pFile->lastErrno = osGetLastError();
-+      rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
-+                       "winFileSize", pFile->zPath);
-     }
++  *pp = sqlite3Fts5MallocZero(&rc, sizeof(Fts5Termset));
++  return rc;
++}
++
++static int sqlite3Fts5TermsetAdd(
++  Fts5Termset *p, 
++  int iIdx,
++  const char *pTerm, int nTerm, 
++  int *pbPresent
++){
++  int rc = SQLITE_OK;
++  *pbPresent = 0;
++  if( p ){
++    int i;
++    u32 hash = 13;
++    Fts5TermsetEntry *pEntry;
++
++    /* Calculate a hash value for this term. This is the same hash checksum
++    ** used by the fts5_hash.c module. This is not important for correct
++    ** operation of the module, but is necessary to ensure that some tests
++    ** designed to produce hash table collisions really do work.  */
++    for(i=nTerm-1; i>=0; i--){
++      hash = (hash << 3) ^ hash ^ pTerm[i];
++    }
++    hash = (hash << 3) ^ hash ^ iIdx;
++    hash = hash % ArraySize(p->apHash);
++
++    for(pEntry=p->apHash[hash]; pEntry; pEntry=pEntry->pNext){
++      if( pEntry->iIdx==iIdx 
++          && pEntry->nTerm==nTerm 
++          && memcmp(pEntry->pTerm, pTerm, nTerm)==0 
++      ){
++        *pbPresent = 1;
++        break;
++      }
++    }
++
++    if( pEntry==0 ){
++      pEntry = sqlite3Fts5MallocZero(&rc, sizeof(Fts5TermsetEntry) + nTerm);
++      if( pEntry ){
++        pEntry->pTerm = (char*)&pEntry[1];
++        pEntry->nTerm = nTerm;
++        pEntry->iIdx = iIdx;
++        memcpy(pEntry->pTerm, pTerm, nTerm);
++        pEntry->pNext = p->apHash[hash];
++        p->apHash[hash] = pEntry;
++      }
++    }
 +  }
-+#else
-+  {
-+    DWORD upperBits;
-+    DWORD lowerBits;
-+    DWORD lastErrno;
- 
--    /* Undo the local locks */
--    if( rc==SQLITE_OK ){
--      p->exclMask &= ~mask;
--      p->sharedMask &= ~mask;
-+    lowerBits = osGetFileSize(pFile->h, &upperBits);
-+    *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
-+    if(   (lowerBits == INVALID_FILE_SIZE)
-+       && ((lastErrno = osGetLastError())!=NO_ERROR) ){
-+      pFile->lastErrno = lastErrno;
-+      rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
-+                       "winFileSize", pFile->zPath);
-     }
--  }else if( flags & SQLITE_SHM_SHARED ){
--    u16 allShared = 0;  /* Union of locks held by connections other than "p" */
-+  }
-+#endif
-+  OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n",
-+           pFile->h, pSize, *pSize, sqlite3ErrName(rc)));
++
 +  return rc;
 +}
- 
--    /* Find out which shared locks are already held by sibling connections.
--    ** If any sibling already holds an exclusive lock, go ahead and return
--    ** SQLITE_BUSY.
--    */
--    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
--      if( (pX->exclMask & mask)!=0 ){
--        rc = SQLITE_BUSY;
--        break;
--      }
--      allShared |= pX->sharedMask;
--    }
++
++static void sqlite3Fts5TermsetFree(Fts5Termset *p){
++  if( p ){
++    u32 i;
++    for(i=0; i<ArraySize(p->apHash); i++){
++      Fts5TermsetEntry *pEntry = p->apHash[i];
++      while( pEntry ){
++        Fts5TermsetEntry *pDel = pEntry;
++        pEntry = pEntry->pNext;
++        sqlite3_free(pDel);
++      }
++    }
++    sqlite3_free(p);
++  }
++}
++
 +/*
-+** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
++** 2014 Jun 09
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This is an SQLite module implementing full-text search.
 +*/
-+#ifndef LOCKFILE_FAIL_IMMEDIATELY
-+# define LOCKFILE_FAIL_IMMEDIATELY 1
-+#endif
- 
--    /* Get shared locks at the system level, if necessary */
--    if( rc==SQLITE_OK ){
--      if( (allShared & mask)==0 ){
--        rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n);
--      }else{
--        rc = SQLITE_OK;
--      }
--    }
-+#ifndef LOCKFILE_EXCLUSIVE_LOCK
-+# define LOCKFILE_EXCLUSIVE_LOCK 2
-+#endif
- 
--    /* Get the local shared locks */
--    if( rc==SQLITE_OK ){
--      p->sharedMask |= mask;
--    }
--  }else{
--    /* Make sure no sibling connections hold locks that will block this
--    ** lock.  If any do, return SQLITE_BUSY right away.
--    */
--    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
--      if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
--        rc = SQLITE_BUSY;
--        break;
--      }
--    }
++
++
++/* #include "fts5Int.h" */
++
++#define FTS5_DEFAULT_PAGE_SIZE   4050
++#define FTS5_DEFAULT_AUTOMERGE      4
++#define FTS5_DEFAULT_USERMERGE      4
++#define FTS5_DEFAULT_CRISISMERGE   16
++#define FTS5_DEFAULT_HASHSIZE    (1024*1024)
++
++/* Maximum allowed page size */
++#define FTS5_MAX_PAGE_SIZE (128*1024)
++
++static int fts5_iswhitespace(char x){
++  return (x==' ');
++}
++
++static int fts5_isopenquote(char x){
++  return (x=='"' || x=='\'' || x=='[' || x=='`');
++}
++
 +/*
-+** Historically, SQLite has used both the LockFile and LockFileEx functions.
-+** When the LockFile function was used, it was always expected to fail
-+** immediately if the lock could not be obtained.  Also, it always expected to
-+** obtain an exclusive lock.  These flags are used with the LockFileEx function
-+** and reflect those expectations; therefore, they should not be changed.
++** Argument pIn points to a character that is part of a nul-terminated 
++** string. Return a pointer to the first character following *pIn in 
++** the string that is not a white-space character.
 +*/
-+#ifndef SQLITE_LOCKFILE_FLAGS
-+# define SQLITE_LOCKFILE_FLAGS   (LOCKFILE_FAIL_IMMEDIATELY | \
-+                                  LOCKFILE_EXCLUSIVE_LOCK)
-+#endif
- 
--    /* Get the exclusive locks at the system level.  Then if successful
--    ** also mark the local connection as being locked.
++static const char *fts5ConfigSkipWhitespace(const char *pIn){
++  const char *p = pIn;
++  if( p ){
++    while( fts5_iswhitespace(*p) ){ p++; }
++  }
++  return p;
++}
++
++/*
++** Argument pIn points to a character that is part of a nul-terminated 
++** string. Return a pointer to the first character following *pIn in 
++** the string that is not a "bareword" character.
++*/
++static const char *fts5ConfigSkipBareword(const char *pIn){
++  const char *p = pIn;
++  while ( sqlite3Fts5IsBareword(*p) ) p++;
++  if( p==pIn ) p = 0;
++  return p;
++}
++
++static int fts5_isdigit(char a){
++  return (a>='0' && a<='9');
++}
++
++
++
++static const char *fts5ConfigSkipLiteral(const char *pIn){
++  const char *p = pIn;
++  switch( *p ){
++    case 'n': case 'N':
++      if( sqlite3_strnicmp("null", p, 4)==0 ){
++        p = &p[4];
++      }else{
++        p = 0;
++      }
++      break;
++
++    case 'x': case 'X':
++      p++;
++      if( *p=='\'' ){
++        p++;
++        while( (*p>='a' && *p<='f') 
++            || (*p>='A' && *p<='F') 
++            || (*p>='0' && *p<='9') 
++            ){
++          p++;
++        }
++        if( *p=='\'' && 0==((p-pIn)%2) ){
++          p++;
++        }else{
++          p = 0;
++        }
++      }else{
++        p = 0;
++      }
++      break;
++
++    case '\'':
++      p++;
++      while( p ){
++        if( *p=='\'' ){
++          p++;
++          if( *p!='\'' ) break;
++        }
++        p++;
++        if( *p==0 ) p = 0;
++      }
++      break;
++
++    default:
++      /* maybe a number */
++      if( *p=='+' || *p=='-' ) p++;
++      while( fts5_isdigit(*p) ) p++;
++
++      /* At this point, if the literal was an integer, the parse is 
++      ** finished. Or, if it is a floating point value, it may continue
++      ** with either a decimal point or an 'E' character. */
++      if( *p=='.' && fts5_isdigit(p[1]) ){
++        p += 2;
++        while( fts5_isdigit(*p) ) p++;
++      }
++      if( p==pIn ) p = 0;
++
++      break;
++  }
++
++  return p;
++}
++
 +/*
-+** Currently, SQLite never calls the LockFileEx function without wanting the
-+** call to fail immediately if the lock cannot be obtained.
++** The first character of the string pointed to by argument z is guaranteed
++** to be an open-quote character (see function fts5_isopenquote()).
++**
++** This function searches for the corresponding close-quote character within
++** the string and, if found, dequotes the string in place and adds a new
++** nul-terminator byte.
++**
++** If the close-quote is found, the value returned is the byte offset of
++** the character immediately following it. Or, if the close-quote is not 
++** found, -1 is returned. If -1 is returned, the buffer is left in an 
++** undefined state.
 +*/
-+#ifndef SQLITE_LOCKFILEEX_FLAGS
-+# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY)
-+#endif
++static int fts5Dequote(char *z){
++  char q;
++  int iIn = 1;
++  int iOut = 0;
++  q = z[0];
++
++  /* Set stack variable q to the close-quote character */
++  assert( q=='[' || q=='\'' || q=='"' || q=='`' );
++  if( q=='[' ) q = ']';  
++
++  while( ALWAYS(z[iIn]) ){
++    if( z[iIn]==q ){
++      if( z[iIn+1]!=q ){
++        /* Character iIn was the close quote. */
++        iIn++;
++        break;
++      }else{
++        /* Character iIn and iIn+1 form an escaped quote character. Skip
++        ** the input cursor past both and copy a single quote character 
++        ** to the output buffer. */
++        iIn += 2;
++        z[iOut++] = q;
++      }
++    }else{
++      z[iOut++] = z[iIn++];
++    }
++  }
++
++  z[iOut] = '\0';
++  return iIn;
++}
 +
 +/*
-+** Acquire a reader lock.
-+** Different API routines are called depending on whether or not this
-+** is Win9x or WinNT.
++** Convert an SQL-style quoted string into a normal string by removing
++** the quote characters.  The conversion is done in-place.  If the
++** input does not begin with a quote character, then this routine
++** is a no-op.
++**
++** Examples:
++**
++**     "abc"   becomes   abc
++**     'xyz'   becomes   xyz
++**     [pqr]   becomes   pqr
++**     `mno`   becomes   mno
 +*/
-+static int winGetReadLock(winFile *pFile){
-+  int res;
-+  OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
-+  if( osIsNT() ){
-+#if SQLITE_OS_WINCE
-+    /*
-+    ** NOTE: Windows CE is handled differently here due its lack of the Win32
-+    **       API LockFileEx.
-     */
--    if( rc==SQLITE_OK ){
--      rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n);
--      if( rc==SQLITE_OK ){
--        assert( (p->sharedMask & mask)==0 );
--        p->exclMask |= mask;
--      }
--    }
-+    res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0);
-+#else
-+    res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0,
-+                      SHARED_SIZE, 0);
-+#endif
-   }
--  sqlite3_mutex_leave(pShmNode->mutex);
--  OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n",
--           osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask,
--           sqlite3ErrName(rc)));
--  return rc;
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    int lk;
-+    sqlite3_randomness(sizeof(lk), &lk);
-+    pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
-+    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
-+                      SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
-+  }
-+#endif
-+  if( res == 0 ){
-+    pFile->lastErrno = osGetLastError();
-+    /* No need to log a failure to lock */
-+  }
-+  OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res));
-+  return res;
- }
- 
- /*
--** Implement a memory barrier or memory fence on shared memory.
--**
--** All loads and stores begun before the barrier must complete before
--** any load or store begun after the barrier.
-+** Undo a readlock
- */
--static void winShmBarrier(
--  sqlite3_file *fd          /* Database holding the shared memory */
--){
--  UNUSED_PARAMETER(fd);
--  /* MemoryBarrier(); // does not work -- do not know why not */
--  winShmEnterMutex();
--  winShmLeaveMutex();
-+static int winUnlockReadLock(winFile *pFile){
-+  int res;
-+  DWORD lastErrno;
-+  OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
-+  if( osIsNT() ){
-+    res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
++static void sqlite3Fts5Dequote(char *z){
++  char quote;                     /* Quote character (if any ) */
++
++  assert( 0==fts5_iswhitespace(z[0]) );
++  quote = z[0];
++  if( quote=='[' || quote=='\'' || quote=='"' || quote=='`' ){
++    fts5Dequote(z);
 +  }
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
++}
++
++
++struct Fts5Enum {
++  const char *zName;
++  int eVal;
++};
++typedef struct Fts5Enum Fts5Enum;
++
++static int fts5ConfigSetEnum(
++  const Fts5Enum *aEnum, 
++  const char *zEnum, 
++  int *peVal
++){
++  int nEnum = (int)strlen(zEnum);
++  int i;
++  int iVal = -1;
++
++  for(i=0; aEnum[i].zName; i++){
++    if( sqlite3_strnicmp(aEnum[i].zName, zEnum, nEnum)==0 ){
++      if( iVal>=0 ) return SQLITE_ERROR;
++      iVal = aEnum[i].eVal;
++    }
 +  }
-+#endif
-+  if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
-+    pFile->lastErrno = lastErrno;
-+    winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
-+                "winUnlockReadLock", pFile->zPath);
++
++  *peVal = iVal;
++  return iVal<0 ? SQLITE_ERROR : SQLITE_OK;
++}
++
++/*
++** Parse a "special" CREATE VIRTUAL TABLE directive and update
++** configuration object pConfig as appropriate.
++**
++** If successful, object pConfig is updated and SQLITE_OK returned. If
++** an error occurs, an SQLite error code is returned and an error message
++** may be left in *pzErr. It is the responsibility of the caller to
++** eventually free any such error message using sqlite3_free().
++*/
++static int fts5ConfigParseSpecial(
++  Fts5Global *pGlobal,
++  Fts5Config *pConfig,            /* Configuration object to update */
++  const char *zCmd,               /* Special command to parse */
++  const char *zArg,               /* Argument to parse */
++  char **pzErr                    /* OUT: Error message */
++){
++  int rc = SQLITE_OK;
++  int nCmd = (int)strlen(zCmd);
++  if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){
++    const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES;
++    const char *p;
++    int bFirst = 1;
++    if( pConfig->aPrefix==0 ){
++      pConfig->aPrefix = sqlite3Fts5MallocZero(&rc, nByte);
++      if( rc ) return rc;
++    }
++
++    p = zArg;
++    while( 1 ){
++      int nPre = 0;
++
++      while( p[0]==' ' ) p++;
++      if( bFirst==0 && p[0]==',' ){
++        p++;
++        while( p[0]==' ' ) p++;
++      }else if( p[0]=='\0' ){
++        break;
++      }
++      if( p[0]<'0' || p[0]>'9' ){
++        *pzErr = sqlite3_mprintf("malformed prefix=... directive");
++        rc = SQLITE_ERROR;
++        break;
++      }
++
++      if( pConfig->nPrefix==FTS5_MAX_PREFIX_INDEXES ){
++        *pzErr = sqlite3_mprintf(
++            "too many prefix indexes (max %d)", FTS5_MAX_PREFIX_INDEXES
++        );
++        rc = SQLITE_ERROR;
++        break;
++      }
++
++      while( p[0]>='0' && p[0]<='9' && nPre<1000 ){
++        nPre = nPre*10 + (p[0] - '0');
++        p++;
++      }
++
++      if( nPre<=0 || nPre>=1000 ){
++        *pzErr = sqlite3_mprintf("prefix length out of range (max 999)");
++        rc = SQLITE_ERROR;
++        break;
++      }
++
++      pConfig->aPrefix[pConfig->nPrefix] = nPre;
++      pConfig->nPrefix++;
++      bFirst = 0;
++    }
++    assert( pConfig->nPrefix<=FTS5_MAX_PREFIX_INDEXES );
++    return rc;
 +  }
-+  OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res));
-+  return res;
- }
- 
- /*
--** This function is called to obtain a pointer to region iRegion of the
--** shared-memory associated with the database file fd. Shared-memory regions
--** are numbered starting from zero. Each shared-memory region is szRegion
--** bytes in size.
--**
--** If an error occurs, an error code is returned and *pp is set to NULL.
--**
--** Otherwise, if the isWrite parameter is 0 and the requested shared-memory
--** region has not been allocated (by any client, including one running in a
--** separate process), then *pp is set to NULL and SQLITE_OK returned. If
--** isWrite is non-zero and the requested shared-memory region has not yet
--** been allocated, it is allocated by this function.
-+** Lock the file with the lock specified by parameter locktype - one
-+** of the following:
- **
--** If the shared-memory region has already been allocated or is allocated by
--** this call as described above, then it is mapped into this processes
--** address space (if it is not already), *pp is set to point to the mapped
--** memory and SQLITE_OK returned.
--*/
--static int winShmMap(
--  sqlite3_file *fd,               /* Handle open on database file */
--  int iRegion,                    /* Region to retrieve */
--  int szRegion,                   /* Size of regions */
--  int isWrite,                    /* True to extend file if necessary */
--  void volatile **pp              /* OUT: Mapped memory */
--){
--  winFile *pDbFd = (winFile*)fd;
--  winShm *pShm = pDbFd->pShm;
--  winShmNode *pShmNode;
--  int rc = SQLITE_OK;
--
--  if( !pShm ){
--    rc = winOpenSharedMemory(pDbFd);
--    if( rc!=SQLITE_OK ) return rc;
--    pShm = pDbFd->pShm;
--  }
--  pShmNode = pShm->pShmNode;
--
--  sqlite3_mutex_enter(pShmNode->mutex);
--  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
-+**     (1) SHARED_LOCK
-+**     (2) RESERVED_LOCK
-+**     (3) PENDING_LOCK
-+**     (4) EXCLUSIVE_LOCK
-+**
-+** Sometimes when requesting one lock state, additional lock states
-+** are inserted in between.  The locking might fail on one of the later
-+** transitions leaving the lock state different from what it started but
-+** still short of its goal.  The following chart shows the allowed
-+** transitions and the inserted intermediate states:
-+**
-+**    UNLOCKED -> SHARED
-+**    SHARED -> RESERVED
-+**    SHARED -> (PENDING) -> EXCLUSIVE
-+**    RESERVED -> (PENDING) -> EXCLUSIVE
-+**    PENDING -> EXCLUSIVE
-+**
-+** This routine will only increase a lock.  The winUnlock() routine
-+** erases all locks at once and returns us immediately to locking level 0.
-+** It is not possible to lower the locking level one step at a time.  You
-+** must go straight to locking level 0.
-+*/
-+static int winLock(sqlite3_file *id, int locktype){
-+  int rc = SQLITE_OK;    /* Return code from subroutines */
-+  int res = 1;           /* Result of a Windows lock call */
-+  int newLocktype;       /* Set pFile->locktype to this value before exiting */
-+  int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
-+  winFile *pFile = (winFile*)id;
-+  DWORD lastErrno = NO_ERROR;
- 
--  if( pShmNode->nRegion<=iRegion ){
--    struct ShmRegion *apNew;           /* New aRegion[] array */
--    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
--    sqlite3_int64 sz;                  /* Current size of wal-index file */
-+  assert( id!=0 );
-+  OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n",
-+           pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
- 
--    pShmNode->szRegion = szRegion;
-+  /* If there is already a lock of this type or more restrictive on the
-+  ** OsFile, do nothing. Don't use the end_lock: exit path, as
-+  ** sqlite3OsEnterMutex() hasn't been called yet.
-+  */
-+  if( pFile->locktype>=locktype ){
-+    OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h));
-+    return SQLITE_OK;
++
++  if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
++    const char *p = (const char*)zArg;
++    int nArg = (int)strlen(zArg) + 1;
++    char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
++    char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
++    char *pSpace = pDel;
++
++    if( azArg && pSpace ){
++      if( pConfig->pTok ){
++        *pzErr = sqlite3_mprintf("multiple tokenize=... directives");
++        rc = SQLITE_ERROR;
++      }else{
++        for(nArg=0; p && *p; nArg++){
++          const char *p2 = fts5ConfigSkipWhitespace(p);
++          if( *p2=='\'' ){
++            p = fts5ConfigSkipLiteral(p2);
++          }else{
++            p = fts5ConfigSkipBareword(p2);
++          }
++          if( p ){
++            memcpy(pSpace, p2, p-p2);
++            azArg[nArg] = pSpace;
++            sqlite3Fts5Dequote(pSpace);
++            pSpace += (p - p2) + 1;
++            p = fts5ConfigSkipWhitespace(p);
++          }
++        }
++        if( p==0 ){
++          *pzErr = sqlite3_mprintf("parse error in tokenize directive");
++          rc = SQLITE_ERROR;
++        }else{
++          rc = sqlite3Fts5GetTokenizer(pGlobal, 
++              (const char**)azArg, nArg, &pConfig->pTok, &pConfig->pTokApi,
++              pzErr
++          );
++        }
++      }
++    }
++
++    sqlite3_free(azArg);
++    sqlite3_free(pDel);
++    return rc;
 +  }
- 
--    /* The requested region is not mapped into this processes address space.
--    ** Check to see if it has been allocated (i.e. if the wal-index file is
--    ** large enough to contain the requested region).
--    */
--    rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
--    if( rc!=SQLITE_OK ){
--      rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
--                       "winShmMap1", pDbFd->zPath);
--      goto shmpage_out;
--    }
-+  /* Make sure the locking sequence is correct
-+  */
-+  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
-+  assert( locktype!=PENDING_LOCK );
-+  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
- 
--    if( sz<nByte ){
--      /* The requested memory region does not exist. If isWrite is set to
--      ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
--      **
--      ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
--      ** the requested memory region.
-+  /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
-+  ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
-+  ** the PENDING_LOCK byte is temporary.
-+  */
-+  newLocktype = pFile->locktype;
-+  if(   (pFile->locktype==NO_LOCK)
-+     || (   (locktype==EXCLUSIVE_LOCK)
-+         && (pFile->locktype==RESERVED_LOCK))
-+  ){
-+    int cnt = 3;
-+    while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
-+                                         PENDING_BYTE, 0, 1, 0))==0 ){
-+      /* Try 3 times to get the pending lock.  This is needed to work
-+      ** around problems caused by indexing and/or anti-virus software on
-+      ** Windows systems.
-+      ** If you are using this code as a model for alternative VFSes, do not
-+      ** copy this retry logic.  It is a hack intended for Windows only.
-       */
--      if( !isWrite ) goto shmpage_out;
--      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
--      if( rc!=SQLITE_OK ){
--        rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
--                         "winShmMap2", pDbFd->zPath);
--        goto shmpage_out;
-+      lastErrno = osGetLastError();
-+      OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n",
-+               pFile->h, cnt, res));
-+      if( lastErrno==ERROR_INVALID_HANDLE ){
-+        pFile->lastErrno = lastErrno;
-+        rc = SQLITE_IOERR_LOCK;
-+        OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n",
-+                 pFile->h, cnt, sqlite3ErrName(rc)));
-+        return rc;
-       }
-+      if( cnt ) sqlite3_win32_sleep(1);
++
++  if( sqlite3_strnicmp("content", zCmd, nCmd)==0 ){
++    if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
++      *pzErr = sqlite3_mprintf("multiple content=... directives");
++      rc = SQLITE_ERROR;
++    }else{
++      if( zArg[0] ){
++        pConfig->eContent = FTS5_CONTENT_EXTERNAL;
++        pConfig->zContent = sqlite3Fts5Mprintf(&rc, "%Q.%Q", pConfig->zDb,zArg);
++      }else{
++        pConfig->eContent = FTS5_CONTENT_NONE;
++      }
 +    }
-+    gotPendingLock = res;
-+    if( !res ){
-+      lastErrno = osGetLastError();
-     }
++    return rc;
 +  }
- 
--    /* Map the requested memory region into this processes address space. */
--    apNew = (struct ShmRegion *)sqlite3_realloc64(
--        pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
--    );
--    if( !apNew ){
--      rc = SQLITE_IOERR_NOMEM;
--      goto shmpage_out;
-+  /* Acquire a shared lock
-+  */
-+  if( locktype==SHARED_LOCK && res ){
-+    assert( pFile->locktype==NO_LOCK );
-+    res = winGetReadLock(pFile);
-+    if( res ){
-+      newLocktype = SHARED_LOCK;
++
++  if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){
++    if( pConfig->zContentRowid ){
++      *pzErr = sqlite3_mprintf("multiple content_rowid=... directives");
++      rc = SQLITE_ERROR;
 +    }else{
-+      lastErrno = osGetLastError();
-     }
--    pShmNode->aRegion = apNew;
++      pConfig->zContentRowid = sqlite3Fts5Strndup(&rc, zArg, -1);
++    }
++    return rc;
 +  }
- 
--    while( pShmNode->nRegion<=iRegion ){
--      HANDLE hMap = NULL;         /* file-mapping handle */
--      void *pMap = 0;             /* Mapped memory region */
-+  /* Acquire a RESERVED lock
-+  */
-+  if( locktype==RESERVED_LOCK && res ){
-+    assert( pFile->locktype==SHARED_LOCK );
-+    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
-+    if( res ){
-+      newLocktype = RESERVED_LOCK;
++
++  if( sqlite3_strnicmp("columnsize", zCmd, nCmd)==0 ){
++    if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){
++      *pzErr = sqlite3_mprintf("malformed columnsize=... directive");
++      rc = SQLITE_ERROR;
 +    }else{
-+      lastErrno = osGetLastError();
++      pConfig->bColumnsize = (zArg[0]=='1');
 +    }
++    return rc;
 +  }
- 
--#if SQLITE_OS_WINRT
--      hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
--          NULL, PAGE_READWRITE, nByte, NULL
--      );
--#elif defined(SQLITE_WIN32_HAS_WIDE)
--      hMap = osCreateFileMappingW(pShmNode->hFile.h,
--          NULL, PAGE_READWRITE, 0, nByte, NULL
--      );
--#elif defined(SQLITE_WIN32_HAS_ANSI)
--      hMap = osCreateFileMappingA(pShmNode->hFile.h,
--          NULL, PAGE_READWRITE, 0, nByte, NULL
--      );
--#endif
--      OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n",
--               osGetCurrentProcessId(), pShmNode->nRegion, nByte,
--               hMap ? "ok" : "failed"));
--      if( hMap ){
--        int iOffset = pShmNode->nRegion*szRegion;
--        int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
--#if SQLITE_OS_WINRT
--        pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
--            iOffset - iOffsetShift, szRegion + iOffsetShift
--        );
--#else
--        pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
--            0, iOffset - iOffsetShift, szRegion + iOffsetShift
--        );
--#endif
--        OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n",
--                 osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
--                 szRegion, pMap ? "ok" : "failed"));
--      }
--      if( !pMap ){
--        pShmNode->lastErrno = osGetLastError();
--        rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
--                         "winShmMap3", pDbFd->zPath);
--        if( hMap ) osCloseHandle(hMap);
--        goto shmpage_out;
--      }
-+  /* Acquire a PENDING lock
-+  */
-+  if( locktype==EXCLUSIVE_LOCK && res ){
-+    newLocktype = PENDING_LOCK;
-+    gotPendingLock = 0;
++
++  if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){
++    const Fts5Enum aDetail[] = {
++      { "none", FTS5_DETAIL_NONE },
++      { "full", FTS5_DETAIL_FULL },
++      { "columns", FTS5_DETAIL_COLUMNS },
++      { 0, 0 }
++    };
++
++    if( (rc = fts5ConfigSetEnum(aDetail, zArg, &pConfig->eDetail)) ){
++      *pzErr = sqlite3_mprintf("malformed detail=... directive");
++    }
++    return rc;
 +  }
- 
--      pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
--      pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
--      pShmNode->nRegion++;
-+  /* Acquire an EXCLUSIVE lock
-+  */
-+  if( locktype==EXCLUSIVE_LOCK && res ){
-+    assert( pFile->locktype>=SHARED_LOCK );
-+    res = winUnlockReadLock(pFile);
-+    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
-+                      SHARED_SIZE, 0);
-+    if( res ){
-+      newLocktype = EXCLUSIVE_LOCK;
-+    }else{
-+      lastErrno = osGetLastError();
-+      winGetReadLock(pFile);
-     }
-   }
- 
--shmpage_out:
--  if( pShmNode->nRegion>iRegion ){
--    int iOffset = iRegion*szRegion;
--    int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
--    char *p = (char *)pShmNode->aRegion[iRegion].pMap;
--    *pp = (void *)&p[iOffsetShift];
-+  /* If we are holding a PENDING lock that ought to be released, then
-+  ** release it now.
-+  */
-+  if( gotPendingLock && locktype==SHARED_LOCK ){
-+    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
++
++  *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd);
++  return SQLITE_ERROR;
++}
++
++/*
++** Allocate an instance of the default tokenizer ("simple") at 
++** Fts5Config.pTokenizer. Return SQLITE_OK if successful, or an SQLite error
++** code if an error occurs.
++*/
++static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){
++  assert( pConfig->pTok==0 && pConfig->pTokApi==0 );
++  return sqlite3Fts5GetTokenizer(
++      pGlobal, 0, 0, &pConfig->pTok, &pConfig->pTokApi, 0
++  );
++}
++
++/*
++** Gobble up the first bareword or quoted word from the input buffer zIn.
++** Return a pointer to the character immediately following the last in
++** the gobbled word if successful, or a NULL pointer otherwise (failed
++** to find close-quote character).
++**
++** Before returning, set pzOut to point to a new buffer containing a
++** nul-terminated, dequoted copy of the gobbled word. If the word was
++** quoted, *pbQuoted is also set to 1 before returning.
++**
++** If *pRc is other than SQLITE_OK when this function is called, it is
++** a no-op (NULL is returned). Otherwise, if an OOM occurs within this
++** function, *pRc is set to SQLITE_NOMEM before returning. *pRc is *not*
++** set if a parse error (failed to find close quote) occurs.
++*/
++static const char *fts5ConfigGobbleWord(
++  int *pRc,                       /* IN/OUT: Error code */
++  const char *zIn,                /* Buffer to gobble string/bareword from */
++  char **pzOut,                   /* OUT: malloc'd buffer containing str/bw */
++  int *pbQuoted                   /* OUT: Set to true if dequoting required */
++){
++  const char *zRet = 0;
++
++  int nIn = (int)strlen(zIn);
++  char *zOut = sqlite3_malloc(nIn+1);
++
++  assert( *pRc==SQLITE_OK );
++  *pbQuoted = 0;
++  *pzOut = 0;
++
++  if( zOut==0 ){
++    *pRc = SQLITE_NOMEM;
++  }else{
++    memcpy(zOut, zIn, nIn+1);
++    if( fts5_isopenquote(zOut[0]) ){
++      int ii = fts5Dequote(zOut);
++      zRet = &zIn[ii];
++      *pbQuoted = 1;
++    }else{
++      zRet = fts5ConfigSkipBareword(zIn);
++      if( zRet ){
++        zOut[zRet-zIn] = '\0';
++      }
++    }
 +  }
 +
-+  /* Update the state of the lock has held in the file descriptor then
-+  ** return the appropriate result code.
-+  */
-+  if( res ){
-+    rc = SQLITE_OK;
-   }else{
--    *pp = 0;
-+    pFile->lastErrno = lastErrno;
-+    rc = SQLITE_BUSY;
-+    OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
-+             pFile->h, locktype, newLocktype));
-   }
--  sqlite3_mutex_leave(pShmNode->mutex);
-+  pFile->locktype = (u8)newLocktype;
-+  OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n",
-+           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
-   return rc;
- }
- 
--#else
--# define winShmMap     0
--# define winShmLock    0
--# define winShmBarrier 0
--# define winShmUnmap   0
--#endif /* #ifndef SQLITE_OMIT_WAL */
--
- /*
--** Cleans up the mapped region of the specified file, if any.
-+** This routine checks if there is a RESERVED lock held on the specified
-+** file by this or any other process. If such a lock is held, return
-+** non-zero, otherwise zero.
- */
--#if SQLITE_MAX_MMAP_SIZE>0
--static int winUnmapfile(winFile *pFile){
--  assert( pFile!=0 );
--  OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
--           "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n",
--           osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
--           pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax));
--  if( pFile->pMapRegion ){
--    if( !osUnmapViewOfFile(pFile->pMapRegion) ){
--      pFile->lastErrno = osGetLastError();
--      OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
--               "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
--               pFile->pMapRegion));
--      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
--                         "winUnmapfile1", pFile->zPath);
--    }
--    pFile->pMapRegion = 0;
--    pFile->mmapSize = 0;
--    pFile->mmapSizeActual = 0;
--  }
--  if( pFile->hMap!=NULL ){
--    if( !osCloseHandle(pFile->hMap) ){
--      pFile->lastErrno = osGetLastError();
--      OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
--               osGetCurrentProcessId(), pFile, pFile->hMap));
--      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
--                         "winUnmapfile2", pFile->zPath);
-+static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
-+  int res;
-+  winFile *pFile = (winFile*)id;
++  if( zRet==0 ){
++    sqlite3_free(zOut);
++  }else{
++    *pzOut = zOut;
++  }
 +
-+  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-+  OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut));
++  return zRet;
++}
 +
-+  assert( id!=0 );
-+  if( pFile->locktype>=RESERVED_LOCK ){
-+    res = 1;
-+    OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res));
-+  }else{
-+    res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0);
-+    if( res ){
-+      winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
-     }
--    pFile->hMap = NULL;
-+    res = !res;
-+    OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res));
-   }
--  OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
--           osGetCurrentProcessId(), pFile));
-+  *pResOut = res;
-+  OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
-+           pFile->h, pResOut, *pResOut));
-   return SQLITE_OK;
- }
- 
- /*
--** Memory map or remap the file opened by file-descriptor pFd (if the file
--** is already mapped, the existing mapping is replaced by the new). Or, if
--** there already exists a mapping for this file, and there are still
--** outstanding xFetch() references to it, this function is a no-op.
-+** Lower the locking level on file descriptor id to locktype.  locktype
-+** must be either NO_LOCK or SHARED_LOCK.
- **
--** If parameter nByte is non-negative, then it is the requested size of
--** the mapping to create. Otherwise, if nByte is less than zero, then the
--** requested size is the size of the file on disk. The actual size of the
--** created mapping is either the requested size or the value configured
--** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller.
-+** If the locking level of the file descriptor is already at or below
-+** the requested locking level, this routine is a no-op.
- **
--** SQLITE_OK is returned if no error occurs (even if the mapping is not
--** recreated as a result of outstanding references) or an SQLite error
--** code otherwise.
-+** It is not possible for this routine to fail if the second argument
-+** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
-+** might return SQLITE_IOERR;
- */
--static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
--  sqlite3_int64 nMap = nByte;
--  int rc;
--
--  assert( nMap>=0 || pFd->nFetchOut==0 );
--  OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n",
--           osGetCurrentProcessId(), pFd, nByte));
--
--  if( pFd->nFetchOut>0 ) return SQLITE_OK;
--
--  if( nMap<0 ){
--    rc = winFileSize((sqlite3_file*)pFd, &nMap);
--    if( rc ){
--      OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n",
--               osGetCurrentProcessId(), pFd));
--      return SQLITE_IOERR_FSTAT;
-+static int winUnlock(sqlite3_file *id, int locktype){
-+  int type;
-+  winFile *pFile = (winFile*)id;
++static int fts5ConfigParseColumn(
++  Fts5Config *p, 
++  char *zCol, 
++  char *zArg, 
++  char **pzErr
++){
 +  int rc = SQLITE_OK;
-+  assert( pFile!=0 );
-+  assert( locktype<=SHARED_LOCK );
-+  OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n",
-+           pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
-+  type = pFile->locktype;
-+  if( type>=EXCLUSIVE_LOCK ){
-+    winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
-+    if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){
-+      /* This should never happen.  We should always be able to
-+      ** reacquire the read lock */
-+      rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
-+                       "winUnlock", pFile->zPath);
-     }
-   }
--  if( nMap>pFd->mmapSizeMax ){
--    nMap = pFd->mmapSizeMax;
-+  if( type>=RESERVED_LOCK ){
-+    winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
-   }
--  nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1);
--
--  if( nMap==0 && pFd->mmapSize>0 ){
--    winUnmapfile(pFd);
-+  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
-+    winUnlockReadLock(pFile);
-   }
--  if( nMap!=pFd->mmapSize ){
--    void *pNew = 0;
--    DWORD protect = PAGE_READONLY;
--    DWORD flags = FILE_MAP_READ;
--
--    winUnmapfile(pFd);
--    if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){
--      protect = PAGE_READWRITE;
--      flags |= FILE_MAP_WRITE;
--    }
--#if SQLITE_OS_WINRT
--    pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL);
--#elif defined(SQLITE_WIN32_HAS_WIDE)
--    pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect,
--                                (DWORD)((nMap>>32) & 0xffffffff),
--                                (DWORD)(nMap & 0xffffffff), NULL);
--#elif defined(SQLITE_WIN32_HAS_ANSI)
--    pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
--                                (DWORD)((nMap>>32) & 0xffffffff),
--                                (DWORD)(nMap & 0xffffffff), NULL);
--#endif
--    if( pFd->hMap==NULL ){
--      pFd->lastErrno = osGetLastError();
--      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
--                       "winMapfile1", pFd->zPath);
--      /* Log the error, but continue normal operation using xRead/xWrite */
--      OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n",
--               osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
--      return SQLITE_OK;
--    }
--    assert( (nMap % winSysInfo.dwPageSize)==0 );
--    assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
--#if SQLITE_OS_WINRT
--    pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
--#else
--    pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
--#endif
--    if( pNew==NULL ){
--      osCloseHandle(pFd->hMap);
--      pFd->hMap = NULL;
--      pFd->lastErrno = osGetLastError();
--      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
--                       "winMapfile2", pFd->zPath);
--      /* Log the error, but continue normal operation using xRead/xWrite */
--      OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n",
--               osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
--      return SQLITE_OK;
--    }
--    pFd->pMapRegion = pNew;
--    pFd->mmapSize = nMap;
--    pFd->mmapSizeActual = nMap;
-+  if( type>=PENDING_LOCK ){
-+    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
-   }
--
--  OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
--           osGetCurrentProcessId(), pFd));
--  return SQLITE_OK;
-+  pFile->locktype = (u8)locktype;
-+  OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n",
-+           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
-+  return rc;
- }
--#endif /* SQLITE_MAX_MMAP_SIZE>0 */
- 
- /*
--** If possible, return a pointer to a mapping of file fd starting at offset
--** iOff. The mapping must be valid for at least nAmt bytes.
--**
--** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
--** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
--** Finally, if an error does occur, return an SQLite error code. The final
--** value of *pp is undefined in this case.
-+** If *pArg is initially negative then this is a query.  Set *pArg to
-+** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
- **
--** If this function does return a pointer, the caller must eventually
--** release the reference by calling winUnfetch().
-+** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
- */
--static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
--#if SQLITE_MAX_MMAP_SIZE>0
--  winFile *pFd = (winFile*)fd;   /* The underlying database file */
--#endif
--  *pp = 0;
-+static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
-+  if( *pArg<0 ){
-+    *pArg = (pFile->ctrlFlags & mask)!=0;
-+  }else if( (*pArg)==0 ){
-+    pFile->ctrlFlags &= ~mask;
-+  }else{
-+    pFile->ctrlFlags |= mask;
++  if( 0==sqlite3_stricmp(zCol, FTS5_RANK_NAME) 
++   || 0==sqlite3_stricmp(zCol, FTS5_ROWID_NAME) 
++  ){
++    *pzErr = sqlite3_mprintf("reserved fts5 column name: %s", zCol);
++    rc = SQLITE_ERROR;
++  }else if( zArg ){
++    if( 0==sqlite3_stricmp(zArg, "unindexed") ){
++      p->abUnindexed[p->nCol] = 1;
++    }else{
++      *pzErr = sqlite3_mprintf("unrecognized column option: %s", zArg);
++      rc = SQLITE_ERROR;
++    }
 +  }
++
++  p->azCol[p->nCol++] = zCol;
++  return rc;
 +}
- 
--  OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n",
--           osGetCurrentProcessId(), fd, iOff, nAmt, pp));
-+/* Forward references to VFS helper methods used for temporary files */
-+static int winGetTempname(sqlite3_vfs *, char **);
-+static int winIsDir(const void *);
-+static BOOL winIsDriveLetterAndColon(const char *);
- 
--#if SQLITE_MAX_MMAP_SIZE>0
--  if( pFd->mmapSizeMax>0 ){
--    if( pFd->pMapRegion==0 ){
--      int rc = winMapfile(pFd, -1);
--      if( rc!=SQLITE_OK ){
--        OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n",
--                 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
++
 +/*
-+** Control and query of the open file handle.
++** Populate the Fts5Config.zContentExprlist string.
 +*/
-+static int winFileControl(sqlite3_file *id, int op, void *pArg){
-+  winFile *pFile = (winFile*)id;
-+  OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg));
-+  switch( op ){
-+    case SQLITE_FCNTL_LOCKSTATE: {
-+      *(int*)pArg = pFile->locktype;
-+      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-+      return SQLITE_OK;
-+    }
-+    case SQLITE_LAST_ERRNO: {
-+      *(int*)pArg = (int)pFile->lastErrno;
-+      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-+      return SQLITE_OK;
-+    }
-+    case SQLITE_FCNTL_CHUNK_SIZE: {
-+      pFile->szChunk = *(int *)pArg;
-+      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-+      return SQLITE_OK;
-+    }
-+    case SQLITE_FCNTL_SIZE_HINT: {
-+      if( pFile->szChunk>0 ){
-+        sqlite3_int64 oldSz;
-+        int rc = winFileSize(id, &oldSz);
-+        if( rc==SQLITE_OK ){
-+          sqlite3_int64 newSz = *(sqlite3_int64*)pArg;
-+          if( newSz>oldSz ){
-+            SimulateIOErrorBenign(1);
-+            rc = winTruncate(id, newSz);
-+            SimulateIOErrorBenign(0);
-+          }
-+        }
-+        OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
-         return rc;
-       }
-+      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-+      return SQLITE_OK;
-+    }
-+    case SQLITE_FCNTL_PERSIST_WAL: {
-+      winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg);
-+      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-+      return SQLITE_OK;
++static int fts5ConfigMakeExprlist(Fts5Config *p){
++  int i;
++  int rc = SQLITE_OK;
++  Fts5Buffer buf = {0, 0, 0};
++
++  sqlite3Fts5BufferAppendPrintf(&rc, &buf, "T.%Q", p->zContentRowid);
++  if( p->eContent!=FTS5_CONTENT_NONE ){
++    for(i=0; i<p->nCol; i++){
++      if( p->eContent==FTS5_CONTENT_EXTERNAL ){
++        sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]);
++      }else{
++        sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i);
++      }
 +    }
-+    case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
-+      winModeBit(pFile, WINFILE_PSOW, (int*)pArg);
-+      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-+      return SQLITE_OK;
++  }
++
++  assert( p->zContentExprlist==0 );
++  p->zContentExprlist = (char*)buf.p;
++  return rc;
++}
++
++/*
++** Arguments nArg/azArg contain the string arguments passed to the xCreate
++** or xConnect method of the virtual table. This function attempts to 
++** allocate an instance of Fts5Config containing the results of parsing
++** those arguments.
++**
++** If successful, SQLITE_OK is returned and *ppOut is set to point to the
++** new Fts5Config object. If an error occurs, an SQLite error code is 
++** returned, *ppOut is set to NULL and an error message may be left in
++** *pzErr. It is the responsibility of the caller to eventually free any 
++** such error message using sqlite3_free().
++*/
++static int sqlite3Fts5ConfigParse(
++  Fts5Global *pGlobal,
++  sqlite3 *db,
++  int nArg,                       /* Number of arguments */
++  const char **azArg,             /* Array of nArg CREATE VIRTUAL TABLE args */
++  Fts5Config **ppOut,             /* OUT: Results of parse */
++  char **pzErr                    /* OUT: Error message */
++){
++  int rc = SQLITE_OK;             /* Return code */
++  Fts5Config *pRet;               /* New object to return */
++  int i;
++  int nByte;
++
++  *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config));
++  if( pRet==0 ) return SQLITE_NOMEM;
++  memset(pRet, 0, sizeof(Fts5Config));
++  pRet->db = db;
++  pRet->iCookie = -1;
++
++  nByte = nArg * (sizeof(char*) + sizeof(u8));
++  pRet->azCol = (char**)sqlite3Fts5MallocZero(&rc, nByte);
++  pRet->abUnindexed = (u8*)&pRet->azCol[nArg];
++  pRet->zDb = sqlite3Fts5Strndup(&rc, azArg[1], -1);
++  pRet->zName = sqlite3Fts5Strndup(&rc, azArg[2], -1);
++  pRet->bColumnsize = 1;
++  pRet->eDetail = FTS5_DETAIL_FULL;
++#ifdef SQLITE_DEBUG
++  pRet->bPrefixIndex = 1;
++#endif
++  if( rc==SQLITE_OK && sqlite3_stricmp(pRet->zName, FTS5_RANK_NAME)==0 ){
++    *pzErr = sqlite3_mprintf("reserved fts5 table name: %s", pRet->zName);
++    rc = SQLITE_ERROR;
++  }
++
++  for(i=3; rc==SQLITE_OK && i<nArg; i++){
++    const char *zOrig = azArg[i];
++    const char *z;
++    char *zOne = 0;
++    char *zTwo = 0;
++    int bOption = 0;
++    int bMustBeCol = 0;
++
++    z = fts5ConfigGobbleWord(&rc, zOrig, &zOne, &bMustBeCol);
++    z = fts5ConfigSkipWhitespace(z);
++    if( z && *z=='=' ){
++      bOption = 1;
++      z++;
++      if( bMustBeCol ) z = 0;
 +    }
-+    case SQLITE_FCNTL_VFSNAME: {
-+      *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
-+      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-+      return SQLITE_OK;
++    z = fts5ConfigSkipWhitespace(z);
++    if( z && z[0] ){
++      int bDummy;
++      z = fts5ConfigGobbleWord(&rc, z, &zTwo, &bDummy);
++      if( z && z[0] ) z = 0;
 +    }
-+    case SQLITE_FCNTL_WIN32_AV_RETRY: {
-+      int *a = (int*)pArg;
-+      if( a[0]>0 ){
-+        winIoerrRetry = a[0];
-+      }else{
-+        a[0] = winIoerrRetry;
-+      }
-+      if( a[1]>0 ){
-+        winIoerrRetryDelay = a[1];
++
++    if( rc==SQLITE_OK ){
++      if( z==0 ){
++        *pzErr = sqlite3_mprintf("parse error in \"%s\"", zOrig);
++        rc = SQLITE_ERROR;
 +      }else{
-+        a[1] = winIoerrRetryDelay;
++        if( bOption ){
++          rc = fts5ConfigParseSpecial(pGlobal, pRet, zOne, zTwo?zTwo:"", pzErr);
++        }else{
++          rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr);
++          zOne = 0;
++        }
 +      }
-+      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-+      return SQLITE_OK;
 +    }
-+#ifdef SQLITE_TEST
-+    case SQLITE_FCNTL_WIN32_SET_HANDLE: {
-+      LPHANDLE phFile = (LPHANDLE)pArg;
-+      HANDLE hOldFile = pFile->h;
-+      pFile->h = *phFile;
-+      *phFile = hOldFile;
-+      OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n",
-+               hOldFile, pFile->h));
-+      return SQLITE_OK;
++
++    sqlite3_free(zOne);
++    sqlite3_free(zTwo);
++  }
++
++  /* If a tokenizer= option was successfully parsed, the tokenizer has
++  ** already been allocated. Otherwise, allocate an instance of the default
++  ** tokenizer (unicode61) now.  */
++  if( rc==SQLITE_OK && pRet->pTok==0 ){
++    rc = fts5ConfigDefaultTokenizer(pGlobal, pRet);
++  }
++
++  /* If no zContent option was specified, fill in the default values. */
++  if( rc==SQLITE_OK && pRet->zContent==0 ){
++    const char *zTail = 0;
++    assert( pRet->eContent==FTS5_CONTENT_NORMAL 
++         || pRet->eContent==FTS5_CONTENT_NONE 
++    );
++    if( pRet->eContent==FTS5_CONTENT_NORMAL ){
++      zTail = "content";
++    }else if( pRet->bColumnsize ){
++      zTail = "docsize";
++    }
++
++    if( zTail ){
++      pRet->zContent = sqlite3Fts5Mprintf(
++          &rc, "%Q.'%q_%s'", pRet->zDb, pRet->zName, zTail
++      );
 +    }
-+#endif
-+    case SQLITE_FCNTL_TEMPFILENAME: {
-+      char *zTFile = 0;
-+      int rc = winGetTempname(pFile->pVfs, &zTFile);
-+      if( rc==SQLITE_OK ){
-+        *(char**)pArg = zTFile;
-+      }
-+      OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
-+      return rc;
-     }
--    if( pFd->mmapSize >= iOff+nAmt ){
--      *pp = &((u8 *)pFd->pMapRegion)[iOff];
--      pFd->nFetchOut++;
-+#if SQLITE_MAX_MMAP_SIZE>0
-+    case SQLITE_FCNTL_MMAP_SIZE: {
-+      i64 newLimit = *(i64*)pArg;
-+      int rc = SQLITE_OK;
-+      if( newLimit>sqlite3GlobalConfig.mxMmap ){
-+        newLimit = sqlite3GlobalConfig.mxMmap;
-+      }
-+      *(i64*)pArg = pFile->mmapSizeMax;
-+      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
-+        pFile->mmapSizeMax = newLimit;
-+        if( pFile->mmapSize>0 ){
-+          winUnmapfile(pFile);
-+          rc = winMapfile(pFile, -1);
-+        }
-+      }
-+      OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
-+      return rc;
-     }
--  }
- #endif
--
--  OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n",
--           osGetCurrentProcessId(), fd, pp, *pp));
--  return SQLITE_OK;
 +  }
-+  OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
-+  return SQLITE_NOTFOUND;
- }
- 
- /*
--** If the third argument is non-NULL, then this function releases a
--** reference obtained by an earlier call to winFetch(). The second
--** argument passed to this function must be the same as the corresponding
--** argument that was passed to the winFetch() invocation.
-+** Return the sector size in bytes of the underlying block device for
-+** the specified file. This is almost always 512 bytes, but may be
-+** larger for some devices.
- **
--** Or, if the third argument is NULL, then this function is being called
--** to inform the VFS layer that, according to POSIX, any existing mapping
--** may now be invalid and should be unmapped.
-+** SQLite code assumes this function cannot fail. It also assumes that
-+** if two files are created in the same file-system directory (i.e.
-+** a database and its journal file) that the sector size will be the
-+** same for both.
- */
--static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){
--#if SQLITE_MAX_MMAP_SIZE>0
--  winFile *pFd = (winFile*)fd;   /* The underlying database file */
--
--  /* If p==0 (unmap the entire file) then there must be no outstanding
--  ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
--  ** then there must be at least one outstanding.  */
--  assert( (p==0)==(pFd->nFetchOut==0) );
--
--  /* If p!=0, it must match the iOff value. */
--  assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
--
--  OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n",
--           osGetCurrentProcessId(), pFd, iOff, p));
--
--  if( p ){
--    pFd->nFetchOut--;
--  }else{
--    /* FIXME:  If Windows truly always prevents truncating or deleting a
--    ** file while a mapping is held, then the following winUnmapfile() call
--    ** is unnecessary can be omitted - potentially improving
--    ** performance.  */
--    winUnmapfile(pFd);
--  }
--
--  assert( pFd->nFetchOut>=0 );
--#endif
--
--  OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n",
--           osGetCurrentProcessId(), fd));
--  return SQLITE_OK;
-+static int winSectorSize(sqlite3_file *id){
-+  (void)id;
-+  return SQLITE_DEFAULT_SECTOR_SIZE;
- }
- 
- /*
--** Here ends the implementation of all sqlite3_file methods.
--**
--********************** End sqlite3_file Methods *******************************
--******************************************************************************/
-+** Return a vector of device characteristics.
-+*/
-+static int winDeviceCharacteristics(sqlite3_file *id){
-+  winFile *p = (winFile*)id;
-+  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
-+         ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
-+}
- 
- /*
--** This vector defines all the methods that can operate on an
--** sqlite3_file for win32.
-+** Windows will only let you create file view mappings
-+** on allocation size granularity boundaries.
-+** During sqlite3_os_init() we do a GetSystemInfo()
-+** to get the granularity size.
- */
--static const sqlite3_io_methods winIoMethod = {
--  3,                              /* iVersion */
--  winClose,                       /* xClose */
--  winRead,                        /* xRead */
--  winWrite,                       /* xWrite */
--  winTruncate,                    /* xTruncate */
--  winSync,                        /* xSync */
--  winFileSize,                    /* xFileSize */
--  winLock,                        /* xLock */
--  winUnlock,                      /* xUnlock */
--  winCheckReservedLock,           /* xCheckReservedLock */
--  winFileControl,                 /* xFileControl */
--  winSectorSize,                  /* xSectorSize */
--  winDeviceCharacteristics,       /* xDeviceCharacteristics */
--  winShmMap,                      /* xShmMap */
--  winShmLock,                     /* xShmLock */
--  winShmBarrier,                  /* xShmBarrier */
--  winShmUnmap,                    /* xShmUnmap */
--  winFetch,                       /* xFetch */
--  winUnfetch                      /* xUnfetch */
--};
-+static SYSTEM_INFO winSysInfo;
- 
--/****************************************************************************
--**************************** sqlite3_vfs methods ****************************
--**
--** This division contains the implementation of methods on the
--** sqlite3_vfs object.
--*/
-+#ifndef SQLITE_OMIT_WAL
- 
--#if defined(__CYGWIN__)
- /*
--** Convert a filename from whatever the underlying operating system
--** supports for filenames into UTF-8.  Space to hold the result is
--** obtained from malloc and must be freed by the calling function.
-+** Helper functions to obtain and relinquish the global mutex. The
-+** global mutex is used to protect the winLockInfo objects used by
-+** this file, all of which may be shared by multiple threads.
-+**
-+** Function winShmMutexHeld() is used to assert() that the global mutex
-+** is held when required. This function is only used as part of assert()
-+** statements. e.g.
-+**
-+**   winShmEnterMutex()
-+**     assert( winShmMutexHeld() );
-+**   winShmLeaveMutex()
- */
--static char *winConvertToUtf8Filename(const void *zFilename){
--  char *zConverted = 0;
--  if( osIsNT() ){
--    zConverted = winUnicodeToUtf8(zFilename);
--  }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
--  }
--#endif
--  /* caller will handle out of memory */
--  return zConverted;
-+static void winShmEnterMutex(void){
-+  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-+}
-+static void winShmLeaveMutex(void){
-+  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-+}
-+#ifndef NDEBUG
-+static int winShmMutexHeld(void) {
-+  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
- }
- #endif
- 
- /*
--** Convert a UTF-8 filename into whatever form the underlying
--** operating system wants filenames in.  Space to hold the result
--** is obtained from malloc and must be freed by the calling
--** function.
-+** Object used to represent a single file opened and mmapped to provide
-+** shared memory.  When multiple threads all reference the same
-+** log-summary, each thread has its own winFile object, but they all
-+** point to a single instance of this object.  In other words, each
-+** log-summary is opened only once per process.
-+**
-+** winShmMutexHeld() must be true when creating or destroying
-+** this object or while reading or writing the following fields:
-+**
-+**      nRef
-+**      pNext
-+**
-+** The following fields are read-only after the object is created:
-+**
-+**      fid
-+**      zFilename
-+**
-+** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
-+** winShmMutexHeld() is true when reading or writing any other field
-+** in this structure.
-+**
- */
--static void *winConvertFromUtf8Filename(const char *zFilename){
--  void *zConverted = 0;
--  if( osIsNT() ){
--    zConverted = winUtf8ToUnicode(zFilename);
--  }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
--  }
-+struct winShmNode {
-+  sqlite3_mutex *mutex;      /* Mutex to access this object */
-+  char *zFilename;           /* Name of the file */
-+  winFile hFile;             /* File handle from winOpen */
-+
-+  int szRegion;              /* Size of shared-memory regions */
-+  int nRegion;               /* Size of array apRegion */
-+  struct ShmRegion {
-+    HANDLE hMap;             /* File handle from CreateFileMapping */
-+    void *pMap;
-+  } *aRegion;
-+  DWORD lastErrno;           /* The Windows errno from the last I/O error */
-+
-+  int nRef;                  /* Number of winShm objects pointing to this */
-+  winShm *pFirst;            /* All winShm objects pointing to this */
-+  winShmNode *pNext;         /* Next in list of all winShmNode objects */
-+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
-+  u8 nextShmId;              /* Next available winShm.id value */
- #endif
--  /* caller will handle out of memory */
--  return zConverted;
--}
-+};
- 
- /*
--** This function returns non-zero if the specified UTF-8 string buffer
--** ends with a directory separator character or one was successfully
--** added to it.
-+** A global array of all winShmNode objects.
-+**
-+** The winShmMutexHeld() must be true while reading or writing this list.
- */
--static int winMakeEndInDirSep(int nBuf, char *zBuf){
--  if( zBuf ){
--    int nLen = sqlite3Strlen30(zBuf);
--    if( nLen>0 ){
--      if( winIsDirSep(zBuf[nLen-1]) ){
--        return 1;
--      }else if( nLen+1<nBuf ){
--        zBuf[nLen] = winGetDirSep();
--        zBuf[nLen+1] = '\0';
--        return 1;
--      }
--    }
--  }
--  return 0;
--}
-+static winShmNode *winShmNodeList = 0;
- 
- /*
--** Create a temporary file name and store the resulting pointer into pzBuf.
--** The pointer returned in pzBuf must be freed via sqlite3_free().
-+** Structure used internally by this VFS to record the state of an
-+** open shared memory connection.
-+**
-+** The following fields are initialized when this object is created and
-+** are read-only thereafter:
-+**
-+**    winShm.pShmNode
-+**    winShm.id
-+**
-+** All other fields are read/write.  The winShm.pShmNode->mutex must be held
-+** while accessing any read/write fields.
- */
--static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
--  static char zChars[] =
--    "abcdefghijklmnopqrstuvwxyz"
--    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
--    "0123456789";
--  size_t i, j;
--  int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
--  int nMax, nBuf, nDir, nLen;
--  char *zBuf;
--
--  /* It's odd to simulate an io-error here, but really this is just
--  ** using the io-error infrastructure to test that SQLite handles this
--  ** function failing.
--  */
--  SimulateIOError( return SQLITE_IOERR );
-+struct winShm {
-+  winShmNode *pShmNode;      /* The underlying winShmNode object */
-+  winShm *pNext;             /* Next winShm with the same winShmNode */
-+  u8 hasMutex;               /* True if holding the winShmNode mutex */
-+  u16 sharedMask;            /* Mask of shared locks held */
-+  u16 exclMask;              /* Mask of exclusive locks held */
-+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
-+  u8 id;                     /* Id of this connection with its winShmNode */
-+#endif
-+};
- 
--  /* Allocate a temporary buffer to store the fully qualified file
--  ** name for the temporary file.  If this fails, we cannot continue.
--  */
--  nMax = pVfs->mxPathname; nBuf = nMax + 2;
--  zBuf = sqlite3MallocZero( nBuf );
--  if( !zBuf ){
--    OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
--    return SQLITE_IOERR_NOMEM;
--  }
-+/*
-+** Constants used for locking
-+*/
-+#define WIN_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
-+#define WIN_SHM_DMS    (WIN_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
- 
--  /* Figure out the effective temporary directory.  First, check if one
--  ** has been explicitly set by the application; otherwise, use the one
--  ** configured by the operating system.
--  */
--  nDir = nMax - (nPre + 15);
--  assert( nDir>0 );
--  if( sqlite3_temp_directory ){
--    int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
--    if( nDirLen>0 ){
--      if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
--        nDirLen++;
--      }
--      if( nDirLen>nDir ){
--        sqlite3_free(zBuf);
--        OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
--        return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
--      }
--      sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
--    }
--  }
--#if defined(__CYGWIN__)
--  else{
--    static const char *azDirs[] = {
--       0, /* getenv("SQLITE_TMPDIR") */
--       0, /* getenv("TMPDIR") */
--       0, /* getenv("TMP") */
--       0, /* getenv("TEMP") */
--       0, /* getenv("USERPROFILE") */
--       "/var/tmp",
--       "/usr/tmp",
--       "/tmp",
--       ".",
--       0        /* List terminator */
--    };
--    unsigned int i;
--    const char *zDir = 0;
-+/*
-+** Apply advisory locks for all n bytes beginning at ofst.
-+*/
-+#define _SHM_UNLCK  1
-+#define _SHM_RDLCK  2
-+#define _SHM_WRLCK  3
-+static int winShmSystemLock(
-+  winShmNode *pFile,    /* Apply locks to this open shared-memory segment */
-+  int lockType,         /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
-+  int ofst,             /* Offset to first byte to be locked/unlocked */
-+  int nByte             /* Number of bytes to lock or unlock */
-+){
-+  int rc = 0;           /* Result code form Lock/UnlockFileEx() */
- 
--    if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
--    if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
--    if( !azDirs[2] ) azDirs[2] = getenv("TMP");
--    if( !azDirs[3] ) azDirs[3] = getenv("TEMP");
--    if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE");
--    for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
--      void *zConverted;
--      if( zDir==0 ) continue;
--      /* If the path starts with a drive letter followed by the colon
--      ** character, assume it is already a native Win32 path; otherwise,
--      ** it must be converted to a native Win32 path via the Cygwin API
--      ** prior to using it.
--      */
--      if( winIsDriveLetterAndColon(zDir) ){
--        zConverted = winConvertFromUtf8Filename(zDir);
--        if( !zConverted ){
--          sqlite3_free(zBuf);
--          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
--          return SQLITE_IOERR_NOMEM;
--        }
--        if( winIsDir(zConverted) ){
--          sqlite3_snprintf(nMax, zBuf, "%s", zDir);
--          sqlite3_free(zConverted);
--          break;
--        }
--        sqlite3_free(zConverted);
--      }else{
--        zConverted = sqlite3MallocZero( nMax+1 );
--        if( !zConverted ){
--          sqlite3_free(zBuf);
--          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
--          return SQLITE_IOERR_NOMEM;
--        }
--        if( cygwin_conv_path(
--                osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
--                zConverted, nMax+1)<0 ){
--          sqlite3_free(zConverted);
--          sqlite3_free(zBuf);
--          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
--          return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
--                             "winGetTempname2", zDir);
--        }
--        if( winIsDir(zConverted) ){
--          /* At this point, we know the candidate directory exists and should
--          ** be used.  However, we may need to convert the string containing
--          ** its name into UTF-8 (i.e. if it is UTF-16 right now).
--          */
--          char *zUtf8 = winConvertToUtf8Filename(zConverted);
--          if( !zUtf8 ){
--            sqlite3_free(zConverted);
--            sqlite3_free(zBuf);
--            OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
--            return SQLITE_IOERR_NOMEM;
--          }
--          sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
--          sqlite3_free(zUtf8);
--          sqlite3_free(zConverted);
--          break;
--        }
--        sqlite3_free(zConverted);
--      }
--    }
--  }
--#elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
--  else if( osIsNT() ){
--    char *zMulti;
--    LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) );
--    if( !zWidePath ){
--      sqlite3_free(zBuf);
--      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
--      return SQLITE_IOERR_NOMEM;
--    }
--    if( osGetTempPathW(nMax, zWidePath)==0 ){
--      sqlite3_free(zWidePath);
--      sqlite3_free(zBuf);
--      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
--      return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
--                         "winGetTempname2", 0);
--    }
--    zMulti = winUnicodeToUtf8(zWidePath);
--    if( zMulti ){
--      sqlite3_snprintf(nMax, zBuf, "%s", zMulti);
--      sqlite3_free(zMulti);
--      sqlite3_free(zWidePath);
--    }else{
--      sqlite3_free(zWidePath);
--      sqlite3_free(zBuf);
--      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
--      return SQLITE_IOERR_NOMEM;
--    }
--  }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    char *zUtf8;
--    char *zMbcsPath = sqlite3MallocZero( nMax );
--    if( !zMbcsPath ){
--      sqlite3_free(zBuf);
--      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
--      return SQLITE_IOERR_NOMEM;
--    }
--    if( osGetTempPathA(nMax, zMbcsPath)==0 ){
--      sqlite3_free(zBuf);
--      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
--      return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
--                         "winGetTempname3", 0);
--    }
--    zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
--    if( zUtf8 ){
--      sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
--      sqlite3_free(zUtf8);
--    }else{
--      sqlite3_free(zBuf);
--      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
--      return SQLITE_IOERR_NOMEM;
--    }
--  }
--#endif /* SQLITE_WIN32_HAS_ANSI */
--#endif /* !SQLITE_OS_WINRT */
-+  /* Access to the winShmNode object is serialized by the caller */
-+  assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
- 
--  /*
--  ** Check to make sure the temporary directory ends with an appropriate
--  ** separator.  If it does not and there is not enough space left to add
--  ** one, fail.
--  */
--  if( !winMakeEndInDirSep(nDir+1, zBuf) ){
--    sqlite3_free(zBuf);
--    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
--    return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0);
--  }
-+  OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n",
-+           pFile->hFile.h, lockType, ofst, nByte));
- 
--  /*
--  ** Check that the output buffer is large enough for the temporary file
--  ** name in the following format:
--  **
--  **   "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0"
--  **
--  ** If not, return SQLITE_ERROR.  The number 17 is used here in order to
--  ** account for the space used by the 15 character random suffix and the
--  ** two trailing NUL characters.  The final directory separator character
--  ** has already added if it was not already present.
--  */
--  nLen = sqlite3Strlen30(zBuf);
--  if( (nLen + nPre + 17) > nBuf ){
--    sqlite3_free(zBuf);
--    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
--    return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0);
-+  /* Release/Acquire the system-level lock */
-+  if( lockType==_SHM_UNLCK ){
-+    rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
-+  }else{
-+    /* Initialize the locking parameters */
-+    DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
-+    if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
-+    rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
-   }
- 
--  sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
--
--  j = sqlite3Strlen30(zBuf);
--  sqlite3_randomness(15, &zBuf[j]);
--  for(i=0; i<15; i++, j++){
--    zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-+  if( rc!= 0 ){
-+    rc = SQLITE_OK;
-+  }else{
-+    pFile->lastErrno =  osGetLastError();
-+    rc = SQLITE_BUSY;
-   }
--  zBuf[j] = 0;
--  zBuf[j+1] = 0;
--  *pzBuf = zBuf;
- 
--  OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf));
--  return SQLITE_OK;
-+  OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n",
-+           pFile->hFile.h, (lockType == _SHM_UNLCK) ? "winUnlockFile" :
-+           "winLockFile", pFile->lastErrno, sqlite3ErrName(rc)));
 +
-+  return rc;
- }
- 
-+/* Forward references to VFS methods */
-+static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
-+static int winDelete(sqlite3_vfs *,const char*,int);
-+
- /*
--** Return TRUE if the named file is really a directory.  Return false if
--** it is something other than a directory, or if there is any kind of memory
--** allocation failure.
-+** Purge the winShmNodeList list of all entries with winShmNode.nRef==0.
-+**
-+** This is not a VFS shared-memory method; it is a utility function called
-+** by VFS shared-memory methods.
- */
--static int winIsDir(const void *zConverted){
--  DWORD attr;
--  int rc = 0;
--  DWORD lastErrno;
--
--  if( osIsNT() ){
--    int cnt = 0;
--    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
--    memset(&sAttrData, 0, sizeof(sAttrData));
--    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
--                             GetFileExInfoStandard,
--                             &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
--    if( !rc ){
--      return 0; /* Invalid name? */
-+static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
-+  winShmNode **pp;
-+  winShmNode *p;
-+  assert( winShmMutexHeld() );
-+  OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n",
-+           osGetCurrentProcessId(), deleteFlag));
-+  pp = &winShmNodeList;
-+  while( (p = *pp)!=0 ){
-+    if( p->nRef==0 ){
-+      int i;
-+      if( p->mutex ){ sqlite3_mutex_free(p->mutex); }
-+      for(i=0; i<p->nRegion; i++){
-+        BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
-+        OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
-+                 osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
-+        UNUSED_VARIABLE_VALUE(bRc);
-+        bRc = osCloseHandle(p->aRegion[i].hMap);
-+        OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n",
-+                 osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
-+        UNUSED_VARIABLE_VALUE(bRc);
-+      }
-+      if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){
-+        SimulateIOErrorBenign(1);
-+        winClose((sqlite3_file *)&p->hFile);
-+        SimulateIOErrorBenign(0);
-+      }
-+      if( deleteFlag ){
-+        SimulateIOErrorBenign(1);
-+        sqlite3BeginBenignMalloc();
-+        winDelete(pVfs, p->zFilename, 0);
-+        sqlite3EndBenignMalloc();
-+        SimulateIOErrorBenign(0);
-+      }
-+      *pp = p->pNext;
-+      sqlite3_free(p->aRegion);
-+      sqlite3_free(p);
-+    }else{
-+      pp = &p->pNext;
-     }
--    attr = sAttrData.dwFileAttributes;
--#if SQLITE_OS_WINCE==0
--  }else{
--    attr = osGetFileAttributesA((char*)zConverted);
--#endif
-   }
--  return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
- }
- 
- /*
--** Open a file.
-+** Open the shared-memory area associated with database file pDbFd.
-+**
-+** When opening a new shared-memory file, if no other instances of that
-+** file are currently open, in this process or in other processes, then
-+** the file must be truncated to zero length or have its header cleared.
- */
--static int winOpen(
--  sqlite3_vfs *pVfs,        /* Used to get maximum path name length */
--  const char *zName,        /* Name of the file (UTF-8) */
--  sqlite3_file *id,         /* Write the SQLite file handle here */
--  int flags,                /* Open mode flags */
--  int *pOutFlags            /* Status return flags */
--){
--  HANDLE h;
--  DWORD lastErrno = 0;
--  DWORD dwDesiredAccess;
--  DWORD dwShareMode;
--  DWORD dwCreationDisposition;
--  DWORD dwFlagsAndAttributes = 0;
--#if SQLITE_OS_WINCE
--  int isTemp = 0;
--#endif
--  winFile *pFile = (winFile*)id;
--  void *zConverted;              /* Filename in OS encoding */
--  const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
--  int cnt = 0;
--
--  /* If argument zPath is a NULL pointer, this function is required to open
--  ** a temporary file. Use this buffer to store the file name in.
--  */
--  char *zTmpname = 0; /* For temporary filename, if necessary. */
--
--  int rc = SQLITE_OK;            /* Function Return Code */
--#if !defined(NDEBUG) || SQLITE_OS_WINCE
--  int eType = flags&0xFFFFFF00;  /* Type of file to open */
--#endif
--
--  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
--  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
--  int isCreate     = (flags & SQLITE_OPEN_CREATE);
--  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
--  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
--
--#ifndef NDEBUG
--  int isOpenJournal = (isCreate && (
--        eType==SQLITE_OPEN_MASTER_JOURNAL
--     || eType==SQLITE_OPEN_MAIN_JOURNAL
--     || eType==SQLITE_OPEN_WAL
--  ));
--#endif
-+static int winOpenSharedMemory(winFile *pDbFd){
-+  struct winShm *p;                  /* The connection to be opened */
-+  struct winShmNode *pShmNode = 0;   /* The underlying mmapped file */
-+  int rc;                            /* Result code */
-+  struct winShmNode *pNew;           /* Newly allocated winShmNode */
-+  int nName;                         /* Size of zName in bytes */
- 
--  OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n",
--           zUtf8Name, id, flags, pOutFlags));
-+  assert( pDbFd->pShm==0 );    /* Not previously opened */
- 
--  /* Check the following statements are true:
--  **
--  **   (a) Exactly one of the READWRITE and READONLY flags must be set, and
--  **   (b) if CREATE is set, then READWRITE must also be set, and
--  **   (c) if EXCLUSIVE is set, then CREATE must also be set.
--  **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
-+  /* Allocate space for the new sqlite3_shm object.  Also speculatively
-+  ** allocate space for a new winShmNode and filename.
-   */
--  assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
--  assert(isCreate==0 || isReadWrite);
--  assert(isExclusive==0 || isCreate);
--  assert(isDelete==0 || isCreate);
-+  p = sqlite3MallocZero( sizeof(*p) );
-+  if( p==0 ) return SQLITE_IOERR_NOMEM;
-+  nName = sqlite3Strlen30(pDbFd->zPath);
-+  pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
-+  if( pNew==0 ){
-+    sqlite3_free(p);
-+    return SQLITE_IOERR_NOMEM;
-+  }
-+  pNew->zFilename = (char*)&pNew[1];
-+  sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
-+  sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
- 
--  /* The main DB, main journal, WAL file and master journal are never
--  ** automatically deleted. Nor are they ever temporary files.  */
--  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
--  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
--  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
--  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
-+  /* Look to see if there is an existing winShmNode that can be used.
-+  ** If no matching winShmNode currently exists, create a new one.
-+  */
-+  winShmEnterMutex();
-+  for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
-+    /* TBD need to come up with better match here.  Perhaps
-+    ** use FILE_ID_BOTH_DIR_INFO Structure.
-+    */
-+    if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break;
++  if( rc==SQLITE_OK && pRet->zContentRowid==0 ){
++    pRet->zContentRowid = sqlite3Fts5Strndup(&rc, "rowid", -1);
 +  }
-+  if( pShmNode ){
-+    sqlite3_free(pNew);
-+  }else{
-+    pShmNode = pNew;
-+    pNew = 0;
-+    ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
-+    pShmNode->pNext = winShmNodeList;
-+    winShmNodeList = pShmNode;
- 
--  /* Assert that the upper layer has set one of the "file-type" flags. */
--  assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB
--       || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
--       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL
--       || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
--  );
-+    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
-+    if( pShmNode->mutex==0 ){
-+      rc = SQLITE_IOERR_NOMEM;
-+      goto shm_open_err;
-+    }
- 
--  assert( pFile!=0 );
--  memset(pFile, 0, sizeof(winFile));
--  pFile->h = INVALID_HANDLE_VALUE;
-+    rc = winOpen(pDbFd->pVfs,
-+                 pShmNode->zFilename,             /* Name of the file (UTF-8) */
-+                 (sqlite3_file*)&pShmNode->hFile,  /* File handle here */
-+                 SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
-+                 0);
-+    if( SQLITE_OK!=rc ){
-+      goto shm_open_err;
-+    }
- 
--#if SQLITE_OS_WINRT
--  if( !zUtf8Name && !sqlite3_temp_directory ){
--    sqlite3_log(SQLITE_ERROR,
--        "sqlite3_temp_directory variable should be set for WinRT");
-+    /* Check to see if another process is holding the dead-man switch.
-+    ** If not, truncate the file to zero length.
-+    */
-+    if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
-+      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
-+      if( rc!=SQLITE_OK ){
-+        rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
-+                         "winOpenShm", pDbFd->zPath);
-+      }
++
++  /* Formulate the zContentExprlist text */
++  if( rc==SQLITE_OK ){
++    rc = fts5ConfigMakeExprlist(pRet);
++  }
++
++  if( rc!=SQLITE_OK ){
++    sqlite3Fts5ConfigFree(pRet);
++    *ppOut = 0;
++  }
++  return rc;
++}
++
++/*
++** Free the configuration object passed as the only argument.
++*/
++static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){
++  if( pConfig ){
++    int i;
++    if( pConfig->pTok ){
++      pConfig->pTokApi->xDelete(pConfig->pTok);
 +    }
-+    if( rc==SQLITE_OK ){
-+      winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
-+      rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
++    sqlite3_free(pConfig->zDb);
++    sqlite3_free(pConfig->zName);
++    for(i=0; i<pConfig->nCol; i++){
++      sqlite3_free(pConfig->azCol[i]);
 +    }
-+    if( rc ) goto shm_open_err;
-   }
++    sqlite3_free(pConfig->azCol);
++    sqlite3_free(pConfig->aPrefix);
++    sqlite3_free(pConfig->zRank);
++    sqlite3_free(pConfig->zRankArgs);
++    sqlite3_free(pConfig->zContent);
++    sqlite3_free(pConfig->zContentRowid);
++    sqlite3_free(pConfig->zContentExprlist);
++    sqlite3_free(pConfig);
++  }
++}
 +
-+  /* Make the new connection a child of the winShmNode */
-+  p->pShmNode = pShmNode;
-+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
-+  p->id = pShmNode->nextShmId++;
- #endif
-+  pShmNode->nRef++;
-+  pDbFd->pShm = p;
-+  winShmLeaveMutex();
- 
--  /* If the second argument to this function is NULL, generate a
--  ** temporary file name to use
-+  /* The reference count on pShmNode has already been incremented under
-+  ** the cover of the winShmEnterMutex() mutex and the pointer from the
-+  ** new (struct winShm) object to the pShmNode has been set. All that is
-+  ** left to do is to link the new object into the linked list starting
-+  ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
-+  ** mutex.
-   */
--  if( !zUtf8Name ){
--    assert( isDelete && !isOpenJournal );
--    rc = winGetTempname(pVfs, &zTmpname);
--    if( rc!=SQLITE_OK ){
--      OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
--      return rc;
--    }
--    zUtf8Name = zTmpname;
--  }
-+  sqlite3_mutex_enter(pShmNode->mutex);
-+  p->pNext = pShmNode->pFirst;
-+  pShmNode->pFirst = p;
-+  sqlite3_mutex_leave(pShmNode->mutex);
-+  return SQLITE_OK;
- 
--  /* Database filenames are double-zero terminated if they are not
--  ** URIs with parameters.  Hence, they can always be passed into
--  ** sqlite3_uri_parameter().
--  */
--  assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
--       zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 );
-+  /* Jump here on any error */
-+shm_open_err:
-+  winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
-+  winShmPurge(pDbFd->pVfs, 0);      /* This call frees pShmNode if required */
-+  sqlite3_free(p);
-+  sqlite3_free(pNew);
-+  winShmLeaveMutex();
++/*
++** Call sqlite3_declare_vtab() based on the contents of the configuration
++** object passed as the only argument. Return SQLITE_OK if successful, or
++** an SQLite error code if an error occurs.
++*/
++static int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig){
++  int i;
++  int rc = SQLITE_OK;
++  char *zSql;
++
++  zSql = sqlite3Fts5Mprintf(&rc, "CREATE TABLE x(");
++  for(i=0; zSql && i<pConfig->nCol; i++){
++    const char *zSep = (i==0?"":", ");
++    zSql = sqlite3Fts5Mprintf(&rc, "%z%s%Q", zSql, zSep, pConfig->azCol[i]);
++  }
++  zSql = sqlite3Fts5Mprintf(&rc, "%z, %Q HIDDEN, %s HIDDEN)", 
++      zSql, pConfig->zName, FTS5_RANK_NAME
++  );
++
++  assert( zSql || rc==SQLITE_NOMEM );
++  if( zSql ){
++    rc = sqlite3_declare_vtab(pConfig->db, zSql);
++    sqlite3_free(zSql);
++  }
++  
 +  return rc;
 +}
- 
--  /* Convert the filename to the system encoding. */
--  zConverted = winConvertFromUtf8Filename(zUtf8Name);
--  if( zConverted==0 ){
--    sqlite3_free(zTmpname);
--    OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
--    return SQLITE_IOERR_NOMEM;
--  }
++
 +/*
-+** Close a connection to shared-memory.  Delete the underlying
-+** storage if deleteFlag is true.
++** Tokenize the text passed via the second and third arguments.
++**
++** The callback is invoked once for each token in the input text. The
++** arguments passed to it are, in order:
++**
++**     void *pCtx          // Copy of 4th argument to sqlite3Fts5Tokenize()
++**     const char *pToken  // Pointer to buffer containing token
++**     int nToken          // Size of token in bytes
++**     int iStart          // Byte offset of start of token within input text
++**     int iEnd            // Byte offset of end of token within input text
++**     int iPos            // Position of token in input (first token is 0)
++**
++** If the callback returns a non-zero value the tokenization is abandoned
++** and no further callbacks are issued. 
++**
++** This function returns SQLITE_OK if successful or an SQLite error code
++** if an error occurs. If the tokenization was abandoned early because
++** the callback returned SQLITE_DONE, this is not an error and this function
++** still returns SQLITE_OK. Or, if the tokenization was abandoned early
++** because the callback returned another non-zero value, it is assumed
++** to be an SQLite error code and returned to the caller.
 +*/
-+static int winShmUnmap(
-+  sqlite3_file *fd,          /* Database holding shared memory */
-+  int deleteFlag             /* Delete after closing if true */
++static int sqlite3Fts5Tokenize(
++  Fts5Config *pConfig,            /* FTS5 Configuration object */
++  int flags,                      /* FTS5_TOKENIZE_* flags */
++  const char *pText, int nText,   /* Text to tokenize */
++  void *pCtx,                     /* Context passed to xToken() */
++  int (*xToken)(void*, int, const char*, int, int, int)    /* Callback */
 +){
-+  winFile *pDbFd;       /* Database holding shared-memory */
-+  winShm *p;            /* The connection to be closed */
-+  winShmNode *pShmNode; /* The underlying shared-memory file */
-+  winShm **pp;          /* For looping over sibling connections */
- 
--  if( winIsDir(zConverted) ){
--    sqlite3_free(zConverted);
--    sqlite3_free(zTmpname);
--    OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name));
--    return SQLITE_CANTOPEN_ISDIR;
--  }
-+  pDbFd = (winFile*)fd;
-+  p = pDbFd->pShm;
-+  if( p==0 ) return SQLITE_OK;
-+  pShmNode = p->pShmNode;
- 
--  if( isReadWrite ){
--    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
--  }else{
--    dwDesiredAccess = GENERIC_READ;
--  }
-+  /* Remove connection p from the set of connections associated
-+  ** with pShmNode */
-+  sqlite3_mutex_enter(pShmNode->mutex);
-+  for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
-+  *pp = p->pNext;
- 
--  /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
--  ** created. SQLite doesn't use it to indicate "exclusive access"
--  ** as it is usually understood.
--  */
--  if( isExclusive ){
--    /* Creates a new file, only if it does not already exist. */
--    /* If the file exists, it fails. */
--    dwCreationDisposition = CREATE_NEW;
--  }else if( isCreate ){
--    /* Open existing file, or create if it doesn't exist */
--    dwCreationDisposition = OPEN_ALWAYS;
--  }else{
--    /* Opens a file, only if it exists. */
--    dwCreationDisposition = OPEN_EXISTING;
-+  /* Free the connection p */
-+  sqlite3_free(p);
-+  pDbFd->pShm = 0;
-+  sqlite3_mutex_leave(pShmNode->mutex);
++  if( pText==0 ) return SQLITE_OK;
++  return pConfig->pTokApi->xTokenize(
++      pConfig->pTok, pCtx, flags, pText, nText, xToken
++  );
++}
 +
-+  /* If pShmNode->nRef has reached 0, then close the underlying
-+  ** shared-memory file, too */
-+  winShmEnterMutex();
-+  assert( pShmNode->nRef>0 );
-+  pShmNode->nRef--;
-+  if( pShmNode->nRef==0 ){
-+    winShmPurge(pDbFd->pVfs, deleteFlag);
-   }
-+  winShmLeaveMutex();
- 
--  dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
-+  return SQLITE_OK;
++/*
++** Argument pIn points to the first character in what is expected to be
++** a comma-separated list of SQL literals followed by a ')' character.
++** If it actually is this, return a pointer to the ')'. Otherwise, return
++** NULL to indicate a parse error.
++*/
++static const char *fts5ConfigSkipArgs(const char *pIn){
++  const char *p = pIn;
++  
++  while( 1 ){
++    p = fts5ConfigSkipWhitespace(p);
++    p = fts5ConfigSkipLiteral(p);
++    p = fts5ConfigSkipWhitespace(p);
++    if( p==0 || *p==')' ) break;
++    if( *p!=',' ){
++      p = 0;
++      break;
++    }
++    p++;
++  }
++
++  return p;
 +}
- 
--  if( isDelete ){
--#if SQLITE_OS_WINCE
--    dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
--    isTemp = 1;
--#else
--    dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
--                               | FILE_ATTRIBUTE_HIDDEN
--                               | FILE_FLAG_DELETE_ON_CLOSE;
--#endif
--  }else{
--    dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
--  }
--  /* Reports from the internet are that performance is always
--  ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
--#if SQLITE_OS_WINCE
--  dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
--#endif
++
 +/*
-+** Change the lock state for a shared-memory segment.
-+*/
-+static int winShmLock(
-+  sqlite3_file *fd,          /* Database file holding the shared memory */
-+  int ofst,                  /* First lock to acquire or release */
-+  int n,                     /* Number of locks to acquire or release */
-+  int flags                  /* What to do with the lock */
-+){
-+  winFile *pDbFd = (winFile*)fd;        /* Connection holding shared memory */
-+  winShm *p = pDbFd->pShm;              /* The shared memory being locked */
-+  winShm *pX;                           /* For looping over all siblings */
-+  winShmNode *pShmNode = p->pShmNode;
-+  int rc = SQLITE_OK;                   /* Result code */
-+  u16 mask;                             /* Mask of locks to take or release */
- 
--  if( osIsNT() ){
--#if SQLITE_OS_WINRT
--    CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
--    extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
--    extendedParameters.dwFileAttributes =
--            dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK;
--    extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK;
--    extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
--    extendedParameters.lpSecurityAttributes = NULL;
--    extendedParameters.hTemplateFile = NULL;
--    while( (h = osCreateFile2((LPCWSTR)zConverted,
--                              dwDesiredAccess,
--                              dwShareMode,
--                              dwCreationDisposition,
--                              &extendedParameters))==INVALID_HANDLE_VALUE &&
--                              winRetryIoerr(&cnt, &lastErrno) ){
--               /* Noop */
--    }
--#else
--    while( (h = osCreateFileW((LPCWSTR)zConverted,
--                              dwDesiredAccess,
--                              dwShareMode, NULL,
--                              dwCreationDisposition,
--                              dwFlagsAndAttributes,
--                              NULL))==INVALID_HANDLE_VALUE &&
--                              winRetryIoerr(&cnt, &lastErrno) ){
--               /* Noop */
--    }
--#endif
--  }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    while( (h = osCreateFileA((LPCSTR)zConverted,
--                              dwDesiredAccess,
--                              dwShareMode, NULL,
--                              dwCreationDisposition,
--                              dwFlagsAndAttributes,
--                              NULL))==INVALID_HANDLE_VALUE &&
--                              winRetryIoerr(&cnt, &lastErrno) ){
--               /* Noop */
--    }
--  }
--#endif
--  winLogIoerr(cnt, __LINE__);
-+  assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
-+  assert( n>=1 );
-+  assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
-+       || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
-+       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
-+       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
-+  assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
- 
--  OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
--           dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
-+  mask = (u16)((1U<<(ofst+n)) - (1U<<ofst));
-+  assert( n>1 || mask==(1<<ofst) );
-+  sqlite3_mutex_enter(pShmNode->mutex);
-+  if( flags & SQLITE_SHM_UNLOCK ){
-+    u16 allMask = 0; /* Mask of locks held by siblings */
- 
--  if( h==INVALID_HANDLE_VALUE ){
--    pFile->lastErrno = lastErrno;
--    winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
--    sqlite3_free(zConverted);
--    sqlite3_free(zTmpname);
--    if( isReadWrite && !isExclusive ){
--      return winOpen(pVfs, zName, id,
--         ((flags|SQLITE_OPEN_READONLY) &
--                     ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
--         pOutFlags);
--    }else{
--      return SQLITE_CANTOPEN_BKPT;
-+    /* See if any siblings hold this same lock */
-+    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
-+      if( pX==p ) continue;
-+      assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
-+      allMask |= pX->sharedMask;
-     }
--  }
- 
--  if( pOutFlags ){
--    if( isReadWrite ){
--      *pOutFlags = SQLITE_OPEN_READWRITE;
-+    /* Unlock the system-level locks */
-+    if( (mask & allMask)==0 ){
-+      rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
-     }else{
--      *pOutFlags = SQLITE_OPEN_READONLY;
-+      rc = SQLITE_OK;
-     }
--  }
- 
--  OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, "
--           "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ?
--           *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
-+    /* Undo the local locks */
++** Parameter zIn contains a rank() function specification. The format of 
++** this is:
++**
++**   + Bareword (function name)
++**   + Open parenthesis - "("
++**   + Zero or more SQL literals in a comma separated list
++**   + Close parenthesis - ")"
++*/
++static int sqlite3Fts5ConfigParseRank(
++  const char *zIn,                /* Input string */
++  char **pzRank,                  /* OUT: Rank function name */
++  char **pzRankArgs               /* OUT: Rank function arguments */
++){
++  const char *p = zIn;
++  const char *pRank;
++  char *zRank = 0;
++  char *zRankArgs = 0;
++  int rc = SQLITE_OK;
++
++  *pzRank = 0;
++  *pzRankArgs = 0;
++
++  if( p==0 ){
++    rc = SQLITE_ERROR;
++  }else{
++    p = fts5ConfigSkipWhitespace(p);
++    pRank = p;
++    p = fts5ConfigSkipBareword(p);
++
++    if( p ){
++      zRank = sqlite3Fts5MallocZero(&rc, 1 + p - pRank);
++      if( zRank ) memcpy(zRank, pRank, p-pRank);
++    }else{
++      rc = SQLITE_ERROR;
++    }
++
 +    if( rc==SQLITE_OK ){
-+      p->exclMask &= ~mask;
-+      p->sharedMask &= ~mask;
++      p = fts5ConfigSkipWhitespace(p);
++      if( *p!='(' ) rc = SQLITE_ERROR;
++      p++;
 +    }
-+  }else if( flags & SQLITE_SHM_SHARED ){
-+    u16 allShared = 0;  /* Union of locks held by connections other than "p" */
- 
--#if SQLITE_OS_WINCE
--  if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
--       && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
--  ){
--    osCloseHandle(h);
--    sqlite3_free(zConverted);
--    sqlite3_free(zTmpname);
--    OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
--    return rc;
--  }
--  if( isTemp ){
--    pFile->zDeleteOnClose = zConverted;
--  }else
--#endif
--  {
--    sqlite3_free(zConverted);
--  }
-+    /* Find out which shared locks are already held by sibling connections.
-+    ** If any sibling already holds an exclusive lock, go ahead and return
-+    ** SQLITE_BUSY.
-+    */
-+    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
-+      if( (pX->exclMask & mask)!=0 ){
-+        rc = SQLITE_BUSY;
-+        break;
++    if( rc==SQLITE_OK ){
++      const char *pArgs; 
++      p = fts5ConfigSkipWhitespace(p);
++      pArgs = p;
++      if( *p!=')' ){
++        p = fts5ConfigSkipArgs(p);
++        if( p==0 ){
++          rc = SQLITE_ERROR;
++        }else{
++          zRankArgs = sqlite3Fts5MallocZero(&rc, 1 + p - pArgs);
++          if( zRankArgs ) memcpy(zRankArgs, pArgs, p-pArgs);
++        }
 +      }
-+      allShared |= pX->sharedMask;
 +    }
++  }
 +
-+    /* Get shared locks at the system level, if necessary */
-+    if( rc==SQLITE_OK ){
-+      if( (allShared & mask)==0 ){
-+        rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n);
-+      }else{
-+        rc = SQLITE_OK;
-+      }
++  if( rc!=SQLITE_OK ){
++    sqlite3_free(zRank);
++    assert( zRankArgs==0 );
++  }else{
++    *pzRank = zRank;
++    *pzRankArgs = zRankArgs;
++  }
++  return rc;
++}
++
++static int sqlite3Fts5ConfigSetValue(
++  Fts5Config *pConfig, 
++  const char *zKey, 
++  sqlite3_value *pVal,
++  int *pbBadkey
++){
++  int rc = SQLITE_OK;
++
++  if( 0==sqlite3_stricmp(zKey, "pgsz") ){
++    int pgsz = 0;
++    if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
++      pgsz = sqlite3_value_int(pVal);
 +    }
- 
--  sqlite3_free(zTmpname);
--  pFile->pMethod = &winIoMethod;
--  pFile->pVfs = pVfs;
--  pFile->h = h;
--  if( isReadonly ){
--    pFile->ctrlFlags |= WINFILE_RDONLY;
--  }
--  if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
--    pFile->ctrlFlags |= WINFILE_PSOW;
--  }
--  pFile->lastErrno = NO_ERROR;
--  pFile->zPath = zName;
--#if SQLITE_MAX_MMAP_SIZE>0
--  pFile->hMap = NULL;
--  pFile->pMapRegion = 0;
--  pFile->mmapSize = 0;
--  pFile->mmapSizeActual = 0;
--  pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
--#endif
-+    /* Get the local shared locks */
++    if( pgsz<=0 || pgsz>FTS5_MAX_PAGE_SIZE ){
++      *pbBadkey = 1;
++    }else{
++      pConfig->pgsz = pgsz;
++    }
++  }
++
++  else if( 0==sqlite3_stricmp(zKey, "hashsize") ){
++    int nHashSize = -1;
++    if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
++      nHashSize = sqlite3_value_int(pVal);
++    }
++    if( nHashSize<=0 ){
++      *pbBadkey = 1;
++    }else{
++      pConfig->nHashSize = nHashSize;
++    }
++  }
++
++  else if( 0==sqlite3_stricmp(zKey, "automerge") ){
++    int nAutomerge = -1;
++    if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
++      nAutomerge = sqlite3_value_int(pVal);
++    }
++    if( nAutomerge<0 || nAutomerge>64 ){
++      *pbBadkey = 1;
++    }else{
++      if( nAutomerge==1 ) nAutomerge = FTS5_DEFAULT_AUTOMERGE;
++      pConfig->nAutomerge = nAutomerge;
++    }
++  }
++
++  else if( 0==sqlite3_stricmp(zKey, "usermerge") ){
++    int nUsermerge = -1;
++    if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
++      nUsermerge = sqlite3_value_int(pVal);
++    }
++    if( nUsermerge<2 || nUsermerge>16 ){
++      *pbBadkey = 1;
++    }else{
++      pConfig->nUsermerge = nUsermerge;
++    }
++  }
++
++  else if( 0==sqlite3_stricmp(zKey, "crisismerge") ){
++    int nCrisisMerge = -1;
++    if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
++      nCrisisMerge = sqlite3_value_int(pVal);
++    }
++    if( nCrisisMerge<0 ){
++      *pbBadkey = 1;
++    }else{
++      if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
++      pConfig->nCrisisMerge = nCrisisMerge;
++    }
++  }
++
++  else if( 0==sqlite3_stricmp(zKey, "rank") ){
++    const char *zIn = (const char*)sqlite3_value_text(pVal);
++    char *zRank;
++    char *zRankArgs;
++    rc = sqlite3Fts5ConfigParseRank(zIn, &zRank, &zRankArgs);
 +    if( rc==SQLITE_OK ){
-+      p->sharedMask |= mask;
++      sqlite3_free(pConfig->zRank);
++      sqlite3_free(pConfig->zRankArgs);
++      pConfig->zRank = zRank;
++      pConfig->zRankArgs = zRankArgs;
++    }else if( rc==SQLITE_ERROR ){
++      rc = SQLITE_OK;
++      *pbBadkey = 1;
 +    }
 +  }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;
++    *pbBadkey = 1;
++  }
++  return rc;
++}
++
++/*
++** Load the contents of the %_config table into memory.
++*/
++static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
++  const char *zSelect = "SELECT k, v FROM %Q.'%q_config'";
++  char *zSql;
++  sqlite3_stmt *p = 0;
++  int rc = SQLITE_OK;
++  int iVersion = 0;
++
++  /* Set default values */
++  pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
++  pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
++  pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE;
++  pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
++  pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;
++
++  zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName);
++  if( zSql ){
++    rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &p, 0);
++    sqlite3_free(zSql);
++  }
++
++  assert( rc==SQLITE_OK || p==0 );
++  if( rc==SQLITE_OK ){
++    while( SQLITE_ROW==sqlite3_step(p) ){
++      const char *zK = (const char*)sqlite3_column_text(p, 0);
++      sqlite3_value *pVal = sqlite3_column_value(p, 1);
++      if( 0==sqlite3_stricmp(zK, "version") ){
++        iVersion = sqlite3_value_int(pVal);
++      }else{
++        int bDummy = 0;
++        sqlite3Fts5ConfigSetValue(pConfig, zK, pVal, &bDummy);
 +      }
 +    }
- 
--  OpenCounter(+1);
-+    /* Get the exclusive locks at the system level.  Then if successful
-+    ** also mark the local connection as being locked.
-+    */
-+    if( rc==SQLITE_OK ){
-+      rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n);
-+      if( rc==SQLITE_OK ){
-+        assert( (p->sharedMask & mask)==0 );
-+        p->exclMask |= mask;
-+      }
++    rc = sqlite3_finalize(p);
++  }
++  
++  if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION ){
++    rc = SQLITE_ERROR;
++    if( pConfig->pzErrmsg ){
++      assert( 0==*pConfig->pzErrmsg );
++      *pConfig->pzErrmsg = sqlite3_mprintf(
++          "invalid fts5 file format (found %d, expected %d) - run 'rebuild'",
++          iVersion, FTS5_CURRENT_VERSION
++      );
 +    }
 +  }
-+  sqlite3_mutex_leave(pShmNode->mutex);
-+  OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n",
-+           osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask,
-+           sqlite3ErrName(rc)));
-   return rc;
- }
- 
- /*
--** Delete the named file.
-+** Implement a memory barrier or memory fence on shared memory.
- **
--** Note that Windows does not allow a file to be deleted if some other
--** process has it open.  Sometimes a virus scanner or indexing program
--** will open a journal file shortly after it is created in order to do
--** whatever it does.  While this other process is holding the
--** file open, we will be unable to delete it.  To work around this
--** problem, we delay 100 milliseconds and try to delete again.  Up
--** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
--** up and returning an error.
-+** All loads and stores begun before the barrier must complete before
-+** any load or store begun after the barrier.
- */
--static int winDelete(
--  sqlite3_vfs *pVfs,          /* Not used on win32 */
--  const char *zFilename,      /* Name of file to delete */
--  int syncDir                 /* Not used on win32 */
-+static void winShmBarrier(
-+  sqlite3_file *fd          /* Database holding the shared memory */
- ){
--  int cnt = 0;
--  int rc;
--  DWORD attr;
--  DWORD lastErrno = 0;
--  void *zConverted;
--  UNUSED_PARAMETER(pVfs);
--  UNUSED_PARAMETER(syncDir);
-+  UNUSED_PARAMETER(fd);
-+  /* MemoryBarrier(); // does not work -- do not know why not */
-+  winShmEnterMutex();
-+  winShmLeaveMutex();
-+}
- 
--  SimulateIOError(return SQLITE_IOERR_DELETE);
--  OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
-+/*
-+** This function is called to obtain a pointer to region iRegion of the
-+** shared-memory associated with the database file fd. Shared-memory regions
-+** are numbered starting from zero. Each shared-memory region is szRegion
-+** bytes in size.
-+**
-+** If an error occurs, an error code is returned and *pp is set to NULL.
-+**
-+** Otherwise, if the isWrite parameter is 0 and the requested shared-memory
-+** region has not been allocated (by any client, including one running in a
-+** separate process), then *pp is set to NULL and SQLITE_OK returned. If
-+** isWrite is non-zero and the requested shared-memory region has not yet
-+** been allocated, it is allocated by this function.
-+**
-+** If the shared-memory region has already been allocated or is allocated by
-+** this call as described above, then it is mapped into this processes
-+** address space (if it is not already), *pp is set to point to the mapped
-+** memory and SQLITE_OK returned.
-+*/
-+static int winShmMap(
-+  sqlite3_file *fd,               /* Handle open on database file */
-+  int iRegion,                    /* Region to retrieve */
-+  int szRegion,                   /* Size of regions */
-+  int isWrite,                    /* True to extend file if necessary */
-+  void volatile **pp              /* OUT: Mapped memory */
-+){
-+  winFile *pDbFd = (winFile*)fd;
-+  winShm *pShm = pDbFd->pShm;
-+  winShmNode *pShmNode;
-+  int rc = SQLITE_OK;
- 
--  zConverted = winConvertFromUtf8Filename(zFilename);
--  if( zConverted==0 ){
--    OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
--    return SQLITE_IOERR_NOMEM;
-+  if( !pShm ){
-+    rc = winOpenSharedMemory(pDbFd);
-+    if( rc!=SQLITE_OK ) return rc;
-+    pShm = pDbFd->pShm;
-   }
--  if( osIsNT() ){
--    do {
--#if SQLITE_OS_WINRT
--      WIN32_FILE_ATTRIBUTE_DATA sAttrData;
--      memset(&sAttrData, 0, sizeof(sAttrData));
--      if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
--                                  &sAttrData) ){
--        attr = sAttrData.dwFileAttributes;
--      }else{
--        lastErrno = osGetLastError();
--        if( lastErrno==ERROR_FILE_NOT_FOUND
--         || lastErrno==ERROR_PATH_NOT_FOUND ){
--          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
--        }else{
--          rc = SQLITE_ERROR;
--        }
--        break;
-+  pShmNode = pShm->pShmNode;
 +
-+  sqlite3_mutex_enter(pShmNode->mutex);
-+  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
++  if( rc==SQLITE_OK ){
++    pConfig->iCookie = iCookie;
++  }
++  return rc;
++}
++
++/*
++** 2014 May 31
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++*/
++
++
++
++/* #include "fts5Int.h" */
++/* #include "fts5parse.h" */
++
++/*
++** All token types in the generated fts5parse.h file are greater than 0.
++*/
++#define FTS5_EOF 0
++
++#define FTS5_LARGEST_INT64  (0xffffffff|(((i64)0x7fffffff)<<32))
++
++typedef struct Fts5ExprTerm Fts5ExprTerm;
++
++/*
++** Functions generated by lemon from fts5parse.y.
++*/
++static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(u64));
++static void sqlite3Fts5ParserFree(void*, void (*freeProc)(void*));
++static void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*);
++#ifndef NDEBUG
++/* #include <stdio.h> */
++static void sqlite3Fts5ParserTrace(FILE*, char*);
++#endif
++
 +
-+  if( pShmNode->nRegion<=iRegion ){
-+    struct ShmRegion *apNew;           /* New aRegion[] array */
-+    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
-+    sqlite3_int64 sz;                  /* Current size of wal-index file */
++struct Fts5Expr {
++  Fts5Index *pIndex;
++  Fts5Config *pConfig;
++  Fts5ExprNode *pRoot;
++  int bDesc;                      /* Iterate in descending rowid order */
++  int nPhrase;                    /* Number of phrases in expression */
++  Fts5ExprPhrase **apExprPhrase;  /* Pointers to phrase objects */
++};
 +
-+    pShmNode->szRegion = szRegion;
++/*
++** eType:
++**   Expression node type. Always one of:
++**
++**       FTS5_AND                 (nChild, apChild valid)
++**       FTS5_OR                  (nChild, apChild valid)
++**       FTS5_NOT                 (nChild, apChild valid)
++**       FTS5_STRING              (pNear valid)
++**       FTS5_TERM                (pNear valid)
++*/
++struct Fts5ExprNode {
++  int eType;                      /* Node type */
++  int bEof;                       /* True at EOF */
++  int bNomatch;                   /* True if entry is not a match */
 +
-+    /* The requested region is not mapped into this processes address space.
-+    ** Check to see if it has been allocated (i.e. if the wal-index file is
-+    ** large enough to contain the requested region).
-+    */
-+    rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
-+    if( rc!=SQLITE_OK ){
-+      rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
-+                       "winShmMap1", pDbFd->zPath);
-+      goto shmpage_out;
-+    }
++  /* Next method for this node. */
++  int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64);
 +
-+    if( sz<nByte ){
-+      /* The requested memory region does not exist. If isWrite is set to
-+      ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
-+      **
-+      ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
-+      ** the requested memory region.
-+      */
-+      if( !isWrite ) goto shmpage_out;
-+      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
-+      if( rc!=SQLITE_OK ){
-+        rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
-+                         "winShmMap2", pDbFd->zPath);
-+        goto shmpage_out;
-       }
-+    }
++  i64 iRowid;                     /* Current rowid */
++  Fts5ExprNearset *pNear;         /* For FTS5_STRING - cluster of phrases */
 +
-+    /* Map the requested memory region into this processes address space. */
-+    apNew = (struct ShmRegion *)sqlite3_realloc64(
-+        pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
-+    );
-+    if( !apNew ){
-+      rc = SQLITE_IOERR_NOMEM;
-+      goto shmpage_out;
-+    }
-+    pShmNode->aRegion = apNew;
++  /* Child nodes. For a NOT node, this array always contains 2 entries. For 
++  ** AND or OR nodes, it contains 2 or more entries.  */
++  int nChild;                     /* Number of child nodes */
++  Fts5ExprNode *apChild[1];       /* Array of child nodes */
++};
 +
-+    while( pShmNode->nRegion<=iRegion ){
-+      HANDLE hMap = NULL;         /* file-mapping handle */
-+      void *pMap = 0;             /* Mapped memory region */
++#define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING)
 +
-+#if SQLITE_OS_WINRT
-+      hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
-+          NULL, PAGE_READWRITE, nByte, NULL
-+      );
-+#elif defined(SQLITE_WIN32_HAS_WIDE)
-+      hMap = osCreateFileMappingW(pShmNode->hFile.h,
-+          NULL, PAGE_READWRITE, 0, nByte, NULL
-+      );
-+#elif defined(SQLITE_WIN32_HAS_ANSI)
-+      hMap = osCreateFileMappingA(pShmNode->hFile.h,
-+          NULL, PAGE_READWRITE, 0, nByte, NULL
-+      );
-+#endif
-+      OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n",
-+               osGetCurrentProcessId(), pShmNode->nRegion, nByte,
-+               hMap ? "ok" : "failed"));
-+      if( hMap ){
-+        int iOffset = pShmNode->nRegion*szRegion;
-+        int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
-+#if SQLITE_OS_WINRT
-+        pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
-+            iOffset - iOffsetShift, szRegion + iOffsetShift
-+        );
- #else
--      attr = osGetFileAttributesW(zConverted);
-+        pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
-+            0, iOffset - iOffsetShift, szRegion + iOffsetShift
-+        );
- #endif
--      if ( attr==INVALID_FILE_ATTRIBUTES ){
--        lastErrno = osGetLastError();
--        if( lastErrno==ERROR_FILE_NOT_FOUND
--         || lastErrno==ERROR_PATH_NOT_FOUND ){
--          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
--        }else{
--          rc = SQLITE_ERROR;
--        }
--        break;
--      }
--      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
--        rc = SQLITE_ERROR; /* Files only. */
--        break;
--      }
--      if ( osDeleteFileW(zConverted) ){
--        rc = SQLITE_OK; /* Deleted OK. */
--        break;
--      }
--      if ( !winRetryIoerr(&cnt, &lastErrno) ){
--        rc = SQLITE_ERROR; /* No more retries. */
--        break;
--      }
--    } while(1);
--  }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    do {
--      attr = osGetFileAttributesA(zConverted);
--      if ( attr==INVALID_FILE_ATTRIBUTES ){
--        lastErrno = osGetLastError();
--        if( lastErrno==ERROR_FILE_NOT_FOUND
--         || lastErrno==ERROR_PATH_NOT_FOUND ){
--          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
--        }else{
--          rc = SQLITE_ERROR;
--        }
--        break;
--      }
--      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
--        rc = SQLITE_ERROR; /* Files only. */
--        break;
--      }
--      if ( osDeleteFileA(zConverted) ){
--        rc = SQLITE_OK; /* Deleted OK. */
--        break;
-+        OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n",
-+                 osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
-+                 szRegion, pMap ? "ok" : "failed"));
-       }
--      if ( !winRetryIoerr(&cnt, &lastErrno) ){
--        rc = SQLITE_ERROR; /* No more retries. */
--        break;
-+      if( !pMap ){
-+        pShmNode->lastErrno = osGetLastError();
-+        rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
-+                         "winShmMap3", pDbFd->zPath);
-+        if( hMap ) osCloseHandle(hMap);
-+        goto shmpage_out;
-       }
--    } while(1);
++/*
++** Invoke the xNext method of an Fts5ExprNode object. This macro should be
++** used as if it has the same signature as the xNext() methods themselves.
++*/
++#define fts5ExprNodeNext(a,b,c,d) (b)->xNext((a), (b), (c), (d))
 +
-+      pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
-+      pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
-+      pShmNode->nRegion++;
-+    }
-   }
--#endif
--  if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
--    rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
-+
-+shmpage_out:
-+  if( pShmNode->nRegion>iRegion ){
-+    int iOffset = iRegion*szRegion;
-+    int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
-+    char *p = (char *)pShmNode->aRegion[iRegion].pMap;
-+    *pp = (void *)&p[iOffsetShift];
-   }else{
--    winLogIoerr(cnt, __LINE__);
-+    *pp = 0;
-   }
--  sqlite3_free(zConverted);
--  OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
-+  sqlite3_mutex_leave(pShmNode->mutex);
-   return rc;
- }
- 
-+#else
-+# define winShmMap     0
-+# define winShmLock    0
-+# define winShmBarrier 0
-+# define winShmUnmap   0
-+#endif /* #ifndef SQLITE_OMIT_WAL */
++/*
++** An instance of the following structure represents a single search term
++** or term prefix.
++*/
++struct Fts5ExprTerm {
++  int bPrefix;                    /* True for a prefix term */
++  char *zTerm;                    /* nul-terminated term */
++  Fts5IndexIter *pIter;           /* Iterator for this term */
++  Fts5ExprTerm *pSynonym;         /* Pointer to first in list of synonyms */
++};
 +
- /*
--** Check the existence and status of a file.
-+** Cleans up the mapped region of the specified file, if any.
- */
--static int winAccess(
--  sqlite3_vfs *pVfs,         /* Not used on win32 */
--  const char *zFilename,     /* Name of file to check */
--  int flags,                 /* Type of test to make on this file */
--  int *pResOut               /* OUT: Result */
--){
--  DWORD attr;
--  int rc = 0;
--  DWORD lastErrno = 0;
--  void *zConverted;
--  UNUSED_PARAMETER(pVfs);
--
--  SimulateIOError( return SQLITE_IOERR_ACCESS; );
--  OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
--           zFilename, flags, pResOut));
--
--  zConverted = winConvertFromUtf8Filename(zFilename);
--  if( zConverted==0 ){
--    OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
--    return SQLITE_IOERR_NOMEM;
--  }
--  if( osIsNT() ){
--    int cnt = 0;
--    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
--    memset(&sAttrData, 0, sizeof(sAttrData));
--    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
--                             GetFileExInfoStandard,
--                             &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
--    if( rc ){
--      /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
--      ** as if it does not exist.
--      */
--      if(    flags==SQLITE_ACCESS_EXISTS
--          && sAttrData.nFileSizeHigh==0
--          && sAttrData.nFileSizeLow==0 ){
--        attr = INVALID_FILE_ATTRIBUTES;
--      }else{
--        attr = sAttrData.dwFileAttributes;
--      }
--    }else{
--      winLogIoerr(cnt, __LINE__);
--      if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
--        sqlite3_free(zConverted);
--        return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
--                           zFilename);
--      }else{
--        attr = INVALID_FILE_ATTRIBUTES;
--      }
-+#if SQLITE_MAX_MMAP_SIZE>0
-+static int winUnmapfile(winFile *pFile){
-+  assert( pFile!=0 );
-+  OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
-+           "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n",
-+           osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
-+           pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax));
-+  if( pFile->pMapRegion ){
-+    if( !osUnmapViewOfFile(pFile->pMapRegion) ){
-+      pFile->lastErrno = osGetLastError();
-+      OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
-+               "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
-+               pFile->pMapRegion));
-+      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
-+                         "winUnmapfile1", pFile->zPath);
-     }
-+    pFile->pMapRegion = 0;
-+    pFile->mmapSize = 0;
-+    pFile->mmapSizeActual = 0;
-   }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    attr = osGetFileAttributesA((char*)zConverted);
--  }
--#endif
--  sqlite3_free(zConverted);
--  switch( flags ){
--    case SQLITE_ACCESS_READ:
--    case SQLITE_ACCESS_EXISTS:
--      rc = attr!=INVALID_FILE_ATTRIBUTES;
--      break;
--    case SQLITE_ACCESS_READWRITE:
--      rc = attr!=INVALID_FILE_ATTRIBUTES &&
--             (attr & FILE_ATTRIBUTE_READONLY)==0;
--      break;
--    default:
--      assert(!"Invalid flags argument");
-+  if( pFile->hMap!=NULL ){
-+    if( !osCloseHandle(pFile->hMap) ){
-+      pFile->lastErrno = osGetLastError();
-+      OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
-+               osGetCurrentProcessId(), pFile, pFile->hMap));
-+      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
-+                         "winUnmapfile2", pFile->zPath);
-+    }
-+    pFile->hMap = NULL;
-   }
--  *pResOut = rc;
--  OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
--           zFilename, pResOut, *pResOut));
-+  OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
-+           osGetCurrentProcessId(), pFile));
-   return SQLITE_OK;
- }
- 
- /*
--** Returns non-zero if the specified path name starts with a drive letter
--** followed by a colon character.
-+** Memory map or remap the file opened by file-descriptor pFd (if the file
-+** is already mapped, the existing mapping is replaced by the new). Or, if
-+** there already exists a mapping for this file, and there are still
-+** outstanding xFetch() references to it, this function is a no-op.
-+**
-+** If parameter nByte is non-negative, then it is the requested size of
-+** the mapping to create. Otherwise, if nByte is less than zero, then the
-+** requested size is the size of the file on disk. The actual size of the
-+** created mapping is either the requested size or the value configured
-+** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller.
-+**
-+** SQLITE_OK is returned if no error occurs (even if the mapping is not
-+** recreated as a result of outstanding references) or an SQLite error
-+** code otherwise.
- */
--static BOOL winIsDriveLetterAndColon(
--  const char *zPathname
--){
--  return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );
--}
-+static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
-+  sqlite3_int64 nMap = nByte;
-+  int rc;
- 
--/*
--** Returns non-zero if the specified path name should be used verbatim.  If
--** non-zero is returned from this function, the calling function must simply
--** use the provided path name verbatim -OR- resolve it into a full path name
--** using the GetFullPathName Win32 API function (if available).
--*/
--static BOOL winIsVerbatimPathname(
--  const char *zPathname
--){
--  /*
--  ** If the path name starts with a forward slash or a backslash, it is either
--  ** a legal UNC name, a volume relative path, or an absolute path name in the
--  ** "Unix" format on Windows.  There is no easy way to differentiate between
--  ** the final two cases; therefore, we return the safer return value of TRUE
--  ** so that callers of this function will simply use it verbatim.
--  */
--  if ( winIsDirSep(zPathname[0]) ){
--    return TRUE;
-+  assert( nMap>=0 || pFd->nFetchOut==0 );
-+  OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n",
-+           osGetCurrentProcessId(), pFd, nByte));
++/*
++** A phrase. One or more terms that must appear in a contiguous sequence
++** within a document for it to match.
++*/
++struct Fts5ExprPhrase {
++  Fts5ExprNode *pNode;            /* FTS5_STRING node this phrase is part of */
++  Fts5Buffer poslist;             /* Current position list */
++  int nTerm;                      /* Number of entries in aTerm[] */
++  Fts5ExprTerm aTerm[1];          /* Terms that make up this phrase */
++};
 +
-+  if( pFd->nFetchOut>0 ) return SQLITE_OK;
++/*
++** One or more phrases that must appear within a certain token distance of
++** each other within each matching document.
++*/
++struct Fts5ExprNearset {
++  int nNear;                      /* NEAR parameter */
++  Fts5Colset *pColset;            /* Columns to search (NULL -> all columns) */
++  int nPhrase;                    /* Number of entries in aPhrase[] array */
++  Fts5ExprPhrase *apPhrase[1];    /* Array of phrase pointers */
++};
 +
-+  if( nMap<0 ){
-+    rc = winFileSize((sqlite3_file*)pFd, &nMap);
-+    if( rc ){
-+      OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n",
-+               osGetCurrentProcessId(), pFd));
-+      return SQLITE_IOERR_FSTAT;
-+    }
++
++/*
++** Parse context.
++*/
++struct Fts5Parse {
++  Fts5Config *pConfig;
++  char *zErr;
++  int rc;
++  int nPhrase;                    /* Size of apPhrase array */
++  Fts5ExprPhrase **apPhrase;      /* Array of all phrases */
++  Fts5ExprNode *pExpr;            /* Result of a successful parse */
++};
++
++static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){
++  va_list ap;
++  va_start(ap, zFmt);
++  if( pParse->rc==SQLITE_OK ){
++    pParse->zErr = sqlite3_vmprintf(zFmt, ap);
++    pParse->rc = SQLITE_ERROR;
 +  }
-+  if( nMap>pFd->mmapSizeMax ){
-+    nMap = pFd->mmapSizeMax;
-   }
-+  nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1);
- 
--  /*
--  ** If the path name starts with a letter and a colon it is either a volume
--  ** relative path or an absolute path.  Callers of this function must not
--  ** attempt to treat it as a relative path name (i.e. they should simply use
--  ** it verbatim).
--  */
--  if ( winIsDriveLetterAndColon(zPathname) ){
--    return TRUE;
-+  if( nMap==0 && pFd->mmapSize>0 ){
-+    winUnmapfile(pFd);
-+  }
-+  if( nMap!=pFd->mmapSize ){
-+    void *pNew = 0;
-+    DWORD protect = PAGE_READONLY;
-+    DWORD flags = FILE_MAP_READ;
-+
-+    winUnmapfile(pFd);
-+    if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){
-+      protect = PAGE_READWRITE;
-+      flags |= FILE_MAP_WRITE;
-+    }
-+#if SQLITE_OS_WINRT
-+    pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL);
-+#elif defined(SQLITE_WIN32_HAS_WIDE)
-+    pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect,
-+                                (DWORD)((nMap>>32) & 0xffffffff),
-+                                (DWORD)(nMap & 0xffffffff), NULL);
-+#elif defined(SQLITE_WIN32_HAS_ANSI)
-+    pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
-+                                (DWORD)((nMap>>32) & 0xffffffff),
-+                                (DWORD)(nMap & 0xffffffff), NULL);
-+#endif
-+    if( pFd->hMap==NULL ){
-+      pFd->lastErrno = osGetLastError();
-+      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
-+                       "winMapfile1", pFd->zPath);
-+      /* Log the error, but continue normal operation using xRead/xWrite */
-+      OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n",
-+               osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
-+      return SQLITE_OK;
-+    }
-+    assert( (nMap % winSysInfo.dwPageSize)==0 );
-+    assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
-+#if SQLITE_OS_WINRT
-+    pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
-+#else
-+    pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
-+#endif
-+    if( pNew==NULL ){
-+      osCloseHandle(pFd->hMap);
-+      pFd->hMap = NULL;
-+      pFd->lastErrno = osGetLastError();
-+      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
-+                       "winMapfile2", pFd->zPath);
-+      /* Log the error, but continue normal operation using xRead/xWrite */
-+      OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n",
-+               osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
-+      return SQLITE_OK;
-+    }
-+    pFd->pMapRegion = pNew;
-+    pFd->mmapSize = nMap;
-+    pFd->mmapSizeActual = nMap;
-   }
- 
--  /*
--  ** If we get to this point, the path name should almost certainly be a purely
--  ** relative one (i.e. not a UNC name, not absolute, and not volume relative).
--  */
--  return FALSE;
-+  OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
-+           osGetCurrentProcessId(), pFd));
-+  return SQLITE_OK;
- }
-+#endif /* SQLITE_MAX_MMAP_SIZE>0 */
- 
- /*
--** Turn a relative pathname into a full pathname.  Write the full
--** pathname into zOut[].  zOut[] will be at least pVfs->mxPathname
--** bytes in size.
-+** If possible, return a pointer to a mapping of file fd starting at offset
-+** iOff. The mapping must be valid for at least nAmt bytes.
-+**
-+** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
-+** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
-+** Finally, if an error does occur, return an SQLite error code. The final
-+** value of *pp is undefined in this case.
-+**
-+** If this function does return a pointer, the caller must eventually
-+** release the reference by calling winUnfetch().
- */
--static int winFullPathname(
--  sqlite3_vfs *pVfs,            /* Pointer to vfs object */
--  const char *zRelative,        /* Possibly relative input path */
--  int nFull,                    /* Size of output buffer in bytes */
--  char *zFull                   /* Output buffer */
--){
-+static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  winFile *pFd = (winFile*)fd;   /* The underlying database file */
-+#endif
-+  *pp = 0;
- 
--#if defined(__CYGWIN__)
--  SimulateIOError( return SQLITE_ERROR );
--  UNUSED_PARAMETER(nFull);
--  assert( nFull>=pVfs->mxPathname );
--  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
--    /*
--    ** NOTE: We are dealing with a relative path name and the data
--    **       directory has been set.  Therefore, use it as the basis
--    **       for converting the relative path name to an absolute
--    **       one by prepending the data directory and a slash.
--    */
--    char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
--    if( !zOut ){
--      return SQLITE_IOERR_NOMEM;
--    }
--    if( cygwin_conv_path(
--            (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
--            CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){
--      sqlite3_free(zOut);
--      return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
--                         "winFullPathname1", zRelative);
--    }else{
--      char *zUtf8 = winConvertToUtf8Filename(zOut);
--      if( !zUtf8 ){
--        sqlite3_free(zOut);
--        return SQLITE_IOERR_NOMEM;
-+  OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n",
-+           osGetCurrentProcessId(), fd, iOff, nAmt, pp));
++  va_end(ap);
++}
 +
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  if( pFd->mmapSizeMax>0 ){
-+    if( pFd->pMapRegion==0 ){
-+      int rc = winMapfile(pFd, -1);
-+      if( rc!=SQLITE_OK ){
-+        OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n",
-+                 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
-+        return rc;
-       }
--      sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
--                       sqlite3_data_directory, winGetDirSep(), zUtf8);
--      sqlite3_free(zUtf8);
--      sqlite3_free(zOut);
--    }
--  }else{
--    char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
--    if( !zOut ){
--      return SQLITE_IOERR_NOMEM;
-     }
--    if( cygwin_conv_path(
--            (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
--            zRelative, zOut, pVfs->mxPathname+1)<0 ){
--      sqlite3_free(zOut);
--      return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
--                         "winFullPathname2", zRelative);
--    }else{
--      char *zUtf8 = winConvertToUtf8Filename(zOut);
--      if( !zUtf8 ){
--        sqlite3_free(zOut);
--        return SQLITE_IOERR_NOMEM;
--      }
--      sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
--      sqlite3_free(zUtf8);
--      sqlite3_free(zOut);
-+    if( pFd->mmapSize >= iOff+nAmt ){
-+      *pp = &((u8 *)pFd->pMapRegion)[iOff];
-+      pFd->nFetchOut++;
-     }
-   }
--  return SQLITE_OK;
- #endif
- 
--#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
--  SimulateIOError( return SQLITE_ERROR );
--  /* WinCE has no concept of a relative pathname, or so I am told. */
--  /* WinRT has no way to convert a relative path to an absolute one. */
--  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
--    /*
--    ** NOTE: We are dealing with a relative path name and the data
--    **       directory has been set.  Therefore, use it as the basis
--    **       for converting the relative path name to an absolute
--    **       one by prepending the data directory and a backslash.
--    */
--    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
--                     sqlite3_data_directory, winGetDirSep(), zRelative);
-+  OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n",
-+           osGetCurrentProcessId(), fd, pp, *pp));
-+  return SQLITE_OK;
++static int fts5ExprIsspace(char t){
++  return t==' ' || t=='\t' || t=='\n' || t=='\r';
 +}
 +
 +/*
-+** If the third argument is non-NULL, then this function releases a
-+** reference obtained by an earlier call to winFetch(). The second
-+** argument passed to this function must be the same as the corresponding
-+** argument that was passed to the winFetch() invocation.
-+**
-+** Or, if the third argument is NULL, then this function is being called
-+** to inform the VFS layer that, according to POSIX, any existing mapping
-+** may now be invalid and should be unmapped.
++** Read the first token from the nul-terminated string at *pz.
 +*/
-+static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  winFile *pFd = (winFile*)fd;   /* The underlying database file */
++static int fts5ExprGetToken(
++  Fts5Parse *pParse, 
++  const char **pz,                /* IN/OUT: Pointer into buffer */
++  Fts5Token *pToken
++){
++  const char *z = *pz;
++  int tok;
++
++  /* Skip past any whitespace */
++  while( fts5ExprIsspace(*z) ) z++;
++
++  pToken->p = z;
++  pToken->n = 1;
++  switch( *z ){
++    case '(':  tok = FTS5_LP;    break;
++    case ')':  tok = FTS5_RP;    break;
++    case '{':  tok = FTS5_LCP;   break;
++    case '}':  tok = FTS5_RCP;   break;
++    case ':':  tok = FTS5_COLON; break;
++    case ',':  tok = FTS5_COMMA; break;
++    case '+':  tok = FTS5_PLUS;  break;
++    case '*':  tok = FTS5_STAR;  break;
++    case '-':  tok = FTS5_MINUS; break;
++    case '\0': tok = FTS5_EOF;   break;
++
++    case '"': {
++      const char *z2;
++      tok = FTS5_STRING;
++
++      for(z2=&z[1]; 1; z2++){
++        if( z2[0]=='"' ){
++          z2++;
++          if( z2[0]!='"' ) break;
++        }
++        if( z2[0]=='\0' ){
++          sqlite3Fts5ParseError(pParse, "unterminated string");
++          return FTS5_EOF;
++        }
++      }
++      pToken->n = (z2 - z);
++      break;
++    }
 +
-+  /* If p==0 (unmap the entire file) then there must be no outstanding
-+  ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
-+  ** then there must be at least one outstanding.  */
-+  assert( (p==0)==(pFd->nFetchOut==0) );
++    default: {
++      const char *z2;
++      if( sqlite3Fts5IsBareword(z[0])==0 ){
++        sqlite3Fts5ParseError(pParse, "fts5: syntax error near \"%.1s\"", z);
++        return FTS5_EOF;
++      }
++      tok = FTS5_STRING;
++      for(z2=&z[1]; sqlite3Fts5IsBareword(*z2); z2++);
++      pToken->n = (z2 - z);
++      if( pToken->n==2 && memcmp(pToken->p, "OR", 2)==0 )  tok = FTS5_OR;
++      if( pToken->n==3 && memcmp(pToken->p, "NOT", 3)==0 ) tok = FTS5_NOT;
++      if( pToken->n==3 && memcmp(pToken->p, "AND", 3)==0 ) tok = FTS5_AND;
++      break;
++    }
++  }
 +
-+  /* If p!=0, it must match the iOff value. */
-+  assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
++  *pz = &pToken->p[pToken->n];
++  return tok;
++}
 +
-+  OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n",
-+           osGetCurrentProcessId(), pFd, iOff, p));
++static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc((int)t); }
++static void fts5ParseFree(void *p){ sqlite3_free(p); }
 +
-+  if( p ){
-+    pFd->nFetchOut--;
-   }else{
--    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
-+    /* FIXME:  If Windows truly always prevents truncating or deleting a
-+    ** file while a mapping is held, then the following winUnmapfile() call
-+    ** is unnecessary can be omitted - potentially improving
-+    ** performance.  */
-+    winUnmapfile(pFd);
-   }
--  return SQLITE_OK;
++static int sqlite3Fts5ExprNew(
++  Fts5Config *pConfig,            /* FTS5 Configuration */
++  int iCol,
++  const char *zExpr,              /* Expression text */
++  Fts5Expr **ppNew, 
++  char **pzErr
++){
++  Fts5Parse sParse;
++  Fts5Token token;
++  const char *z = zExpr;
++  int t;                          /* Next token type */
++  void *pEngine;
++  Fts5Expr *pNew;
++
++  *ppNew = 0;
++  *pzErr = 0;
++  memset(&sParse, 0, sizeof(sParse));
++  pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc);
++  if( pEngine==0 ){ return SQLITE_NOMEM; }
++  sParse.pConfig = pConfig;
 +
-+  assert( pFd->nFetchOut>=0 );
- #endif
- 
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
--  DWORD nByte;
--  void *zConverted;
--  char *zOut;
-+  OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n",
-+           osGetCurrentProcessId(), fd));
-+  return SQLITE_OK;
++  do {
++    t = fts5ExprGetToken(&sParse, &z, &token);
++    sqlite3Fts5Parser(pEngine, t, token, &sParse);
++  }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
++  sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
++
++  /* If the LHS of the MATCH expression was a user column, apply the
++  ** implicit column-filter.  */
++  if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){
++    int n = sizeof(Fts5Colset);
++    Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
++    if( pColset ){
++      pColset->nCol = 1;
++      pColset->aiCol[0] = iCol;
++      sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset);
++    }
++  }
++
++  assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 );
++  if( sParse.rc==SQLITE_OK ){
++    *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
++    if( pNew==0 ){
++      sParse.rc = SQLITE_NOMEM;
++      sqlite3Fts5ParseNodeFree(sParse.pExpr);
++    }else{
++      if( !sParse.pExpr ){
++        const int nByte = sizeof(Fts5ExprNode);
++        pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte);
++        if( pNew->pRoot ){
++          pNew->pRoot->bEof = 1;
++        }
++      }else{
++        pNew->pRoot = sParse.pExpr;
++      }
++      pNew->pIndex = 0;
++      pNew->pConfig = pConfig;
++      pNew->apExprPhrase = sParse.apPhrase;
++      pNew->nPhrase = sParse.nPhrase;
++      sParse.apPhrase = 0;
++    }
++  }else{
++    sqlite3Fts5ParseNodeFree(sParse.pExpr);
++  }
++
++  sqlite3_free(sParse.apPhrase);
++  *pzErr = sParse.zErr;
++  return sParse.rc;
 +}
- 
--  /* If this path name begins with "/X:", where "X" is any alphabetic
--  ** character, discard the initial "/" from the pathname.
--  */
--  if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
--    zRelative++;
--  }
-+/*
-+** Here ends the implementation of all sqlite3_file methods.
-+**
-+********************** End sqlite3_file Methods *******************************
-+******************************************************************************/
- 
--  /* It's odd to simulate an io-error here, but really this is just
--  ** using the io-error infrastructure to test that SQLite handles this
--  ** function failing. This function could fail if, for example, the
--  ** current working directory has been unlinked.
--  */
--  SimulateIOError( return SQLITE_ERROR );
--  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
--    /*
--    ** NOTE: We are dealing with a relative path name and the data
--    **       directory has been set.  Therefore, use it as the basis
--    **       for converting the relative path name to an absolute
--    **       one by prepending the data directory and a backslash.
--    */
--    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
--                     sqlite3_data_directory, winGetDirSep(), zRelative);
--    return SQLITE_OK;
--  }
--  zConverted = winConvertFromUtf8Filename(zRelative);
--  if( zConverted==0 ){
--    return SQLITE_IOERR_NOMEM;
--  }
++
 +/*
-+** This vector defines all the methods that can operate on an
-+** sqlite3_file for win32.
++** Free the expression node object passed as the only argument.
 +*/
-+static const sqlite3_io_methods winIoMethod = {
-+  3,                              /* iVersion */
-+  winClose,                       /* xClose */
-+  winRead,                        /* xRead */
-+  winWrite,                       /* xWrite */
-+  winTruncate,                    /* xTruncate */
-+  winSync,                        /* xSync */
-+  winFileSize,                    /* xFileSize */
-+  winLock,                        /* xLock */
-+  winUnlock,                      /* xUnlock */
-+  winCheckReservedLock,           /* xCheckReservedLock */
-+  winFileControl,                 /* xFileControl */
-+  winSectorSize,                  /* xSectorSize */
-+  winDeviceCharacteristics,       /* xDeviceCharacteristics */
-+  winShmMap,                      /* xShmMap */
-+  winShmLock,                     /* xShmLock */
-+  winShmBarrier,                  /* xShmBarrier */
-+  winShmUnmap,                    /* xShmUnmap */
-+  winFetch,                       /* xFetch */
-+  winUnfetch                      /* xUnfetch */
-+};
++static void sqlite3Fts5ParseNodeFree(Fts5ExprNode *p){
++  if( p ){
++    int i;
++    for(i=0; i<p->nChild; i++){
++      sqlite3Fts5ParseNodeFree(p->apChild[i]);
++    }
++    sqlite3Fts5ParseNearsetFree(p->pNear);
++    sqlite3_free(p);
++  }
++}
 +
-+/****************************************************************************
-+**************************** sqlite3_vfs methods ****************************
-+**
-+** This division contains the implementation of methods on the
-+** sqlite3_vfs object.
++/*
++** Free the expression object passed as the only argument.
 +*/
++static void sqlite3Fts5ExprFree(Fts5Expr *p){
++  if( p ){
++    sqlite3Fts5ParseNodeFree(p->pRoot);
++    sqlite3_free(p->apExprPhrase);
++    sqlite3_free(p);
++  }
++}
 +
-+#if defined(__CYGWIN__)
 +/*
-+** Convert a filename from whatever the underlying operating system
-+** supports for filenames into UTF-8.  Space to hold the result is
-+** obtained from malloc and must be freed by the calling function.
++** Argument pTerm must be a synonym iterator. Return the current rowid
++** that it points to.
 +*/
-+static char *winConvertToUtf8Filename(const void *zFilename){
-+  char *zConverted = 0;
-   if( osIsNT() ){
--    LPWSTR zTemp;
--    nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
--    if( nByte==0 ){
--      sqlite3_free(zConverted);
--      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
--                         "winFullPathname1", zRelative);
--    }
--    nByte += 3;
--    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
--    if( zTemp==0 ){
--      sqlite3_free(zConverted);
--      return SQLITE_IOERR_NOMEM;
--    }
--    nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
--    if( nByte==0 ){
--      sqlite3_free(zConverted);
--      sqlite3_free(zTemp);
--      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
--                         "winFullPathname2", zRelative);
--    }
--    sqlite3_free(zConverted);
--    zOut = winUnicodeToUtf8(zTemp);
--    sqlite3_free(zTemp);
-+    zConverted = winUnicodeToUtf8(zFilename);
-   }
- #ifdef SQLITE_WIN32_HAS_ANSI
-   else{
--    char *zTemp;
--    nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
--    if( nByte==0 ){
--      sqlite3_free(zConverted);
--      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
--                         "winFullPathname3", zRelative);
--    }
--    nByte += 3;
--    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
--    if( zTemp==0 ){
--      sqlite3_free(zConverted);
--      return SQLITE_IOERR_NOMEM;
--    }
--    nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
--    if( nByte==0 ){
--      sqlite3_free(zConverted);
--      sqlite3_free(zTemp);
--      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
--                         "winFullPathname4", zRelative);
--    }
--    sqlite3_free(zConverted);
--    zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
--    sqlite3_free(zTemp);
--  }
--#endif
--  if( zOut ){
--    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut);
--    sqlite3_free(zOut);
--    return SQLITE_OK;
--  }else{
--    return SQLITE_IOERR_NOMEM;
-+    zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
-   }
- #endif
-+  /* caller will handle out of memory */
-+  return zConverted;
- }
-+#endif
- 
--#ifndef SQLITE_OMIT_LOAD_EXTENSION
- /*
--** Interfaces for opening a shared library, finding entry points
--** within the shared library, and closing the shared library.
-+** Convert a UTF-8 filename into whatever form the underlying
-+** operating system wants filenames in.  Space to hold the result
-+** is obtained from malloc and must be freed by the calling
-+** function.
- */
--static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
--  HANDLE h;
--#if defined(__CYGWIN__)
--  int nFull = pVfs->mxPathname+1;
--  char *zFull = sqlite3MallocZero( nFull );
-+static void *winConvertFromUtf8Filename(const char *zFilename){
-   void *zConverted = 0;
--  if( zFull==0 ){
--    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
--    return 0;
--  }
--  if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
--    sqlite3_free(zFull);
--    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
--    return 0;
--  }
--  zConverted = winConvertFromUtf8Filename(zFull);
--  sqlite3_free(zFull);
--#else
--  void *zConverted = winConvertFromUtf8Filename(zFilename);
--  UNUSED_PARAMETER(pVfs);
--#endif
--  if( zConverted==0 ){
--    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
--    return 0;
--  }
-   if( osIsNT() ){
--#if SQLITE_OS_WINRT
--    h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
--#else
--    h = osLoadLibraryW((LPCWSTR)zConverted);
--#endif
-+    zConverted = winUtf8ToUnicode(zFilename);
-   }
- #ifdef SQLITE_WIN32_HAS_ANSI
-   else{
--    h = osLoadLibraryA((char*)zConverted);
-+    zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
-   }
- #endif
--  OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h));
--  sqlite3_free(zConverted);
--  return (void*)h;
--}
--static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
--  UNUSED_PARAMETER(pVfs);
--  winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut);
--}
--static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
--  FARPROC proc;
--  UNUSED_PARAMETER(pVfs);
--  proc = osGetProcAddressA((HANDLE)pH, zSym);
--  OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n",
--           (void*)pH, zSym, (void*)proc));
--  return (void(*)(void))proc;
--}
--static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
--  UNUSED_PARAMETER(pVfs);
--  osFreeLibrary((HANDLE)pHandle);
--  OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle));
-+  /* caller will handle out of memory */
-+  return zConverted;
- }
--#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
--  #define winDlOpen  0
--  #define winDlError 0
--  #define winDlSym   0
--  #define winDlClose 0
--#endif
--
- 
- /*
--** Write up to nBuf bytes of randomness into zBuf.
-+** This function returns non-zero if the specified UTF-8 string buffer
-+** ends with a directory separator character or one was successfully
-+** added to it.
- */
--static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
--  int n = 0;
--  UNUSED_PARAMETER(pVfs);
--#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
--  n = nBuf;
--  memset(zBuf, 0, nBuf);
--#else
--  if( sizeof(SYSTEMTIME)<=nBuf-n ){
--    SYSTEMTIME x;
--    osGetSystemTime(&x);
--    memcpy(&zBuf[n], &x, sizeof(x));
--    n += sizeof(x);
--  }
--  if( sizeof(DWORD)<=nBuf-n ){
--    DWORD pid = osGetCurrentProcessId();
--    memcpy(&zBuf[n], &pid, sizeof(pid));
--    n += sizeof(pid);
-+static int winMakeEndInDirSep(int nBuf, char *zBuf){
-+  if( zBuf ){
-+    int nLen = sqlite3Strlen30(zBuf);
-+    if( nLen>0 ){
-+      if( winIsDirSep(zBuf[nLen-1]) ){
-+        return 1;
-+      }else if( nLen+1<nBuf ){
-+        zBuf[nLen] = winGetDirSep();
-+        zBuf[nLen+1] = '\0';
-+        return 1;
++static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
++  i64 iRet = 0;
++  int bRetValid = 0;
++  Fts5ExprTerm *p;
++
++  assert( pTerm->pSynonym );
++  assert( bDesc==0 || bDesc==1 );
++  for(p=pTerm; p; p=p->pSynonym){
++    if( 0==sqlite3Fts5IterEof(p->pIter) ){
++      i64 iRowid = p->pIter->iRowid;
++      if( bRetValid==0 || (bDesc!=(iRowid<iRet)) ){
++        iRet = iRowid;
++        bRetValid = 1;
 +      }
 +    }
-   }
--#if SQLITE_OS_WINRT
--  if( sizeof(ULONGLONG)<=nBuf-n ){
--    ULONGLONG cnt = osGetTickCount64();
--    memcpy(&zBuf[n], &cnt, sizeof(cnt));
--    n += sizeof(cnt);
-+  return 0;
++  }
++
++  if( pbEof && bRetValid==0 ) *pbEof = 1;
++  return iRet;
 +}
 +
 +/*
-+** Create a temporary file name and store the resulting pointer into pzBuf.
-+** The pointer returned in pzBuf must be freed via sqlite3_free().
++** Argument pTerm must be a synonym iterator.
 +*/
-+static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
-+  static char zChars[] =
-+    "abcdefghijklmnopqrstuvwxyz"
-+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-+    "0123456789";
-+  size_t i, j;
-+  int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
-+  int nMax, nBuf, nDir, nLen;
-+  char *zBuf;
++static int fts5ExprSynonymList(
++  Fts5ExprTerm *pTerm, 
++  i64 iRowid,
++  Fts5Buffer *pBuf,               /* Use this buffer for space if required */
++  u8 **pa, int *pn
++){
++  Fts5PoslistReader aStatic[4];
++  Fts5PoslistReader *aIter = aStatic;
++  int nIter = 0;
++  int nAlloc = 4;
++  int rc = SQLITE_OK;
++  Fts5ExprTerm *p;
++
++  assert( pTerm->pSynonym );
++  for(p=pTerm; p; p=p->pSynonym){
++    Fts5IndexIter *pIter = p->pIter;
++    if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){
++      if( pIter->nData==0 ) continue;
++      if( nIter==nAlloc ){
++        int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
++        Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
++        if( aNew==0 ){
++          rc = SQLITE_NOMEM;
++          goto synonym_poslist_out;
++        }
++        memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter);
++        nAlloc = nAlloc*2;
++        if( aIter!=aStatic ) sqlite3_free(aIter);
++        aIter = aNew;
++      }
++      sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &aIter[nIter]);
++      assert( aIter[nIter].bEof==0 );
++      nIter++;
++    }
++  }
 +
-+  /* 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( nIter==1 ){
++    *pa = (u8*)aIter[0].a;
++    *pn = aIter[0].n;
++  }else{
++    Fts5PoslistWriter writer = {0};
++    i64 iPrev = -1;
++    fts5BufferZero(pBuf);
++    while( 1 ){
++      int i;
++      i64 iMin = FTS5_LARGEST_INT64;
++      for(i=0; i<nIter; i++){
++        if( aIter[i].bEof==0 ){
++          if( aIter[i].iPos==iPrev ){
++            if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) continue;
++          }
++          if( aIter[i].iPos<iMin ){
++            iMin = aIter[i].iPos;
++          }
++        }
++      }
++      if( iMin==FTS5_LARGEST_INT64 || rc!=SQLITE_OK ) break;
++      rc = sqlite3Fts5PoslistWriterAppend(pBuf, &writer, iMin);
++      iPrev = iMin;
++    }
++    if( rc==SQLITE_OK ){
++      *pa = pBuf->p;
++      *pn = pBuf->n;
++    }
++  }
 +
-+  /* Allocate a temporary buffer to store the fully qualified file
-+  ** name for the temporary file.  If this fails, we cannot continue.
-+  */
-+  nMax = pVfs->mxPathname; nBuf = nMax + 2;
-+  zBuf = sqlite3MallocZero( nBuf );
-+  if( !zBuf ){
-+    OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-+    return SQLITE_IOERR_NOMEM;
-   }
--#else
--  if( sizeof(DWORD)<=nBuf-n ){
--    DWORD cnt = osGetTickCount();
--    memcpy(&zBuf[n], &cnt, sizeof(cnt));
--    n += sizeof(cnt);
++ synonym_poslist_out:
++  if( aIter!=aStatic ) sqlite3_free(aIter);
++  return rc;
++}
 +
-+  /* Figure out the effective temporary directory.  First, check if one
-+  ** has been explicitly set by the application; otherwise, use the one
-+  ** configured by the operating system.
-+  */
-+  nDir = nMax - (nPre + 15);
-+  assert( nDir>0 );
-+  if( sqlite3_temp_directory ){
-+    int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
-+    if( nDirLen>0 ){
-+      if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
-+        nDirLen++;
-+      }
-+      if( nDirLen>nDir ){
-+        sqlite3_free(zBuf);
-+        OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
-+        return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
++
++/*
++** All individual term iterators in pPhrase are guaranteed to be valid and
++** pointing to the same rowid when this function is called. This function 
++** checks if the current rowid really is a match, and if so populates
++** the pPhrase->poslist buffer accordingly. Output parameter *pbMatch
++** is set to true if this is really a match, or false otherwise.
++**
++** SQLITE_OK is returned if an error occurs, or an SQLite error code 
++** otherwise. It is not considered an error code if the current rowid is 
++** not a match.
++*/
++static int fts5ExprPhraseIsMatch(
++  Fts5ExprNode *pNode,            /* Node pPhrase belongs to */
++  Fts5ExprPhrase *pPhrase,        /* Phrase object to initialize */
++  int *pbMatch                    /* OUT: Set to true if really a match */
++){
++  Fts5PoslistWriter writer = {0};
++  Fts5PoslistReader aStatic[4];
++  Fts5PoslistReader *aIter = aStatic;
++  int i;
++  int rc = SQLITE_OK;
++  
++  fts5BufferZero(&pPhrase->poslist);
++
++  /* If the aStatic[] array is not large enough, allocate a large array
++  ** using sqlite3_malloc(). This approach could be improved upon. */
++  if( pPhrase->nTerm>ArraySize(aStatic) ){
++    int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
++    aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
++    if( !aIter ) return SQLITE_NOMEM;
++  }
++  memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm);
++
++  /* Initialize a term iterator for each term in the phrase */
++  for(i=0; i<pPhrase->nTerm; i++){
++    Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
++    int n = 0;
++    int bFlag = 0;
++    u8 *a = 0;
++    if( pTerm->pSynonym ){
++      Fts5Buffer buf = {0, 0, 0};
++      rc = fts5ExprSynonymList(pTerm, pNode->iRowid, &buf, &a, &n);
++      if( rc ){
++        sqlite3_free(a);
++        goto ismatch_out;
 +      }
-+      sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
++      if( a==buf.p ) bFlag = 1;
++    }else{
++      a = (u8*)pTerm->pIter->pData;
++      n = pTerm->pIter->nData;
 +    }
-   }
--#endif
--  if( sizeof(LARGE_INTEGER)<=nBuf-n ){
--    LARGE_INTEGER i;
--    osQueryPerformanceCounter(&i);
--    memcpy(&zBuf[n], &i, sizeof(i));
--    n += sizeof(i);
-+#if defined(__CYGWIN__)
-+  else{
-+    static const char *azDirs[] = {
-+       0, /* getenv("SQLITE_TMPDIR") */
-+       0, /* getenv("TMPDIR") */
-+       0, /* getenv("TMP") */
-+       0, /* getenv("TEMP") */
-+       0, /* getenv("USERPROFILE") */
-+       "/var/tmp",
-+       "/usr/tmp",
-+       "/tmp",
-+       ".",
-+       0        /* List terminator */
-+    };
-+    unsigned int i;
-+    const char *zDir = 0;
-+
-+    if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
-+    if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
-+    if( !azDirs[2] ) azDirs[2] = getenv("TMP");
-+    if( !azDirs[3] ) azDirs[3] = getenv("TEMP");
-+    if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE");
-+    for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
-+      void *zConverted;
-+      if( zDir==0 ) continue;
-+      /* If the path starts with a drive letter followed by the colon
-+      ** character, assume it is already a native Win32 path; otherwise,
-+      ** it must be converted to a native Win32 path via the Cygwin API
-+      ** prior to using it.
-+      */
-+      if( winIsDriveLetterAndColon(zDir) ){
-+        zConverted = winConvertFromUtf8Filename(zDir);
-+        if( !zConverted ){
-+          sqlite3_free(zBuf);
-+          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-+          return SQLITE_IOERR_NOMEM;
-+        }
-+        if( winIsDir(zConverted) ){
-+          sqlite3_snprintf(nMax, zBuf, "%s", zDir);
-+          sqlite3_free(zConverted);
-+          break;
-+        }
-+        sqlite3_free(zConverted);
-+      }else{
-+        zConverted = sqlite3MallocZero( nMax+1 );
-+        if( !zConverted ){
-+          sqlite3_free(zBuf);
-+          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-+          return SQLITE_IOERR_NOMEM;
-+        }
-+        if( cygwin_conv_path(
-+                osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
-+                zConverted, nMax+1)<0 ){
-+          sqlite3_free(zConverted);
-+          sqlite3_free(zBuf);
-+          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
-+          return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
-+                             "winGetTempname2", zDir);
-+        }
-+        if( winIsDir(zConverted) ){
-+          /* At this point, we know the candidate directory exists and should
-+          ** be used.  However, we may need to convert the string containing
-+          ** its name into UTF-8 (i.e. if it is UTF-16 right now).
-+          */
-+          char *zUtf8 = winConvertToUtf8Filename(zConverted);
-+          if( !zUtf8 ){
-+            sqlite3_free(zConverted);
-+            sqlite3_free(zBuf);
-+            OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-+            return SQLITE_IOERR_NOMEM;
++    sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
++    aIter[i].bFlag = (u8)bFlag;
++    if( aIter[i].bEof ) goto ismatch_out;
++  }
++
++  while( 1 ){
++    int bMatch;
++    i64 iPos = aIter[0].iPos;
++    do {
++      bMatch = 1;
++      for(i=0; i<pPhrase->nTerm; i++){
++        Fts5PoslistReader *pPos = &aIter[i];
++        i64 iAdj = iPos + i;
++        if( pPos->iPos!=iAdj ){
++          bMatch = 0;
++          while( pPos->iPos<iAdj ){
++            if( sqlite3Fts5PoslistReaderNext(pPos) ) goto ismatch_out;
 +          }
-+          sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
-+          sqlite3_free(zUtf8);
-+          sqlite3_free(zConverted);
-+          break;
++          if( pPos->iPos>iAdj ) iPos = pPos->iPos-i;
 +        }
-+        sqlite3_free(zConverted);
 +      }
++    }while( bMatch==0 );
++
++    /* Append position iPos to the output */
++    rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
++    if( rc!=SQLITE_OK ) goto ismatch_out;
++
++    for(i=0; i<pPhrase->nTerm; i++){
++      if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
 +    }
-   }
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
--  if( sizeof(UUID)<=nBuf-n ){
--    UUID id;
--    memset(&id, 0, sizeof(UUID));
--    osUuidCreate(&id);
--    memcpy(zBuf, &id, sizeof(UUID));
--    n += sizeof(UUID);
-+#elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
-+  else if( osIsNT() ){
-+    char *zMulti;
-+    LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) );
-+    if( !zWidePath ){
-+      sqlite3_free(zBuf);
-+      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-+      return SQLITE_IOERR_NOMEM;
-+    }
-+    if( osGetTempPathW(nMax, zWidePath)==0 ){
-+      sqlite3_free(zWidePath);
-+      sqlite3_free(zBuf);
-+      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
-+      return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
-+                         "winGetTempname2", 0);
-+    }
-+    zMulti = winUnicodeToUtf8(zWidePath);
-+    if( zMulti ){
-+      sqlite3_snprintf(nMax, zBuf, "%s", zMulti);
-+      sqlite3_free(zMulti);
-+      sqlite3_free(zWidePath);
-+    }else{
-+      sqlite3_free(zWidePath);
-+      sqlite3_free(zBuf);
-+      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-+      return SQLITE_IOERR_NOMEM;
++  }
++
++ ismatch_out:
++  *pbMatch = (pPhrase->poslist.n>0);
++  for(i=0; i<pPhrase->nTerm; i++){
++    if( aIter[i].bFlag ) sqlite3_free((u8*)aIter[i].a);
++  }
++  if( aIter!=aStatic ) sqlite3_free(aIter);
++  return rc;
++}
++
++typedef struct Fts5LookaheadReader Fts5LookaheadReader;
++struct Fts5LookaheadReader {
++  const u8 *a;                    /* Buffer containing position list */
++  int n;                          /* Size of buffer a[] in bytes */
++  int i;                          /* Current offset in position list */
++  i64 iPos;                       /* Current position */
++  i64 iLookahead;                 /* Next position */
++};
++
++#define FTS5_LOOKAHEAD_EOF (((i64)1) << 62)
++
++static int fts5LookaheadReaderNext(Fts5LookaheadReader *p){
++  p->iPos = p->iLookahead;
++  if( sqlite3Fts5PoslistNext64(p->a, p->n, &p->i, &p->iLookahead) ){
++    p->iLookahead = FTS5_LOOKAHEAD_EOF;
++  }
++  return (p->iPos==FTS5_LOOKAHEAD_EOF);
++}
++
++static int fts5LookaheadReaderInit(
++  const u8 *a, int n,             /* Buffer to read position list from */
++  Fts5LookaheadReader *p          /* Iterator object to initialize */
++){
++  memset(p, 0, sizeof(Fts5LookaheadReader));
++  p->a = a;
++  p->n = n;
++  fts5LookaheadReaderNext(p);
++  return fts5LookaheadReaderNext(p);
++}
++
++typedef struct Fts5NearTrimmer Fts5NearTrimmer;
++struct Fts5NearTrimmer {
++  Fts5LookaheadReader reader;     /* Input iterator */
++  Fts5PoslistWriter writer;       /* Writer context */
++  Fts5Buffer *pOut;               /* Output poslist */
++};
++
++/*
++** The near-set object passed as the first argument contains more than
++** one phrase. All phrases currently point to the same row. The
++** Fts5ExprPhrase.poslist buffers are populated accordingly. This function
++** tests if the current row contains instances of each phrase sufficiently
++** close together to meet the NEAR constraint. Non-zero is returned if it
++** does, or zero otherwise.
++**
++** If in/out parameter (*pRc) is set to other than SQLITE_OK when this
++** function is called, it is a no-op. Or, if an error (e.g. SQLITE_NOMEM)
++** occurs within this function (*pRc) is set accordingly before returning.
++** The return value is undefined in both these cases.
++** 
++** If no error occurs and non-zero (a match) is returned, the position-list
++** of each phrase object is edited to contain only those entries that
++** meet the constraint before returning.
++*/
++static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
++  Fts5NearTrimmer aStatic[4];
++  Fts5NearTrimmer *a = aStatic;
++  Fts5ExprPhrase **apPhrase = pNear->apPhrase;
++
++  int i;
++  int rc = *pRc;
++  int bMatch;
++
++  assert( pNear->nPhrase>1 );
++
++  /* If the aStatic[] array is not large enough, allocate a large array
++  ** using sqlite3_malloc(). This approach could be improved upon. */
++  if( pNear->nPhrase>ArraySize(aStatic) ){
++    int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
++    a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
++  }else{
++    memset(aStatic, 0, sizeof(aStatic));
++  }
++  if( rc!=SQLITE_OK ){
++    *pRc = rc;
++    return 0;
++  }
++
++  /* Initialize a lookahead iterator for each phrase. After passing the
++  ** buffer and buffer size to the lookaside-reader init function, zero
++  ** the phrase poslist buffer. The new poslist for the phrase (containing
++  ** the same entries as the original with some entries removed on account 
++  ** of the NEAR constraint) is written over the original even as it is
++  ** being read. This is safe as the entries for the new poslist are a
++  ** subset of the old, so it is not possible for data yet to be read to
++  ** be overwritten.  */
++  for(i=0; i<pNear->nPhrase; i++){
++    Fts5Buffer *pPoslist = &apPhrase[i]->poslist;
++    fts5LookaheadReaderInit(pPoslist->p, pPoslist->n, &a[i].reader);
++    pPoslist->n = 0;
++    a[i].pOut = pPoslist;
++  }
++
++  while( 1 ){
++    int iAdv;
++    i64 iMin;
++    i64 iMax;
++
++    /* This block advances the phrase iterators until they point to a set of
++    ** entries that together comprise a match.  */
++    iMax = a[0].reader.iPos;
++    do {
++      bMatch = 1;
++      for(i=0; i<pNear->nPhrase; i++){
++        Fts5LookaheadReader *pPos = &a[i].reader;
++        iMin = iMax - pNear->apPhrase[i]->nTerm - pNear->nNear;
++        if( pPos->iPos<iMin || pPos->iPos>iMax ){
++          bMatch = 0;
++          while( pPos->iPos<iMin ){
++            if( fts5LookaheadReaderNext(pPos) ) goto ismatch_out;
++          }
++          if( pPos->iPos>iMax ) iMax = pPos->iPos;
++        }
++      }
++    }while( bMatch==0 );
++
++    /* Add an entry to each output position list */
++    for(i=0; i<pNear->nPhrase; i++){
++      i64 iPos = a[i].reader.iPos;
++      Fts5PoslistWriter *pWriter = &a[i].writer;
++      if( a[i].pOut->n==0 || iPos!=pWriter->iPrev ){
++        sqlite3Fts5PoslistWriterAppend(a[i].pOut, pWriter, iPos);
++      }
 +    }
-   }
--  if( sizeof(UUID)<=nBuf-n ){
--    UUID id;
--    memset(&id, 0, sizeof(UUID));
--    osUuidCreateSequential(&id);
--    memcpy(zBuf, &id, sizeof(UUID));
--    n += sizeof(UUID);
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    char *zUtf8;
-+    char *zMbcsPath = sqlite3MallocZero( nMax );
-+    if( !zMbcsPath ){
-+      sqlite3_free(zBuf);
-+      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-+      return SQLITE_IOERR_NOMEM;
++
++    iAdv = 0;
++    iMin = a[0].reader.iLookahead;
++    for(i=0; i<pNear->nPhrase; i++){
++      if( a[i].reader.iLookahead < iMin ){
++        iMin = a[i].reader.iLookahead;
++        iAdv = i;
++      }
 +    }
-+    if( osGetTempPathA(nMax, zMbcsPath)==0 ){
-+      sqlite3_free(zBuf);
-+      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
-+      return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
-+                         "winGetTempname3", 0);
++    if( fts5LookaheadReaderNext(&a[iAdv].reader) ) goto ismatch_out;
++  }
++
++  ismatch_out: {
++    int bRet = a[0].pOut->n>0;
++    *pRc = rc;
++    if( a!=aStatic ) sqlite3_free(a);
++    return bRet;
++  }
++}
++
++/*
++** Advance iterator pIter until it points to a value equal to or laster
++** than the initial value of *piLast. If this means the iterator points
++** to a value laster than *piLast, update *piLast to the new lastest value.
++**
++** If the iterator reaches EOF, set *pbEof to true before returning. If
++** an error occurs, set *pRc to an error code. If either *pbEof or *pRc
++** are set, return a non-zero value. Otherwise, return zero.
++*/
++static int fts5ExprAdvanceto(
++  Fts5IndexIter *pIter,           /* Iterator to advance */
++  int bDesc,                      /* True if iterator is "rowid DESC" */
++  i64 *piLast,                    /* IN/OUT: Lastest rowid seen so far */
++  int *pRc,                       /* OUT: Error code */
++  int *pbEof                      /* OUT: Set to true if EOF */
++){
++  i64 iLast = *piLast;
++  i64 iRowid;
++
++  iRowid = pIter->iRowid;
++  if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){
++    int rc = sqlite3Fts5IterNextFrom(pIter, iLast);
++    if( rc || sqlite3Fts5IterEof(pIter) ){
++      *pRc = rc;
++      *pbEof = 1;
++      return 1;
 +    }
-+    zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
-+    if( zUtf8 ){
-+      sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
-+      sqlite3_free(zUtf8);
-+    }else{
-+      sqlite3_free(zBuf);
-+      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-+      return SQLITE_IOERR_NOMEM;
++    iRowid = pIter->iRowid;
++    assert( (bDesc==0 && iRowid>=iLast) || (bDesc==1 && iRowid<=iLast) );
++  }
++  *piLast = iRowid;
++
++  return 0;
++}
++
++static int fts5ExprSynonymAdvanceto(
++  Fts5ExprTerm *pTerm,            /* Term iterator to advance */
++  int bDesc,                      /* True if iterator is "rowid DESC" */
++  i64 *piLast,                    /* IN/OUT: Lastest rowid seen so far */
++  int *pRc                        /* OUT: Error code */
++){
++  int rc = SQLITE_OK;
++  i64 iLast = *piLast;
++  Fts5ExprTerm *p;
++  int bEof = 0;
++
++  for(p=pTerm; rc==SQLITE_OK && p; p=p->pSynonym){
++    if( sqlite3Fts5IterEof(p->pIter)==0 ){
++      i64 iRowid = p->pIter->iRowid;
++      if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){
++        rc = sqlite3Fts5IterNextFrom(p->pIter, iLast);
++      }
 +    }
-   }
--#endif
--#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
--  return n;
--}
--
--
--/*
--** Sleep for a little while.  Return the amount of time slept.
--*/
--static int winSleep(sqlite3_vfs *pVfs, int microsec){
--  sqlite3_win32_sleep((microsec+999)/1000);
--  UNUSED_PARAMETER(pVfs);
--  return ((microsec+999)/1000)*1000;
--}
--
--/*
--** The following variable, if set to a non-zero value, is interpreted as
--** the number of seconds since 1970 and is used to set the result of
--** sqlite3OsCurrentTime() during testing.
--*/
--#ifdef SQLITE_TEST
--SQLITE_API int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
--#endif
-+#endif /* SQLITE_WIN32_HAS_ANSI */
-+#endif /* !SQLITE_OS_WINRT */
- 
--/*
--** Find the current time (in Universal Coordinated Time).  Write into *piNow
--** the current time and date as a Julian Day number times 86_400_000.  In
--** other words, write into *piNow the number of milliseconds since the Julian
--** epoch of noon in Greenwich on November 24, 4714 B.C according to the
--** proleptic Gregorian calendar.
--**
--** On success, return SQLITE_OK.  Return SQLITE_ERROR if the time and date
--** cannot be found.
--*/
--static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
--  /* FILETIME structure is a 64-bit value representing the number of
--     100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
-+  /*
-+  ** Check to make sure the temporary directory ends with an appropriate
-+  ** separator.  If it does not and there is not enough space left to add
-+  ** one, fail.
-   */
--  FILETIME ft;
--  static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000;
--#ifdef SQLITE_TEST
--  static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
--#endif
--  /* 2^32 - to avoid use of LL and warnings in gcc */
--  static const sqlite3_int64 max32BitValue =
--      (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 +
--      (sqlite3_int64)294967296;
-+  if( !winMakeEndInDirSep(nDir+1, zBuf) ){
-+    sqlite3_free(zBuf);
-+    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
-+    return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0);
 +  }
- 
--#if SQLITE_OS_WINCE
--  SYSTEMTIME time;
--  osGetSystemTime(&time);
--  /* if SystemTimeToFileTime() fails, it returns zero. */
--  if (!osSystemTimeToFileTime(&time,&ft)){
--    return SQLITE_ERROR;
-+  /*
-+  ** Check that the output buffer is large enough for the temporary file
-+  ** name in the following format:
-+  **
-+  **   "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0"
-+  **
-+  ** If not, return SQLITE_ERROR.  The number 17 is used here in order to
-+  ** account for the space used by the 15 character random suffix and the
-+  ** two trailing NUL characters.  The final directory separator character
-+  ** has already added if it was not already present.
-+  */
-+  nLen = sqlite3Strlen30(zBuf);
-+  if( (nLen + nPre + 17) > nBuf ){
-+    sqlite3_free(zBuf);
-+    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
-+    return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0);
-   }
--#else
--  osGetSystemTimeAsFileTime( &ft );
--#endif
- 
--  *piNow = winFiletimeEpoch +
--            ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) +
--               (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
-+  sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
- 
--#ifdef SQLITE_TEST
--  if( sqlite3_current_time ){
--    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
-+  j = sqlite3Strlen30(zBuf);
-+  sqlite3_randomness(15, &zBuf[j]);
-+  for(i=0; i<15; i++, j++){
-+    zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-   }
--#endif
--  UNUSED_PARAMETER(pVfs);
-+  zBuf[j] = 0;
-+  zBuf[j+1] = 0;
-+  *pzBuf = zBuf;
 +
-+  OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf));
-   return SQLITE_OK;
- }
- 
- /*
--** Find the current time (in Universal Coordinated Time).  Write the
--** current time and date as a Julian Day number into *prNow and
--** return 0.  Return 1 if the time and date cannot be found.
-+** Return TRUE if the named file is really a directory.  Return false if
-+** it is something other than a directory, or if there is any kind of memory
-+** allocation failure.
- */
--static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
--  int rc;
--  sqlite3_int64 i;
--  rc = winCurrentTimeInt64(pVfs, &i);
--  if( !rc ){
--    *prNow = i/86400000.0;
--  }
--  return rc;
--}
-+static int winIsDir(const void *zConverted){
-+  DWORD attr;
-+  int rc = 0;
-+  DWORD lastErrno;
- 
--/*
--** The idea is that this function works like a combination of
--** GetLastError() and FormatMessage() on Windows (or errno and
--** strerror_r() on Unix). After an error is returned by an OS
--** function, SQLite calls this function with zBuf pointing to
--** a buffer of nBuf bytes. The OS layer should populate the
--** buffer with a nul-terminated UTF-8 encoded error message
--** describing the last IO error to have occurred within the calling
--** thread.
--**
--** If the error message is too large for the supplied buffer,
--** it should be truncated. The return value of xGetLastError
--** is zero if the error message fits in the buffer, or non-zero
--** otherwise (if the message was truncated). If non-zero is returned,
--** then it is not necessary to include the nul-terminator character
--** in the output buffer.
--**
--** Not supplying an error message will have no adverse effect
--** on SQLite. It is fine to have an implementation that never
--** returns an error message:
--**
--**   int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
--**     assert(zBuf[0]=='\0');
--**     return 0;
--**   }
--**
--** However if an error message is supplied, it will be incorporated
--** by sqlite into the error message available to the user using
--** sqlite3_errmsg(), possibly making IO errors easier to debug.
--*/
--static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
--  UNUSED_PARAMETER(pVfs);
--  return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf);
-+  if( osIsNT() ){
-+    int cnt = 0;
-+    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
-+    memset(&sAttrData, 0, sizeof(sAttrData));
-+    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
-+                             GetFileExInfoStandard,
-+                             &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
-+    if( !rc ){
-+      return 0; /* Invalid name? */
++  if( rc!=SQLITE_OK ){
++    *pRc = rc;
++    bEof = 1;
++  }else{
++    *piLast = fts5ExprSynonymRowid(pTerm, bDesc, &bEof);
++  }
++  return bEof;
++}
++
++
++static int fts5ExprNearTest(
++  int *pRc,
++  Fts5Expr *pExpr,                /* Expression that pNear is a part of */
++  Fts5ExprNode *pNode             /* The "NEAR" node (FTS5_STRING) */
++){
++  Fts5ExprNearset *pNear = pNode->pNear;
++  int rc = *pRc;
++
++  if( pExpr->pConfig->eDetail!=FTS5_DETAIL_FULL ){
++    Fts5ExprTerm *pTerm;
++    Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
++    pPhrase->poslist.n = 0;
++    for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
++      Fts5IndexIter *pIter = pTerm->pIter;
++      if( sqlite3Fts5IterEof(pIter)==0 ){
++        if( pIter->iRowid==pNode->iRowid && pIter->nData>0 ){
++          pPhrase->poslist.n = 1;
++        }
++      }
 +    }
-+    attr = sAttrData.dwFileAttributes;
-+#if SQLITE_OS_WINCE==0
++    return pPhrase->poslist.n;
 +  }else{
-+    attr = osGetFileAttributesA((char*)zConverted);
-+#endif
++    int i;
++
++    /* Check that each phrase in the nearset matches the current row.
++    ** Populate the pPhrase->poslist buffers at the same time. If any
++    ** phrase is not a match, break out of the loop early.  */
++    for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
++      Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
++      if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){
++        int bMatch = 0;
++        rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch);
++        if( bMatch==0 ) break;
++      }else{
++        Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
++        fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData);
++      }
++    }
++
++    *pRc = rc;
++    if( i==pNear->nPhrase && (i==1 || fts5ExprNearIsMatch(pRc, pNear)) ){
++      return 1;
++    }
++    return 0;
 +  }
-+  return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
- }
- 
- /*
--** Initialize and deinitialize the operating system interface.
-+** Open a file.
- */
--SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
--  static sqlite3_vfs winVfs = {
--    3,                   /* iVersion */
--    sizeof(winFile),     /* szOsFile */
--    SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
--    0,                   /* pNext */
--    "win32",             /* zName */
--    0,                   /* pAppData */
--    winOpen,             /* xOpen */
--    winDelete,           /* xDelete */
--    winAccess,           /* xAccess */
--    winFullPathname,     /* xFullPathname */
--    winDlOpen,           /* xDlOpen */
--    winDlError,          /* xDlError */
--    winDlSym,            /* xDlSym */
--    winDlClose,          /* xDlClose */
--    winRandomness,       /* xRandomness */
--    winSleep,            /* xSleep */
--    winCurrentTime,      /* xCurrentTime */
--    winGetLastError,     /* xGetLastError */
--    winCurrentTimeInt64, /* xCurrentTimeInt64 */
--    winSetSystemCall,    /* xSetSystemCall */
--    winGetSystemCall,    /* xGetSystemCall */
--    winNextSystemCall,   /* xNextSystemCall */
--  };
--#if defined(SQLITE_WIN32_HAS_WIDE)
--  static sqlite3_vfs winLongPathVfs = {
--    3,                   /* iVersion */
--    sizeof(winFile),     /* szOsFile */
--    SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
--    0,                   /* pNext */
--    "win32-longpath",    /* zName */
--    0,                   /* pAppData */
--    winOpen,             /* xOpen */
--    winDelete,           /* xDelete */
--    winAccess,           /* xAccess */
--    winFullPathname,     /* xFullPathname */
--    winDlOpen,           /* xDlOpen */
--    winDlError,          /* xDlError */
--    winDlSym,            /* xDlSym */
--    winDlClose,          /* xDlClose */
--    winRandomness,       /* xRandomness */
--    winSleep,            /* xSleep */
--    winCurrentTime,      /* xCurrentTime */
--    winGetLastError,     /* xGetLastError */
--    winCurrentTimeInt64, /* xCurrentTimeInt64 */
--    winSetSystemCall,    /* xSetSystemCall */
--    winGetSystemCall,    /* xGetSystemCall */
--    winNextSystemCall,   /* xNextSystemCall */
--  };
-+static int winOpen(
-+  sqlite3_vfs *pVfs,        /* Used to get maximum path name length */
-+  const char *zName,        /* Name of the file (UTF-8) */
-+  sqlite3_file *id,         /* Write the SQLite file handle here */
-+  int flags,                /* Open mode flags */
-+  int *pOutFlags            /* Status return flags */
-+){
-+  HANDLE h;
-+  DWORD lastErrno = 0;
-+  DWORD dwDesiredAccess;
-+  DWORD dwShareMode;
-+  DWORD dwCreationDisposition;
-+  DWORD dwFlagsAndAttributes = 0;
-+#if SQLITE_OS_WINCE
-+  int isTemp = 0;
- #endif
-+  winFile *pFile = (winFile*)id;
-+  void *zConverted;              /* Filename in OS encoding */
-+  const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
-+  int cnt = 0;
- 
--  /* Double-check that the aSyscall[] array has been constructed
--  ** correctly.  See ticket [bb3a86e890c8e96ab] */
--  assert( ArraySize(aSyscall)==80 );
-+  /* If argument zPath is a NULL pointer, this function is required to open
-+  ** a temporary file. Use this buffer to store the file name in.
-+  */
-+  char *zTmpname = 0; /* For temporary filename, if necessary. */
- 
--  /* get memory map allocation granularity */
--  memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
--#if SQLITE_OS_WINRT
--  osGetNativeSystemInfo(&winSysInfo);
--#else
--  osGetSystemInfo(&winSysInfo);
-+  int rc = SQLITE_OK;            /* Function Return Code */
-+#if !defined(NDEBUG) || SQLITE_OS_WINCE
-+  int eType = flags&0xFFFFFF00;  /* Type of file to open */
- #endif
--  assert( winSysInfo.dwAllocationGranularity>0 );
--  assert( winSysInfo.dwPageSize>0 );
- 
--  sqlite3_vfs_register(&winVfs, 1);
-+  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
-+  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
-+  int isCreate     = (flags & SQLITE_OPEN_CREATE);
-+  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
-+  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
- 
--#if defined(SQLITE_WIN32_HAS_WIDE)
--  sqlite3_vfs_register(&winLongPathVfs, 0);
-+#ifndef NDEBUG
-+  int isOpenJournal = (isCreate && (
-+        eType==SQLITE_OPEN_MASTER_JOURNAL
-+     || eType==SQLITE_OPEN_MAIN_JOURNAL
-+     || eType==SQLITE_OPEN_WAL
-+  ));
- #endif
- 
--  return SQLITE_OK;
--}
-+  OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n",
-+           zUtf8Name, id, flags, pOutFlags));
++}
 +
-+  /* Check the following statements are true:
-+  **
-+  **   (a) Exactly one of the READWRITE and READONLY flags must be set, and
-+  **   (b) if CREATE is set, then READWRITE must also be set, and
-+  **   (c) if EXCLUSIVE is set, then CREATE must also be set.
-+  **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
-+  */
-+  assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
-+  assert(isCreate==0 || isReadWrite);
-+  assert(isExclusive==0 || isCreate);
-+  assert(isDelete==0 || isCreate);
-+
-+  /* The main DB, main journal, WAL file and master journal are never
-+  ** automatically deleted. Nor are they ever temporary files.  */
-+  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
-+  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
-+  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
-+  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
-+
-+  /* Assert that the upper layer has set one of the "file-type" flags. */
-+  assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB
-+       || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
-+       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL
-+       || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
-+  );
 +
-+  assert( pFile!=0 );
-+  memset(pFile, 0, sizeof(winFile));
-+  pFile->h = INVALID_HANDLE_VALUE;
- 
--SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
- #if SQLITE_OS_WINRT
--  if( sleepObj!=NULL ){
--    osCloseHandle(sleepObj);
--    sleepObj = NULL;
-+  if( !zUtf8Name && !sqlite3_temp_directory ){
-+    sqlite3_log(SQLITE_ERROR,
-+        "sqlite3_temp_directory variable should be set for WinRT");
-   }
- #endif
--  return SQLITE_OK;
--}
--
--#endif /* SQLITE_OS_WIN */
--
--/************** End of os_win.c **********************************************/
--/************** Begin file bitvec.c ******************************************/
--/*
--** 2008 February 16
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
--**
--**    May you do good and not evil.
--**    May you find forgiveness for yourself and forgive others.
--**    May you share freely, never taking more than you give.
--**
--*************************************************************************
--** This file implements an object that represents a fixed-length
--** bitmap.  Bits are numbered starting with 1.
--**
--** A bitmap is used to record which pages of a database file have been
--** journalled during a transaction, or which pages have the "dont-write"
--** property.  Usually only a few pages are meet either condition.
--** So the bitmap is usually sparse and has low cardinality.
--** But sometimes (for example when during a DROP of a large table) most
--** or all of the pages in a database can get journalled.  In those cases, 
--** the bitmap becomes dense with high cardinality.  The algorithm needs 
--** to handle both cases well.
--**
--** The size of the bitmap is fixed when the object is created.
--**
--** All bits are clear when the bitmap is created.  Individual bits
--** may be set or cleared one at a time.
--**
--** Test operations are about 100 times more common that set operations.
--** Clear operations are exceedingly rare.  There are usually between
--** 5 and 500 set operations per Bitvec object, though the number of sets can
--** sometimes grow into tens of thousands or larger.  The size of the
--** Bitvec object is the number of pages in the database file at the
--** start of a transaction, and is thus usually less than a few thousand,
--** but can be as large as 2 billion for a really big database.
--*/
- 
--/* Size of the Bitvec structure in bytes. */
--#define BITVEC_SZ        512
-+  /* If the second argument to this function is NULL, generate a
-+  ** temporary file name to use
-+  */
-+  if( !zUtf8Name ){
-+    assert( isDelete && !isOpenJournal );
-+    rc = winGetTempname(pVfs, &zTmpname);
-+    if( rc!=SQLITE_OK ){
-+      OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
-+      return rc;
++/*
++** Initialize all term iterators in the pNear object. If any term is found
++** to match no documents at all, return immediately without initializing any
++** further iterators.
++**
++** If an error occurs, return an SQLite error code. Otherwise, return
++** SQLITE_OK. It is not considered an error if some term matches zero
++** documents.
++*/
++static int fts5ExprNearInitAll(
++  Fts5Expr *pExpr,
++  Fts5ExprNode *pNode
++){
++  Fts5ExprNearset *pNear = pNode->pNear;
++  int i;
++
++  assert( pNode->bNomatch==0 );
++  for(i=0; i<pNear->nPhrase; i++){
++    Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
++    if( pPhrase->nTerm==0 ){
++      pNode->bEof = 1;
++      return SQLITE_OK;
++    }else{
++      int j;
++      for(j=0; j<pPhrase->nTerm; j++){
++        Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
++        Fts5ExprTerm *p;
++        int bHit = 0;
++
++        for(p=pTerm; p; p=p->pSynonym){
++          int rc;
++          if( p->pIter ){
++            sqlite3Fts5IterClose(p->pIter);
++            p->pIter = 0;
++          }
++          rc = sqlite3Fts5IndexQuery(
++              pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
++              (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
++              (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
++              pNear->pColset,
++              &p->pIter
++          );
++          assert( (rc==SQLITE_OK)==(p->pIter!=0) );
++          if( rc!=SQLITE_OK ) return rc;
++          if( 0==sqlite3Fts5IterEof(p->pIter) ){
++            bHit = 1;
++          }
++        }
++
++        if( bHit==0 ){
++          pNode->bEof = 1;
++          return SQLITE_OK;
++        }
++      }
 +    }
-+    zUtf8Name = zTmpname;
 +  }
- 
--/* Round the union size down to the nearest pointer boundary, since that's how 
--** it will be aligned within the Bitvec struct. */
--#define BITVEC_USIZE     (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))
-+  /* Database filenames are double-zero terminated if they are not
-+  ** URIs with parameters.  Hence, they can always be passed into
-+  ** sqlite3_uri_parameter().
-+  */
-+  assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
-+       zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 );
- 
--/* Type of the array "element" for the bitmap representation. 
--** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. 
--** Setting this to the "natural word" size of your CPU may improve
--** performance. */
--#define BITVEC_TELEM     u8
--/* Size, in bits, of the bitmap element. */
--#define BITVEC_SZELEM    8
--/* Number of elements in a bitmap array. */
--#define BITVEC_NELEM     (BITVEC_USIZE/sizeof(BITVEC_TELEM))
--/* Number of bits in the bitmap array. */
--#define BITVEC_NBIT      (BITVEC_NELEM*BITVEC_SZELEM)
-+  /* Convert the filename to the system encoding. */
-+  zConverted = winConvertFromUtf8Filename(zUtf8Name);
-+  if( zConverted==0 ){
-+    sqlite3_free(zTmpname);
-+    OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
-+    return SQLITE_IOERR_NOMEM;
-+  }
- 
--/* Number of u32 values in hash table. */
--#define BITVEC_NINT      (BITVEC_USIZE/sizeof(u32))
--/* Maximum number of entries in hash table before 
--** sub-dividing and re-hashing. */
--#define BITVEC_MXHASH    (BITVEC_NINT/2)
--/* Hashing function for the aHash representation.
--** Empirical testing showed that the *37 multiplier 
--** (an arbitrary prime)in the hash function provided 
--** no fewer collisions than the no-op *1. */
--#define BITVEC_HASH(X)   (((X)*1)%BITVEC_NINT)
-+  if( winIsDir(zConverted) ){
-+    sqlite3_free(zConverted);
-+    sqlite3_free(zTmpname);
-+    OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name));
-+    return SQLITE_CANTOPEN_ISDIR;
-+  }
- 
--#define BITVEC_NPTR      (BITVEC_USIZE/sizeof(Bitvec *))
-+  if( isReadWrite ){
-+    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
-+  }else{
-+    dwDesiredAccess = GENERIC_READ;
-+  }
- 
-+  /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
-+  ** created. SQLite doesn't use it to indicate "exclusive access"
-+  ** as it is usually understood.
-+  */
-+  if( isExclusive ){
-+    /* Creates a new file, only if it does not already exist. */
-+    /* If the file exists, it fails. */
-+    dwCreationDisposition = CREATE_NEW;
-+  }else if( isCreate ){
-+    /* Open existing file, or create if it doesn't exist */
-+    dwCreationDisposition = OPEN_ALWAYS;
++
++  pNode->bEof = 0;
++  return SQLITE_OK;
++}
++
++/*
++** If pExpr is an ASC iterator, this function returns a value with the
++** same sign as:
++**
++**   (iLhs - iRhs)
++**
++** Otherwise, if this is a DESC iterator, the opposite is returned:
++**
++**   (iRhs - iLhs)
++*/
++static int fts5RowidCmp(
++  Fts5Expr *pExpr,
++  i64 iLhs,
++  i64 iRhs
++){
++  assert( pExpr->bDesc==0 || pExpr->bDesc==1 );
++  if( pExpr->bDesc==0 ){
++    if( iLhs<iRhs ) return -1;
++    return (iLhs > iRhs);
 +  }else{
-+    /* Opens a file, only if it exists. */
-+    dwCreationDisposition = OPEN_EXISTING;
++    if( iLhs>iRhs ) return -1;
++    return (iLhs < iRhs);
 +  }
- 
--/*
--** A bitmap is an instance of the following structure.
--**
--** This bitmap records the existence of zero or more bits
--** with values between 1 and iSize, inclusive.
--**
--** There are three possible representations of the bitmap.
--** If iSize<=BITVEC_NBIT, then Bitvec.u.aBitmap[] is a straight
--** bitmap.  The least significant bit is bit 1.
--**
--** If iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is
--** a hash table that will hold up to BITVEC_MXHASH distinct values.
--**
--** Otherwise, the value i is redirected into one of BITVEC_NPTR
--** sub-bitmaps pointed to by Bitvec.u.apSub[].  Each subbitmap
--** handles up to iDivisor separate values of i.  apSub[0] holds
--** values between 1 and iDivisor.  apSub[1] holds values between
--** iDivisor+1 and 2*iDivisor.  apSub[N] holds values between
--** N*iDivisor+1 and (N+1)*iDivisor.  Each subbitmap is normalized
--** to hold deal with values between 1 and iDivisor.
--*/
--struct Bitvec {
--  u32 iSize;      /* Maximum bit index.  Max iSize is 4,294,967,296. */
--  u32 nSet;       /* Number of bits that are set - only valid for aHash
--                  ** element.  Max is BITVEC_NINT.  For BITVEC_SZ of 512,
--                  ** this would be 125. */
--  u32 iDivisor;   /* Number of bits handled by each apSub[] entry. */
--                  /* Should >=0 for apSub element. */
--                  /* Max iDivisor is max(u32) / BITVEC_NPTR + 1.  */
--                  /* For a BITVEC_SZ of 512, this would be 34,359,739. */
--  union {
--    BITVEC_TELEM aBitmap[BITVEC_NELEM];    /* Bitmap representation */
--    u32 aHash[BITVEC_NINT];      /* Hash table representation */
--    Bitvec *apSub[BITVEC_NPTR];  /* Recursive representation */
--  } u;
--};
-+  dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
- 
--/*
--** Create a new bitmap object able to handle bits between 0 and iSize,
--** inclusive.  Return a pointer to the new object.  Return NULL if 
--** malloc fails.
--*/
--SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){
--  Bitvec *p;
--  assert( sizeof(*p)==BITVEC_SZ );
--  p = sqlite3MallocZero( sizeof(*p) );
--  if( p ){
--    p->iSize = iSize;
-+  if( isDelete ){
-+#if SQLITE_OS_WINCE
-+    dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
-+    isTemp = 1;
-+#else
-+    dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
-+                               | FILE_ATTRIBUTE_HIDDEN
-+                               | FILE_FLAG_DELETE_ON_CLOSE;
-+#endif
++}
++
++static void fts5ExprSetEof(Fts5ExprNode *pNode){
++  int i;
++  pNode->bEof = 1;
++  pNode->bNomatch = 0;
++  for(i=0; i<pNode->nChild; i++){
++    fts5ExprSetEof(pNode->apChild[i]);
++  }
++}
++
++static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){
++  if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
++    Fts5ExprNearset *pNear = pNode->pNear;
++    int i;
++    for(i=0; i<pNear->nPhrase; i++){
++      Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
++      pPhrase->poslist.n = 0;
++    }
 +  }else{
-+    dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
-   }
--  return p;
--}
-+  /* Reports from the internet are that performance is always
-+  ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
-+#if SQLITE_OS_WINCE
-+  dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
-+#endif
- 
--/*
--** Check to see if the i-th bit is set.  Return true or false.
--** If p is NULL (if the bitmap has not been created) or if
--** i is out of range, then return false.
--*/
--SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){
--  if( p==0 ) return 0;
--  if( i>p->iSize || i==0 ) return 0;
--  i--;
--  while( p->iDivisor ){
--    u32 bin = i/p->iDivisor;
--    i = i%p->iDivisor;
--    p = p->u.apSub[bin];
--    if (!p) {
--      return 0;
-+  if( osIsNT() ){
-+#if SQLITE_OS_WINRT
-+    CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
-+    extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+    extendedParameters.dwFileAttributes =
-+            dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK;
-+    extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK;
-+    extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
-+    extendedParameters.lpSecurityAttributes = NULL;
-+    extendedParameters.hTemplateFile = NULL;
-+    while( (h = osCreateFile2((LPCWSTR)zConverted,
-+                              dwDesiredAccess,
-+                              dwShareMode,
-+                              dwCreationDisposition,
-+                              &extendedParameters))==INVALID_HANDLE_VALUE &&
-+                              winRetryIoerr(&cnt, &lastErrno) ){
-+               /* Noop */
-     }
--  }
--  if( p->iSize<=BITVEC_NBIT ){
--    return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0;
--  } else{
--    u32 h = BITVEC_HASH(i++);
--    while( p->u.aHash[h] ){
--      if( p->u.aHash[h]==i ) return 1;
--      h = (h+1) % BITVEC_NINT;
-+#else
-+    while( (h = osCreateFileW((LPCWSTR)zConverted,
-+                              dwDesiredAccess,
-+                              dwShareMode, NULL,
-+                              dwCreationDisposition,
-+                              dwFlagsAndAttributes,
-+                              NULL))==INVALID_HANDLE_VALUE &&
-+                              winRetryIoerr(&cnt, &lastErrno) ){
-+               /* Noop */
-     }
--    return 0;
-+#endif
-   }
--}
--
--/*
--** Set the i-th bit.  Return 0 on success and an error code if
--** anything goes wrong.
--**
--** This routine might cause sub-bitmaps to be allocated.  Failing
--** to get the memory needed to hold the sub-bitmap is the only
--** that can go wrong with an insert, assuming p and i are valid.
--**
--** The calling function must ensure that p is a valid Bitvec object
--** and that the value for "i" is within range of the Bitvec object.
--** Otherwise the behavior is undefined.
--*/
--SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){
--  u32 h;
--  if( p==0 ) return SQLITE_OK;
--  assert( i>0 );
--  assert( i<=p->iSize );
--  i--;
--  while((p->iSize > BITVEC_NBIT) && p->iDivisor) {
--    u32 bin = i/p->iDivisor;
--    i = i%p->iDivisor;
--    if( p->u.apSub[bin]==0 ){
--      p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
--      if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    while( (h = osCreateFileA((LPCSTR)zConverted,
-+                              dwDesiredAccess,
-+                              dwShareMode, NULL,
-+                              dwCreationDisposition,
-+                              dwFlagsAndAttributes,
-+                              NULL))==INVALID_HANDLE_VALUE &&
-+                              winRetryIoerr(&cnt, &lastErrno) ){
-+               /* Noop */
-     }
--    p = p->u.apSub[bin];
-   }
--  if( p->iSize<=BITVEC_NBIT ){
--    p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1));
--    return SQLITE_OK;
--  }
--  h = BITVEC_HASH(i++);
--  /* if there wasn't a hash collision, and this doesn't */
--  /* completely fill the hash, then just add it without */
--  /* worring about sub-dividing and re-hashing. */
--  if( !p->u.aHash[h] ){
--    if (p->nSet<(BITVEC_NINT-1)) {
--      goto bitvec_set_end;
--    } else {
--      goto bitvec_set_rehash;
-+#endif
-+  winLogIoerr(cnt, __LINE__);
-+
-+  OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
-+           dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
-+
-+  if( h==INVALID_HANDLE_VALUE ){
-+    pFile->lastErrno = lastErrno;
-+    winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
-+    sqlite3_free(zConverted);
-+    sqlite3_free(zTmpname);
-+    if( isReadWrite && !isExclusive ){
-+      return winOpen(pVfs, zName, id,
-+         ((flags|SQLITE_OPEN_READONLY) &
-+                     ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
-+         pOutFlags);
-+    }else{
-+      return SQLITE_CANTOPEN_BKPT;
-     }
-   }
--  /* there was a collision, check to see if it's already */
--  /* in hash, if not, try to find a spot for it */
--  do {
--    if( p->u.aHash[h]==i ) return SQLITE_OK;
--    h++;
--    if( h>=BITVEC_NINT ) h = 0;
--  } while( p->u.aHash[h] );
--  /* we didn't find it in the hash.  h points to the first */
--  /* available free spot. check to see if this is going to */
--  /* make our hash too "full".  */
--bitvec_set_rehash:
--  if( p->nSet>=BITVEC_MXHASH ){
--    unsigned int j;
--    int rc;
--    u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
--    if( aiValues==0 ){
--      return SQLITE_NOMEM;
++    int i;
++    for(i=0; i<pNode->nChild; i++){
++      fts5ExprNodeZeroPoslist(pNode->apChild[i]);
++    }
++  }
++}
++
++
++
++/*
++** Compare the values currently indicated by the two nodes as follows:
++**
++**    res = (*p1) - (*p2)
++**
++** Nodes that point to values that come later in the iteration order are
++** considered to be larger. Nodes at EOF are the largest of all.
++**
++** This means that if the iteration order is ASC, then numerically larger
++** rowids are considered larger. Or if it is the default DESC, numerically
++** smaller rowids are larger.
++*/
++static int fts5NodeCompare(
++  Fts5Expr *pExpr,
++  Fts5ExprNode *p1, 
++  Fts5ExprNode *p2
++){
++  if( p2->bEof ) return -1;
++  if( p1->bEof ) return +1;
++  return fts5RowidCmp(pExpr, p1->iRowid, p2->iRowid);
++}
++
++/*
++** All individual term iterators in pNear are guaranteed to be valid when
++** this function is called. This function checks if all term iterators
++** point to the same rowid, and if not, advances them until they do.
++** If an EOF is reached before this happens, *pbEof is set to true before
++** returning.
++**
++** SQLITE_OK is returned if an error occurs, or an SQLite error code 
++** otherwise. It is not considered an error code if an iterator reaches
++** EOF.
++*/
++static int fts5ExprNodeTest_STRING(
++  Fts5Expr *pExpr,                /* Expression pPhrase belongs to */
++  Fts5ExprNode *pNode
++){
++  Fts5ExprNearset *pNear = pNode->pNear;
++  Fts5ExprPhrase *pLeft = pNear->apPhrase[0];
++  int rc = SQLITE_OK;
++  i64 iLast;                      /* Lastest rowid any iterator points to */
++  int i, j;                       /* Phrase and token index, respectively */
++  int bMatch;                     /* True if all terms are at the same rowid */
++  const int bDesc = pExpr->bDesc;
++
++  /* Check that this node should not be FTS5_TERM */
++  assert( pNear->nPhrase>1 
++       || pNear->apPhrase[0]->nTerm>1 
++       || pNear->apPhrase[0]->aTerm[0].pSynonym
++  );
++
++  /* Initialize iLast, the "lastest" rowid any iterator points to. If the
++  ** iterator skips through rowids in the default ascending order, this means
++  ** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it
++  ** means the minimum rowid.  */
++  if( pLeft->aTerm[0].pSynonym ){
++    iLast = fts5ExprSynonymRowid(&pLeft->aTerm[0], bDesc, 0);
++  }else{
++    iLast = pLeft->aTerm[0].pIter->iRowid;
++  }
++
++  do {
++    bMatch = 1;
++    for(i=0; i<pNear->nPhrase; i++){
++      Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
++      for(j=0; j<pPhrase->nTerm; j++){
++        Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
++        if( pTerm->pSynonym ){
++          i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0);
++          if( iRowid==iLast ) continue;
++          bMatch = 0;
++          if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){
++            pNode->bNomatch = 0;
++            pNode->bEof = 1;
++            return rc;
++          }
++        }else{
++          Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
++          if( pIter->iRowid==iLast || pIter->bEof ) continue;
++          bMatch = 0;
++          if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){
++            return rc;
++          }
++        }
++      }
++    }
++  }while( bMatch==0 );
++
++  pNode->iRowid = iLast;
++  pNode->bNomatch = ((0==fts5ExprNearTest(&rc, pExpr, pNode)) && rc==SQLITE_OK);
++  assert( pNode->bEof==0 || pNode->bNomatch==0 );
++
++  return rc;
++}
++
++/*
++** Advance the first term iterator in the first phrase of pNear. Set output
++** variable *pbEof to true if it reaches EOF or if an error occurs.
++**
++** Return SQLITE_OK if successful, or an SQLite error code if an error
++** occurs.
++*/
++static int fts5ExprNodeNext_STRING(
++  Fts5Expr *pExpr,                /* Expression pPhrase belongs to */
++  Fts5ExprNode *pNode,            /* FTS5_STRING or FTS5_TERM node */
++  int bFromValid,
++  i64 iFrom 
++){
++  Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0];
++  int rc = SQLITE_OK;
 +
-+  if( pOutFlags ){
-+    if( isReadWrite ){
-+      *pOutFlags = SQLITE_OPEN_READWRITE;
-     }else{
--      memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
--      memset(p->u.apSub, 0, sizeof(p->u.apSub));
--      p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
--      rc = sqlite3BitvecSet(p, i);
--      for(j=0; j<BITVEC_NINT; j++){
--        if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
--      }
--      sqlite3StackFree(0, aiValues);
--      return rc;
-+      *pOutFlags = SQLITE_OPEN_READONLY;
-     }
-   }
--bitvec_set_end:
--  p->nSet++;
--  p->u.aHash[h] = i;
--  return SQLITE_OK;
--}
- 
--/*
--** Clear the i-th bit.
--**
--** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
--** that BitvecClear can use to rebuilt its hash table.
--*/
--SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){
--  if( p==0 ) return;
--  assert( i>0 );
--  i--;
--  while( p->iDivisor ){
--    u32 bin = i/p->iDivisor;
--    i = i%p->iDivisor;
--    p = p->u.apSub[bin];
--    if (!p) {
--      return;
--    }
-+  OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, "
-+           "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ?
-+           *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
++  pNode->bNomatch = 0;
++  if( pTerm->pSynonym ){
++    int bEof = 1;
++    Fts5ExprTerm *p;
++
++    /* Find the firstest rowid any synonym points to. */
++    i64 iRowid = fts5ExprSynonymRowid(pTerm, pExpr->bDesc, 0);
++
++    /* Advance each iterator that currently points to iRowid. Or, if iFrom
++    ** is valid - each iterator that points to a rowid before iFrom.  */
++    for(p=pTerm; p; p=p->pSynonym){
++      if( sqlite3Fts5IterEof(p->pIter)==0 ){
++        i64 ii = p->pIter->iRowid;
++        if( ii==iRowid 
++         || (bFromValid && ii!=iFrom && (ii>iFrom)==pExpr->bDesc) 
++        ){
++          if( bFromValid ){
++            rc = sqlite3Fts5IterNextFrom(p->pIter, iFrom);
++          }else{
++            rc = sqlite3Fts5IterNext(p->pIter);
++          }
++          if( rc!=SQLITE_OK ) break;
++          if( sqlite3Fts5IterEof(p->pIter)==0 ){
++            bEof = 0;
++          }
++        }else{
++          bEof = 0;
++        }
++      }
++    }
 +
-+#if SQLITE_OS_WINCE
-+  if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
-+       && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
-+  ){
-+    osCloseHandle(h);
-+    sqlite3_free(zConverted);
-+    sqlite3_free(zTmpname);
-+    OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
-+    return rc;
-   }
--  if( p->iSize<=BITVEC_NBIT ){
--    p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1)));
--  }else{
--    unsigned int j;
--    u32 *aiValues = pBuf;
--    memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
--    memset(p->u.aHash, 0, sizeof(p->u.aHash));
--    p->nSet = 0;
--    for(j=0; j<BITVEC_NINT; j++){
--      if( aiValues[j] && aiValues[j]!=(i+1) ){
--        u32 h = BITVEC_HASH(aiValues[j]-1);
--        p->nSet++;
--        while( p->u.aHash[h] ){
--          h++;
--          if( h>=BITVEC_NINT ) h = 0;
--        }
--        p->u.aHash[h] = aiValues[j];
--      }
--    }
-+  if( isTemp ){
-+    pFile->zDeleteOnClose = zConverted;
-+  }else
-+#endif
-+  {
-+    sqlite3_free(zConverted);
-   }
--}
- 
--/*
--** Destroy a bitmap object.  Reclaim all memory used.
--*/
--SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec *p){
--  if( p==0 ) return;
--  if( p->iDivisor ){
--    unsigned int i;
--    for(i=0; i<BITVEC_NPTR; i++){
--      sqlite3BitvecDestroy(p->u.apSub[i]);
--    }
-+  sqlite3_free(zTmpname);
-+  pFile->pMethod = &winIoMethod;
-+  pFile->pVfs = pVfs;
-+  pFile->h = h;
-+  if( isReadonly ){
-+    pFile->ctrlFlags |= WINFILE_RDONLY;
-   }
--  sqlite3_free(p);
--}
-+  if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
-+    pFile->ctrlFlags |= WINFILE_PSOW;
++    /* Set the EOF flag if either all synonym iterators are at EOF or an
++    ** error has occurred.  */
++    pNode->bEof = (rc || bEof);
++  }else{
++    Fts5IndexIter *pIter = pTerm->pIter;
++
++    assert( Fts5NodeIsString(pNode) );
++    if( bFromValid ){
++      rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
++    }else{
++      rc = sqlite3Fts5IterNext(pIter);
++    }
++
++    pNode->bEof = (rc || sqlite3Fts5IterEof(pIter));
 +  }
-+  pFile->lastErrno = NO_ERROR;
-+  pFile->zPath = zName;
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  pFile->hMap = NULL;
-+  pFile->pMapRegion = 0;
-+  pFile->mmapSize = 0;
-+  pFile->mmapSizeActual = 0;
-+  pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
-+#endif
- 
--/*
--** Return the value of the iSize parameter specified when Bitvec *p
--** was created.
--*/
--SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){
--  return p->iSize;
-+  OpenCounter(+1);
++
++  if( pNode->bEof==0 ){
++    assert( rc==SQLITE_OK );
++    rc = fts5ExprNodeTest_STRING(pExpr, pNode);
++  }
++
 +  return rc;
- }
- 
--#ifndef SQLITE_OMIT_BUILTIN_TEST
--/*
--** Let V[] be an array of unsigned characters sufficient to hold
--** up to N bits.  Let I be an integer between 0 and N.  0<=I<N.
--** Then the following macros can be used to set, clear, or test
--** individual bits within V.
--*/
--#define SETBIT(V,I)      V[I>>3] |= (1<<(I&7))
--#define CLEARBIT(V,I)    V[I>>3] &= ~(1<<(I&7))
--#define TESTBIT(V,I)     (V[I>>3]&(1<<(I&7)))!=0
--
- /*
--** This routine runs an extensive test of the Bitvec code.
--**
--** The input is an array of integers that acts as a program
--** to test the Bitvec.  The integers are opcodes followed
--** by 0, 1, or 3 operands, depending on the opcode.  Another
--** opcode follows immediately after the last operand.
--**
--** There are 6 opcodes numbered from 0 through 5.  0 is the
--** "halt" opcode and causes the test to end.
--**
--**    0          Halt and return the number of errors
--**    1 N S X    Set N bits beginning with S and incrementing by X
--**    2 N S X    Clear N bits beginning with S and incrementing by X
--**    3 N        Set N randomly chosen bits
--**    4 N        Clear N randomly chosen bits
--**    5 N S X    Set N bits from S increment X in array only, not in bitvec
--**
--** The opcodes 1 through 4 perform set and clear operations are performed
--** on both a Bitvec object and on a linear array of bits obtained from malloc.
--** Opcode 5 works on the linear array only, not on the Bitvec.
--** Opcode 5 is used to deliberately induce a fault in order to
--** confirm that error detection works.
--**
--** At the conclusion of the test the linear array is compared
--** against the Bitvec object.  If there are any differences,
--** an error is returned.  If they are the same, zero is returned.
-+** Delete the named file.
- **
--** If a memory allocation error occurs, return -1.
-+** Note that Windows does not allow a file to be deleted if some other
-+** process has it open.  Sometimes a virus scanner or indexing program
-+** will open a journal file shortly after it is created in order to do
-+** whatever it does.  While this other process is holding the
-+** file open, we will be unable to delete it.  To work around this
-+** problem, we delay 100 milliseconds and try to delete again.  Up
-+** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
-+** up and returning an error.
- */
--SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
--  Bitvec *pBitvec = 0;
--  unsigned char *pV = 0;
--  int rc = -1;
--  int i, nx, pc, op;
--  void *pTmpSpace;
--
--  /* Allocate the Bitvec to be tested and a linear array of
--  ** bits to act as the reference */
--  pBitvec = sqlite3BitvecCreate( sz );
--  pV = sqlite3MallocZero( (sz+7)/8 + 1 );
--  pTmpSpace = sqlite3_malloc64(BITVEC_SZ);
--  if( pBitvec==0 || pV==0 || pTmpSpace==0  ) goto bitvec_end;
-+static int winDelete(
-+  sqlite3_vfs *pVfs,          /* Not used on win32 */
-+  const char *zFilename,      /* Name of file to delete */
-+  int syncDir                 /* Not used on win32 */
++}
++
++
++static int fts5ExprNodeTest_TERM(
++  Fts5Expr *pExpr,                /* Expression that pNear is a part of */
++  Fts5ExprNode *pNode             /* The "NEAR" node (FTS5_TERM) */
++){
++  /* As this "NEAR" object is actually a single phrase that consists 
++  ** of a single term only, grab pointers into the poslist managed by the
++  ** fts5_index.c iterator object. This is much faster than synthesizing 
++  ** a new poslist the way we have to for more complicated phrase or NEAR
++  ** expressions.  */
++  Fts5ExprPhrase *pPhrase = pNode->pNear->apPhrase[0];
++  Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
++
++  assert( pNode->eType==FTS5_TERM );
++  assert( pNode->pNear->nPhrase==1 && pPhrase->nTerm==1 );
++  assert( pPhrase->aTerm[0].pSynonym==0 );
++
++  pPhrase->poslist.n = pIter->nData;
++  if( pExpr->pConfig->eDetail==FTS5_DETAIL_FULL ){
++    pPhrase->poslist.p = (u8*)pIter->pData;
++  }
++  pNode->iRowid = pIter->iRowid;
++  pNode->bNomatch = (pPhrase->poslist.n==0);
++  return SQLITE_OK;
++}
++
++/*
++** xNext() method for a node of type FTS5_TERM.
++*/
++static int fts5ExprNodeNext_TERM(
++  Fts5Expr *pExpr, 
++  Fts5ExprNode *pNode,
++  int bFromValid,
++  i64 iFrom
 +){
-+  int cnt = 0;
 +  int rc;
-+  DWORD attr;
-+  DWORD lastErrno = 0;
-+  void *zConverted;
-+  UNUSED_PARAMETER(pVfs);
-+  UNUSED_PARAMETER(syncDir);
- 
--  /* NULL pBitvec tests */
--  sqlite3BitvecSet(0, 1);
--  sqlite3BitvecClear(0, 1, pTmpSpace);
-+  SimulateIOError(return SQLITE_IOERR_DELETE);
-+  OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
- 
--  /* Run the program */
--  pc = 0;
--  while( (op = aOp[pc])!=0 ){
--    switch( op ){
--      case 1:
--      case 2:
--      case 5: {
--        nx = 4;
--        i = aOp[pc+2] - 1;
--        aOp[pc+2] += aOp[pc+3];
-+  zConverted = winConvertFromUtf8Filename(zFilename);
-+  if( zConverted==0 ){
-+    OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
-+    return SQLITE_IOERR_NOMEM;
-+  }
-+  if( osIsNT() ){
-+    do {
-+#if SQLITE_OS_WINRT
-+      WIN32_FILE_ATTRIBUTE_DATA sAttrData;
-+      memset(&sAttrData, 0, sizeof(sAttrData));
-+      if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
-+                                  &sAttrData) ){
-+        attr = sAttrData.dwFileAttributes;
-+      }else{
-+        lastErrno = osGetLastError();
-+        if( lastErrno==ERROR_FILE_NOT_FOUND
-+         || lastErrno==ERROR_PATH_NOT_FOUND ){
-+          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
-+        }else{
-+          rc = SQLITE_ERROR;
++  Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter;
++
++  assert( pNode->bEof==0 );
++  if( bFromValid ){
++    rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
++  }else{
++    rc = sqlite3Fts5IterNext(pIter);
++  }
++  if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){
++    rc = fts5ExprNodeTest_TERM(pExpr, pNode);
++  }else{
++    pNode->bEof = 1;
++    pNode->bNomatch = 0;
++  }
++  return rc;
++}
++
++static void fts5ExprNodeTest_OR(
++  Fts5Expr *pExpr,                /* Expression of which pNode is a part */
++  Fts5ExprNode *pNode             /* Expression node to test */
++){
++  Fts5ExprNode *pNext = pNode->apChild[0];
++  int i;
++
++  for(i=1; i<pNode->nChild; i++){
++    Fts5ExprNode *pChild = pNode->apChild[i];
++    int cmp = fts5NodeCompare(pExpr, pNext, pChild);
++    if( cmp>0 || (cmp==0 && pChild->bNomatch==0) ){
++      pNext = pChild;
++    }
++  }
++  pNode->iRowid = pNext->iRowid;
++  pNode->bEof = pNext->bEof;
++  pNode->bNomatch = pNext->bNomatch;
++}
++
++static int fts5ExprNodeNext_OR(
++  Fts5Expr *pExpr, 
++  Fts5ExprNode *pNode,
++  int bFromValid,
++  i64 iFrom
++){
++  int i;
++  i64 iLast = pNode->iRowid;
++
++  for(i=0; i<pNode->nChild; i++){
++    Fts5ExprNode *p1 = pNode->apChild[i];
++    assert( p1->bEof || fts5RowidCmp(pExpr, p1->iRowid, iLast)>=0 );
++    if( p1->bEof==0 ){
++      if( (p1->iRowid==iLast) 
++       || (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0)
++      ){
++        int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom);
++        if( rc!=SQLITE_OK ){
++          pNode->bNomatch = 0;
++          return rc;
 +        }
-         break;
-       }
--      case 3:
--      case 4: 
--      default: {
--        nx = 2;
--        sqlite3_randomness(sizeof(i), &i);
-+#else
-+      attr = osGetFileAttributesW(zConverted);
-+#endif
-+      if ( attr==INVALID_FILE_ATTRIBUTES ){
-+        lastErrno = osGetLastError();
-+        if( lastErrno==ERROR_FILE_NOT_FOUND
-+         || lastErrno==ERROR_PATH_NOT_FOUND ){
-+          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
-+        }else{
-+          rc = SQLITE_ERROR;
++      }
++    }
++  }
++
++  fts5ExprNodeTest_OR(pExpr, pNode);
++  return SQLITE_OK;
++}
++
++/*
++** Argument pNode is an FTS5_AND node.
++*/
++static int fts5ExprNodeTest_AND(
++  Fts5Expr *pExpr,                /* Expression pPhrase belongs to */
++  Fts5ExprNode *pAnd              /* FTS5_AND node to advance */
++){
++  int iChild;
++  i64 iLast = pAnd->iRowid;
++  int rc = SQLITE_OK;
++  int bMatch;
++
++  assert( pAnd->bEof==0 );
++  do {
++    pAnd->bNomatch = 0;
++    bMatch = 1;
++    for(iChild=0; iChild<pAnd->nChild; iChild++){
++      Fts5ExprNode *pChild = pAnd->apChild[iChild];
++      int cmp = fts5RowidCmp(pExpr, iLast, pChild->iRowid);
++      if( cmp>0 ){
++        /* Advance pChild until it points to iLast or laster */
++        rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast);
++        if( rc!=SQLITE_OK ){
++          pAnd->bNomatch = 0;
++          return rc;
 +        }
-         break;
-       }
--    }
--    if( (--aOp[pc+1]) > 0 ) nx = 0;
--    pc += nx;
--    i = (i & 0x7fffffff)%sz;
--    if( (op & 1)!=0 ){
--      SETBIT(pV, (i+1));
--      if( op!=5 ){
--        if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end;
-+      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
-+        rc = SQLITE_ERROR; /* Files only. */
++      }
++
++      /* If the child node is now at EOF, so is the parent AND node. Otherwise,
++      ** the child node is guaranteed to have advanced at least as far as
++      ** rowid iLast. So if it is not at exactly iLast, pChild->iRowid is the
++      ** new lastest rowid seen so far.  */
++      assert( pChild->bEof || fts5RowidCmp(pExpr, iLast, pChild->iRowid)<=0 );
++      if( pChild->bEof ){
++        fts5ExprSetEof(pAnd);
++        bMatch = 1;
 +        break;
-       }
--    }else{
--      CLEARBIT(pV, (i+1));
--      sqlite3BitvecClear(pBitvec, i+1, pTmpSpace);
--    }
-+      if ( osDeleteFileW(zConverted) ){
-+        rc = SQLITE_OK; /* Deleted OK. */
++      }else if( iLast!=pChild->iRowid ){
++        bMatch = 0;
++        iLast = pChild->iRowid;
++      }
++
++      if( pChild->bNomatch ){
++        pAnd->bNomatch = 1;
++      }
++    }
++  }while( bMatch==0 );
++
++  if( pAnd->bNomatch && pAnd!=pExpr->pRoot ){
++    fts5ExprNodeZeroPoslist(pAnd);
++  }
++  pAnd->iRowid = iLast;
++  return SQLITE_OK;
++}
++
++static int fts5ExprNodeNext_AND(
++  Fts5Expr *pExpr, 
++  Fts5ExprNode *pNode,
++  int bFromValid,
++  i64 iFrom
++){
++  int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
++  if( rc==SQLITE_OK ){
++    rc = fts5ExprNodeTest_AND(pExpr, pNode);
++  }else{
++    pNode->bNomatch = 0;
++  }
++  return rc;
++}
++
++static int fts5ExprNodeTest_NOT(
++  Fts5Expr *pExpr,                /* Expression pPhrase belongs to */
++  Fts5ExprNode *pNode             /* FTS5_NOT node to advance */
++){
++  int rc = SQLITE_OK;
++  Fts5ExprNode *p1 = pNode->apChild[0];
++  Fts5ExprNode *p2 = pNode->apChild[1];
++  assert( pNode->nChild==2 );
++
++  while( rc==SQLITE_OK && p1->bEof==0 ){
++    int cmp = fts5NodeCompare(pExpr, p1, p2);
++    if( cmp>0 ){
++      rc = fts5ExprNodeNext(pExpr, p2, 1, p1->iRowid);
++      cmp = fts5NodeCompare(pExpr, p1, p2);
++    }
++    assert( rc!=SQLITE_OK || cmp<=0 );
++    if( cmp || p2->bNomatch ) break;
++    rc = fts5ExprNodeNext(pExpr, p1, 0, 0);
++  }
++  pNode->bEof = p1->bEof;
++  pNode->bNomatch = p1->bNomatch;
++  pNode->iRowid = p1->iRowid;
++  if( p1->bEof ){
++    fts5ExprNodeZeroPoslist(p2);
++  }
++  return rc;
++}
++
++static int fts5ExprNodeNext_NOT(
++  Fts5Expr *pExpr, 
++  Fts5ExprNode *pNode,
++  int bFromValid,
++  i64 iFrom
++){
++  int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
++  if( rc==SQLITE_OK ){
++    rc = fts5ExprNodeTest_NOT(pExpr, pNode);
++  }
++  if( rc!=SQLITE_OK ){
++    pNode->bNomatch = 0;
++  }
++  return rc;
++}
++
++/*
++** If pNode currently points to a match, this function returns SQLITE_OK
++** without modifying it. Otherwise, pNode is advanced until it does point
++** to a match or EOF is reached.
++*/
++static int fts5ExprNodeTest(
++  Fts5Expr *pExpr,                /* Expression of which pNode is a part */
++  Fts5ExprNode *pNode             /* Expression node to test */
++){
++  int rc = SQLITE_OK;
++  if( pNode->bEof==0 ){
++    switch( pNode->eType ){
++
++      case FTS5_STRING: {
++        rc = fts5ExprNodeTest_STRING(pExpr, pNode);
 +        break;
 +      }
-+      if ( !winRetryIoerr(&cnt, &lastErrno) ){
-+        rc = SQLITE_ERROR; /* No more retries. */
++
++      case FTS5_TERM: {
++        rc = fts5ExprNodeTest_TERM(pExpr, pNode);
 +        break;
 +      }
-+    } while(1);
-+  }
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    do {
-+      attr = osGetFileAttributesA(zConverted);
-+      if ( attr==INVALID_FILE_ATTRIBUTES ){
-+        lastErrno = osGetLastError();
-+        if( lastErrno==ERROR_FILE_NOT_FOUND
-+         || lastErrno==ERROR_PATH_NOT_FOUND ){
-+          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
-+        }else{
-+          rc = SQLITE_ERROR;
-+        }
++
++      case FTS5_AND: {
++        rc = fts5ExprNodeTest_AND(pExpr, pNode);
 +        break;
 +      }
-+      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
-+        rc = SQLITE_ERROR; /* Files only. */
++
++      case FTS5_OR: {
++        fts5ExprNodeTest_OR(pExpr, pNode);
 +        break;
 +      }
-+      if ( osDeleteFileA(zConverted) ){
-+        rc = SQLITE_OK; /* Deleted OK. */
++
++      default: assert( pNode->eType==FTS5_NOT ); {
++        rc = fts5ExprNodeTest_NOT(pExpr, pNode);
 +        break;
 +      }
-+      if ( !winRetryIoerr(&cnt, &lastErrno) ){
-+        rc = SQLITE_ERROR; /* No more retries. */
++    }
++  }
++  return rc;
++}
++
++ 
++/*
++** Set node pNode, which is part of expression pExpr, to point to the first
++** match. If there are no matches, set the Node.bEof flag to indicate EOF.
++**
++** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
++** It is not an error if there are no matches.
++*/
++static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
++  int rc = SQLITE_OK;
++  pNode->bEof = 0;
++  pNode->bNomatch = 0;
++
++  if( Fts5NodeIsString(pNode) ){
++    /* Initialize all term iterators in the NEAR object. */
++    rc = fts5ExprNearInitAll(pExpr, pNode);
++  }else if( pNode->xNext==0 ){
++    pNode->bEof = 1;
++  }else{
++    int i;
++    int nEof = 0;
++    for(i=0; i<pNode->nChild && rc==SQLITE_OK; i++){
++      Fts5ExprNode *pChild = pNode->apChild[i];
++      rc = fts5ExprNodeFirst(pExpr, pNode->apChild[i]);
++      assert( pChild->bEof==0 || pChild->bEof==1 );
++      nEof += pChild->bEof;
++    }
++    pNode->iRowid = pNode->apChild[0]->iRowid;
++
++    switch( pNode->eType ){
++      case FTS5_AND:
++        if( nEof>0 ) fts5ExprSetEof(pNode);
++        break;
++
++      case FTS5_OR:
++        if( pNode->nChild==nEof ) fts5ExprSetEof(pNode);
 +        break;
++
++      default:
++        assert( pNode->eType==FTS5_NOT );
++        pNode->bEof = pNode->apChild[0]->bEof;
++        break;
++    }
++  }
++
++  if( rc==SQLITE_OK ){
++    rc = fts5ExprNodeTest(pExpr, pNode);
++  }
++  return rc;
++}
++
++
++/*
++** Begin iterating through the set of documents in index pIdx matched by
++** the MATCH expression passed as the first argument. If the "bDesc" 
++** parameter is passed a non-zero value, iteration is in descending rowid 
++** order. Or, if it is zero, in ascending order.
++**
++** If iterating in ascending rowid order (bDesc==0), the first document
++** visited is that with the smallest rowid that is larger than or equal
++** to parameter iFirst. Or, if iterating in ascending order (bDesc==1),
++** then the first document visited must have a rowid smaller than or
++** equal to iFirst.
++**
++** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
++** is not considered an error if the query does not match any documents.
++*/
++static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
++  Fts5ExprNode *pRoot = p->pRoot;
++  int rc;                         /* Return code */
++
++  p->pIndex = pIdx;
++  p->bDesc = bDesc;
++  rc = fts5ExprNodeFirst(p, pRoot);
++
++  /* If not at EOF but the current rowid occurs earlier than iFirst in
++  ** the iteration order, move to document iFirst or later. */
++  if( rc==SQLITE_OK 
++   && 0==pRoot->bEof 
++   && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 
++  ){
++    rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
++  }
++
++  /* If the iterator is not at a real match, skip forward until it is. */
++  while( pRoot->bNomatch ){
++    assert( pRoot->bEof==0 && rc==SQLITE_OK );
++    rc = fts5ExprNodeNext(p, pRoot, 0, 0);
++  }
++  return rc;
++}
++
++/*
++** Move to the next document 
++**
++** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
++** is not considered an error if the query does not match any documents.
++*/
++static int sqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){
++  int rc;
++  Fts5ExprNode *pRoot = p->pRoot;
++  assert( pRoot->bEof==0 && pRoot->bNomatch==0 );
++  do {
++    rc = fts5ExprNodeNext(p, pRoot, 0, 0);
++    assert( pRoot->bNomatch==0 || (rc==SQLITE_OK && pRoot->bEof==0) );
++  }while( pRoot->bNomatch );
++  if( fts5RowidCmp(p, pRoot->iRowid, iLast)>0 ){
++    pRoot->bEof = 1;
++  }
++  return rc;
++}
++
++static int sqlite3Fts5ExprEof(Fts5Expr *p){
++  return p->pRoot->bEof;
++}
++
++static i64 sqlite3Fts5ExprRowid(Fts5Expr *p){
++  return p->pRoot->iRowid;
++}
++
++static int fts5ParseStringFromToken(Fts5Token *pToken, char **pz){
++  int rc = SQLITE_OK;
++  *pz = sqlite3Fts5Strndup(&rc, pToken->p, pToken->n);
++  return rc;
++}
++
++/*
++** Free the phrase object passed as the only argument.
++*/
++static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){
++  if( pPhrase ){
++    int i;
++    for(i=0; i<pPhrase->nTerm; i++){
++      Fts5ExprTerm *pSyn;
++      Fts5ExprTerm *pNext;
++      Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
++      sqlite3_free(pTerm->zTerm);
++      sqlite3Fts5IterClose(pTerm->pIter);
++      for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
++        pNext = pSyn->pSynonym;
++        sqlite3Fts5IterClose(pSyn->pIter);
++        fts5BufferFree((Fts5Buffer*)&pSyn[1]);
++        sqlite3_free(pSyn);
++      }
++    }
++    if( pPhrase->poslist.nSpace>0 ) fts5BufferFree(&pPhrase->poslist);
++    sqlite3_free(pPhrase);
++  }
++}
++
++/*
++** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated
++** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is
++** appended to it and the results returned.
++**
++** If an OOM error occurs, both the pNear and pPhrase objects are freed and
++** NULL returned.
++*/
++static Fts5ExprNearset *sqlite3Fts5ParseNearset(
++  Fts5Parse *pParse,              /* Parse context */
++  Fts5ExprNearset *pNear,         /* Existing nearset, or NULL */
++  Fts5ExprPhrase *pPhrase         /* Recently parsed phrase */
++){
++  const int SZALLOC = 8;
++  Fts5ExprNearset *pRet = 0;
++
++  if( pParse->rc==SQLITE_OK ){
++    if( pPhrase==0 ){
++      return pNear;
++    }
++    if( pNear==0 ){
++      int nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
++      pRet = sqlite3_malloc(nByte);
++      if( pRet==0 ){
++        pParse->rc = SQLITE_NOMEM;
++      }else{
++        memset(pRet, 0, nByte);
++      }
++    }else if( (pNear->nPhrase % SZALLOC)==0 ){
++      int nNew = pNear->nPhrase + SZALLOC;
++      int nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
++
++      pRet = (Fts5ExprNearset*)sqlite3_realloc(pNear, nByte);
++      if( pRet==0 ){
++        pParse->rc = SQLITE_NOMEM;
 +      }
-+    } while(1);
-   }
--
--  /* Test to make sure the linear array exactly matches the
--  ** Bitvec object.  Start with the assumption that they do
--  ** match (rc==0).  Change rc to non-zero if a discrepancy
--  ** is found.
--  */
--  rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1)
--          + sqlite3BitvecTest(pBitvec, 0)
--          + (sqlite3BitvecSize(pBitvec) - sz);
--  for(i=1; i<=sz; i++){
--    if(  (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){
--      rc = i;
--      break;
--    }
-+#endif
-+  if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
-+    rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
++    }else{
++      pRet = pNear;
++    }
++  }
++
++  if( pRet==0 ){
++    assert( pParse->rc!=SQLITE_OK );
++    sqlite3Fts5ParseNearsetFree(pNear);
++    sqlite3Fts5ParsePhraseFree(pPhrase);
 +  }else{
-+    winLogIoerr(cnt, __LINE__);
-   }
--
--  /* Free allocated structure */
--bitvec_end:
--  sqlite3_free(pTmpSpace);
--  sqlite3_free(pV);
--  sqlite3BitvecDestroy(pBitvec);
-+  sqlite3_free(zConverted);
-+  OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
-   return rc;
- }
--#endif /* SQLITE_OMIT_BUILTIN_TEST */
--
--/************** End of bitvec.c **********************************************/
--/************** Begin file pcache.c ******************************************/
--/*
--** 2008 August 05
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
--**
--**    May you do good and not evil.
--**    May you find forgiveness for yourself and forgive others.
--**    May you share freely, never taking more than you give.
--**
--*************************************************************************
--** This file implements that page cache.
--*/
- 
- /*
--** A complete page cache is an instance of this structure.
-+** Check the existence and status of a file.
- */
--struct PCache {
--  PgHdr *pDirty, *pDirtyTail;         /* List of dirty pages in LRU order */
--  PgHdr *pSynced;                     /* Last synced page in dirty page list */
--  int nRef;                           /* Number of referenced pages */
--  int szCache;                        /* Configured cache size */
--  int szPage;                         /* Size of every page in this cache */
--  int szExtra;                        /* Size of extra space for each page */
--  u8 bPurgeable;                      /* True if pages are on backing store */
--  u8 eCreate;                         /* eCreate value for for xFetch() */
--  int (*xStress)(void*,PgHdr*);       /* Call to try make a page clean */
--  void *pStress;                      /* Argument to xStress */
--  sqlite3_pcache *pCache;             /* Pluggable cache module */
--  PgHdr *pPage1;                      /* Reference to page 1 */
--};
--
--/********************************** Linked List Management ********************/
--
--/* Allowed values for second argument to pcacheManageDirtyList() */
--#define PCACHE_DIRTYLIST_REMOVE   1    /* Remove pPage from dirty list */
--#define PCACHE_DIRTYLIST_ADD      2    /* Add pPage to the dirty list */
--#define PCACHE_DIRTYLIST_FRONT    3    /* Move pPage to the front of the list */
-+static int winAccess(
-+  sqlite3_vfs *pVfs,         /* Not used on win32 */
-+  const char *zFilename,     /* Name of file to check */
-+  int flags,                 /* Type of test to make on this file */
-+  int *pResOut               /* OUT: Result */
++    if( pRet->nPhrase>0 ){
++      Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1];
++      assert( pLast==pParse->apPhrase[pParse->nPhrase-2] );
++      if( pPhrase->nTerm==0 ){
++        fts5ExprPhraseFree(pPhrase);
++        pRet->nPhrase--;
++        pParse->nPhrase--;
++        pPhrase = pLast;
++      }else if( pLast->nTerm==0 ){
++        fts5ExprPhraseFree(pLast);
++        pParse->apPhrase[pParse->nPhrase-2] = pPhrase;
++        pParse->nPhrase--;
++        pRet->nPhrase--;
++      }
++    }
++    pRet->apPhrase[pRet->nPhrase++] = pPhrase;
++  }
++  return pRet;
++}
++
++typedef struct TokenCtx TokenCtx;
++struct TokenCtx {
++  Fts5ExprPhrase *pPhrase;
++  int rc;
++};
++
++/*
++** Callback for tokenizing terms used by ParseTerm().
++*/
++static int fts5ParseTokenize(
++  void *pContext,                 /* Pointer to Fts5InsertCtx object */
++  int tflags,                     /* Mask of FTS5_TOKEN_* flags */
++  const char *pToken,             /* Buffer containing token */
++  int nToken,                     /* Size of token in bytes */
++  int iUnused1,                   /* Start offset of token */
++  int iUnused2                    /* End offset of token */
 +){
-+  DWORD attr;
-+  int rc = 0;
-+  DWORD lastErrno = 0;
-+  void *zConverted;
-+  UNUSED_PARAMETER(pVfs);
- 
--/*
--** Manage pPage's participation on the dirty list.  Bits of the addRemove
--** argument determines what operation to do.  The 0x01 bit means first
--** remove pPage from the dirty list.  The 0x02 means add pPage back to
--** the dirty list.  Doing both moves pPage to the front of the dirty list.
--*/
--static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
--  PCache *p = pPage->pCache;
-+  SimulateIOError( return SQLITE_IOERR_ACCESS; );
-+  OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
-+           zFilename, flags, pResOut));
- 
--  if( addRemove & PCACHE_DIRTYLIST_REMOVE ){
--    assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
--    assert( pPage->pDirtyPrev || pPage==p->pDirty );
--  
--    /* Update the PCache1.pSynced variable if necessary. */
--    if( p->pSynced==pPage ){
--      PgHdr *pSynced = pPage->pDirtyPrev;
--      while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){
--        pSynced = pSynced->pDirtyPrev;
--      }
--      p->pSynced = pSynced;
--    }
--  
--    if( pPage->pDirtyNext ){
--      pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev;
--    }else{
--      assert( pPage==p->pDirtyTail );
--      p->pDirtyTail = pPage->pDirtyPrev;
--    }
--    if( pPage->pDirtyPrev ){
--      pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
--    }else{
--      assert( pPage==p->pDirty );
--      p->pDirty = pPage->pDirtyNext;
--      if( p->pDirty==0 && p->bPurgeable ){
--        assert( p->eCreate==1 );
--        p->eCreate = 2;
--      }
--    }
--    pPage->pDirtyNext = 0;
--    pPage->pDirtyPrev = 0;
-+  zConverted = winConvertFromUtf8Filename(zFilename);
-+  if( zConverted==0 ){
-+    OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
-+    return SQLITE_IOERR_NOMEM;
-   }
--  if( addRemove & PCACHE_DIRTYLIST_ADD ){
--    assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage );
--  
--    pPage->pDirtyNext = p->pDirty;
--    if( pPage->pDirtyNext ){
--      assert( pPage->pDirtyNext->pDirtyPrev==0 );
--      pPage->pDirtyNext->pDirtyPrev = pPage;
-+  if( osIsNT() ){
-+    int cnt = 0;
-+    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
-+    memset(&sAttrData, 0, sizeof(sAttrData));
-+    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
-+                             GetFileExInfoStandard,
-+                             &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
-+    if( rc ){
-+      /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
-+      ** as if it does not exist.
-+      */
-+      if(    flags==SQLITE_ACCESS_EXISTS
-+          && sAttrData.nFileSizeHigh==0
-+          && sAttrData.nFileSizeLow==0 ){
-+        attr = INVALID_FILE_ATTRIBUTES;
++  int rc = SQLITE_OK;
++  const int SZALLOC = 8;
++  TokenCtx *pCtx = (TokenCtx*)pContext;
++  Fts5ExprPhrase *pPhrase = pCtx->pPhrase;
++
++  UNUSED_PARAM2(iUnused1, iUnused2);
++
++  /* If an error has already occurred, this is a no-op */
++  if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
++  if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
++
++  if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){
++    Fts5ExprTerm *pSyn;
++    int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
++    pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
++    if( pSyn==0 ){
++      rc = SQLITE_NOMEM;
++    }else{
++      memset(pSyn, 0, nByte);
++      pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
++      memcpy(pSyn->zTerm, pToken, nToken);
++      pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
++      pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
++    }
++  }else{
++    Fts5ExprTerm *pTerm;
++    if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){
++      Fts5ExprPhrase *pNew;
++      int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
++
++      pNew = (Fts5ExprPhrase*)sqlite3_realloc(pPhrase, 
++          sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
++      );
++      if( pNew==0 ){
++        rc = SQLITE_NOMEM;
 +      }else{
-+        attr = sAttrData.dwFileAttributes;
++        if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase));
++        pCtx->pPhrase = pPhrase = pNew;
++        pNew->nTerm = nNew - SZALLOC;
 +      }
-     }else{
--      p->pDirtyTail = pPage;
--      if( p->bPurgeable ){
--        assert( p->eCreate==2 );
--        p->eCreate = 1;
-+      winLogIoerr(cnt, __LINE__);
-+      if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
-+        sqlite3_free(zConverted);
-+        return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
-+                           zFilename);
-+      }else{
-+        attr = INVALID_FILE_ATTRIBUTES;
-       }
-     }
--    p->pDirty = pPage;
--    if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
--      p->pSynced = pPage;
--    }
--  }
--}
--
--/*
--** Wrapper around the pluggable caches xUnpin method. If the cache is
--** being used for an in-memory database, this function is a no-op.
--*/
--static void pcacheUnpin(PgHdr *p){
--  if( p->pCache->bPurgeable ){
--    if( p->pgno==1 ){
--      p->pCache->pPage1 = 0;
--    }
--    sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0);
--  }
--}
--
--/*
--** Compute the number of pages of cache requested.  p->szCache is the
--** cache size requested by the "PRAGMA cache_size" statement.
--**
--**
--*/
--static int numberOfCachePages(PCache *p){
--  if( p->szCache>=0 ){
--    /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
--    ** suggested cache size is set to N. */
--    return p->szCache;
--  }else{
--    /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
--    ** the number of cache pages is adjusted to use approximately abs(N*1024)
--    ** bytes of memory. */
--    return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
-   }
--}
--
--/*************************************************** General Interfaces ******
--**
--** Initialize and shutdown the page cache subsystem. Neither of these 
--** functions are threadsafe.
--*/
--SQLITE_PRIVATE int sqlite3PcacheInitialize(void){
--  if( sqlite3GlobalConfig.pcache2.xInit==0 ){
--    /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the
--    ** built-in default page cache is used instead of the application defined
--    ** page cache. */
--    sqlite3PCacheSetDefault();
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    attr = osGetFileAttributesA((char*)zConverted);
-   }
--  return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg);
--}
--SQLITE_PRIVATE void sqlite3PcacheShutdown(void){
--  if( sqlite3GlobalConfig.pcache2.xShutdown ){
--    /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */
--    sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg);
-+#endif
-+  sqlite3_free(zConverted);
-+  switch( flags ){
-+    case SQLITE_ACCESS_READ:
-+    case SQLITE_ACCESS_EXISTS:
-+      rc = attr!=INVALID_FILE_ATTRIBUTES;
-+      break;
-+    case SQLITE_ACCESS_READWRITE:
-+      rc = attr!=INVALID_FILE_ATTRIBUTES &&
-+             (attr & FILE_ATTRIBUTE_READONLY)==0;
-+      break;
-+    default:
-+      assert(!"Invalid flags argument");
-   }
-+  *pResOut = rc;
-+  OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
-+           zFilename, pResOut, *pResOut));
-+  return SQLITE_OK;
- }
- 
- /*
--** Return the size in bytes of a PCache object.
--*/
--SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); }
--
--/*
--** Create a new PCache object. Storage space to hold the object
--** has already been allocated and is passed in as the p pointer. 
--** The caller discovers how much space needs to be allocated by 
--** calling sqlite3PcacheSize().
-+** Returns non-zero if the specified path name starts with a drive letter
-+** followed by a colon character.
- */
--SQLITE_PRIVATE int sqlite3PcacheOpen(
--  int szPage,                  /* Size of every page */
--  int szExtra,                 /* Extra space associated with each page */
--  int bPurgeable,              /* True if pages are on backing store */
--  int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */
--  void *pStress,               /* Argument to xStress */
--  PCache *p                    /* Preallocated space for the PCache */
-+static BOOL winIsDriveLetterAndColon(
-+  const char *zPathname
- ){
--  memset(p, 0, sizeof(PCache));
--  p->szPage = 1;
--  p->szExtra = szExtra;
--  p->bPurgeable = bPurgeable;
--  p->eCreate = 2;
--  p->xStress = xStress;
--  p->pStress = pStress;
--  p->szCache = 100;
--  return sqlite3PcacheSetPageSize(p, szPage);
--}
--
--/*
--** Change the page size for PCache object. The caller must ensure that there
--** are no outstanding page references when this function is called.
--*/
--SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
--  assert( pCache->nRef==0 && pCache->pDirty==0 );
--  if( pCache->szPage ){
--    sqlite3_pcache *pNew;
--    pNew = sqlite3GlobalConfig.pcache2.xCreate(
--                szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
--                pCache->bPurgeable
--    );
--    if( pNew==0 ) return SQLITE_NOMEM;
--    sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
--    if( pCache->pCache ){
--      sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
--    }
--    pCache->pCache = pNew;
--    pCache->pPage1 = 0;
--    pCache->szPage = szPage;
--  }
--  return SQLITE_OK;
-+  return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );
- }
- 
- /*
--** Try to obtain a page from the cache.
--**
--** This routine returns a pointer to an sqlite3_pcache_page object if
--** such an object is already in cache, or if a new one is created.
--** This routine returns a NULL pointer if the object was not in cache
--** and could not be created.
--**
--** The createFlags should be 0 to check for existing pages and should
--** be 3 (not 1, but 3) to try to create a new page.
--**
--** If the createFlag is 0, then NULL is always returned if the page
--** is not already in the cache.  If createFlag is 1, then a new page
--** is created only if that can be done without spilling dirty pages
--** and without exceeding the cache size limit.
--**
--** The caller needs to invoke sqlite3PcacheFetchFinish() to properly
--** initialize the sqlite3_pcache_page object and convert it into a
--** PgHdr object.  The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish()
--** routines are split this way for performance reasons. When separated
--** they can both (usually) operate without having to push values to
--** the stack on entry and pop them back off on exit, which saves a
--** lot of pushing and popping.
-+** Returns non-zero if the specified path name should be used verbatim.  If
-+** non-zero is returned from this function, the calling function must simply
-+** use the provided path name verbatim -OR- resolve it into a full path name
-+** using the GetFullPathName Win32 API function (if available).
- */
--SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(
--  PCache *pCache,       /* Obtain the page from this cache */
--  Pgno pgno,            /* Page number to obtain */
--  int createFlag        /* If true, create page if it does not exist already */
-+static BOOL winIsVerbatimPathname(
-+  const char *zPathname
- ){
--  int eCreate;
-+  /*
-+  ** If the path name starts with a forward slash or a backslash, it is either
-+  ** a legal UNC name, a volume relative path, or an absolute path name in the
-+  ** "Unix" format on Windows.  There is no easy way to differentiate between
-+  ** the final two cases; therefore, we return the safer return value of TRUE
-+  ** so that callers of this function will simply use it verbatim.
-+  */
-+  if ( winIsDirSep(zPathname[0]) ){
-+    return TRUE;
++    }
++
++    if( rc==SQLITE_OK ){
++      pTerm = &pPhrase->aTerm[pPhrase->nTerm++];
++      memset(pTerm, 0, sizeof(Fts5ExprTerm));
++      pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken);
++    }
 +  }
- 
--  assert( pCache!=0 );
--  assert( pCache->pCache!=0 );
--  assert( createFlag==3 || createFlag==0 );
--  assert( pgno>0 );
-+  /*
-+  ** If the path name starts with a letter and a colon it is either a volume
-+  ** relative path or an absolute path.  Callers of this function must not
-+  ** attempt to treat it as a relative path name (i.e. they should simply use
-+  ** it verbatim).
-+  */
-+  if ( winIsDriveLetterAndColon(zPathname) ){
-+    return TRUE;
++
++  pCtx->rc = rc;
++  return rc;
++}
++
++
++/*
++** Free the phrase object passed as the only argument.
++*/
++static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase *pPhrase){
++  fts5ExprPhraseFree(pPhrase);
++}
++
++/*
++** Free the phrase object passed as the second argument.
++*/
++static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset *pNear){
++  if( pNear ){
++    int i;
++    for(i=0; i<pNear->nPhrase; i++){
++      fts5ExprPhraseFree(pNear->apPhrase[i]);
++    }
++    sqlite3_free(pNear->pColset);
++    sqlite3_free(pNear);
 +  }
- 
--  /* eCreate defines what to do if the page does not exist.
--  **    0     Do not allocate a new page.  (createFlag==0)
--  **    1     Allocate a new page if doing so is inexpensive.
--  **          (createFlag==1 AND bPurgeable AND pDirty)
--  **    2     Allocate a new page even it doing so is difficult.
--  **          (createFlag==1 AND !(bPurgeable AND pDirty)
-+  /*
-+  ** If we get to this point, the path name should almost certainly be a purely
-+  ** relative one (i.e. not a UNC name, not absolute, and not volume relative).
-   */
--  eCreate = createFlag & pCache->eCreate;
--  assert( eCreate==0 || eCreate==1 || eCreate==2 );
--  assert( createFlag==0 || pCache->eCreate==eCreate );
--  assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) );
--  return sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
-+  return FALSE;
- }
- 
- /*
--** If the sqlite3PcacheFetch() routine is unable to allocate a new
--** page because new clean pages are available for reuse and the cache
--** size limit has been reached, then this routine can be invoked to 
--** try harder to allocate a page.  This routine might invoke the stress
--** callback to spill dirty pages to the journal.  It will then try to
--** allocate the new page and will only fail to allocate a new page on
--** an OOM error.
--**
--** This routine should be invoked only after sqlite3PcacheFetch() fails.
-+** Turn a relative pathname into a full pathname.  Write the full
-+** pathname into zOut[].  zOut[] will be at least pVfs->mxPathname
-+** bytes in size.
- */
--SQLITE_PRIVATE int sqlite3PcacheFetchStress(
--  PCache *pCache,                 /* Obtain the page from this cache */
--  Pgno pgno,                      /* Page number to obtain */
--  sqlite3_pcache_page **ppPage    /* Write result here */
-+static int winFullPathname(
-+  sqlite3_vfs *pVfs,            /* Pointer to vfs object */
-+  const char *zRelative,        /* Possibly relative input path */
-+  int nFull,                    /* Size of output buffer in bytes */
-+  char *zFull                   /* Output buffer */
- ){
--  PgHdr *pPg;
--  if( pCache->eCreate==2 ) return 0;
- 
--
--  /* Find a dirty page to write-out and recycle. First try to find a 
--  ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
--  ** cleared), but if that is not possible settle for any other 
--  ** unreferenced dirty page.
--  */
--  for(pPg=pCache->pSynced; 
--      pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); 
--      pPg=pPg->pDirtyPrev
--  );
--  pCache->pSynced = pPg;
--  if( !pPg ){
--    for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
--  }
--  if( pPg ){
--    int rc;
--#ifdef SQLITE_LOG_CACHE_SPILL
--    sqlite3_log(SQLITE_FULL, 
--                "spill page %d making room for %d - cache used: %d/%d",
--                pPg->pgno, pgno,
--                sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
--                numberOfCachePages(pCache));
--#endif
--    rc = pCache->xStress(pCache->pStress, pPg);
--    if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
--      return rc;
-+#if defined(__CYGWIN__)
-+  SimulateIOError( return SQLITE_ERROR );
-+  UNUSED_PARAMETER(nFull);
-+  assert( nFull>=pVfs->mxPathname );
-+  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
-+    /*
-+    ** NOTE: We are dealing with a relative path name and the data
-+    **       directory has been set.  Therefore, use it as the basis
-+    **       for converting the relative path name to an absolute
-+    **       one by prepending the data directory and a slash.
-+    */
-+    char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
-+    if( !zOut ){
-+      return SQLITE_IOERR_NOMEM;
-+    }
-+    if( cygwin_conv_path(
-+            (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
-+            CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){
-+      sqlite3_free(zOut);
-+      return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
-+                         "winFullPathname1", zRelative);
-+    }else{
-+      char *zUtf8 = winConvertToUtf8Filename(zOut);
-+      if( !zUtf8 ){
-+        sqlite3_free(zOut);
-+        return SQLITE_IOERR_NOMEM;
-+      }
-+      sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
-+                       sqlite3_data_directory, winGetDirSep(), zUtf8);
-+      sqlite3_free(zUtf8);
-+      sqlite3_free(zOut);
-+    }
-+  }else{
-+    char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
-+    if( !zOut ){
-+      return SQLITE_IOERR_NOMEM;
-+    }
-+    if( cygwin_conv_path(
-+            (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
-+            zRelative, zOut, pVfs->mxPathname+1)<0 ){
-+      sqlite3_free(zOut);
-+      return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
-+                         "winFullPathname2", zRelative);
-+    }else{
-+      char *zUtf8 = winConvertToUtf8Filename(zOut);
-+      if( !zUtf8 ){
-+        sqlite3_free(zOut);
-+        return SQLITE_IOERR_NOMEM;
-+      }
-+      sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
-+      sqlite3_free(zUtf8);
-+      sqlite3_free(zOut);
-     }
-   }
--  *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
--  return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK;
--}
-+  return SQLITE_OK;
-+#endif
- 
--/*
--** This is a helper routine for sqlite3PcacheFetchFinish()
--**
--** In the uncommon case where the page being fetched has not been
--** initialized, this routine is invoked to do the initialization.
--** This routine is broken out into a separate function since it
--** requires extra stack manipulation that can be avoided in the common
--** case.
--*/
--static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
--  PCache *pCache,             /* Obtain the page from this cache */
--  Pgno pgno,                  /* Page number obtained */
--  sqlite3_pcache_page *pPage  /* Page obtained by prior PcacheFetch() call */
--){
--  PgHdr *pPgHdr;
--  assert( pPage!=0 );
--  pPgHdr = (PgHdr*)pPage->pExtra;
--  assert( pPgHdr->pPage==0 );
-- memset(pPgHdr, 0, sizeof(PgHdr));
--  pPgHdr->pPage = pPage;
--  pPgHdr->pData = pPage->pBuf;
--  pPgHdr->pExtra = (void *)&pPgHdr[1];
--  memset(pPgHdr->pExtra, 0, pCache->szExtra);
--  pPgHdr->pCache = pCache;
--  pPgHdr->pgno = pgno;
--  return sqlite3PcacheFetchFinish(pCache,pgno,pPage);
--}
-+#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
-+  SimulateIOError( return SQLITE_ERROR );
-+  /* WinCE has no concept of a relative pathname, or so I am told. */
-+  /* WinRT has no way to convert a relative path to an absolute one. */
-+  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
-+    /*
-+    ** NOTE: We are dealing with a relative path name and the data
-+    **       directory has been set.  Therefore, use it as the basis
-+    **       for converting the relative path name to an absolute
-+    **       one by prepending the data directory and a backslash.
-+    */
-+    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
-+                     sqlite3_data_directory, winGetDirSep(), zRelative);
++}
++
++static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){
++  assert( pParse->pExpr==0 );
++  pParse->pExpr = p;
++}
++
++/*
++** This function is called by the parser to process a string token. The
++** string may or may not be quoted. In any case it is tokenized and a
++** phrase object consisting of all tokens returned.
++*/
++static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
++  Fts5Parse *pParse,              /* Parse context */
++  Fts5ExprPhrase *pAppend,        /* Phrase to append to */
++  Fts5Token *pToken,              /* String to tokenize */
++  int bPrefix                     /* True if there is a trailing "*" */
++){
++  Fts5Config *pConfig = pParse->pConfig;
++  TokenCtx sCtx;                  /* Context object passed to callback */
++  int rc;                         /* Tokenize return code */
++  char *z = 0;
++
++  memset(&sCtx, 0, sizeof(TokenCtx));
++  sCtx.pPhrase = pAppend;
++
++  rc = fts5ParseStringFromToken(pToken, &z);
++  if( rc==SQLITE_OK ){
++    int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_PREFIX : 0);
++    int n;
++    sqlite3Fts5Dequote(z);
++    n = (int)strlen(z);
++    rc = sqlite3Fts5Tokenize(pConfig, flags, z, n, &sCtx, fts5ParseTokenize);
++  }
++  sqlite3_free(z);
++  if( rc || (rc = sCtx.rc) ){
++    pParse->rc = rc;
++    fts5ExprPhraseFree(sCtx.pPhrase);
++    sCtx.pPhrase = 0;
++  }else{
++
++    if( pAppend==0 ){
++      if( (pParse->nPhrase % 8)==0 ){
++        int nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
++        Fts5ExprPhrase **apNew;
++        apNew = (Fts5ExprPhrase**)sqlite3_realloc(pParse->apPhrase, nByte);
++        if( apNew==0 ){
++          pParse->rc = SQLITE_NOMEM;
++          fts5ExprPhraseFree(sCtx.pPhrase);
++          return 0;
++        }
++        pParse->apPhrase = apNew;
++      }
++      pParse->nPhrase++;
++    }
++
++    if( sCtx.pPhrase==0 ){
++      /* This happens when parsing a token or quoted phrase that contains
++      ** no token characters at all. (e.g ... MATCH '""'). */
++      sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase));
++    }else if( sCtx.pPhrase->nTerm ){
++      sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix;
++    }
++    pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
++  }
++
++  return sCtx.pPhrase;
++}
++
++/*
++** Create a new FTS5 expression by cloning phrase iPhrase of the
++** expression passed as the second argument.
++*/
++static int sqlite3Fts5ExprClonePhrase(
++  Fts5Expr *pExpr, 
++  int iPhrase, 
++  Fts5Expr **ppNew
++){
++  int rc = SQLITE_OK;             /* Return code */
++  Fts5ExprPhrase *pOrig;          /* The phrase extracted from pExpr */
++  Fts5Expr *pNew = 0;             /* Expression to return via *ppNew */
++  TokenCtx sCtx = {0,0};          /* Context object for fts5ParseTokenize */
++
++  pOrig = pExpr->apExprPhrase[iPhrase];
++  pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
++  if( rc==SQLITE_OK ){
++    pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc, 
++        sizeof(Fts5ExprPhrase*));
++  }
++  if( rc==SQLITE_OK ){
++    pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, 
++        sizeof(Fts5ExprNode));
++  }
++  if( rc==SQLITE_OK ){
++    pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, 
++        sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
++  }
++  if( rc==SQLITE_OK ){
++    Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
++    if( pColsetOrig ){
++      int nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
++      Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
++      if( pColset ){ 
++        memcpy(pColset, pColsetOrig, nByte);
++      }
++      pNew->pRoot->pNear->pColset = pColset;
++    }
++  }
++
++  if( pOrig->nTerm ){
++    int i;                          /* Used to iterate through phrase terms */
++    for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
++      int tflags = 0;
++      Fts5ExprTerm *p;
++      for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
++        const char *zTerm = p->zTerm;
++        rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm),
++            0, 0);
++        tflags = FTS5_TOKEN_COLOCATED;
++      }
++      if( rc==SQLITE_OK ){
++        sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
++      }
++    }
 +  }else{
-+    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
++    /* This happens when parsing a token or quoted phrase that contains
++    ** no token characters at all. (e.g ... MATCH '""'). */
++    sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
 +  }
-+  return SQLITE_OK;
-+#endif
- 
--/*
--** This routine converts the sqlite3_pcache_page object returned by
--** sqlite3PcacheFetch() into an initialized PgHdr object.  This routine
--** must be called after sqlite3PcacheFetch() in order to get a usable
--** result.
--*/
--SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(
--  PCache *pCache,             /* Obtain the page from this cache */
--  Pgno pgno,                  /* Page number obtained */
--  sqlite3_pcache_page *pPage  /* Page obtained by prior PcacheFetch() call */
--){
--  PgHdr *pPgHdr;
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
-+  DWORD nByte;
-+  void *zConverted;
-+  char *zOut;
- 
--  if( pPage==0 ) return 0;
--  pPgHdr = (PgHdr *)pPage->pExtra;
-+  /* If this path name begins with "/X:", where "X" is any alphabetic
-+  ** character, discard the initial "/" from the pathname.
-+  */
-+  if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
-+    zRelative++;
++
++  if( rc==SQLITE_OK ){
++    /* All the allocations succeeded. Put the expression object together. */
++    pNew->pIndex = pExpr->pIndex;
++    pNew->pConfig = pExpr->pConfig;
++    pNew->nPhrase = 1;
++    pNew->apExprPhrase[0] = sCtx.pPhrase;
++    pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase;
++    pNew->pRoot->pNear->nPhrase = 1;
++    sCtx.pPhrase->pNode = pNew->pRoot;
++
++    if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){
++      pNew->pRoot->eType = FTS5_TERM;
++      pNew->pRoot->xNext = fts5ExprNodeNext_TERM;
++    }else{
++      pNew->pRoot->eType = FTS5_STRING;
++      pNew->pRoot->xNext = fts5ExprNodeNext_STRING;
++    }
++  }else{
++    sqlite3Fts5ExprFree(pNew);
++    fts5ExprPhraseFree(sCtx.pPhrase);
++    pNew = 0;
 +  }
- 
--  if( !pPgHdr->pPage ){
--    return pcacheFetchFinishWithInit(pCache, pgno, pPage);
-+  /* It's odd to simulate an io-error here, but really this is just
-+  ** using the io-error infrastructure to test that SQLite handles this
-+  ** function failing. This function could fail if, for example, the
-+  ** current working directory has been unlinked.
-+  */
-+  SimulateIOError( return SQLITE_ERROR );
-+  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
-+    /*
-+    ** NOTE: We are dealing with a relative path name and the data
-+    **       directory has been set.  Therefore, use it as the basis
-+    **       for converting the relative path name to an absolute
-+    **       one by prepending the data directory and a backslash.
-+    */
-+    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
-+                     sqlite3_data_directory, winGetDirSep(), zRelative);
-+    return SQLITE_OK;
-   }
--  if( 0==pPgHdr->nRef ){
--    pCache->nRef++;
-+  zConverted = winConvertFromUtf8Filename(zRelative);
-+  if( zConverted==0 ){
-+    return SQLITE_IOERR_NOMEM;
-   }
--  pPgHdr->nRef++;
--  if( pgno==1 ){
--    pCache->pPage1 = pPgHdr;
-+  if( osIsNT() ){
-+    LPWSTR zTemp;
-+    nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
-+    if( nByte==0 ){
-+      sqlite3_free(zConverted);
-+      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
-+                         "winFullPathname1", zRelative);
++
++  *ppNew = pNew;
++  return rc;
++}
++
++
++/*
++** Token pTok has appeared in a MATCH expression where the NEAR operator
++** is expected. If token pTok does not contain "NEAR", store an error
++** in the pParse object.
++*/
++static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token *pTok){
++  if( pTok->n!=4 || memcmp("NEAR", pTok->p, 4) ){
++    sqlite3Fts5ParseError(
++        pParse, "fts5: syntax error near \"%.*s\"", pTok->n, pTok->p
++    );
++  }
++}
++
++static void sqlite3Fts5ParseSetDistance(
++  Fts5Parse *pParse, 
++  Fts5ExprNearset *pNear,
++  Fts5Token *p
++){
++  if( pNear ){
++    int nNear = 0;
++    int i;
++    if( p->n ){
++      for(i=0; i<p->n; i++){
++        char c = (char)p->p[i];
++        if( c<'0' || c>'9' ){
++          sqlite3Fts5ParseError(
++              pParse, "expected integer, got \"%.*s\"", p->n, p->p
++              );
++          return;
++        }
++        nNear = nNear * 10 + (p->p[i] - '0');
++      }
++    }else{
++      nNear = FTS5_DEFAULT_NEARDIST;
 +    }
-+    nByte += 3;
-+    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
-+    if( zTemp==0 ){
-+      sqlite3_free(zConverted);
-+      return SQLITE_IOERR_NOMEM;
++    pNear->nNear = nNear;
++  }
++}
++
++/*
++** The second argument passed to this function may be NULL, or it may be
++** an existing Fts5Colset object. This function returns a pointer to
++** a new colset object containing the contents of (p) with new value column
++** number iCol appended. 
++**
++** If an OOM error occurs, store an error code in pParse and return NULL.
++** The old colset object (if any) is not freed in this case.
++*/
++static Fts5Colset *fts5ParseColset(
++  Fts5Parse *pParse,              /* Store SQLITE_NOMEM here if required */
++  Fts5Colset *p,                  /* Existing colset object */
++  int iCol                        /* New column to add to colset object */
++){
++  int nCol = p ? p->nCol : 0;     /* Num. columns already in colset object */
++  Fts5Colset *pNew;               /* New colset object to return */
++
++  assert( pParse->rc==SQLITE_OK );
++  assert( iCol>=0 && iCol<pParse->pConfig->nCol );
++
++  pNew = sqlite3_realloc(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
++  if( pNew==0 ){
++    pParse->rc = SQLITE_NOMEM;
++  }else{
++    int *aiCol = pNew->aiCol;
++    int i, j;
++    for(i=0; i<nCol; i++){
++      if( aiCol[i]==iCol ) return pNew;
++      if( aiCol[i]>iCol ) break;
 +    }
-+    nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
-+    if( nByte==0 ){
-+      sqlite3_free(zConverted);
-+      sqlite3_free(zTemp);
-+      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
-+                         "winFullPathname2", zRelative);
++    for(j=nCol; j>i; j--){
++      aiCol[j] = aiCol[j-1];
 +    }
-+    sqlite3_free(zConverted);
-+    zOut = winUnicodeToUtf8(zTemp);
-+    sqlite3_free(zTemp);
-   }
--  return pPgHdr;
--}
--
--/*
--** Decrement the reference count on a page. If the page is clean and the
--** reference count drops to 0, then it is made eligible for recycling.
--*/
--SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
--  assert( p->nRef>0 );
--  p->nRef--;
--  if( p->nRef==0 ){
--    p->pCache->nRef--;
--    if( (p->flags&PGHDR_DIRTY)==0 ){
--      pcacheUnpin(p);
--    }else if( p->pDirtyPrev!=0 ){
--      /* Move the page to the head of the dirty list. */
--      pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    char *zTemp;
-+    nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
-+    if( nByte==0 ){
-+      sqlite3_free(zConverted);
-+      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
-+                         "winFullPathname3", zRelative);
++    aiCol[i] = iCol;
++    pNew->nCol = nCol+1;
++
++#ifndef NDEBUG
++    /* Check that the array is in order and contains no duplicate entries. */
++    for(i=1; i<pNew->nCol; i++) assert( pNew->aiCol[i]>pNew->aiCol[i-1] );
++#endif
++  }
++
++  return pNew;
++}
++
++/*
++** Allocate and return an Fts5Colset object specifying the inverse of
++** the colset passed as the second argument. Free the colset passed
++** as the second argument before returning.
++*/
++static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){
++  Fts5Colset *pRet;
++  int nCol = pParse->pConfig->nCol;
++
++  pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc, 
++      sizeof(Fts5Colset) + sizeof(int)*nCol
++  );
++  if( pRet ){
++    int i;
++    int iOld = 0;
++    for(i=0; i<nCol; i++){
++      if( iOld>=p->nCol || p->aiCol[iOld]!=i ){
++        pRet->aiCol[pRet->nCol++] = i;
++      }else{
++        iOld++;
++      }
 +    }
-+    nByte += 3;
-+    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
-+    if( zTemp==0 ){
-+      sqlite3_free(zConverted);
-+      return SQLITE_IOERR_NOMEM;
++  }
++
++  sqlite3_free(p);
++  return pRet;
++}
++
++static Fts5Colset *sqlite3Fts5ParseColset(
++  Fts5Parse *pParse,              /* Store SQLITE_NOMEM here if required */
++  Fts5Colset *pColset,            /* Existing colset object */
++  Fts5Token *p
++){
++  Fts5Colset *pRet = 0;
++  int iCol;
++  char *z;                        /* Dequoted copy of token p */
++
++  z = sqlite3Fts5Strndup(&pParse->rc, p->p, p->n);
++  if( pParse->rc==SQLITE_OK ){
++    Fts5Config *pConfig = pParse->pConfig;
++    sqlite3Fts5Dequote(z);
++    for(iCol=0; iCol<pConfig->nCol; iCol++){
++      if( 0==sqlite3_stricmp(pConfig->azCol[iCol], z) ) break;
++    }
++    if( iCol==pConfig->nCol ){
++      sqlite3Fts5ParseError(pParse, "no such column: %s", z);
++    }else{
++      pRet = fts5ParseColset(pParse, pColset, iCol);
++    }
++    sqlite3_free(z);
++  }
++
++  if( pRet==0 ){
++    assert( pParse->rc!=SQLITE_OK );
++    sqlite3_free(pColset);
++  }
++
++  return pRet;
++}
++
++/*
++** If argument pOrig is NULL, or if (*pRc) is set to anything other than
++** SQLITE_OK when this function is called, NULL is returned. 
++**
++** Otherwise, a copy of (*pOrig) is made into memory obtained from
++** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation
++** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned.
++*/
++static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
++  Fts5Colset *pRet;
++  if( pOrig ){
++    int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
++    pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
++    if( pRet ){ 
++      memcpy(pRet, pOrig, nByte);
 +    }
-+    nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
-+    if( nByte==0 ){
-+      sqlite3_free(zConverted);
-+      sqlite3_free(zTemp);
-+      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
-+                         "winFullPathname4", zRelative);
-     }
-+    sqlite3_free(zConverted);
-+    zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
-+    sqlite3_free(zTemp);
-   }
-+#endif
-+  if( zOut ){
-+    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut);
-+    sqlite3_free(zOut);
-+    return SQLITE_OK;
 +  }else{
-+    return SQLITE_IOERR_NOMEM;
++    pRet = 0;
 +  }
-+#endif
- }
- 
-+#ifndef SQLITE_OMIT_LOAD_EXTENSION
- /*
--** Increase the reference count of a supplied page by 1.
--*/
--SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
--  assert(p->nRef>0);
--  p->nRef++;
--}
--
--/*
--** Drop a page from the cache. There must be exactly one reference to the
--** page. This function deletes that reference, so after it returns the
--** page pointed to by p is invalid.
-+** Interfaces for opening a shared library, finding entry points
-+** within the shared library, and closing the shared library.
- */
--SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
--  assert( p->nRef==1 );
--  if( p->flags&PGHDR_DIRTY ){
--    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
-+static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
-+  HANDLE h;
-+#if defined(__CYGWIN__)
-+  int nFull = pVfs->mxPathname+1;
-+  char *zFull = sqlite3MallocZero( nFull );
-+  void *zConverted = 0;
-+  if( zFull==0 ){
-+    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
-+    return 0;
-   }
--  p->pCache->nRef--;
--  if( p->pgno==1 ){
--    p->pCache->pPage1 = 0;
-+  if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
-+    sqlite3_free(zFull);
-+    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
-+    return 0;
-   }
--  sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1);
--}
--
--/*
--** Make sure the page is marked as dirty. If it isn't dirty already,
--** make it so.
--*/
--SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
--  p->flags &= ~PGHDR_DONT_WRITE;
--  assert( p->nRef>0 );
--  if( 0==(p->flags & PGHDR_DIRTY) ){
--    p->flags |= PGHDR_DIRTY;
--    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
-+  zConverted = winConvertFromUtf8Filename(zFull);
-+  sqlite3_free(zFull);
-+#else
-+  void *zConverted = winConvertFromUtf8Filename(zFilename);
-+  UNUSED_PARAMETER(pVfs);
-+#endif
-+  if( zConverted==0 ){
-+    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
-+    return 0;
-   }
--}
--
--/*
--** Make sure the page is marked as clean. If it isn't clean already,
--** make it so.
--*/
--SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
--  if( (p->flags & PGHDR_DIRTY) ){
--    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
--    p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC);
--    if( p->nRef==0 ){
--      pcacheUnpin(p);
--    }
-+  if( osIsNT() ){
-+#if SQLITE_OS_WINRT
-+    h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
-+#else
-+    h = osLoadLibraryW((LPCWSTR)zConverted);
-+#endif
-   }
--}
--
--/*
--** Make every page in the cache clean.
--*/
--SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){
--  PgHdr *p;
--  while( (p = pCache->pDirty)!=0 ){
--    sqlite3PcacheMakeClean(p);
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    h = osLoadLibraryA((char*)zConverted);
-   }
-+#endif
-+  OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h));
-+  sqlite3_free(zConverted);
-+  return (void*)h;
- }
--
--/*
--** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
--*/
--SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){
--  PgHdr *p;
--  for(p=pCache->pDirty; p; p=p->pDirtyNext){
--    p->flags &= ~PGHDR_NEED_SYNC;
--  }
--  pCache->pSynced = pCache->pDirtyTail;
-+static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
-+  UNUSED_PARAMETER(pVfs);
-+  winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut);
- }
--
--/*
--** Change the page number of page p to newPgno. 
--*/
--SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
--  PCache *pCache = p->pCache;
--  assert( p->nRef>0 );
--  assert( newPgno>0 );
--  sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
--  p->pgno = newPgno;
--  if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
--    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
--  }
-+static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
-+  FARPROC proc;
-+  UNUSED_PARAMETER(pVfs);
-+  proc = osGetProcAddressA((HANDLE)pH, zSym);
-+  OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n",
-+           (void*)pH, zSym, (void*)proc));
-+  return (void(*)(void))proc;
- }
-+static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
-+  UNUSED_PARAMETER(pVfs);
-+  osFreeLibrary((HANDLE)pHandle);
-+  OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle));
++  return pRet;
 +}
-+#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
-+  #define winDlOpen  0
-+  #define winDlError 0
-+  #define winDlSym   0
-+  #define winDlClose 0
-+#endif
 +
- 
- /*
--** Drop every cache entry whose page number is greater than "pgno". The
--** caller must ensure that there are no outstanding references to any pages
--** other than page 1 with a page number greater than pgno.
--**
--** If there is a reference to page 1 and the pgno parameter passed to this
--** function is 0, then the data area associated with page 1 is zeroed, but
--** the page object is not dropped.
-+** Write up to nBuf bytes of randomness into zBuf.
- */
--SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
--  if( pCache->pCache ){
--    PgHdr *p;
--    PgHdr *pNext;
--    for(p=pCache->pDirty; p; p=pNext){
--      pNext = p->pDirtyNext;
--      /* This routine never gets call with a positive pgno except right
--      ** after sqlite3PcacheCleanAll().  So if there are dirty pages,
--      ** it must be that pgno==0.
--      */
--      assert( p->pgno>0 );
--      if( ALWAYS(p->pgno>pgno) ){
--        assert( p->flags&PGHDR_DIRTY );
--        sqlite3PcacheMakeClean(p);
--      }
--    }
--    if( pgno==0 && pCache->pPage1 ){
--      memset(pCache->pPage1->pData, 0, pCache->szPage);
--      pgno = 1;
--    }
--    sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
-+static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-+  int n = 0;
-+  UNUSED_PARAMETER(pVfs);
-+#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
-+  n = nBuf;
-+  memset(zBuf, 0, nBuf);
-+#else
-+  if( sizeof(SYSTEMTIME)<=nBuf-n ){
-+    SYSTEMTIME x;
-+    osGetSystemTime(&x);
-+    memcpy(&zBuf[n], &x, sizeof(x));
-+    n += sizeof(x);
-+  }
-+  if( sizeof(DWORD)<=nBuf-n ){
-+    DWORD pid = osGetCurrentProcessId();
-+    memcpy(&zBuf[n], &pid, sizeof(pid));
-+    n += sizeof(pid);
-+  }
-+#if SQLITE_OS_WINRT
-+  if( sizeof(ULONGLONG)<=nBuf-n ){
-+    ULONGLONG cnt = osGetTickCount64();
-+    memcpy(&zBuf[n], &cnt, sizeof(cnt));
-+    n += sizeof(cnt);
++/*
++** Remove from colset pColset any columns that are not also in colset pMerge.
++*/
++static void fts5MergeColset(Fts5Colset *pColset, Fts5Colset *pMerge){
++  int iIn = 0;          /* Next input in pColset */
++  int iMerge = 0;       /* Next input in pMerge */
++  int iOut = 0;         /* Next output slot in pColset */
++
++  while( iIn<pColset->nCol && iMerge<pMerge->nCol ){
++    int iDiff = pColset->aiCol[iIn] - pMerge->aiCol[iMerge];
++    if( iDiff==0 ){
++      pColset->aiCol[iOut++] = pMerge->aiCol[iMerge];
++      iMerge++;
++      iIn++;
++    }else if( iDiff>0 ){
++      iMerge++;
++    }else{
++      iIn++;
++    }
 +  }
-+#else
-+  if( sizeof(DWORD)<=nBuf-n ){
-+    DWORD cnt = osGetTickCount();
-+    memcpy(&zBuf[n], &cnt, sizeof(cnt));
-+    n += sizeof(cnt);
-+  }
-+#endif
-+  if( sizeof(LARGE_INTEGER)<=nBuf-n ){
-+    LARGE_INTEGER i;
-+    osQueryPerformanceCounter(&i);
-+    memcpy(&zBuf[n], &i, sizeof(i));
-+    n += sizeof(i);
-+  }
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
-+  if( sizeof(UUID)<=nBuf-n ){
-+    UUID id;
-+    memset(&id, 0, sizeof(UUID));
-+    osUuidCreate(&id);
-+    memcpy(zBuf, &id, sizeof(UUID));
-+    n += sizeof(UUID);
-+  }
-+  if( sizeof(UUID)<=nBuf-n ){
-+    UUID id;
-+    memset(&id, 0, sizeof(UUID));
-+    osUuidCreateSequential(&id);
-+    memcpy(zBuf, &id, sizeof(UUID));
-+    n += sizeof(UUID);
-   }
-+#endif
-+#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
-+  return n;
- }
- 
--/*
--** Close a cache.
--*/
--SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
--  assert( pCache->pCache!=0 );
--  sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
--}
- 
--/* 
--** Discard the contents of the cache.
++  pColset->nCol = iOut;
++}
++
 +/*
-+** Sleep for a little while.  Return the amount of time slept.
- */
--SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){
--  sqlite3PcacheTruncate(pCache, 0);
-+static int winSleep(sqlite3_vfs *pVfs, int microsec){
-+  sqlite3_win32_sleep((microsec+999)/1000);
-+  UNUSED_PARAMETER(pVfs);
-+  return ((microsec+999)/1000)*1000;
- }
- 
- /*
--** Merge two lists of pages connected by pDirty and in pgno order.
--** Do not both fixing the pDirtyPrev pointers.
-+** The following variable, if set to a non-zero value, is interpreted as
-+** the number of seconds since 1970 and is used to set the result of
-+** sqlite3OsCurrentTime() during testing.
- */
--static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
--  PgHdr result, *pTail;
--  pTail = &result;
--  while( pA && pB ){
--    if( pA->pgno<pB->pgno ){
--      pTail->pDirty = pA;
--      pTail = pA;
--      pA = pA->pDirty;
--    }else{
--      pTail->pDirty = pB;
--      pTail = pB;
--      pB = pB->pDirty;
--    }
--  }
--  if( pA ){
--    pTail->pDirty = pA;
--  }else if( pB ){
--    pTail->pDirty = pB;
--  }else{
--    pTail->pDirty = 0;
--  }
--  return result.pDirty;
--}
-+#ifdef SQLITE_TEST
-+SQLITE_API int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
-+#endif
- 
- /*
--** Sort the list of pages in accending order by pgno.  Pages are
--** connected by pDirty pointers.  The pDirtyPrev pointers are
--** corrupted by this sort.
-+** Find the current time (in Universal Coordinated Time).  Write into *piNow
-+** the current time and date as a Julian Day number times 86_400_000.  In
-+** other words, write into *piNow the number of milliseconds since the Julian
-+** epoch of noon in Greenwich on November 24, 4714 B.C according to the
-+** proleptic Gregorian calendar.
- **
--** Since there cannot be more than 2^31 distinct pages in a database,
--** there cannot be more than 31 buckets required by the merge sorter.
--** One extra bucket is added to catch overflow in case something
--** ever changes to make the previous sentence incorrect.
-+** On success, return SQLITE_OK.  Return SQLITE_ERROR if the time and date
-+** cannot be found.
- */
--#define N_SORT_BUCKET  32
--static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
--  PgHdr *a[N_SORT_BUCKET], *p;
--  int i;
--  memset(a, 0, sizeof(a));
--  while( pIn ){
--    p = pIn;
--    pIn = p->pDirty;
--    p->pDirty = 0;
--    for(i=0; ALWAYS(i<N_SORT_BUCKET-1); i++){
--      if( a[i]==0 ){
--        a[i] = p;
--        break;
--      }else{
--        p = pcacheMergeDirtyList(a[i], p);
--        a[i] = 0;
--      }
--    }
--    if( NEVER(i==N_SORT_BUCKET-1) ){
--      /* To get here, there need to be 2^(N_SORT_BUCKET) elements in
--      ** the input list.  But that is impossible.
--      */
--      a[i] = pcacheMergeDirtyList(a[i], p);
--    }
-+static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
-+  /* FILETIME structure is a 64-bit value representing the number of
-+     100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
-+  */
-+  FILETIME ft;
-+  static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000;
-+#ifdef SQLITE_TEST
-+  static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
-+#endif
-+  /* 2^32 - to avoid use of LL and warnings in gcc */
-+  static const sqlite3_int64 max32BitValue =
-+      (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 +
-+      (sqlite3_int64)294967296;
++** Recursively apply colset pColset to expression node pNode and all of
++** its decendents. If (*ppFree) is not NULL, it contains a spare copy
++** of pColset. This function may use the spare copy and set (*ppFree) to
++** zero, or it may create copies of pColset using fts5CloneColset().
++*/
++static void fts5ParseSetColset(
++  Fts5Parse *pParse, 
++  Fts5ExprNode *pNode, 
++  Fts5Colset *pColset,
++  Fts5Colset **ppFree
++){
++  if( pParse->rc==SQLITE_OK ){
++    assert( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING 
++         || pNode->eType==FTS5_AND  || pNode->eType==FTS5_OR
++         || pNode->eType==FTS5_NOT  || pNode->eType==FTS5_EOF
++    );
++    if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
++      Fts5ExprNearset *pNear = pNode->pNear;
++      if( pNear->pColset ){
++        fts5MergeColset(pNear->pColset, pColset);
++        if( pNear->pColset->nCol==0 ){
++          pNode->eType = FTS5_EOF;
++          pNode->xNext = 0;
++        }
++      }else if( *ppFree ){
++        pNear->pColset = pColset;
++        *ppFree = 0;
++      }else{
++        pNear->pColset = fts5CloneColset(&pParse->rc, pColset);
++      }
++    }else{
++      int i;
++      assert( pNode->eType!=FTS5_EOF || pNode->nChild==0 );
++      for(i=0; i<pNode->nChild; i++){
++        fts5ParseSetColset(pParse, pNode->apChild[i], pColset, ppFree);
++      }
++    }
++  }
++}
 +
-+#if SQLITE_OS_WINCE
-+  SYSTEMTIME time;
-+  osGetSystemTime(&time);
-+  /* if SystemTimeToFileTime() fails, it returns zero. */
-+  if (!osSystemTimeToFileTime(&time,&ft)){
-+    return SQLITE_ERROR;
-   }
--  p = a[0];
--  for(i=1; i<N_SORT_BUCKET; i++){
--    p = pcacheMergeDirtyList(p, a[i]);
-+#else
-+  osGetSystemTimeAsFileTime( &ft );
-+#endif
++/*
++** Apply colset pColset to expression node pExpr and all of its descendents.
++*/
++static void sqlite3Fts5ParseSetColset(
++  Fts5Parse *pParse, 
++  Fts5ExprNode *pExpr, 
++  Fts5Colset *pColset 
++){
++  Fts5Colset *pFree = pColset;
++  if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){
++    pParse->rc = SQLITE_ERROR;
++    pParse->zErr = sqlite3_mprintf(
++      "fts5: column queries are not supported (detail=none)"
++    );
++  }else{
++    fts5ParseSetColset(pParse, pExpr, pColset, &pFree);
++  }
++  sqlite3_free(pFree);
++}
 +
-+  *piNow = winFiletimeEpoch +
-+            ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) +
-+               (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
++static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
++  switch( pNode->eType ){
++    case FTS5_STRING: {
++      Fts5ExprNearset *pNear = pNode->pNear;
++      if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1 
++       && pNear->apPhrase[0]->aTerm[0].pSynonym==0
++      ){
++        pNode->eType = FTS5_TERM;
++        pNode->xNext = fts5ExprNodeNext_TERM;
++      }else{
++        pNode->xNext = fts5ExprNodeNext_STRING;
++      }
++      break;
++    };
 +
-+#ifdef SQLITE_TEST
-+  if( sqlite3_current_time ){
-+    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
-   }
--  return p;
-+#endif
-+  UNUSED_PARAMETER(pVfs);
-+  return SQLITE_OK;
- }
- 
- /*
--** Return a list of all dirty pages in the cache, sorted by page number.
-+** Find the current time (in Universal Coordinated Time).  Write the
-+** current time and date as a Julian Day number into *prNow and
-+** return 0.  Return 1 if the time and date cannot be found.
- */
--SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
--  PgHdr *p;
--  for(p=pCache->pDirty; p; p=p->pDirtyNext){
--    p->pDirty = p->pDirtyNext;
-+static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
-+  int rc;
-+  sqlite3_int64 i;
-+  rc = winCurrentTimeInt64(pVfs, &i);
-+  if( !rc ){
-+    *prNow = i/86400000.0;
-   }
--  return pcacheSortDirtyList(pCache->pDirty);
-+  return rc;
- }
- 
--/* 
--** Return the total number of referenced pages held by the cache.
-+/*
-+** The idea is that this function works like a combination of
-+** GetLastError() and FormatMessage() on Windows (or errno and
-+** strerror_r() on Unix). After an error is returned by an OS
-+** function, SQLite calls this function with zBuf pointing to
-+** a buffer of nBuf bytes. The OS layer should populate the
-+** buffer with a nul-terminated UTF-8 encoded error message
-+** describing the last IO error to have occurred within the calling
-+** thread.
-+**
-+** If the error message is too large for the supplied buffer,
-+** it should be truncated. The return value of xGetLastError
-+** is zero if the error message fits in the buffer, or non-zero
-+** otherwise (if the message was truncated). If non-zero is returned,
-+** then it is not necessary to include the nul-terminator character
-+** in the output buffer.
-+**
-+** Not supplying an error message will have no adverse effect
-+** on SQLite. It is fine to have an implementation that never
-+** returns an error message:
-+**
-+**   int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-+**     assert(zBuf[0]=='\0');
-+**     return 0;
-+**   }
-+**
-+** However if an error message is supplied, it will be incorporated
-+** by sqlite into the error message available to the user using
-+** sqlite3_errmsg(), possibly making IO errors easier to debug.
- */
--SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
--  return pCache->nRef;
-+static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-+  UNUSED_PARAMETER(pVfs);
-+  return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf);
- }
- 
- /*
--** Return the number of references to the page supplied as an argument.
-+** Initialize and deinitialize the operating system interface.
- */
--SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){
--  return p->nRef;
--}
-+SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
-+  static sqlite3_vfs winVfs = {
-+    3,                   /* iVersion */
-+    sizeof(winFile),     /* szOsFile */
-+    SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
-+    0,                   /* pNext */
-+    "win32",             /* zName */
-+    0,                   /* pAppData */
-+    winOpen,             /* xOpen */
-+    winDelete,           /* xDelete */
-+    winAccess,           /* xAccess */
-+    winFullPathname,     /* xFullPathname */
-+    winDlOpen,           /* xDlOpen */
-+    winDlError,          /* xDlError */
-+    winDlSym,            /* xDlSym */
-+    winDlClose,          /* xDlClose */
-+    winRandomness,       /* xRandomness */
-+    winSleep,            /* xSleep */
-+    winCurrentTime,      /* xCurrentTime */
-+    winGetLastError,     /* xGetLastError */
-+    winCurrentTimeInt64, /* xCurrentTimeInt64 */
-+    winSetSystemCall,    /* xSetSystemCall */
-+    winGetSystemCall,    /* xGetSystemCall */
-+    winNextSystemCall,   /* xNextSystemCall */
-+  };
-+#if defined(SQLITE_WIN32_HAS_WIDE)
-+  static sqlite3_vfs winLongPathVfs = {
-+    3,                   /* iVersion */
-+    sizeof(winFile),     /* szOsFile */
-+    SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
-+    0,                   /* pNext */
-+    "win32-longpath",    /* zName */
-+    0,                   /* pAppData */
-+    winOpen,             /* xOpen */
-+    winDelete,           /* xDelete */
-+    winAccess,           /* xAccess */
-+    winFullPathname,     /* xFullPathname */
-+    winDlOpen,           /* xDlOpen */
-+    winDlError,          /* xDlError */
-+    winDlSym,            /* xDlSym */
-+    winDlClose,          /* xDlClose */
-+    winRandomness,       /* xRandomness */
-+    winSleep,            /* xSleep */
-+    winCurrentTime,      /* xCurrentTime */
-+    winGetLastError,     /* xGetLastError */
-+    winCurrentTimeInt64, /* xCurrentTimeInt64 */
-+    winSetSystemCall,    /* xSetSystemCall */
-+    winGetSystemCall,    /* xGetSystemCall */
-+    winNextSystemCall,   /* xNextSystemCall */
-+  };
-+#endif
- 
--/* 
--** Return the total number of pages in the cache.
--*/
--SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){
--  assert( pCache->pCache!=0 );
--  return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
--}
-+  /* Double-check that the aSyscall[] array has been constructed
-+  ** correctly.  See ticket [bb3a86e890c8e96ab] */
-+  assert( ArraySize(aSyscall)==80 );
- 
--#ifdef SQLITE_TEST
--/*
--** Get the suggested cache-size value.
--*/
--SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){
--  return numberOfCachePages(pCache);
--}
-+  /* get memory map allocation granularity */
-+  memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
-+#if SQLITE_OS_WINRT
-+  osGetNativeSystemInfo(&winSysInfo);
-+#else
-+  osGetSystemInfo(&winSysInfo);
- #endif
-+  assert( winSysInfo.dwAllocationGranularity>0 );
-+  assert( winSysInfo.dwPageSize>0 );
- 
--/*
--** Set the suggested cache-size value.
--*/
--SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
--  assert( pCache->pCache!=0 );
--  pCache->szCache = mxPage;
--  sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
--                                         numberOfCachePages(pCache));
--}
--
--/*
--** Free up as much memory as possible from the page cache.
--*/
--SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
--  assert( pCache->pCache!=0 );
--  sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
--}
-+  sqlite3_vfs_register(&winVfs, 1);
- 
--/*
--** Return the size of the header added by this middleware layer
--** in the page-cache hierarchy.
--*/
--SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
-+#if defined(SQLITE_WIN32_HAS_WIDE)
-+  sqlite3_vfs_register(&winLongPathVfs, 0);
-+#endif
- 
-+  return SQLITE_OK;
++    case FTS5_OR: {
++      pNode->xNext = fts5ExprNodeNext_OR;
++      break;
++    };
++
++    case FTS5_AND: {
++      pNode->xNext = fts5ExprNodeNext_AND;
++      break;
++    };
++
++    default: assert( pNode->eType==FTS5_NOT ); {
++      pNode->xNext = fts5ExprNodeNext_NOT;
++      break;
++    };
++  }
 +}
- 
--#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
--/*
--** For all dirty pages currently in the cache, invoke the specified
--** callback. This is only used if the SQLITE_CHECK_PAGES macro is
--** defined.
--*/
--SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){
--  PgHdr *pDirty;
--  for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){
--    xIter(pDirty);
-+SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
-+#if SQLITE_OS_WINRT
-+  if( sleepObj!=NULL ){
-+    osCloseHandle(sleepObj);
-+    sleepObj = NULL;
-   }
--}
- #endif
-+  return SQLITE_OK;
++
++static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
++  if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){
++    int nByte = sizeof(Fts5ExprNode*) * pSub->nChild;
++    memcpy(&p->apChild[p->nChild], pSub->apChild, nByte);
++    p->nChild += pSub->nChild;
++    sqlite3_free(pSub);
++  }else{
++    p->apChild[p->nChild++] = pSub;
++  }
 +}
- 
--/************** End of pcache.c **********************************************/
--/************** Begin file pcache1.c *****************************************/
-+#endif /* SQLITE_OS_WIN */
 +
-+/************** End of os_win.c **********************************************/
-+/************** Begin file bitvec.c ******************************************/
- /*
--** 2008 November 05
-+** 2008 February 16
- **
- ** The author disclaims copyright to this source code.  In place of
- ** a legal notice, here is a blessing:
-@@ -39935,1052 +42486,1078 @@
- **    May you share freely, never taking more than you give.
- **
- *************************************************************************
-+** This file implements an object that represents a fixed-length
-+** bitmap.  Bits are numbered starting with 1.
- **
--** This file implements the default page cache implementation (the
--** sqlite3_pcache interface). It also contains part of the implementation
--** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
--** If the default page cache implementation is overridden, then neither of
--** these two features are available.
--*/
--
--
--typedef struct PCache1 PCache1;
--typedef struct PgHdr1 PgHdr1;
--typedef struct PgFreeslot PgFreeslot;
--typedef struct PGroup PGroup;
--
--/* Each page cache (or PCache) belongs to a PGroup.  A PGroup is a set 
--** of one or more PCaches that are able to recycle each other's unpinned
--** pages when they are under memory pressure.  A PGroup is an instance of
--** the following object.
--**
--** This page cache implementation works in one of two modes:
--**
--**   (1)  Every PCache is the sole member of its own PGroup.  There is
--**        one PGroup per PCache.
--**
--**   (2)  There is a single global PGroup that all PCaches are a member
--**        of.
-+** A bitmap is used to record which pages of a database file have been
-+** journalled during a transaction, or which pages have the "dont-write"
-+** property.  Usually only a few pages are meet either condition.
-+** So the bitmap is usually sparse and has low cardinality.
-+** But sometimes (for example when during a DROP of a large table) most
-+** or all of the pages in a database can get journalled.  In those cases, 
-+** the bitmap becomes dense with high cardinality.  The algorithm needs 
-+** to handle both cases well.
- **
--** Mode 1 uses more memory (since PCache instances are not able to rob
--** unused pages from other PCaches) but it also operates without a mutex,
--** and is therefore often faster.  Mode 2 requires a mutex in order to be
--** threadsafe, but recycles pages more efficiently.
-+** The size of the bitmap is fixed when the object is created.
- **
--** For mode (1), PGroup.mutex is NULL.  For mode (2) there is only a single
--** PGroup which is the pcache1.grp global variable and its mutex is
--** SQLITE_MUTEX_STATIC_LRU.
--*/
--struct PGroup {
--  sqlite3_mutex *mutex;          /* MUTEX_STATIC_LRU or NULL */
--  unsigned int nMaxPage;         /* Sum of nMax for purgeable caches */
--  unsigned int nMinPage;         /* Sum of nMin for purgeable caches */
--  unsigned int mxPinned;         /* nMaxpage + 10 - nMinPage */
--  unsigned int nCurrentPage;     /* Number of purgeable pages allocated */
--  PgHdr1 *pLruHead, *pLruTail;   /* LRU list of unpinned pages */
--};
--
--/* Each page cache is an instance of the following object.  Every
--** open database file (including each in-memory database and each
--** temporary or transient database) has a single page cache which
--** is an instance of this object.
-+** All bits are clear when the bitmap is created.  Individual bits
-+** may be set or cleared one at a time.
- **
--** Pointers to structures of this type are cast and returned as 
--** opaque sqlite3_pcache* handles.
-+** Test operations are about 100 times more common that set operations.
-+** Clear operations are exceedingly rare.  There are usually between
-+** 5 and 500 set operations per Bitvec object, though the number of sets can
-+** sometimes grow into tens of thousands or larger.  The size of the
-+** Bitvec object is the number of pages in the database file at the
-+** start of a transaction, and is thus usually less than a few thousand,
-+** but can be as large as 2 billion for a really big database.
- */
--struct PCache1 {
--  /* Cache configuration parameters. Page size (szPage) and the purgeable
--  ** flag (bPurgeable) are set when the cache is created. nMax may be 
--  ** modified at any time by a call to the pcache1Cachesize() method.
--  ** The PGroup mutex must be held when accessing nMax.
--  */
--  PGroup *pGroup;                     /* PGroup this cache belongs to */
--  int szPage;                         /* Size of allocated pages in bytes */
--  int szExtra;                        /* Size of extra space in bytes */
--  int bPurgeable;                     /* True if cache is purgeable */
--  unsigned int nMin;                  /* Minimum number of pages reserved */
--  unsigned int nMax;                  /* Configured "cache_size" value */
--  unsigned int n90pct;                /* nMax*9/10 */
--  unsigned int iMaxKey;               /* Largest key seen since xTruncate() */
- 
--  /* Hash table of all pages. The following variables may only be accessed
--  ** when the accessor is holding the PGroup mutex.
--  */
--  unsigned int nRecyclable;           /* Number of pages in the LRU list */
--  unsigned int nPage;                 /* Total number of pages in apHash */
--  unsigned int nHash;                 /* Number of slots in apHash[] */
--  PgHdr1 **apHash;                    /* Hash table for fast lookup by key */
--};
-+/* Size of the Bitvec structure in bytes. */
-+#define BITVEC_SZ        512
- 
--/*
--** Each cache entry is represented by an instance of the following 
--** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
--** PgHdr1.pCache->szPage bytes is allocated directly before this structure 
--** in memory.
--*/
--struct PgHdr1 {
--  sqlite3_pcache_page page;
--  unsigned int iKey;             /* Key value (page number) */
--  u8 isPinned;                   /* Page in use, not on the LRU list */
--  PgHdr1 *pNext;                 /* Next in hash table chain */
--  PCache1 *pCache;               /* Cache that currently owns this page */
--  PgHdr1 *pLruNext;              /* Next in LRU list of unpinned pages */
--  PgHdr1 *pLruPrev;              /* Previous in LRU list of unpinned pages */
--};
-+/* Round the union size down to the nearest pointer boundary, since that's how 
-+** it will be aligned within the Bitvec struct. */
-+#define BITVEC_USIZE     (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))
- 
--/*
--** Free slots in the allocator used to divide up the buffer provided using
--** the SQLITE_CONFIG_PAGECACHE mechanism.
--*/
--struct PgFreeslot {
--  PgFreeslot *pNext;  /* Next free slot */
--};
-+/* Type of the array "element" for the bitmap representation. 
-+** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. 
-+** Setting this to the "natural word" size of your CPU may improve
-+** performance. */
-+#define BITVEC_TELEM     u8
-+/* Size, in bits, of the bitmap element. */
-+#define BITVEC_SZELEM    8
-+/* Number of elements in a bitmap array. */
-+#define BITVEC_NELEM     (BITVEC_USIZE/sizeof(BITVEC_TELEM))
-+/* Number of bits in the bitmap array. */
-+#define BITVEC_NBIT      (BITVEC_NELEM*BITVEC_SZELEM)
- 
--/*
--** Global data used by this cache.
--*/
--static SQLITE_WSD struct PCacheGlobal {
--  PGroup grp;                    /* The global PGroup for mode (2) */
-+/* Number of u32 values in hash table. */
-+#define BITVEC_NINT      (BITVEC_USIZE/sizeof(u32))
-+/* Maximum number of entries in hash table before 
-+** sub-dividing and re-hashing. */
-+#define BITVEC_MXHASH    (BITVEC_NINT/2)
-+/* Hashing function for the aHash representation.
-+** Empirical testing showed that the *37 multiplier 
-+** (an arbitrary prime)in the hash function provided 
-+** no fewer collisions than the no-op *1. */
-+#define BITVEC_HASH(X)   (((X)*1)%BITVEC_NINT)
- 
--  /* Variables related to SQLITE_CONFIG_PAGECACHE settings.  The
--  ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all
--  ** fixed at sqlite3_initialize() time and do not require mutex protection.
--  ** The nFreeSlot and pFree values do require mutex protection.
--  */
--  int isInit;                    /* True if initialized */
--  int szSlot;                    /* Size of each free slot */
--  int nSlot;                     /* The number of pcache slots */
--  int nReserve;                  /* Try to keep nFreeSlot above this */
--  void *pStart, *pEnd;           /* Bounds of pagecache malloc range */
--  /* Above requires no mutex.  Use mutex below for variable that follow. */
--  sqlite3_mutex *mutex;          /* Mutex for accessing the following: */
--  PgFreeslot *pFree;             /* Free page blocks */
--  int nFreeSlot;                 /* Number of unused pcache slots */
--  /* The following value requires a mutex to change.  We skip the mutex on
--  ** reading because (1) most platforms read a 32-bit integer atomically and
--  ** (2) even if an incorrect value is read, no great harm is done since this
--  ** is really just an optimization. */
--  int bUnderPressure;            /* True if low on PAGECACHE memory */
--} pcache1_g;
-+#define BITVEC_NPTR      (BITVEC_USIZE/sizeof(Bitvec *))
- 
--/*
--** All code in this file should access the global structure above via the
--** alias "pcache1". This ensures that the WSD emulation is used when
--** compiling for systems that do not support real WSD.
--*/
--#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g))
- 
- /*
--** Macros to enter and leave the PCache LRU mutex.
-+** A bitmap is an instance of the following structure.
-+**
-+** This bitmap records the existence of zero or more bits
-+** with values between 1 and iSize, inclusive.
-+**
-+** There are three possible representations of the bitmap.
-+** If iSize<=BITVEC_NBIT, then Bitvec.u.aBitmap[] is a straight
-+** bitmap.  The least significant bit is bit 1.
-+**
-+** If iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is
-+** a hash table that will hold up to BITVEC_MXHASH distinct values.
-+**
-+** Otherwise, the value i is redirected into one of BITVEC_NPTR
-+** sub-bitmaps pointed to by Bitvec.u.apSub[].  Each subbitmap
-+** handles up to iDivisor separate values of i.  apSub[0] holds
-+** values between 1 and iDivisor.  apSub[1] holds values between
-+** iDivisor+1 and 2*iDivisor.  apSub[N] holds values between
-+** N*iDivisor+1 and (N+1)*iDivisor.  Each subbitmap is normalized
-+** to hold deal with values between 1 and iDivisor.
- */
--#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
--#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
--
--/******************************************************************************/
--/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
-+struct Bitvec {
-+  u32 iSize;      /* Maximum bit index.  Max iSize is 4,294,967,296. */
-+  u32 nSet;       /* Number of bits that are set - only valid for aHash
-+                  ** element.  Max is BITVEC_NINT.  For BITVEC_SZ of 512,
-+                  ** this would be 125. */
-+  u32 iDivisor;   /* Number of bits handled by each apSub[] entry. */
-+                  /* Should >=0 for apSub element. */
-+                  /* Max iDivisor is max(u32) / BITVEC_NPTR + 1.  */
-+                  /* For a BITVEC_SZ of 512, this would be 34,359,739. */
-+  union {
-+    BITVEC_TELEM aBitmap[BITVEC_NELEM];    /* Bitmap representation */
-+    u32 aHash[BITVEC_NINT];      /* Hash table representation */
-+    Bitvec *apSub[BITVEC_NPTR];  /* Recursive representation */
-+  } u;
-+};
- 
- /*
--** This function is called during initialization if a static buffer is 
--** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE
--** verb to sqlite3_config(). Parameter pBuf points to an allocation large
--** enough to contain 'n' buffers of 'sz' bytes each.
--**
--** This routine is called from sqlite3_initialize() and so it is guaranteed
--** to be serialized already.  There is no need for further mutexing.
-+** Create a new bitmap object able to handle bits between 0 and iSize,
-+** inclusive.  Return a pointer to the new object.  Return NULL if 
-+** malloc fails.
- */
--SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
--  if( pcache1.isInit ){
--    PgFreeslot *p;
--    sz = ROUNDDOWN8(sz);
--    pcache1.szSlot = sz;
--    pcache1.nSlot = pcache1.nFreeSlot = n;
--    pcache1.nReserve = n>90 ? 10 : (n/10 + 1);
--    pcache1.pStart = pBuf;
--    pcache1.pFree = 0;
--    pcache1.bUnderPressure = 0;
--    while( n-- ){
--      p = (PgFreeslot*)pBuf;
--      p->pNext = pcache1.pFree;
--      pcache1.pFree = p;
--      pBuf = (void*)&((char*)pBuf)[sz];
--    }
--    pcache1.pEnd = pBuf;
-+SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){
-+  Bitvec *p;
-+  assert( sizeof(*p)==BITVEC_SZ );
-+  p = sqlite3MallocZero( sizeof(*p) );
-+  if( p ){
-+    p->iSize = iSize;
-   }
-+  return p;
- }
- 
- /*
--** Malloc function used within this file to allocate space from the buffer
--** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no 
--** such buffer exists or there is no space left in it, this function falls 
--** back to sqlite3Malloc().
--**
--** Multiple threads can run this routine at the same time.  Global variables
--** in pcache1 need to be protected via mutex.
-+** Check to see if the i-th bit is set.  Return true or false.
-+** If p is NULL (if the bitmap has not been created) or if
-+** i is out of range, then return false.
- */
--static void *pcache1Alloc(int nByte){
--  void *p = 0;
--  assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
--  if( nByte<=pcache1.szSlot ){
--    sqlite3_mutex_enter(pcache1.mutex);
--    p = (PgHdr1 *)pcache1.pFree;
--    if( p ){
--      pcache1.pFree = pcache1.pFree->pNext;
--      pcache1.nFreeSlot--;
--      pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
--      assert( pcache1.nFreeSlot>=0 );
--      sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
--      sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
-+SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){
-+  if( p==0 ) return 0;
-+  if( i>p->iSize || i==0 ) return 0;
-+  i--;
-+  while( p->iDivisor ){
-+    u32 bin = i/p->iDivisor;
-+    i = i%p->iDivisor;
-+    p = p->u.apSub[bin];
-+    if (!p) {
-+      return 0;
-     }
--    sqlite3_mutex_leave(pcache1.mutex);
-   }
--  if( p==0 ){
--    /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool.  Get
--    ** it from sqlite3Malloc instead.
--    */
--    p = sqlite3Malloc(nByte);
--#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
--    if( p ){
--      int sz = sqlite3MallocSize(p);
--      sqlite3_mutex_enter(pcache1.mutex);
--      sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
--      sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
--      sqlite3_mutex_leave(pcache1.mutex);
-+  if( p->iSize<=BITVEC_NBIT ){
-+    return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0;
-+  } else{
-+    u32 h = BITVEC_HASH(i++);
-+    while( p->u.aHash[h] ){
-+      if( p->u.aHash[h]==i ) return 1;
-+      h = (h+1) % BITVEC_NINT;
-     }
--#endif
--    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
-+    return 0;
-   }
--  return p;
- }
- 
- /*
--** Free an allocated buffer obtained from pcache1Alloc().
-+** Set the i-th bit.  Return 0 on success and an error code if
-+** anything goes wrong.
-+**
-+** This routine might cause sub-bitmaps to be allocated.  Failing
-+** to get the memory needed to hold the sub-bitmap is the only
-+** that can go wrong with an insert, assuming p and i are valid.
-+**
-+** The calling function must ensure that p is a valid Bitvec object
-+** and that the value for "i" is within range of the Bitvec object.
-+** Otherwise the behavior is undefined.
- */
--static int pcache1Free(void *p){
--  int nFreed = 0;
--  if( p==0 ) return 0;
--  if( p>=pcache1.pStart && p<pcache1.pEnd ){
--    PgFreeslot *pSlot;
--    sqlite3_mutex_enter(pcache1.mutex);
--    sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1);
--    pSlot = (PgFreeslot*)p;
--    pSlot->pNext = pcache1.pFree;
--    pcache1.pFree = pSlot;
--    pcache1.nFreeSlot++;
--    pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
--    assert( pcache1.nFreeSlot<=pcache1.nSlot );
--    sqlite3_mutex_leave(pcache1.mutex);
--  }else{
--    assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
--    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
--    nFreed = sqlite3MallocSize(p);
--#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
--    sqlite3_mutex_enter(pcache1.mutex);
--    sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
--    sqlite3_mutex_leave(pcache1.mutex);
--#endif
--    sqlite3_free(p);
-+SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){
-+  u32 h;
-+  if( p==0 ) return SQLITE_OK;
-+  assert( i>0 );
-+  assert( i<=p->iSize );
-+  i--;
-+  while((p->iSize > BITVEC_NBIT) && p->iDivisor) {
-+    u32 bin = i/p->iDivisor;
-+    i = i%p->iDivisor;
-+    if( p->u.apSub[bin]==0 ){
-+      p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
-+      if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
-+    }
-+    p = p->u.apSub[bin];
-   }
--  return nFreed;
--}
--
--#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
--/*
--** Return the size of a pcache allocation
--*/
--static int pcache1MemSize(void *p){
--  if( p>=pcache1.pStart && p<pcache1.pEnd ){
--    return pcache1.szSlot;
--  }else{
--    int iSize;
--    assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
--    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
--    iSize = sqlite3MallocSize(p);
--    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
--    return iSize;
-+  if( p->iSize<=BITVEC_NBIT ){
-+    p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1));
-+    return SQLITE_OK;
-   }
-+  h = BITVEC_HASH(i++);
-+  /* if there wasn't a hash collision, and this doesn't */
-+  /* completely fill the hash, then just add it without */
-+  /* worring about sub-dividing and re-hashing. */
-+  if( !p->u.aHash[h] ){
-+    if (p->nSet<(BITVEC_NINT-1)) {
-+      goto bitvec_set_end;
-+    } else {
-+      goto bitvec_set_rehash;
++/*
++** Allocate and return a new expression object. If anything goes wrong (i.e.
++** OOM error), leave an error code in pParse and return NULL.
++*/
++static Fts5ExprNode *sqlite3Fts5ParseNode(
++  Fts5Parse *pParse,              /* Parse context */
++  int eType,                      /* FTS5_STRING, AND, OR or NOT */
++  Fts5ExprNode *pLeft,            /* Left hand child expression */
++  Fts5ExprNode *pRight,           /* Right hand child expression */
++  Fts5ExprNearset *pNear          /* For STRING expressions, the near cluster */
++){
++  Fts5ExprNode *pRet = 0;
++
++  if( pParse->rc==SQLITE_OK ){
++    int nChild = 0;               /* Number of children of returned node */
++    int nByte;                    /* Bytes of space to allocate for this node */
++ 
++    assert( (eType!=FTS5_STRING && !pNear)
++         || (eType==FTS5_STRING && !pLeft && !pRight)
++    );
++    if( eType==FTS5_STRING && pNear==0 ) return 0;
++    if( eType!=FTS5_STRING && pLeft==0 ) return pRight;
++    if( eType!=FTS5_STRING && pRight==0 ) return pLeft;
++
++    if( eType==FTS5_NOT ){
++      nChild = 2;
++    }else if( eType==FTS5_AND || eType==FTS5_OR ){
++      nChild = 2;
++      if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
++      if( pRight->eType==eType ) nChild += pRight->nChild-1;
++    }
++
++    nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
++    pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
++
++    if( pRet ){
++      pRet->eType = eType;
++      pRet->pNear = pNear;
++      fts5ExprAssignXNext(pRet);
++      if( eType==FTS5_STRING ){
++        int iPhrase;
++        for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
++          pNear->apPhrase[iPhrase]->pNode = pRet;
++          if( pNear->apPhrase[iPhrase]->nTerm==0 ){
++            pRet->xNext = 0;
++            pRet->eType = FTS5_EOF;
++          }
++        }
++
++        if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL 
++         && (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm>1)
++        ){
++          assert( pParse->rc==SQLITE_OK );
++          pParse->rc = SQLITE_ERROR;
++          assert( pParse->zErr==0 );
++          pParse->zErr = sqlite3_mprintf(
++              "fts5: %s queries are not supported (detail!=full)", 
++              pNear->nPhrase==1 ? "phrase": "NEAR"
++          );
++          sqlite3_free(pRet);
++          pRet = 0;
++        }
++
++      }else{
++        fts5ExprAddChildren(pRet, pLeft);
++        fts5ExprAddChildren(pRet, pRight);
++      }
++    }
++  }
++
++  if( pRet==0 ){
++    assert( pParse->rc!=SQLITE_OK );
++    sqlite3Fts5ParseNodeFree(pLeft);
++    sqlite3Fts5ParseNodeFree(pRight);
++    sqlite3Fts5ParseNearsetFree(pNear);
++  }
++  return pRet;
++}
++
++static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
++  Fts5Parse *pParse,              /* Parse context */
++  Fts5ExprNode *pLeft,            /* Left hand child expression */
++  Fts5ExprNode *pRight            /* Right hand child expression */
++){
++  Fts5ExprNode *pRet = 0;
++  Fts5ExprNode *pPrev;
++
++  if( pParse->rc ){
++    sqlite3Fts5ParseNodeFree(pLeft);
++    sqlite3Fts5ParseNodeFree(pRight);
++  }else{
++
++    assert( pLeft->eType==FTS5_STRING 
++        || pLeft->eType==FTS5_TERM
++        || pLeft->eType==FTS5_EOF
++        || pLeft->eType==FTS5_AND
++    );
++    assert( pRight->eType==FTS5_STRING 
++        || pRight->eType==FTS5_TERM 
++        || pRight->eType==FTS5_EOF 
++    );
++
++    if( pLeft->eType==FTS5_AND ){
++      pPrev = pLeft->apChild[pLeft->nChild-1];
++    }else{
++      pPrev = pLeft;
++    }
++    assert( pPrev->eType==FTS5_STRING 
++        || pPrev->eType==FTS5_TERM 
++        || pPrev->eType==FTS5_EOF 
++        );
++
++    if( pRight->eType==FTS5_EOF ){
++      assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] );
++      sqlite3Fts5ParseNodeFree(pRight);
++      pRet = pLeft;
++      pParse->nPhrase--;
++    }
++    else if( pPrev->eType==FTS5_EOF ){
++      Fts5ExprPhrase **ap;
++
++      if( pPrev==pLeft ){
++        pRet = pRight;
++      }else{
++        pLeft->apChild[pLeft->nChild-1] = pRight;
++        pRet = pLeft;
++      }
++
++      ap = &pParse->apPhrase[pParse->nPhrase-1-pRight->pNear->nPhrase];
++      assert( ap[0]==pPrev->pNear->apPhrase[0] );
++      memmove(ap, &ap[1], sizeof(Fts5ExprPhrase*)*pRight->pNear->nPhrase);
++      pParse->nPhrase--;
++
++      sqlite3Fts5ParseNodeFree(pPrev);
++    }
++    else{
++      pRet = sqlite3Fts5ParseNode(pParse, FTS5_AND, pLeft, pRight, 0);
 +    }
 +  }
-+  /* there was a collision, check to see if it's already */
-+  /* in hash, if not, try to find a spot for it */
-+  do {
-+    if( p->u.aHash[h]==i ) return SQLITE_OK;
-+    h++;
-+    if( h>=BITVEC_NINT ) h = 0;
-+  } while( p->u.aHash[h] );
-+  /* we didn't find it in the hash.  h points to the first */
-+  /* available free spot. check to see if this is going to */
-+  /* make our hash too "full".  */
-+bitvec_set_rehash:
-+  if( p->nSet>=BITVEC_MXHASH ){
-+    unsigned int j;
-+    int rc;
-+    u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
-+    if( aiValues==0 ){
-+      return SQLITE_NOMEM;
-+    }else{
-+      memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
-+      memset(p->u.apSub, 0, sizeof(p->u.apSub));
-+      p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
-+      rc = sqlite3BitvecSet(p, i);
-+      for(j=0; j<BITVEC_NINT; j++){
-+        if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
++
++  return pRet;
++}
++
++static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
++  int nByte = 0;
++  Fts5ExprTerm *p;
++  char *zQuoted;
++
++  /* Determine the maximum amount of space required. */
++  for(p=pTerm; p; p=p->pSynonym){
++    nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
++  }
++  zQuoted = sqlite3_malloc(nByte);
++
++  if( zQuoted ){
++    int i = 0;
++    for(p=pTerm; p; p=p->pSynonym){
++      char *zIn = p->zTerm;
++      zQuoted[i++] = '"';
++      while( *zIn ){
++        if( *zIn=='"' ) zQuoted[i++] = '"';
++        zQuoted[i++] = *zIn++;
 +      }
-+      sqlite3StackFree(0, aiValues);
-+      return rc;
++      zQuoted[i++] = '"';
++      if( p->pSynonym ) zQuoted[i++] = '|';
 +    }
++    if( pTerm->bPrefix ){
++      zQuoted[i++] = ' ';
++      zQuoted[i++] = '*';
++    }
++    zQuoted[i++] = '\0';
 +  }
-+bitvec_set_end:
-+  p->nSet++;
-+  p->u.aHash[h] = i;
-+  return SQLITE_OK;
- }
--#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
- 
- /*
--** Allocate a new page object initially associated with cache pCache.
-+** Clear the i-th bit.
-+**
-+** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
-+** that BitvecClear can use to rebuilt its hash table.
- */
--static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
--  PgHdr1 *p = 0;
--  void *pPg;
--
--  /* The group mutex must be released before pcache1Alloc() is called. This
--  ** is because it may call sqlite3_release_memory(), which assumes that 
--  ** this mutex is not held. */
--  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
--  pcache1LeaveMutex(pCache->pGroup);
--#ifdef SQLITE_PCACHE_SEPARATE_HEADER
--  pPg = pcache1Alloc(pCache->szPage);
--  p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
--  if( !pPg || !p ){
--    pcache1Free(pPg);
--    sqlite3_free(p);
--    pPg = 0;
-+SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){
-+  if( p==0 ) return;
-+  assert( i>0 );
-+  i--;
-+  while( p->iDivisor ){
-+    u32 bin = i/p->iDivisor;
-+    i = i%p->iDivisor;
-+    p = p->u.apSub[bin];
-+    if (!p) {
-+      return;
++  return zQuoted;
++}
++
++static char *fts5PrintfAppend(char *zApp, const char *zFmt, ...){
++  char *zNew;
++  va_list ap;
++  va_start(ap, zFmt);
++  zNew = sqlite3_vmprintf(zFmt, ap);
++  va_end(ap);
++  if( zApp && zNew ){
++    char *zNew2 = sqlite3_mprintf("%s%s", zApp, zNew);
++    sqlite3_free(zNew);
++    zNew = zNew2;
++  }
++  sqlite3_free(zApp);
++  return zNew;
++}
++
++/*
++** Compose a tcl-readable representation of expression pExpr. Return a 
++** pointer to a buffer containing that representation. It is the 
++** responsibility of the caller to at some point free the buffer using 
++** sqlite3_free().
++*/
++static char *fts5ExprPrintTcl(
++  Fts5Config *pConfig, 
++  const char *zNearsetCmd,
++  Fts5ExprNode *pExpr
++){
++  char *zRet = 0;
++  if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
++    Fts5ExprNearset *pNear = pExpr->pNear;
++    int i; 
++    int iTerm;
++
++    zRet = fts5PrintfAppend(zRet, "%s ", zNearsetCmd);
++    if( zRet==0 ) return 0;
++    if( pNear->pColset ){
++      int *aiCol = pNear->pColset->aiCol;
++      int nCol = pNear->pColset->nCol;
++      if( nCol==1 ){
++        zRet = fts5PrintfAppend(zRet, "-col %d ", aiCol[0]);
++      }else{
++        zRet = fts5PrintfAppend(zRet, "-col {%d", aiCol[0]);
++        for(i=1; i<pNear->pColset->nCol; i++){
++          zRet = fts5PrintfAppend(zRet, " %d", aiCol[i]);
++        }
++        zRet = fts5PrintfAppend(zRet, "} ");
++      }
++      if( zRet==0 ) return 0;
 +    }
-   }
--#else
--  pPg = pcache1Alloc(ROUND8(sizeof(PgHdr1)) + pCache->szPage + pCache->szExtra);
--  p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
--#endif
--  pcache1EnterMutex(pCache->pGroup);
--
--  if( pPg ){
--    p->page.pBuf = pPg;
--    p->page.pExtra = &p[1];
--    if( pCache->bPurgeable ){
--      pCache->pGroup->nCurrentPage++;
-+  if( p->iSize<=BITVEC_NBIT ){
-+    p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1)));
++
++    if( pNear->nPhrase>1 ){
++      zRet = fts5PrintfAppend(zRet, "-near %d ", pNear->nNear);
++      if( zRet==0 ) return 0;
++    }
++
++    zRet = fts5PrintfAppend(zRet, "--");
++    if( zRet==0 ) return 0;
++
++    for(i=0; i<pNear->nPhrase; i++){
++      Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
++
++      zRet = fts5PrintfAppend(zRet, " {");
++      for(iTerm=0; zRet && iTerm<pPhrase->nTerm; iTerm++){
++        char *zTerm = pPhrase->aTerm[iTerm].zTerm;
++        zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" ", zTerm);
++        if( pPhrase->aTerm[iTerm].bPrefix ){
++          zRet = fts5PrintfAppend(zRet, "*");
++        }
++      }
++
++      if( zRet ) zRet = fts5PrintfAppend(zRet, "}");
++      if( zRet==0 ) return 0;
++    }
++
 +  }else{
-+    unsigned int j;
-+    u32 *aiValues = pBuf;
-+    memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
-+    memset(p->u.aHash, 0, sizeof(p->u.aHash));
-+    p->nSet = 0;
-+    for(j=0; j<BITVEC_NINT; j++){
-+      if( aiValues[j] && aiValues[j]!=(i+1) ){
-+        u32 h = BITVEC_HASH(aiValues[j]-1);
-+        p->nSet++;
-+        while( p->u.aHash[h] ){
-+          h++;
-+          if( h>=BITVEC_NINT ) h = 0;
++    char const *zOp = 0;
++    int i;
++    switch( pExpr->eType ){
++      case FTS5_AND: zOp = "AND"; break;
++      case FTS5_NOT: zOp = "NOT"; break;
++      default: 
++        assert( pExpr->eType==FTS5_OR );
++        zOp = "OR"; 
++        break;
++    }
++
++    zRet = sqlite3_mprintf("%s", zOp);
++    for(i=0; zRet && i<pExpr->nChild; i++){
++      char *z = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->apChild[i]);
++      if( !z ){
++        sqlite3_free(zRet);
++        zRet = 0;
++      }else{
++        zRet = fts5PrintfAppend(zRet, " [%z]", z);
++      }
++    }
++  }
++
++  return zRet;
++}
++
++static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
++  char *zRet = 0;
++  if( pExpr->eType==0 ){
++    return sqlite3_mprintf("\"\"");
++  }else
++  if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
++    Fts5ExprNearset *pNear = pExpr->pNear;
++    int i; 
++    int iTerm;
++
++    if( pNear->pColset ){
++      int iCol = pNear->pColset->aiCol[0];
++      zRet = fts5PrintfAppend(zRet, "%s : ", pConfig->azCol[iCol]);
++      if( zRet==0 ) return 0;
++    }
++
++    if( pNear->nPhrase>1 ){
++      zRet = fts5PrintfAppend(zRet, "NEAR(");
++      if( zRet==0 ) return 0;
++    }
++
++    for(i=0; i<pNear->nPhrase; i++){
++      Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
++      if( i!=0 ){
++        zRet = fts5PrintfAppend(zRet, " ");
++        if( zRet==0 ) return 0;
++      }
++      for(iTerm=0; iTerm<pPhrase->nTerm; iTerm++){
++        char *zTerm = fts5ExprTermPrint(&pPhrase->aTerm[iTerm]);
++        if( zTerm ){
++          zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" + ", zTerm);
++          sqlite3_free(zTerm);
++        }
++        if( zTerm==0 || zRet==0 ){
++          sqlite3_free(zRet);
++          return 0;
 +        }
-+        p->u.aHash[h] = aiValues[j];
 +      }
-     }
--    return p;
-   }
--  return 0;
- }
- 
- /*
--** Free a page object allocated by pcache1AllocPage().
--**
--** The pointer is allowed to be NULL, which is prudent.  But it turns out
--** that the current implementation happens to never call this routine
--** with a NULL pointer, so we mark the NULL test with ALWAYS().
-+** Destroy a bitmap object.  Reclaim all memory used.
- */
--static void pcache1FreePage(PgHdr1 *p){
--  if( ALWAYS(p) ){
--    PCache1 *pCache = p->pCache;
--    assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
--    pcache1Free(p->page.pBuf);
--#ifdef SQLITE_PCACHE_SEPARATE_HEADER
--    sqlite3_free(p);
--#endif
--    if( pCache->bPurgeable ){
--      pCache->pGroup->nCurrentPage--;
-+SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec *p){
-+  if( p==0 ) return;
-+  if( p->iDivisor ){
-+    unsigned int i;
-+    for(i=0; i<BITVEC_NPTR; i++){
-+      sqlite3BitvecDestroy(p->u.apSub[i]);
-     }
-   }
-+  sqlite3_free(p);
- }
- 
- /*
--** Malloc function used by SQLite to obtain space from the buffer configured
--** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer
--** exists, this function falls back to sqlite3Malloc().
-+** Return the value of the iSize parameter specified when Bitvec *p
-+** was created.
- */
--SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){
--  return pcache1Alloc(sz);
-+SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){
-+  return p->iSize;
- }
- 
-+#ifndef SQLITE_OMIT_BUILTIN_TEST
- /*
--** Free an allocated buffer obtained from sqlite3PageMalloc().
-+** Let V[] be an array of unsigned characters sufficient to hold
-+** up to N bits.  Let I be an integer between 0 and N.  0<=I<N.
-+** Then the following macros can be used to set, clear, or test
-+** individual bits within V.
- */
--SQLITE_PRIVATE void sqlite3PageFree(void *p){
--  pcache1Free(p);
--}
--
-+#define SETBIT(V,I)      V[I>>3] |= (1<<(I&7))
-+#define CLEARBIT(V,I)    V[I>>3] &= ~(1<<(I&7))
-+#define TESTBIT(V,I)     (V[I>>3]&(1<<(I&7)))!=0
- 
- /*
--** Return true if it desirable to avoid allocating a new page cache
--** entry.
-+** This routine runs an extensive test of the Bitvec code.
- **
--** If memory was allocated specifically to the page cache using
--** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then
--** it is desirable to avoid allocating a new page cache entry because
--** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient
--** for all page cache needs and we should not need to spill the
--** allocation onto the heap.
-+** The input is an array of integers that acts as a program
-+** to test the Bitvec.  The integers are opcodes followed
-+** by 0, 1, or 3 operands, depending on the opcode.  Another
-+** opcode follows immediately after the last operand.
- **
--** Or, the heap is used for all page cache memory but the heap is
--** under memory pressure, then again it is desirable to avoid
--** allocating a new page cache entry in order to avoid stressing
--** the heap even further.
--*/
--static int pcache1UnderMemoryPressure(PCache1 *pCache){
--  if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){
--    return pcache1.bUnderPressure;
--  }else{
--    return sqlite3HeapNearlyFull();
--  }
--}
--
--/******************************************************************************/
--/******** General Implementation Functions ************************************/
--
--/*
--** This function is used to resize the hash table used by the cache passed
--** as the first argument.
-+** There are 6 opcodes numbered from 0 through 5.  0 is the
-+** "halt" opcode and causes the test to end.
- **
--** The PCache mutex must be held when this function is called.
-+**    0          Halt and return the number of errors
-+**    1 N S X    Set N bits beginning with S and incrementing by X
-+**    2 N S X    Clear N bits beginning with S and incrementing by X
-+**    3 N        Set N randomly chosen bits
-+**    4 N        Clear N randomly chosen bits
-+**    5 N S X    Set N bits from S increment X in array only, not in bitvec
-+**
-+** The opcodes 1 through 4 perform set and clear operations are performed
-+** on both a Bitvec object and on a linear array of bits obtained from malloc.
-+** Opcode 5 works on the linear array only, not on the Bitvec.
-+** Opcode 5 is used to deliberately induce a fault in order to
-+** confirm that error detection works.
-+**
-+** At the conclusion of the test the linear array is compared
-+** against the Bitvec object.  If there are any differences,
-+** an error is returned.  If they are the same, zero is returned.
-+**
-+** If a memory allocation error occurs, return -1.
- */
--static void pcache1ResizeHash(PCache1 *p){
--  PgHdr1 **apNew;
--  unsigned int nNew;
--  unsigned int i;
-+SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
-+  Bitvec *pBitvec = 0;
-+  unsigned char *pV = 0;
-+  int rc = -1;
-+  int i, nx, pc, op;
-+  void *pTmpSpace;
- 
--  assert( sqlite3_mutex_held(p->pGroup->mutex) );
-+  /* Allocate the Bitvec to be tested and a linear array of
-+  ** bits to act as the reference */
-+  pBitvec = sqlite3BitvecCreate( sz );
-+  pV = sqlite3MallocZero( (sz+7)/8 + 1 );
-+  pTmpSpace = sqlite3_malloc64(BITVEC_SZ);
-+  if( pBitvec==0 || pV==0 || pTmpSpace==0  ) goto bitvec_end;
- 
--  nNew = p->nHash*2;
--  if( nNew<256 ){
--    nNew = 256;
--  }
-+  /* NULL pBitvec tests */
-+  sqlite3BitvecSet(0, 1);
-+  sqlite3BitvecClear(0, 1, pTmpSpace);
- 
--  pcache1LeaveMutex(p->pGroup);
--  if( p->nHash ){ sqlite3BeginBenignMalloc(); }
--  apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew);
--  if( p->nHash ){ sqlite3EndBenignMalloc(); }
--  pcache1EnterMutex(p->pGroup);
--  if( apNew ){
--    for(i=0; i<p->nHash; i++){
--      PgHdr1 *pPage;
--      PgHdr1 *pNext = p->apHash[i];
--      while( (pPage = pNext)!=0 ){
--        unsigned int h = pPage->iKey % nNew;
--        pNext = pPage->pNext;
--        pPage->pNext = apNew[h];
--        apNew[h] = pPage;
-+  /* Run the program */
-+  pc = 0;
-+  while( (op = aOp[pc])!=0 ){
-+    switch( op ){
-+      case 1:
-+      case 2:
-+      case 5: {
-+        nx = 4;
-+        i = aOp[pc+2] - 1;
-+        aOp[pc+2] += aOp[pc+3];
++    }
++
++    if( pNear->nPhrase>1 ){
++      zRet = fts5PrintfAppend(zRet, ", %d)", pNear->nNear);
++      if( zRet==0 ) return 0;
++    }
++
++  }else{
++    char const *zOp = 0;
++    int i;
++
++    switch( pExpr->eType ){
++      case FTS5_AND: zOp = " AND "; break;
++      case FTS5_NOT: zOp = " NOT "; break;
++      default:  
++        assert( pExpr->eType==FTS5_OR );
++        zOp = " OR "; 
 +        break;
++    }
++
++    for(i=0; i<pExpr->nChild; i++){
++      char *z = fts5ExprPrint(pConfig, pExpr->apChild[i]);
++      if( z==0 ){
++        sqlite3_free(zRet);
++        zRet = 0;
++      }else{
++        int e = pExpr->apChild[i]->eType;
++        int b = (e!=FTS5_STRING && e!=FTS5_TERM && e!=FTS5_EOF);
++        zRet = fts5PrintfAppend(zRet, "%s%s%z%s", 
++            (i==0 ? "" : zOp),
++            (b?"(":""), z, (b?")":"")
++        );
 +      }
-+      case 3:
-+      case 4: 
-+      default: {
-+        nx = 2;
-+        sqlite3_randomness(sizeof(i), &i);
++      if( zRet==0 ) break;
++    }
++  }
++
++  return zRet;
++}
++
++/*
++** The implementation of user-defined scalar functions fts5_expr() (bTcl==0)
++** and fts5_expr_tcl() (bTcl!=0).
++*/
++static void fts5ExprFunction(
++  sqlite3_context *pCtx,          /* Function call context */
++  int nArg,                       /* Number of args */
++  sqlite3_value **apVal,          /* Function arguments */
++  int bTcl
++){
++  Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
++  sqlite3 *db = sqlite3_context_db_handle(pCtx);
++  const char *zExpr = 0;
++  char *zErr = 0;
++  Fts5Expr *pExpr = 0;
++  int rc;
++  int i;
++
++  const char **azConfig;          /* Array of arguments for Fts5Config */
++  const char *zNearsetCmd = "nearset";
++  int nConfig;                    /* Size of azConfig[] */
++  Fts5Config *pConfig = 0;
++  int iArg = 1;
++
++  if( nArg<1 ){
++    zErr = sqlite3_mprintf("wrong number of arguments to function %s",
++        bTcl ? "fts5_expr_tcl" : "fts5_expr"
++    );
++    sqlite3_result_error(pCtx, zErr, -1);
++    sqlite3_free(zErr);
++    return;
++  }
++
++  if( bTcl && nArg>1 ){
++    zNearsetCmd = (const char*)sqlite3_value_text(apVal[1]);
++    iArg = 2;
++  }
++
++  nConfig = 3 + (nArg-iArg);
++  azConfig = (const char**)sqlite3_malloc(sizeof(char*) * nConfig);
++  if( azConfig==0 ){
++    sqlite3_result_error_nomem(pCtx);
++    return;
++  }
++  azConfig[0] = 0;
++  azConfig[1] = "main";
++  azConfig[2] = "tbl";
++  for(i=3; iArg<nArg; iArg++){
++    azConfig[i++] = (const char*)sqlite3_value_text(apVal[iArg]);
++  }
++
++  zExpr = (const char*)sqlite3_value_text(apVal[0]);
++
++  rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr);
++  }
++  if( rc==SQLITE_OK ){
++    char *zText;
++    if( pExpr->pRoot->xNext==0 ){
++      zText = sqlite3_mprintf("");
++    }else if( bTcl ){
++      zText = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->pRoot);
++    }else{
++      zText = fts5ExprPrint(pConfig, pExpr->pRoot);
++    }
++    if( zText==0 ){
++      rc = SQLITE_NOMEM;
++    }else{
++      sqlite3_result_text(pCtx, zText, -1, SQLITE_TRANSIENT);
++      sqlite3_free(zText);
++    }
++  }
++
++  if( rc!=SQLITE_OK ){
++    if( zErr ){
++      sqlite3_result_error(pCtx, zErr, -1);
++      sqlite3_free(zErr);
++    }else{
++      sqlite3_result_error_code(pCtx, rc);
++    }
++  }
++  sqlite3_free((void *)azConfig);
++  sqlite3Fts5ConfigFree(pConfig);
++  sqlite3Fts5ExprFree(pExpr);
++}
++
++static void fts5ExprFunctionHr(
++  sqlite3_context *pCtx,          /* Function call context */
++  int nArg,                       /* Number of args */
++  sqlite3_value **apVal           /* Function arguments */
++){
++  fts5ExprFunction(pCtx, nArg, apVal, 0);
++}
++static void fts5ExprFunctionTcl(
++  sqlite3_context *pCtx,          /* Function call context */
++  int nArg,                       /* Number of args */
++  sqlite3_value **apVal           /* Function arguments */
++){
++  fts5ExprFunction(pCtx, nArg, apVal, 1);
++}
++
++/*
++** The implementation of an SQLite user-defined-function that accepts a
++** single integer as an argument. If the integer is an alpha-numeric 
++** unicode code point, 1 is returned. Otherwise 0.
++*/
++static void fts5ExprIsAlnum(
++  sqlite3_context *pCtx,          /* Function call context */
++  int nArg,                       /* Number of args */
++  sqlite3_value **apVal           /* Function arguments */
++){
++  int iCode;
++  if( nArg!=1 ){
++    sqlite3_result_error(pCtx, 
++        "wrong number of arguments to function fts5_isalnum", -1
++    );
++    return;
++  }
++  iCode = sqlite3_value_int(apVal[0]);
++  sqlite3_result_int(pCtx, sqlite3Fts5UnicodeIsalnum(iCode));
++}
++
++static void fts5ExprFold(
++  sqlite3_context *pCtx,          /* Function call context */
++  int nArg,                       /* Number of args */
++  sqlite3_value **apVal           /* Function arguments */
++){
++  if( nArg!=1 && nArg!=2 ){
++    sqlite3_result_error(pCtx, 
++        "wrong number of arguments to function fts5_fold", -1
++    );
++  }else{
++    int iCode;
++    int bRemoveDiacritics = 0;
++    iCode = sqlite3_value_int(apVal[0]);
++    if( nArg==2 ) bRemoveDiacritics = sqlite3_value_int(apVal[1]);
++    sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics));
++  }
++}
++
++/*
++** This is called during initialization to register the fts5_expr() scalar
++** UDF with the SQLite handle passed as the only argument.
++*/
++static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
++  struct Fts5ExprFunc {
++    const char *z;
++    void (*x)(sqlite3_context*,int,sqlite3_value**);
++  } aFunc[] = {
++    { "fts5_expr",     fts5ExprFunctionHr },
++    { "fts5_expr_tcl", fts5ExprFunctionTcl },
++    { "fts5_isalnum",  fts5ExprIsAlnum },
++    { "fts5_fold",     fts5ExprFold },
++  };
++  int i;
++  int rc = SQLITE_OK;
++  void *pCtx = (void*)pGlobal;
++
++  for(i=0; rc==SQLITE_OK && i<ArraySize(aFunc); i++){
++    struct Fts5ExprFunc *p = &aFunc[i];
++    rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
++  }
++
++  /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */
++#ifndef NDEBUG
++  (void)sqlite3Fts5ParserTrace;
++#endif
++
++  return rc;
++}
++
++/*
++** Return the number of phrases in expression pExpr.
++*/
++static int sqlite3Fts5ExprPhraseCount(Fts5Expr *pExpr){
++  return (pExpr ? pExpr->nPhrase : 0);
++}
++
++/*
++** Return the number of terms in the iPhrase'th phrase in pExpr.
++*/
++static int sqlite3Fts5ExprPhraseSize(Fts5Expr *pExpr, int iPhrase){
++  if( iPhrase<0 || iPhrase>=pExpr->nPhrase ) return 0;
++  return pExpr->apExprPhrase[iPhrase]->nTerm;
++}
++
++/*
++** This function is used to access the current position list for phrase
++** iPhrase.
++*/
++static int sqlite3Fts5ExprPoslist(Fts5Expr *pExpr, int iPhrase, const u8 **pa){
++  int nRet;
++  Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase];
++  Fts5ExprNode *pNode = pPhrase->pNode;
++  if( pNode->bEof==0 && pNode->iRowid==pExpr->pRoot->iRowid ){
++    *pa = pPhrase->poslist.p;
++    nRet = pPhrase->poslist.n;
++  }else{
++    *pa = 0;
++    nRet = 0;
++  }
++  return nRet;
++}
++
++struct Fts5PoslistPopulator {
++  Fts5PoslistWriter writer;
++  int bOk;                        /* True if ok to populate */
++  int bMiss;
++};
++
++static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
++  Fts5PoslistPopulator *pRet;
++  pRet = sqlite3_malloc(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
++  if( pRet ){
++    int i;
++    memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
++    for(i=0; i<pExpr->nPhrase; i++){
++      Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
++      Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
++      assert( pExpr->apExprPhrase[i]->nTerm==1 );
++      if( bLive && 
++          (pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
++      ){
++        pRet[i].bMiss = 1;
++      }else{
++        pBuf->n = 0;
++      }
++    }
++  }
++  return pRet;
++}
++
++struct Fts5ExprCtx {
++  Fts5Expr *pExpr;
++  Fts5PoslistPopulator *aPopulator;
++  i64 iOff;
++};
++typedef struct Fts5ExprCtx Fts5ExprCtx;
++
++/*
++** TODO: Make this more efficient!
++*/
++static int fts5ExprColsetTest(Fts5Colset *pColset, int iCol){
++  int i;
++  for(i=0; i<pColset->nCol; i++){
++    if( pColset->aiCol[i]==iCol ) return 1;
++  }
++  return 0;
++}
++
++static int fts5ExprPopulatePoslistsCb(
++  void *pCtx,                /* Copy of 2nd argument to xTokenize() */
++  int tflags,                /* Mask of FTS5_TOKEN_* flags */
++  const char *pToken,        /* Pointer to buffer containing token */
++  int nToken,                /* Size of token in bytes */
++  int iUnused1,              /* Byte offset of token within input text */
++  int iUnused2               /* Byte offset of end of token within input text */
++){
++  Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx;
++  Fts5Expr *pExpr = p->pExpr;
++  int i;
++
++  UNUSED_PARAM2(iUnused1, iUnused2);
++
++  if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
++  if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++;
++  for(i=0; i<pExpr->nPhrase; i++){
++    Fts5ExprTerm *pTerm;
++    if( p->aPopulator[i].bOk==0 ) continue;
++    for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
++      int nTerm = (int)strlen(pTerm->zTerm);
++      if( (nTerm==nToken || (nTerm<nToken && pTerm->bPrefix))
++       && memcmp(pTerm->zTerm, pToken, nTerm)==0
++      ){
++        int rc = sqlite3Fts5PoslistWriterAppend(
++            &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff
++        );
++        if( rc ) return rc;
 +        break;
-       }
-     }
--    sqlite3_free(p->apHash);
--    p->apHash = apNew;
--    p->nHash = nNew;
-+    if( (--aOp[pc+1]) > 0 ) nx = 0;
-+    pc += nx;
-+    i = (i & 0x7fffffff)%sz;
-+    if( (op & 1)!=0 ){
-+      SETBIT(pV, (i+1));
-+      if( op!=5 ){
-+        if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end;
 +      }
++    }
++  }
++  return SQLITE_OK;
++}
++
++static int sqlite3Fts5ExprPopulatePoslists(
++  Fts5Config *pConfig,
++  Fts5Expr *pExpr, 
++  Fts5PoslistPopulator *aPopulator,
++  int iCol, 
++  const char *z, int n
++){
++  int i;
++  Fts5ExprCtx sCtx;
++  sCtx.pExpr = pExpr;
++  sCtx.aPopulator = aPopulator;
++  sCtx.iOff = (((i64)iCol) << 32) - 1;
++
++  for(i=0; i<pExpr->nPhrase; i++){
++    Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
++    Fts5Colset *pColset = pNode->pNear->pColset;
++    if( (pColset && 0==fts5ExprColsetTest(pColset, iCol)) 
++     || aPopulator[i].bMiss
++    ){
++      aPopulator[i].bOk = 0;
 +    }else{
-+      CLEARBIT(pV, (i+1));
-+      sqlite3BitvecClear(pBitvec, i+1, pTmpSpace);
++      aPopulator[i].bOk = 1;
 +    }
 +  }
 +
-+  /* Test to make sure the linear array exactly matches the
-+  ** Bitvec object.  Start with the assumption that they do
-+  ** match (rc==0).  Change rc to non-zero if a discrepancy
-+  ** is found.
-+  */
-+  rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1)
-+          + sqlite3BitvecTest(pBitvec, 0)
-+          + (sqlite3BitvecSize(pBitvec) - sz);
-+  for(i=1; i<=sz; i++){
-+    if(  (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){
-+      rc = i;
-+      break;
++  return sqlite3Fts5Tokenize(pConfig, 
++      FTS5_TOKENIZE_DOCUMENT, z, n, (void*)&sCtx, fts5ExprPopulatePoslistsCb
++  );
++}
++
++static void fts5ExprClearPoslists(Fts5ExprNode *pNode){
++  if( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING ){
++    pNode->pNear->apPhrase[0]->poslist.n = 0;
++  }else{
++    int i;
++    for(i=0; i<pNode->nChild; i++){
++      fts5ExprClearPoslists(pNode->apChild[i]);
 +    }
-   }
++  }
++}
 +
-+  /* Free allocated structure */
-+bitvec_end:
-+  sqlite3_free(pTmpSpace);
-+  sqlite3_free(pV);
-+  sqlite3BitvecDestroy(pBitvec);
-+  return rc;
- }
-+#endif /* SQLITE_OMIT_BUILTIN_TEST */
- 
-+/************** End of bitvec.c **********************************************/
-+/************** Begin file pcache.c ******************************************/
- /*
--** This function is used internally to remove the page pPage from the 
--** PGroup LRU list, if is part of it. If pPage is not part of the PGroup
--** LRU list, then this function is a no-op.
-+** 2008 August 05
- **
--** The PGroup mutex must be held when this function is called.
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
-+**
-+**    May you do good and not evil.
-+**    May you find forgiveness for yourself and forgive others.
-+**    May you share freely, never taking more than you give.
-+**
-+*************************************************************************
-+** This file implements that page cache.
- */
--static void pcache1PinPage(PgHdr1 *pPage){
--  PCache1 *pCache;
--  PGroup *pGroup;
- 
--  assert( pPage!=0 );
--  assert( pPage->isPinned==0 );
--  pCache = pPage->pCache;
--  pGroup = pCache->pGroup;
--  assert( pPage->pLruNext || pPage==pGroup->pLruTail );
--  assert( pPage->pLruPrev || pPage==pGroup->pLruHead );
--  assert( sqlite3_mutex_held(pGroup->mutex) );
--  if( pPage->pLruPrev ){
--    pPage->pLruPrev->pLruNext = pPage->pLruNext;
--  }else{
--    pGroup->pLruHead = pPage->pLruNext;
--  }
--  if( pPage->pLruNext ){
--    pPage->pLruNext->pLruPrev = pPage->pLruPrev;
--  }else{
--    pGroup->pLruTail = pPage->pLruPrev;
--  }
--  pPage->pLruNext = 0;
--  pPage->pLruPrev = 0;
--  pPage->isPinned = 1;
--  pCache->nRecyclable--;
--}
-+/*
-+** A complete page cache is an instance of this structure.
-+*/
-+struct PCache {
-+  PgHdr *pDirty, *pDirtyTail;         /* List of dirty pages in LRU order */
-+  PgHdr *pSynced;                     /* Last synced page in dirty page list */
-+  int nRef;                           /* Number of referenced pages */
-+  int szCache;                        /* Configured cache size */
-+  int szPage;                         /* Size of every page in this cache */
-+  int szExtra;                        /* Size of extra space for each page */
-+  u8 bPurgeable;                      /* True if pages are on backing store */
-+  u8 eCreate;                         /* eCreate value for for xFetch() */
-+  int (*xStress)(void*,PgHdr*);       /* Call to try make a page clean */
-+  void *pStress;                      /* Argument to xStress */
-+  sqlite3_pcache *pCache;             /* Pluggable cache module */
-+  PgHdr *pPage1;                      /* Reference to page 1 */
-+};
++static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){
++  pNode->iRowid = iRowid;
++  pNode->bEof = 0;
++  switch( pNode->eType ){
++    case FTS5_TERM:
++    case FTS5_STRING:
++      return (pNode->pNear->apPhrase[0]->poslist.n>0);
 +
-+/********************************** Linked List Management ********************/
- 
-+/* Allowed values for second argument to pcacheManageDirtyList() */
-+#define PCACHE_DIRTYLIST_REMOVE   1    /* Remove pPage from dirty list */
-+#define PCACHE_DIRTYLIST_ADD      2    /* Add pPage to the dirty list */
-+#define PCACHE_DIRTYLIST_FRONT    3    /* Move pPage to the front of the list */
- 
- /*
--** Remove the page supplied as an argument from the hash table 
--** (PCache1.apHash structure) that it is currently stored in.
--**
--** The PGroup mutex must be held when this function is called.
-+** Manage pPage's participation on the dirty list.  Bits of the addRemove
-+** argument determines what operation to do.  The 0x01 bit means first
-+** remove pPage from the dirty list.  The 0x02 means add pPage back to
-+** the dirty list.  Doing both moves pPage to the front of the dirty list.
- */
--static void pcache1RemoveFromHash(PgHdr1 *pPage){
--  unsigned int h;
--  PCache1 *pCache = pPage->pCache;
--  PgHdr1 **pp;
--
--  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
--  h = pPage->iKey % pCache->nHash;
--  for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext);
--  *pp = (*pp)->pNext;
-+static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
-+  PCache *p = pPage->pCache;
- 
--  pCache->nPage--;
-+  if( addRemove & PCACHE_DIRTYLIST_REMOVE ){
-+    assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
-+    assert( pPage->pDirtyPrev || pPage==p->pDirty );
-+  
-+    /* Update the PCache1.pSynced variable if necessary. */
-+    if( p->pSynced==pPage ){
-+      PgHdr *pSynced = pPage->pDirtyPrev;
-+      while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){
-+        pSynced = pSynced->pDirtyPrev;
++    case FTS5_AND: {
++      int i;
++      for(i=0; i<pNode->nChild; i++){
++        if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid)==0 ){
++          fts5ExprClearPoslists(pNode);
++          return 0;
++        }
 +      }
-+      p->pSynced = pSynced;
-+    }
-+  
-+    if( pPage->pDirtyNext ){
-+      pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev;
-+    }else{
-+      assert( pPage==p->pDirtyTail );
-+      p->pDirtyTail = pPage->pDirtyPrev;
++      break;
 +    }
-+    if( pPage->pDirtyPrev ){
-+      pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
-+    }else{
-+      assert( pPage==p->pDirty );
-+      p->pDirty = pPage->pDirtyNext;
-+      if( p->pDirty==0 && p->bPurgeable ){
-+        assert( p->eCreate==1 );
-+        p->eCreate = 2;
++
++    case FTS5_OR: {
++      int i;
++      int bRet = 0;
++      for(i=0; i<pNode->nChild; i++){
++        if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid) ){
++          bRet = 1;
++        }
 +      }
++      return bRet;
 +    }
-+    pPage->pDirtyNext = 0;
-+    pPage->pDirtyPrev = 0;
-+  }
-+  if( addRemove & PCACHE_DIRTYLIST_ADD ){
-+    assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage );
-+  
-+    pPage->pDirtyNext = p->pDirty;
-+    if( pPage->pDirtyNext ){
-+      assert( pPage->pDirtyNext->pDirtyPrev==0 );
-+      pPage->pDirtyNext->pDirtyPrev = pPage;
-+    }else{
-+      p->pDirtyTail = pPage;
-+      if( p->bPurgeable ){
-+        assert( p->eCreate==2 );
-+        p->eCreate = 1;
++
++    default: {
++      assert( pNode->eType==FTS5_NOT );
++      if( 0==fts5ExprCheckPoslists(pNode->apChild[0], iRowid)
++          || 0!=fts5ExprCheckPoslists(pNode->apChild[1], iRowid)
++        ){
++        fts5ExprClearPoslists(pNode);
++        return 0;
 +      }
++      break;
 +    }
-+    p->pDirty = pPage;
-+    if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
-+      p->pSynced = pPage;
-+    }
-+  }
- }
- 
- /*
--** If there are currently more than nMaxPage pages allocated, try
--** to recycle pages to reduce the number allocated to nMaxPage.
-+** Wrapper around the pluggable caches xUnpin method. If the cache is
-+** being used for an in-memory database, this function is a no-op.
- */
--static void pcache1EnforceMaxPage(PGroup *pGroup){
--  assert( sqlite3_mutex_held(pGroup->mutex) );
--  while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){
--    PgHdr1 *p = pGroup->pLruTail;
--    assert( p->pCache->pGroup==pGroup );
--    assert( p->isPinned==0 );
--    pcache1PinPage(p);
--    pcache1RemoveFromHash(p);
--    pcache1FreePage(p);
-+static void pcacheUnpin(PgHdr *p){
-+  if( p->pCache->bPurgeable ){
-+    if( p->pgno==1 ){
-+      p->pCache->pPage1 = 0;
-+    }
-+    sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0);
-   }
- }
- 
- /*
--** Discard all pages from cache pCache with a page number (key value) 
--** greater than or equal to iLimit. Any pinned pages that meet this 
--** criteria are unpinned before they are discarded.
-+** Compute the number of pages of cache requested.  p->szCache is the
-+** cache size requested by the "PRAGMA cache_size" statement.
-+**
- **
--** The PCache mutex must be held when this function is called.
- */
--static void pcache1TruncateUnsafe(
--  PCache1 *pCache,             /* The cache to truncate */
--  unsigned int iLimit          /* Drop pages with this pgno or larger */
--){
--  TESTONLY( unsigned int nPage = 0; )  /* To assert pCache->nPage is correct */
--  unsigned int h;
--  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
--  for(h=0; h<pCache->nHash; h++){
--    PgHdr1 **pp = &pCache->apHash[h]; 
--    PgHdr1 *pPage;
--    while( (pPage = *pp)!=0 ){
--      if( pPage->iKey>=iLimit ){
--        pCache->nPage--;
--        *pp = pPage->pNext;
--        if( !pPage->isPinned ) pcache1PinPage(pPage);
--        pcache1FreePage(pPage);
--      }else{
--        pp = &pPage->pNext;
--        TESTONLY( nPage++; )
--      }
--    }
-+static int numberOfCachePages(PCache *p){
-+  if( p->szCache>=0 ){
-+    /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
-+    ** suggested cache size is set to N. */
-+    return p->szCache;
-+  }else{
-+    /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
-+    ** the number of cache pages is adjusted to use approximately abs(N*1024)
-+    ** bytes of memory. */
-+    return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
 +  }
++  return 1;
 +}
 +
-+/*************************************************** General Interfaces ******
-+**
-+** Initialize and shutdown the page cache subsystem. Neither of these 
-+** functions are threadsafe.
-+*/
-+SQLITE_PRIVATE int sqlite3PcacheInitialize(void){
-+  if( sqlite3GlobalConfig.pcache2.xInit==0 ){
-+    /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the
-+    ** built-in default page cache is used instead of the application defined
-+    ** page cache. */
-+    sqlite3PCacheSetDefault();
-+  }
-+  return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg);
++static void sqlite3Fts5ExprCheckPoslists(Fts5Expr *pExpr, i64 iRowid){
++  fts5ExprCheckPoslists(pExpr->pRoot, iRowid);
 +}
-+SQLITE_PRIVATE void sqlite3PcacheShutdown(void){
-+  if( sqlite3GlobalConfig.pcache2.xShutdown ){
-+    /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */
-+    sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg);
-   }
--  assert( pCache->nPage==nPage );
- }
- 
--/******************************************************************************/
--/******** sqlite3_pcache Methods **********************************************/
++
 +/*
-+** Return the size in bytes of a PCache object.
++** This function is only called for detail=columns tables. 
 +*/
-+SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); }
- 
- /*
--** Implementation of the sqlite3_pcache.xInit method.
-+** Create a new PCache object. Storage space to hold the object
-+** has already been allocated and is passed in as the p pointer. 
-+** The caller discovers how much space needs to be allocated by 
-+** calling sqlite3PcacheSize().
- */
--static int pcache1Init(void *NotUsed){
--  UNUSED_PARAMETER(NotUsed);
--  assert( pcache1.isInit==0 );
--  memset(&pcache1, 0, sizeof(pcache1));
--  if( sqlite3GlobalConfig.bCoreMutex ){
--    pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
--    pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
-+SQLITE_PRIVATE int sqlite3PcacheOpen(
-+  int szPage,                  /* Size of every page */
-+  int szExtra,                 /* Extra space associated with each page */
-+  int bPurgeable,              /* True if pages are on backing store */
-+  int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */
-+  void *pStress,               /* Argument to xStress */
-+  PCache *p                    /* Preallocated space for the PCache */
-+){
-+  memset(p, 0, sizeof(PCache));
-+  p->szPage = 1;
-+  p->szExtra = szExtra;
-+  p->bPurgeable = bPurgeable;
-+  p->eCreate = 2;
-+  p->xStress = xStress;
-+  p->pStress = pStress;
-+  p->szCache = 100;
-+  return sqlite3PcacheSetPageSize(p, szPage);
-+}
-+
-+/*
-+** Change the page size for PCache object. The caller must ensure that there
-+** are no outstanding page references when this function is called.
-+*/
-+SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
-+  assert( pCache->nRef==0 && pCache->pDirty==0 );
-+  if( pCache->szPage ){
-+    sqlite3_pcache *pNew;
-+    pNew = sqlite3GlobalConfig.pcache2.xCreate(
-+                szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
-+                pCache->bPurgeable
-+    );
-+    if( pNew==0 ) return SQLITE_NOMEM;
-+    sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
-+    if( pCache->pCache ){
-+      sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
-+    }
-+    pCache->pCache = pNew;
-+    pCache->pPage1 = 0;
-+    pCache->szPage = szPage;
-   }
--  pcache1.grp.mxPinned = 10;
--  pcache1.isInit = 1;
-   return SQLITE_OK;
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xShutdown method.
--** Note that the static mutex allocated in xInit does 
--** not need to be freed.
-+** Try to obtain a page from the cache.
-+**
-+** This routine returns a pointer to an sqlite3_pcache_page object if
-+** such an object is already in cache, or if a new one is created.
-+** This routine returns a NULL pointer if the object was not in cache
-+** and could not be created.
-+**
-+** The createFlags should be 0 to check for existing pages and should
-+** be 3 (not 1, but 3) to try to create a new page.
-+**
-+** If the createFlag is 0, then NULL is always returned if the page
-+** is not already in the cache.  If createFlag is 1, then a new page
-+** is created only if that can be done without spilling dirty pages
-+** and without exceeding the cache size limit.
-+**
-+** The caller needs to invoke sqlite3PcacheFetchFinish() to properly
-+** initialize the sqlite3_pcache_page object and convert it into a
-+** PgHdr object.  The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish()
-+** routines are split this way for performance reasons. When separated
-+** they can both (usually) operate without having to push values to
-+** the stack on entry and pop them back off on exit, which saves a
-+** lot of pushing and popping.
- */
--static void pcache1Shutdown(void *NotUsed){
--  UNUSED_PARAMETER(NotUsed);
--  assert( pcache1.isInit!=0 );
--  memset(&pcache1, 0, sizeof(pcache1));
--}
-+SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(
-+  PCache *pCache,       /* Obtain the page from this cache */
-+  Pgno pgno,            /* Page number to obtain */
-+  int createFlag        /* If true, create page if it does not exist already */
-+){
-+  int eCreate;
- 
--/* forward declaration */
--static void pcache1Destroy(sqlite3_pcache *p);
-+  assert( pCache!=0 );
-+  assert( pCache->pCache!=0 );
-+  assert( createFlag==3 || createFlag==0 );
-+  assert( pgno>0 );
-+
-+  /* eCreate defines what to do if the page does not exist.
-+  **    0     Do not allocate a new page.  (createFlag==0)
-+  **    1     Allocate a new page if doing so is inexpensive.
-+  **          (createFlag==1 AND bPurgeable AND pDirty)
-+  **    2     Allocate a new page even it doing so is difficult.
-+  **          (createFlag==1 AND !(bPurgeable AND pDirty)
-+  */
-+  eCreate = createFlag & pCache->eCreate;
-+  assert( eCreate==0 || eCreate==1 || eCreate==2 );
-+  assert( createFlag==0 || pCache->eCreate==eCreate );
-+  assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) );
-+  return sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
-+}
- 
- /*
--** Implementation of the sqlite3_pcache.xCreate method.
-+** If the sqlite3PcacheFetch() routine is unable to allocate a new
-+** page because new clean pages are available for reuse and the cache
-+** size limit has been reached, then this routine can be invoked to 
-+** try harder to allocate a page.  This routine might invoke the stress
-+** callback to spill dirty pages to the journal.  It will then try to
-+** allocate the new page and will only fail to allocate a new page on
-+** an OOM error.
- **
--** Allocate a new cache.
-+** This routine should be invoked only after sqlite3PcacheFetch() fails.
- */
--static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
--  PCache1 *pCache;      /* The newly created page cache */
--  PGroup *pGroup;       /* The group the new page cache will belong to */
--  int sz;               /* Bytes of memory required to allocate the new cache */
-+SQLITE_PRIVATE int sqlite3PcacheFetchStress(
-+  PCache *pCache,                 /* Obtain the page from this cache */
-+  Pgno pgno,                      /* Page number to obtain */
-+  sqlite3_pcache_page **ppPage    /* Write result here */
-+){
-+  PgHdr *pPg;
-+  if( pCache->eCreate==2 ) return 0;
- 
--  /*
--  ** The separateCache variable is true if each PCache has its own private
--  ** PGroup.  In other words, separateCache is true for mode (1) where no
--  ** mutexing is required.
--  **
--  **   *  Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
--  **
--  **   *  Always use a unified cache in single-threaded applications
--  **
--  **   *  Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off)
--  **      use separate caches (mode-1)
-+
-+  /* Find a dirty page to write-out and recycle. First try to find a 
-+  ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
-+  ** cleared), but if that is not possible settle for any other 
-+  ** unreferenced dirty page.
-   */
--#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
--  const int separateCache = 0;
--#else
--  int separateCache = sqlite3GlobalConfig.bCoreMutex>0;
-+  for(pPg=pCache->pSynced; 
-+      pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); 
-+      pPg=pPg->pDirtyPrev
-+  );
-+  pCache->pSynced = pPg;
-+  if( !pPg ){
-+    for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
-+  }
-+  if( pPg ){
-+    int rc;
-+#ifdef SQLITE_LOG_CACHE_SPILL
-+    sqlite3_log(SQLITE_FULL, 
-+                "spill page %d making room for %d - cache used: %d/%d",
-+                pPg->pgno, pgno,
-+                sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
-+                numberOfCachePages(pCache));
- #endif
--
--  assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
--  assert( szExtra < 300 );
--
--  sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
--  pCache = (PCache1 *)sqlite3MallocZero(sz);
--  if( pCache ){
--    if( separateCache ){
--      pGroup = (PGroup*)&pCache[1];
--      pGroup->mxPinned = 10;
--    }else{
--      pGroup = &pcache1.grp;
--    }
--    pCache->pGroup = pGroup;
--    pCache->szPage = szPage;
--    pCache->szExtra = szExtra;
--    pCache->bPurgeable = (bPurgeable ? 1 : 0);
--    pcache1EnterMutex(pGroup);
--    pcache1ResizeHash(pCache);
--    if( bPurgeable ){
--      pCache->nMin = 10;
--      pGroup->nMinPage += pCache->nMin;
--      pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
--    }
--    pcache1LeaveMutex(pGroup);
--    if( pCache->nHash==0 ){
--      pcache1Destroy((sqlite3_pcache*)pCache);
--      pCache = 0;
-+    rc = pCache->xStress(pCache->pStress, pPg);
-+    if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
-+      return rc;
-     }
-   }
--  return (sqlite3_pcache *)pCache;
-+  *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
-+  return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK;
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xCachesize method. 
-+** This is a helper routine for sqlite3PcacheFetchFinish()
- **
--** Configure the cache_size limit for a cache.
-+** In the uncommon case where the page being fetched has not been
-+** initialized, this routine is invoked to do the initialization.
-+** This routine is broken out into a separate function since it
-+** requires extra stack manipulation that can be avoided in the common
-+** case.
- */
--static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
--  PCache1 *pCache = (PCache1 *)p;
--  if( pCache->bPurgeable ){
--    PGroup *pGroup = pCache->pGroup;
--    pcache1EnterMutex(pGroup);
--    pGroup->nMaxPage += (nMax - pCache->nMax);
--    pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
--    pCache->nMax = nMax;
--    pCache->n90pct = pCache->nMax*9/10;
--    pcache1EnforceMaxPage(pGroup);
--    pcache1LeaveMutex(pGroup);
--  }
-+static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
-+  PCache *pCache,             /* Obtain the page from this cache */
-+  Pgno pgno,                  /* Page number obtained */
-+  sqlite3_pcache_page *pPage  /* Page obtained by prior PcacheFetch() call */
-+){
-+  PgHdr *pPgHdr;
-+  assert( pPage!=0 );
-+  pPgHdr = (PgHdr*)pPage->pExtra;
-+  assert( pPgHdr->pPage==0 );
-+ memset(pPgHdr, 0, sizeof(PgHdr));
-+  pPgHdr->pPage = pPage;
-+  pPgHdr->pData = pPage->pBuf;
-+  pPgHdr->pExtra = (void *)&pPgHdr[1];
-+  memset(pPgHdr->pExtra, 0, pCache->szExtra);
-+  pPgHdr->pCache = pCache;
-+  pPgHdr->pgno = pgno;
-+  return sqlite3PcacheFetchFinish(pCache,pgno,pPage);
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xShrink method. 
--**
--** Free up as much memory as possible.
-+** This routine converts the sqlite3_pcache_page object returned by
-+** sqlite3PcacheFetch() into an initialized PgHdr object.  This routine
-+** must be called after sqlite3PcacheFetch() in order to get a usable
-+** result.
- */
--static void pcache1Shrink(sqlite3_pcache *p){
--  PCache1 *pCache = (PCache1*)p;
--  if( pCache->bPurgeable ){
--    PGroup *pGroup = pCache->pGroup;
--    int savedMaxPage;
--    pcache1EnterMutex(pGroup);
--    savedMaxPage = pGroup->nMaxPage;
--    pGroup->nMaxPage = 0;
--    pcache1EnforceMaxPage(pGroup);
--    pGroup->nMaxPage = savedMaxPage;
--    pcache1LeaveMutex(pGroup);
-+SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(
-+  PCache *pCache,             /* Obtain the page from this cache */
-+  Pgno pgno,                  /* Page number obtained */
-+  sqlite3_pcache_page *pPage  /* Page obtained by prior PcacheFetch() call */
++static int sqlite3Fts5ExprPhraseCollist(
++  Fts5Expr *pExpr, 
++  int iPhrase, 
++  const u8 **ppCollist, 
++  int *pnCollist
 +){
-+  PgHdr *pPgHdr;
++  Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase];
++  Fts5ExprNode *pNode = pPhrase->pNode;
++  int rc = SQLITE_OK;
 +
-+  if( pPage==0 ) return 0;
-+  pPgHdr = (PgHdr *)pPage->pExtra;
++  assert( iPhrase>=0 && iPhrase<pExpr->nPhrase );
++  assert( pExpr->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
 +
-+  if( !pPgHdr->pPage ){
-+    return pcacheFetchFinishWithInit(pCache, pgno, pPage);
-+  }
-+  if( 0==pPgHdr->nRef ){
-+    pCache->nRef++;
-+  }
-+  pPgHdr->nRef++;
-+  if( pgno==1 ){
-+    pCache->pPage1 = pPgHdr;
-   }
-+  return pPgHdr;
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xPagecount method. 
-+** Decrement the reference count on a page. If the page is clean and the
-+** reference count drops to 0, then it is made eligible for recycling.
- */
--static int pcache1Pagecount(sqlite3_pcache *p){
--  int n;
--  PCache1 *pCache = (PCache1*)p;
--  pcache1EnterMutex(pCache->pGroup);
--  n = pCache->nPage;
--  pcache1LeaveMutex(pCache->pGroup);
--  return n;
-+SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
-+  assert( p->nRef>0 );
-+  p->nRef--;
-+  if( p->nRef==0 ){
-+    p->pCache->nRef--;
-+    if( (p->flags&PGHDR_DIRTY)==0 ){
-+      pcacheUnpin(p);
-+    }else if( p->pDirtyPrev!=0 ){
-+      /* Move the page to the head of the dirty list. */
-+      pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
++  if( pNode->bEof==0 
++   && pNode->iRowid==pExpr->pRoot->iRowid 
++   && pPhrase->poslist.n>0
++  ){
++    Fts5ExprTerm *pTerm = &pPhrase->aTerm[0];
++    if( pTerm->pSynonym ){
++      Fts5Buffer *pBuf = (Fts5Buffer*)&pTerm->pSynonym[1];
++      rc = fts5ExprSynonymList(
++          pTerm, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist
++      );
++    }else{
++      *ppCollist = pPhrase->aTerm[0].pIter->pData;
++      *pnCollist = pPhrase->aTerm[0].pIter->nData;
 +    }
++  }else{
++    *ppCollist = 0;
++    *pnCollist = 0;
 +  }
- }
- 
--
- /*
--** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described
--** in the header of the pcache1Fetch() procedure.
--**
--** This steps are broken out into a separate procedure because they are
--** usually not needed, and by avoiding the stack initialization required
--** for these steps, the main pcache1Fetch() procedure can run faster.
-+** Increase the reference count of a supplied page by 1.
- */
--static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
--  PCache1 *pCache, 
--  unsigned int iKey, 
--  int createFlag
--){
--  unsigned int nPinned;
--  PGroup *pGroup = pCache->pGroup;
--  PgHdr1 *pPage = 0;
-+SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
-+  assert(p->nRef>0);
-+  p->nRef++;
-+}
- 
--  /* Step 3: Abort if createFlag is 1 but the cache is nearly full */
--  assert( pCache->nPage >= pCache->nRecyclable );
--  nPinned = pCache->nPage - pCache->nRecyclable;
--  assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
--  assert( pCache->n90pct == pCache->nMax*9/10 );
--  if( createFlag==1 && (
--        nPinned>=pGroup->mxPinned
--     || nPinned>=pCache->n90pct
--     || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
--  )){
--    return 0;
-+/*
-+** Drop a page from the cache. There must be exactly one reference to the
-+** page. This function deletes that reference, so after it returns the
-+** page pointed to by p is invalid.
-+*/
-+SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
-+  assert( p->nRef==1 );
-+  if( p->flags&PGHDR_DIRTY ){
-+    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
-   }
--
--  if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
--  assert( pCache->nHash>0 && pCache->apHash );
--
--  /* Step 4. Try to recycle a page. */
--  if( pCache->bPurgeable && pGroup->pLruTail && (
--         (pCache->nPage+1>=pCache->nMax)
--      || pGroup->nCurrentPage>=pGroup->nMaxPage
--      || pcache1UnderMemoryPressure(pCache)
--  )){
--    PCache1 *pOther;
--    pPage = pGroup->pLruTail;
--    assert( pPage->isPinned==0 );
--    pcache1RemoveFromHash(pPage);
--    pcache1PinPage(pPage);
--    pOther = pPage->pCache;
--
--    /* We want to verify that szPage and szExtra are the same for pOther
--    ** and pCache.  Assert that we can verify this by comparing sums. */
--    assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 );
--    assert( pCache->szExtra<512 );
--    assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 );
--    assert( pOther->szExtra<512 );
--
--    if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
--      pcache1FreePage(pPage);
--      pPage = 0;
--    }else{
--      pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
--    }
-+  p->pCache->nRef--;
-+  if( p->pgno==1 ){
-+    p->pCache->pPage1 = 0;
-   }
-+  sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1);
++
++  return rc;
 +}
- 
--  /* Step 5. If a usable page buffer has still not been found, 
--  ** attempt to allocate a new one. 
--  */
--  if( !pPage ){
--    if( createFlag==1 ) sqlite3BeginBenignMalloc();
--    pPage = pcache1AllocPage(pCache);
--    if( createFlag==1 ) sqlite3EndBenignMalloc();
++
++
++/*
++** 2014 August 11
++**
++** 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.
++**
++******************************************************************************
++**
++*/
++
++
++
++/* #include "fts5Int.h" */
++
++typedef struct Fts5HashEntry Fts5HashEntry;
++
 +/*
-+** Make sure the page is marked as dirty. If it isn't dirty already,
-+** make it so.
++** This file contains the implementation of an in-memory hash table used
++** to accumuluate "term -> doclist" content before it is flused to a level-0
++** segment.
 +*/
-+SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
-+  p->flags &= ~PGHDR_DONT_WRITE;
-+  assert( p->nRef>0 );
-+  if( 0==(p->flags & PGHDR_DIRTY) ){
-+    p->flags |= PGHDR_DIRTY;
-+    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
-   }
-+}
- 
--  if( pPage ){
--    unsigned int h = iKey % pCache->nHash;
--    pCache->nPage++;
--    pPage->iKey = iKey;
--    pPage->pNext = pCache->apHash[h];
--    pPage->pCache = pCache;
--    pPage->pLruPrev = 0;
--    pPage->pLruNext = 0;
--    pPage->isPinned = 1;
--    *(void **)pPage->page.pExtra = 0;
--    pCache->apHash[h] = pPage;
--    if( iKey>pCache->iMaxKey ){
--      pCache->iMaxKey = iKey;
++
++
++struct Fts5Hash {
++  int eDetail;                    /* Copy of Fts5Config.eDetail */
++  int *pnByte;                    /* Pointer to bytes counter */
++  int nEntry;                     /* Number of entries currently in hash */
++  int nSlot;                      /* Size of aSlot[] array */
++  Fts5HashEntry *pScan;           /* Current ordered scan item */
++  Fts5HashEntry **aSlot;          /* Array of hash slots */
++};
++
 +/*
-+** Make sure the page is marked as clean. If it isn't clean already,
-+** make it so.
++** Each entry in the hash table is represented by an object of the 
++** following type. Each object, its key (a nul-terminated string) and 
++** its current data are stored in a single memory allocation. The 
++** key immediately follows the object in memory. The position list
++** data immediately follows the key data in memory.
++**
++** The data that follows the key is in a similar, but not identical format
++** to the doclist data stored in the database. It is:
++**
++**   * Rowid, as a varint
++**   * Position list, without 0x00 terminator.
++**   * Size of previous position list and rowid, as a 4 byte
++**     big-endian integer.
++**
++** iRowidOff:
++**   Offset of last rowid written to data area. Relative to first byte of
++**   structure.
++**
++** nData:
++**   Bytes of data written since iRowidOff.
 +*/
-+SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
-+  if( (p->flags & PGHDR_DIRTY) ){
-+    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
-+    p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC);
-+    if( p->nRef==0 ){
-+      pcacheUnpin(p);
-     }
-   }
--  return pPage;
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xFetch method. 
--**
--** Fetch a page by key value.
--**
--** Whether or not a new page may be allocated by this function depends on
--** the value of the createFlag argument.  0 means do not allocate a new
--** page.  1 means allocate a new page if space is easily available.  2 
--** means to try really hard to allocate a new page.
--**
--** For a non-purgeable cache (a cache used as the storage for an in-memory
--** database) there is really no difference between createFlag 1 and 2.  So
--** the calling function (pcache.c) will never have a createFlag of 1 on
--** a non-purgeable cache.
--**
--** There are three different approaches to obtaining space for a page,
--** depending on the value of parameter createFlag (which may be 0, 1 or 2).
--**
--**   1. Regardless of the value of createFlag, the cache is searched for a 
--**      copy of the requested page. If one is found, it is returned.
--**
--**   2. If createFlag==0 and the page is not already in the cache, NULL is
--**      returned.
--**
--**   3. If createFlag is 1, and the page is not already in the cache, then
--**      return NULL (do not allocate a new page) if any of the following
--**      conditions are true:
--**
--**       (a) the number of pages pinned by the cache is greater than
--**           PCache1.nMax, or
--**
--**       (b) the number of pages pinned by the cache is greater than
--**           the sum of nMax for all purgeable caches, less the sum of 
--**           nMin for all other purgeable caches, or
--**
--**   4. If none of the first three conditions apply and the cache is marked
--**      as purgeable, and if one of the following is true:
--**
--**       (a) The number of pages allocated for the cache is already 
--**           PCache1.nMax, or
--**
--**       (b) The number of pages allocated for all purgeable caches is
--**           already equal to or greater than the sum of nMax for all
--**           purgeable caches,
--**
--**       (c) The system is under memory pressure and wants to avoid
--**           unnecessary pages cache entry allocations
--**
--**      then attempt to recycle a page from the LRU list. If it is the right
--**      size, return the recycled buffer. Otherwise, free the buffer and
--**      proceed to step 5. 
--**
--**   5. Otherwise, allocate and return a new page buffer.
-+** Make every page in the cache clean.
- */
--static sqlite3_pcache_page *pcache1Fetch(
--  sqlite3_pcache *p, 
--  unsigned int iKey, 
--  int createFlag
--){
--  PCache1 *pCache = (PCache1 *)p;
--  PgHdr1 *pPage = 0;
--
--  assert( offsetof(PgHdr1,page)==0 );
--  assert( pCache->bPurgeable || createFlag!=1 );
--  assert( pCache->bPurgeable || pCache->nMin==0 );
--  assert( pCache->bPurgeable==0 || pCache->nMin==10 );
--  assert( pCache->nMin==0 || pCache->bPurgeable );
--  assert( pCache->nHash>0 );
--  pcache1EnterMutex(pCache->pGroup);
--
--  /* Step 1: Search the hash table for an existing entry. */
--  pPage = pCache->apHash[iKey % pCache->nHash];
--  while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; }
-+SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){
-+  PgHdr *p;
-+  while( (p = pCache->pDirty)!=0 ){
-+    sqlite3PcacheMakeClean(p);
-+  }
-+}
- 
--  /* Step 2: Abort if no existing page is found and createFlag is 0 */
--  if( pPage ){
--    if( !pPage->isPinned ) pcache1PinPage(pPage);
--  }else if( createFlag ){
--    /* Steps 3, 4, and 5 implemented by this subroutine */
--    pPage = pcache1FetchStage2(pCache, iKey, createFlag);
++struct Fts5HashEntry {
++  Fts5HashEntry *pHashNext;       /* Next hash entry with same hash-key */
++  Fts5HashEntry *pScanNext;       /* Next entry in sorted order */
++  
++  int nAlloc;                     /* Total size of allocation */
++  int iSzPoslist;                 /* Offset of space for 4-byte poslist size */
++  int nData;                      /* Total bytes of data (incl. structure) */
++  int nKey;                       /* Length of key in bytes */
++  u8 bDel;                        /* Set delete-flag @ iSzPoslist */
++  u8 bContent;                    /* Set content-flag (detail=none mode) */
++  i16 iCol;                       /* Column of last value written */
++  int iPos;                       /* Position of last value written */
++  i64 iRowid;                     /* Rowid of last value written */
++};
++
 +/*
-+** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
++** Eqivalent to:
++**
++**   char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; }
 +*/
-+SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){
-+  PgHdr *p;
-+  for(p=pCache->pDirty; p; p=p->pDirtyNext){
-+    p->flags &= ~PGHDR_NEED_SYNC;
-   }
--  assert( pPage==0 || pCache->iMaxKey>=iKey );
--  pcache1LeaveMutex(pCache->pGroup);
--  return (sqlite3_pcache_page*)pPage;
-+  pCache->pSynced = pCache->pDirtyTail;
- }
- 
++#define fts5EntryKey(p) ( ((char *)(&(p)[1])) )
++
++
 +/*
-+** Change the page number of page p to newPgno. 
++** Allocate a new hash table.
 +*/
-+SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
-+  PCache *pCache = p->pCache;
-+  assert( p->nRef>0 );
-+  assert( newPgno>0 );
-+  sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
-+  p->pgno = newPgno;
-+  if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
-+    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
-+  }
-+}
- 
- /*
--** Implementation of the sqlite3_pcache.xUnpin method.
-+** Drop every cache entry whose page number is greater than "pgno". The
-+** caller must ensure that there are no outstanding references to any pages
-+** other than page 1 with a page number greater than pgno.
- **
--** Mark a page as unpinned (eligible for asynchronous recycling).
-+** If there is a reference to page 1 and the pgno parameter passed to this
-+** function is 0, then the data area associated with page 1 is zeroed, but
-+** the page object is not dropped.
- */
--static void pcache1Unpin(
--  sqlite3_pcache *p, 
--  sqlite3_pcache_page *pPg, 
--  int reuseUnlikely
--){
--  PCache1 *pCache = (PCache1 *)p;
--  PgHdr1 *pPage = (PgHdr1 *)pPg;
--  PGroup *pGroup = pCache->pGroup;
-- 
--  assert( pPage->pCache==pCache );
--  pcache1EnterMutex(pGroup);
--
--  /* It is an error to call this function if the page is already 
--  ** part of the PGroup LRU list.
--  */
--  assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
--  assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage );
--  assert( pPage->isPinned==1 );
--
--  if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
--    pcache1RemoveFromHash(pPage);
--    pcache1FreePage(pPage);
--  }else{
--    /* Add the page to the PGroup LRU list. */
--    if( pGroup->pLruHead ){
--      pGroup->pLruHead->pLruPrev = pPage;
--      pPage->pLruNext = pGroup->pLruHead;
--      pGroup->pLruHead = pPage;
--    }else{
--      pGroup->pLruTail = pPage;
--      pGroup->pLruHead = pPage;
-+SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
-+  if( pCache->pCache ){
-+    PgHdr *p;
-+    PgHdr *pNext;
-+    for(p=pCache->pDirty; p; p=pNext){
-+      pNext = p->pDirtyNext;
-+      /* This routine never gets call with a positive pgno except right
-+      ** after sqlite3PcacheCleanAll().  So if there are dirty pages,
-+      ** it must be that pgno==0.
-+      */
-+      assert( p->pgno>0 );
-+      if( ALWAYS(p->pgno>pgno) ){
-+        assert( p->flags&PGHDR_DIRTY );
-+        sqlite3PcacheMakeClean(p);
-+      }
-     }
--    pCache->nRecyclable++;
--    pPage->isPinned = 0;
-+    if( pgno==0 && pCache->pPage1 ){
-+      memset(pCache->pPage1->pData, 0, pCache->szPage);
-+      pgno = 1;
++static int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte){
++  int rc = SQLITE_OK;
++  Fts5Hash *pNew;
++
++  *ppNew = pNew = (Fts5Hash*)sqlite3_malloc(sizeof(Fts5Hash));
++  if( pNew==0 ){
++    rc = SQLITE_NOMEM;
++  }else{
++    int nByte;
++    memset(pNew, 0, sizeof(Fts5Hash));
++    pNew->pnByte = pnByte;
++    pNew->eDetail = pConfig->eDetail;
++
++    pNew->nSlot = 1024;
++    nByte = sizeof(Fts5HashEntry*) * pNew->nSlot;
++    pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc(nByte);
++    if( pNew->aSlot==0 ){
++      sqlite3_free(pNew);
++      *ppNew = 0;
++      rc = SQLITE_NOMEM;
++    }else{
++      memset(pNew->aSlot, 0, nByte);
 +    }
-+    sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
-   }
--
--  pcache1LeaveMutex(pCache->pGroup);
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xRekey method. 
-+** Close a cache.
- */
--static void pcache1Rekey(
--  sqlite3_pcache *p,
--  sqlite3_pcache_page *pPg,
--  unsigned int iOld,
--  unsigned int iNew
--){
--  PCache1 *pCache = (PCache1 *)p;
--  PgHdr1 *pPage = (PgHdr1 *)pPg;
--  PgHdr1 **pp;
--  unsigned int h; 
--  assert( pPage->iKey==iOld );
--  assert( pPage->pCache==pCache );
-+SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
-+  assert( pCache->pCache!=0 );
-+  sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
++  }
++  return rc;
 +}
- 
--  pcache1EnterMutex(pCache->pGroup);
-+/* 
-+** Discard the contents of the cache.
++
++/*
++** Free a hash table object.
 +*/
-+SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){
-+  sqlite3PcacheTruncate(pCache, 0);
++static void sqlite3Fts5HashFree(Fts5Hash *pHash){
++  if( pHash ){
++    sqlite3Fts5HashClear(pHash);
++    sqlite3_free(pHash->aSlot);
++    sqlite3_free(pHash);
++  }
 +}
- 
--  h = iOld%pCache->nHash;
--  pp = &pCache->apHash[h];
--  while( (*pp)!=pPage ){
--    pp = &(*pp)->pNext;
++
 +/*
-+** Merge two lists of pages connected by pDirty and in pgno order.
-+** Do not both fixing the pDirtyPrev pointers.
++** Empty (but do not delete) a hash table.
 +*/
-+static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
-+  PgHdr result, *pTail;
-+  pTail = &result;
-+  while( pA && pB ){
-+    if( pA->pgno<pB->pgno ){
-+      pTail->pDirty = pA;
-+      pTail = pA;
-+      pA = pA->pDirty;
-+    }else{
-+      pTail->pDirty = pB;
-+      pTail = pB;
-+      pB = pB->pDirty;
-+    }
-   }
--  *pp = pPage->pNext;
--
--  h = iNew%pCache->nHash;
--  pPage->iKey = iNew;
--  pPage->pNext = pCache->apHash[h];
--  pCache->apHash[h] = pPage;
--  if( iNew>pCache->iMaxKey ){
--    pCache->iMaxKey = iNew;
-+  if( pA ){
-+    pTail->pDirty = pA;
-+  }else if( pB ){
-+    pTail->pDirty = pB;
-+  }else{
-+    pTail->pDirty = 0;
-   }
--
--  pcache1LeaveMutex(pCache->pGroup);
-+  return result.pDirty;
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xTruncate method. 
-+** Sort the list of pages in accending order by pgno.  Pages are
-+** connected by pDirty pointers.  The pDirtyPrev pointers are
-+** corrupted by this sort.
- **
--** Discard all unpinned pages in the cache with a page number equal to
--** or greater than parameter iLimit. Any pinned pages with a page number
--** equal to or greater than iLimit are implicitly unpinned.
-+** Since there cannot be more than 2^31 distinct pages in a database,
-+** there cannot be more than 31 buckets required by the merge sorter.
-+** One extra bucket is added to catch overflow in case something
-+** ever changes to make the previous sentence incorrect.
- */
--static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){
--  PCache1 *pCache = (PCache1 *)p;
--  pcache1EnterMutex(pCache->pGroup);
--  if( iLimit<=pCache->iMaxKey ){
--    pcache1TruncateUnsafe(pCache, iLimit);
--    pCache->iMaxKey = iLimit-1;
-+#define N_SORT_BUCKET  32
-+static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
-+  PgHdr *a[N_SORT_BUCKET], *p;
++static void sqlite3Fts5HashClear(Fts5Hash *pHash){
 +  int i;
-+  memset(a, 0, sizeof(a));
-+  while( pIn ){
-+    p = pIn;
-+    pIn = p->pDirty;
-+    p->pDirty = 0;
-+    for(i=0; ALWAYS(i<N_SORT_BUCKET-1); i++){
-+      if( a[i]==0 ){
-+        a[i] = p;
-+        break;
-+      }else{
-+        p = pcacheMergeDirtyList(a[i], p);
-+        a[i] = 0;
-+      }
-+    }
-+    if( NEVER(i==N_SORT_BUCKET-1) ){
-+      /* To get here, there need to be 2^(N_SORT_BUCKET) elements in
-+      ** the input list.  But that is impossible.
-+      */
-+      a[i] = pcacheMergeDirtyList(a[i], p);
++  for(i=0; i<pHash->nSlot; i++){
++    Fts5HashEntry *pNext;
++    Fts5HashEntry *pSlot;
++    for(pSlot=pHash->aSlot[i]; pSlot; pSlot=pNext){
++      pNext = pSlot->pHashNext;
++      sqlite3_free(pSlot);
 +    }
-   }
--  pcache1LeaveMutex(pCache->pGroup);
-+  p = a[0];
-+  for(i=1; i<N_SORT_BUCKET; i++){
-+    p = pcacheMergeDirtyList(p, a[i]);
-+  }
-+  return p;
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xDestroy method. 
--**
--** Destroy a cache allocated using pcache1Create().
-+** Return a list of all dirty pages in the cache, sorted by page number.
- */
--static void pcache1Destroy(sqlite3_pcache *p){
--  PCache1 *pCache = (PCache1 *)p;
--  PGroup *pGroup = pCache->pGroup;
--  assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
--  pcache1EnterMutex(pGroup);
--  pcache1TruncateUnsafe(pCache, 0);
--  assert( pGroup->nMaxPage >= pCache->nMax );
--  pGroup->nMaxPage -= pCache->nMax;
--  assert( pGroup->nMinPage >= pCache->nMin );
--  pGroup->nMinPage -= pCache->nMin;
--  pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
--  pcache1EnforceMaxPage(pGroup);
--  pcache1LeaveMutex(pGroup);
--  sqlite3_free(pCache->apHash);
--  sqlite3_free(pCache);
-+SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
-+  PgHdr *p;
-+  for(p=pCache->pDirty; p; p=p->pDirtyNext){
-+    p->pDirty = p->pDirtyNext;
 +  }
-+  return pcacheSortDirtyList(pCache->pDirty);
++  memset(pHash->aSlot, 0, pHash->nSlot * sizeof(Fts5HashEntry*));
++  pHash->nEntry = 0;
 +}
 +
-+/* 
-+** Return the total number of referenced pages held by the cache.
-+*/
-+SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
-+  return pCache->nRef;
- }
- 
- /*
--** This function is called during initialization (sqlite3_initialize()) to
--** install the default pluggable cache module, assuming the user has not
--** already provided an alternative.
-+** Return the number of references to the page supplied as an argument.
- */
--SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){
--  static const sqlite3_pcache_methods2 defaultMethods = {
--    1,                       /* iVersion */
--    0,                       /* pArg */
--    pcache1Init,             /* xInit */
--    pcache1Shutdown,         /* xShutdown */
--    pcache1Create,           /* xCreate */
--    pcache1Cachesize,        /* xCachesize */
--    pcache1Pagecount,        /* xPagecount */
--    pcache1Fetch,            /* xFetch */
--    pcache1Unpin,            /* xUnpin */
--    pcache1Rekey,            /* xRekey */
--    pcache1Truncate,         /* xTruncate */
--    pcache1Destroy,          /* xDestroy */
--    pcache1Shrink            /* xShrink */
--  };
--  sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
-+SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){
-+  return p->nRef;
++static unsigned int fts5HashKey(int nSlot, const u8 *p, int n){
++  int i;
++  unsigned int h = 13;
++  for(i=n-1; i>=0; i--){
++    h = (h << 3) ^ h ^ p[i];
++  }
++  return (h % nSlot);
 +}
 +
-+/* 
-+** Return the total number of pages in the cache.
-+*/
-+SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){
-+  assert( pCache->pCache!=0 );
-+  return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
- }
- 
-+#ifdef SQLITE_TEST
- /*
--** Return the size of the header on each page of this PCACHE implementation.
-+** Get the suggested cache-size value.
- */
--SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); }
-+SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){
-+  return numberOfCachePages(pCache);
++static unsigned int fts5HashKey2(int nSlot, u8 b, const u8 *p, int n){
++  int i;
++  unsigned int h = 13;
++  for(i=n-1; i>=0; i--){
++    h = (h << 3) ^ h ^ p[i];
++  }
++  h = (h << 3) ^ h ^ b;
++  return (h % nSlot);
 +}
-+#endif
- 
- /*
--** Return the global mutex used by this PCACHE implementation.  The
--** sqlite3_status() routine needs access to this mutex.
-+** Set the suggested cache-size value.
- */
--SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){
--  return pcache1.mutex;
-+SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
-+  assert( pCache->pCache!=0 );
-+  pCache->szCache = mxPage;
-+  sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
-+                                         numberOfCachePages(pCache));
- }
- 
--#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- /*
--** This function is called to free superfluous dynamically allocated memory
--** held by the pager system. Memory in use by any SQLite pager allocated
--** by the current thread may be sqlite3_free()ed.
--**
--** nReq is the number of bytes of memory required. Once this much has
--** been released, the function returns. The return value is the total number 
--** of bytes of memory released.
-+** Free up as much memory as possible from the page cache.
- */
--SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
--  int nFree = 0;
--  assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
--  assert( sqlite3_mutex_notheld(pcache1.mutex) );
--  if( pcache1.pStart==0 ){
--    PgHdr1 *p;
--    pcache1EnterMutex(&pcache1.grp);
--    while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
--      nFree += pcache1MemSize(p->page.pBuf);
--#ifdef SQLITE_PCACHE_SEPARATE_HEADER
--      nFree += sqlite3MemSize(p);
--#endif
--      assert( p->isPinned==0 );
--      pcache1PinPage(p);
--      pcache1RemoveFromHash(p);
--      pcache1FreePage(p);
--    }
--    pcache1LeaveMutex(&pcache1.grp);
--  }
--  return nFree;
-+SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
-+  assert( pCache->pCache!=0 );
-+  sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
- }
--#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
- 
--#ifdef SQLITE_TEST
- /*
--** This function is used by test procedures to inspect the internal state
--** of the global cache.
-+** Return the size of the header added by this middleware layer
-+** in the page-cache hierarchy.
- */
--SQLITE_PRIVATE void sqlite3PcacheStats(
--  int *pnCurrent,      /* OUT: Total number of pages cached */
--  int *pnMax,          /* OUT: Global maximum cache size */
--  int *pnMin,          /* OUT: Sum of PCache1.nMin for purgeable caches */
--  int *pnRecyclable    /* OUT: Total number of pages available for recycling */
--){
--  PgHdr1 *p;
--  int nRecyclable = 0;
--  for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){
--    assert( p->isPinned==0 );
--    nRecyclable++;
-+SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
 +
-+
-+#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
 +/*
-+** For all dirty pages currently in the cache, invoke the specified
-+** callback. This is only used if the SQLITE_CHECK_PAGES macro is
-+** defined.
++** Resize the hash table by doubling the number of slots.
 +*/
-+SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){
-+  PgHdr *pDirty;
-+  for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){
-+    xIter(pDirty);
-   }
--  *pnCurrent = pcache1.grp.nCurrentPage;
--  *pnMax = (int)pcache1.grp.nMaxPage;
--  *pnMin = (int)pcache1.grp.nMinPage;
--  *pnRecyclable = nRecyclable;
- }
- #endif
- 
--/************** End of pcache1.c *********************************************/
--/************** Begin file rowset.c ******************************************/
-+/************** End of pcache.c **********************************************/
-+/************** Begin file pcache1.c *****************************************/
- /*
--** 2008 December 3
-+** 2008 November 05
- **
- ** The author disclaims copyright to this source code.  In place of
- ** a legal notice, here is a blessing:
-@@ -40991,11779 +43568,12180 @@
- **
- *************************************************************************
- **
--** This module implements an object we call a "RowSet".
--**
--** The RowSet object is a collection of rowids.  Rowids
--** are inserted into the RowSet in an arbitrary order.  Inserts
--** can be intermixed with tests to see if a given rowid has been
--** previously inserted into the RowSet.
--**
--** After all inserts are finished, it is possible to extract the
--** elements of the RowSet in sorted order.  Once this extraction
--** process has started, no new elements may be inserted.
--**
--** Hence, the primitive operations for a RowSet are:
--**
--**    CREATE
--**    INSERT
--**    TEST
--**    SMALLEST
--**    DESTROY
-+** This file implements the default page cache implementation (the
-+** sqlite3_pcache interface). It also contains part of the implementation
-+** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
-+** If the default page cache implementation is overridden, then neither of
-+** these two features are available.
-+*/
-+
-+
-+typedef struct PCache1 PCache1;
-+typedef struct PgHdr1 PgHdr1;
-+typedef struct PgFreeslot PgFreeslot;
-+typedef struct PGroup PGroup;
-+
-+/* Each page cache (or PCache) belongs to a PGroup.  A PGroup is a set 
-+** of one or more PCaches that are able to recycle each other's unpinned
-+** pages when they are under memory pressure.  A PGroup is an instance of
-+** the following object.
- **
--** The CREATE and DESTROY primitives are the constructor and destructor,
--** obviously.  The INSERT primitive adds a new element to the RowSet.
--** TEST checks to see if an element is already in the RowSet.  SMALLEST
--** extracts the least value from the RowSet.
-+** This page cache implementation works in one of two modes:
- **
--** The INSERT primitive might allocate additional memory.  Memory is
--** allocated in chunks so most INSERTs do no allocation.  There is an 
--** upper bound on the size of allocated memory.  No memory is freed
--** until DESTROY.
-+**   (1)  Every PCache is the sole member of its own PGroup.  There is
-+**        one PGroup per PCache.
- **
--** The TEST primitive includes a "batch" number.  The TEST primitive
--** will only see elements that were inserted before the last change
--** in the batch number.  In other words, if an INSERT occurs between
--** two TESTs where the TESTs have the same batch nubmer, then the
--** value added by the INSERT will not be visible to the second TEST.
--** The initial batch number is zero, so if the very first TEST contains
--** a non-zero batch number, it will see all prior INSERTs.
-+**   (2)  There is a single global PGroup that all PCaches are a member
-+**        of.
- **
--** No INSERTs may occurs after a SMALLEST.  An assertion will fail if
--** that is attempted.
-+** Mode 1 uses more memory (since PCache instances are not able to rob
-+** unused pages from other PCaches) but it also operates without a mutex,
-+** and is therefore often faster.  Mode 2 requires a mutex in order to be
-+** threadsafe, but recycles pages more efficiently.
- **
--** The cost of an INSERT is roughly constant.  (Sometimes new memory
--** has to be allocated on an INSERT.)  The cost of a TEST with a new
--** batch number is O(NlogN) where N is the number of elements in the RowSet.
--** The cost of a TEST using the same batch number is O(logN).  The cost
--** of the first SMALLEST is O(NlogN).  Second and subsequent SMALLEST
--** primitives are constant time.  The cost of DESTROY is O(N).
-+** For mode (1), PGroup.mutex is NULL.  For mode (2) there is only a single
-+** PGroup which is the pcache1.grp global variable and its mutex is
-+** SQLITE_MUTEX_STATIC_LRU.
-+*/
-+struct PGroup {
-+  sqlite3_mutex *mutex;          /* MUTEX_STATIC_LRU or NULL */
-+  unsigned int nMaxPage;         /* Sum of nMax for purgeable caches */
-+  unsigned int nMinPage;         /* Sum of nMin for purgeable caches */
-+  unsigned int mxPinned;         /* nMaxpage + 10 - nMinPage */
-+  unsigned int nCurrentPage;     /* Number of purgeable pages allocated */
-+  PgHdr1 *pLruHead, *pLruTail;   /* LRU list of unpinned pages */
-+};
++static int fts5HashResize(Fts5Hash *pHash){
++  int nNew = pHash->nSlot*2;
++  int i;
++  Fts5HashEntry **apNew;
++  Fts5HashEntry **apOld = pHash->aSlot;
++
++  apNew = (Fts5HashEntry**)sqlite3_malloc(nNew*sizeof(Fts5HashEntry*));
++  if( !apNew ) return SQLITE_NOMEM;
++  memset(apNew, 0, nNew*sizeof(Fts5HashEntry*));
++
++  for(i=0; i<pHash->nSlot; i++){
++    while( apOld[i] ){
++      unsigned int iHash;
++      Fts5HashEntry *p = apOld[i];
++      apOld[i] = p->pHashNext;
++      iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p),
++                          (int)strlen(fts5EntryKey(p)));
++      p->pHashNext = apNew[iHash];
++      apNew[iHash] = p;
++    }
++  }
 +
-+/* Each page cache is an instance of the following object.  Every
-+** open database file (including each in-memory database and each
-+** temporary or transient database) has a single page cache which
-+** is an instance of this object.
- **
--** There is an added cost of O(N) when switching between TEST and
--** SMALLEST primitives.
-+** Pointers to structures of this type are cast and returned as 
-+** opaque sqlite3_pcache* handles.
- */
-+struct PCache1 {
-+  /* Cache configuration parameters. Page size (szPage) and the purgeable
-+  ** flag (bPurgeable) are set when the cache is created. nMax may be 
-+  ** modified at any time by a call to the pcache1Cachesize() method.
-+  ** The PGroup mutex must be held when accessing nMax.
-+  */
-+  PGroup *pGroup;                     /* PGroup this cache belongs to */
-+  int szPage;                         /* Size of allocated pages in bytes */
-+  int szExtra;                        /* Size of extra space in bytes */
-+  int bPurgeable;                     /* True if cache is purgeable */
-+  unsigned int nMin;                  /* Minimum number of pages reserved */
-+  unsigned int nMax;                  /* Configured "cache_size" value */
-+  unsigned int n90pct;                /* nMax*9/10 */
-+  unsigned int iMaxKey;               /* Largest key seen since xTruncate() */
- 
-+  /* Hash table of all pages. The following variables may only be accessed
-+  ** when the accessor is holding the PGroup mutex.
-+  */
-+  unsigned int nRecyclable;           /* Number of pages in the LRU list */
-+  unsigned int nPage;                 /* Total number of pages in apHash */
-+  unsigned int nHash;                 /* Number of slots in apHash[] */
-+  PgHdr1 **apHash;                    /* Hash table for fast lookup by key */
-+};
- 
- /*
--** Target size for allocation chunks.
-+** Each cache entry is represented by an instance of the following 
-+** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
-+** PgHdr1.pCache->szPage bytes is allocated directly before this structure 
-+** in memory.
- */
--#define ROWSET_ALLOCATION_SIZE 1024
-+struct PgHdr1 {
-+  sqlite3_pcache_page page;
-+  unsigned int iKey;             /* Key value (page number) */
-+  u8 isPinned;                   /* Page in use, not on the LRU list */
-+  PgHdr1 *pNext;                 /* Next in hash table chain */
-+  PCache1 *pCache;               /* Cache that currently owns this page */
-+  PgHdr1 *pLruNext;              /* Next in LRU list of unpinned pages */
-+  PgHdr1 *pLruPrev;              /* Previous in LRU list of unpinned pages */
-+};
- 
- /*
--** The number of rowset entries per allocation chunk.
-+** Free slots in the allocator used to divide up the buffer provided using
-+** the SQLITE_CONFIG_PAGECACHE mechanism.
- */
--#define ROWSET_ENTRY_PER_CHUNK  \
--                       ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry))
-+struct PgFreeslot {
-+  PgFreeslot *pNext;  /* Next free slot */
-+};
- 
- /*
--** Each entry in a RowSet is an instance of the following object.
--**
--** This same object is reused to store a linked list of trees of RowSetEntry
--** objects.  In that alternative use, pRight points to the next entry
--** in the list, pLeft points to the tree, and v is unused.  The
--** RowSet.pForest value points to the head of this forest list.
-+** Global data used by this cache.
- */
--struct RowSetEntry {            
--  i64 v;                        /* ROWID value for this entry */
--  struct RowSetEntry *pRight;   /* Right subtree (larger entries) or list */
--  struct RowSetEntry *pLeft;    /* Left subtree (smaller entries) */
--};
-+static SQLITE_WSD struct PCacheGlobal {
-+  PGroup grp;                    /* The global PGroup for mode (2) */
++  sqlite3_free(apOld);
++  pHash->nSlot = nNew;
++  pHash->aSlot = apNew;
++  return SQLITE_OK;
++}
 +
-+  /* Variables related to SQLITE_CONFIG_PAGECACHE settings.  The
-+  ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all
-+  ** fixed at sqlite3_initialize() time and do not require mutex protection.
-+  ** The nFreeSlot and pFree values do require mutex protection.
-+  */
-+  int isInit;                    /* True if initialized */
-+  int szSlot;                    /* Size of each free slot */
-+  int nSlot;                     /* The number of pcache slots */
-+  int nReserve;                  /* Try to keep nFreeSlot above this */
-+  void *pStart, *pEnd;           /* Bounds of pagecache malloc range */
-+  /* Above requires no mutex.  Use mutex below for variable that follow. */
-+  sqlite3_mutex *mutex;          /* Mutex for accessing the following: */
-+  PgFreeslot *pFree;             /* Free page blocks */
-+  int nFreeSlot;                 /* Number of unused pcache slots */
-+  /* The following value requires a mutex to change.  We skip the mutex on
-+  ** reading because (1) most platforms read a 32-bit integer atomically and
-+  ** (2) even if an incorrect value is read, no great harm is done since this
-+  ** is really just an optimization. */
-+  int bUnderPressure;            /* True if low on PAGECACHE memory */
-+} pcache1_g;
- 
- /*
--** RowSetEntry objects are allocated in large chunks (instances of the
--** following structure) to reduce memory allocation overhead.  The
--** chunks are kept on a linked list so that they can be deallocated
--** when the RowSet is destroyed.
-+** All code in this file should access the global structure above via the
-+** alias "pcache1". This ensures that the WSD emulation is used when
-+** compiling for systems that do not support real WSD.
- */
--struct RowSetChunk {
--  struct RowSetChunk *pNextChunk;        /* Next chunk on list of them all */
--  struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */
--};
-+#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g))
- 
- /*
--** A RowSet in an instance of the following structure.
--**
--** A typedef of this structure if found in sqliteInt.h.
-+** Macros to enter and leave the PCache LRU mutex.
- */
--struct RowSet {
--  struct RowSetChunk *pChunk;    /* List of all chunk allocations */
--  sqlite3 *db;                   /* The database connection */
--  struct RowSetEntry *pEntry;    /* List of entries using pRight */
--  struct RowSetEntry *pLast;     /* Last entry on the pEntry list */
--  struct RowSetEntry *pFresh;    /* Source of new entry objects */
--  struct RowSetEntry *pForest;   /* List of binary trees of entries */
--  u16 nFresh;                    /* Number of objects on pFresh */
--  u16 rsFlags;                   /* Various flags */
--  int iBatch;                    /* Current insert batch */
--};
-+#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
-+#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
-+
-+/******************************************************************************/
-+/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
- 
- /*
--** Allowed values for RowSet.rsFlags
-+** This function is called during initialization if a static buffer is 
-+** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE
-+** verb to sqlite3_config(). Parameter pBuf points to an allocation large
-+** enough to contain 'n' buffers of 'sz' bytes each.
-+**
-+** This routine is called from sqlite3_initialize() and so it is guaranteed
-+** to be serialized already.  There is no need for further mutexing.
- */
--#define ROWSET_SORTED  0x01   /* True if RowSet.pEntry is sorted */
--#define ROWSET_NEXT    0x02   /* True if sqlite3RowSetNext() has been called */
-+SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
-+  if( pcache1.isInit ){
-+    PgFreeslot *p;
-+    sz = ROUNDDOWN8(sz);
-+    pcache1.szSlot = sz;
-+    pcache1.nSlot = pcache1.nFreeSlot = n;
-+    pcache1.nReserve = n>90 ? 10 : (n/10 + 1);
-+    pcache1.pStart = pBuf;
-+    pcache1.pFree = 0;
-+    pcache1.bUnderPressure = 0;
-+    while( n-- ){
-+      p = (PgFreeslot*)pBuf;
-+      p->pNext = pcache1.pFree;
-+      pcache1.pFree = p;
-+      pBuf = (void*)&((char*)pBuf)[sz];
-+    }
-+    pcache1.pEnd = pBuf;
-+  }
-+}
- 
- /*
--** Turn bulk memory into a RowSet object.  N bytes of memory
--** are available at pSpace.  The db pointer is used as a memory context
--** for any subsequent allocations that need to occur.
--** Return a pointer to the new RowSet object.
-+** Malloc function used within this file to allocate space from the buffer
-+** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no 
-+** such buffer exists or there is no space left in it, this function falls 
-+** back to sqlite3Malloc().
- **
--** It must be the case that N is sufficient to make a Rowset.  If not
--** an assertion fault occurs.
--** 
--** If N is larger than the minimum, use the surplus as an initial
--** allocation of entries available to be filled.
-+** Multiple threads can run this routine at the same time.  Global variables
-+** in pcache1 need to be protected via mutex.
- */
--SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
--  RowSet *p;
--  assert( N >= ROUND8(sizeof(*p)) );
--  p = pSpace;
--  p->pChunk = 0;
--  p->db = db;
--  p->pEntry = 0;
--  p->pLast = 0;
--  p->pForest = 0;
--  p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
--  p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
--  p->rsFlags = ROWSET_SORTED;
--  p->iBatch = 0;
-+static void *pcache1Alloc(int nByte){
-+  void *p = 0;
-+  assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
-+  if( nByte<=pcache1.szSlot ){
-+    sqlite3_mutex_enter(pcache1.mutex);
-+    p = (PgHdr1 *)pcache1.pFree;
-+    if( p ){
-+      pcache1.pFree = pcache1.pFree->pNext;
-+      pcache1.nFreeSlot--;
-+      pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
-+      assert( pcache1.nFreeSlot>=0 );
-+      sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
-+      sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
++static void fts5HashAddPoslistSize(Fts5Hash *pHash, Fts5HashEntry *p){
++  if( p->iSzPoslist ){
++    u8 *pPtr = (u8*)p;
++    if( pHash->eDetail==FTS5_DETAIL_NONE ){
++      assert( p->nData==p->iSzPoslist );
++      if( p->bDel ){
++        pPtr[p->nData++] = 0x00;
++        if( p->bContent ){
++          pPtr[p->nData++] = 0x00;
++        }
++      }
++    }else{
++      int nSz = (p->nData - p->iSzPoslist - 1);       /* Size in bytes */
++      int nPos = nSz*2 + p->bDel;                     /* Value of nPos field */
++
++      assert( p->bDel==0 || p->bDel==1 );
++      if( nPos<=127 ){
++        pPtr[p->iSzPoslist] = (u8)nPos;
++      }else{
++        int nByte = sqlite3Fts5GetVarintLen((u32)nPos);
++        memmove(&pPtr[p->iSzPoslist + nByte], &pPtr[p->iSzPoslist + 1], nSz);
++        sqlite3Fts5PutVarint(&pPtr[p->iSzPoslist], nPos);
++        p->nData += (nByte-1);
++      }
++    }
++
++    p->iSzPoslist = 0;
++    p->bDel = 0;
++    p->bContent = 0;
++  }
++}
++
++/*
++** Add an entry to the in-memory hash table. The key is the concatenation
++** of bByte and (pToken/nToken). The value is (iRowid/iCol/iPos).
++**
++**     (bByte || pToken) -> (iRowid,iCol,iPos)
++**
++** Or, if iCol is negative, then the value is a delete marker.
++*/
++static int sqlite3Fts5HashWrite(
++  Fts5Hash *pHash,
++  i64 iRowid,                     /* Rowid for this entry */
++  int iCol,                       /* Column token appears in (-ve -> delete) */
++  int iPos,                       /* Position of token within column */
++  char bByte,                     /* First byte of token */
++  const char *pToken, int nToken  /* Token to add or remove to or from index */
++){
++  unsigned int iHash;
++  Fts5HashEntry *p;
++  u8 *pPtr;
++  int nIncr = 0;                  /* Amount to increment (*pHash->pnByte) by */
++  int bNew;                       /* If non-delete entry should be written */
++  
++  bNew = (pHash->eDetail==FTS5_DETAIL_FULL);
++
++  /* Attempt to locate an existing hash entry */
++  iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
++  for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
++    char *zKey = fts5EntryKey(p);
++    if( zKey[0]==bByte 
++     && p->nKey==nToken
++     && memcmp(&zKey[1], pToken, nToken)==0 
++    ){
++      break;
 +    }
-+    sqlite3_mutex_leave(pcache1.mutex);
 +  }
++
++  /* If an existing hash entry cannot be found, create a new one. */
 +  if( p==0 ){
-+    /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool.  Get
-+    ** it from sqlite3Malloc instead.
++    /* Figure out how much space to allocate */
++    char *zKey;
++    int nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
++    if( nByte<128 ) nByte = 128;
++
++    /* Grow the Fts5Hash.aSlot[] array if necessary. */
++    if( (pHash->nEntry*2)>=pHash->nSlot ){
++      int rc = fts5HashResize(pHash);
++      if( rc!=SQLITE_OK ) return rc;
++      iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
++    }
++
++    /* Allocate new Fts5HashEntry and add it to the hash table. */
++    p = (Fts5HashEntry*)sqlite3_malloc(nByte);
++    if( !p ) return SQLITE_NOMEM;
++    memset(p, 0, sizeof(Fts5HashEntry));
++    p->nAlloc = nByte;
++    zKey = fts5EntryKey(p);
++    zKey[0] = bByte;
++    memcpy(&zKey[1], pToken, nToken);
++    assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) );
++    p->nKey = nToken;
++    zKey[nToken+1] = '\0';
++    p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry);
++    p->pHashNext = pHash->aSlot[iHash];
++    pHash->aSlot[iHash] = p;
++    pHash->nEntry++;
++
++    /* Add the first rowid field to the hash-entry */
++    p->nData += sqlite3Fts5PutVarint(&((u8*)p)[p->nData], iRowid);
++    p->iRowid = iRowid;
++
++    p->iSzPoslist = p->nData;
++    if( pHash->eDetail!=FTS5_DETAIL_NONE ){
++      p->nData += 1;
++      p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
++    }
++
++    nIncr += p->nData;
++  }else{
++
++    /* Appending to an existing hash-entry. Check that there is enough 
++    ** space to append the largest possible new entry. Worst case scenario 
++    ** is:
++    **
++    **     + 9 bytes for a new rowid,
++    **     + 4 byte reserved for the "poslist size" varint.
++    **     + 1 byte for a "new column" byte,
++    **     + 3 bytes for a new column number (16-bit max) as a varint,
++    **     + 5 bytes for the new position offset (32-bit max).
 +    */
-+    p = sqlite3Malloc(nByte);
-+#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
-+    if( p ){
-+      int sz = sqlite3MallocSize(p);
-+      sqlite3_mutex_enter(pcache1.mutex);
-+      sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
-+      sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
-+      sqlite3_mutex_leave(pcache1.mutex);
++    if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){
++      int nNew = p->nAlloc * 2;
++      Fts5HashEntry *pNew;
++      Fts5HashEntry **pp;
++      pNew = (Fts5HashEntry*)sqlite3_realloc(p, nNew);
++      if( pNew==0 ) return SQLITE_NOMEM;
++      pNew->nAlloc = nNew;
++      for(pp=&pHash->aSlot[iHash]; *pp!=p; pp=&(*pp)->pHashNext);
++      *pp = pNew;
++      p = pNew;
 +    }
-+#endif
-+    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
++    nIncr -= p->nData;
 +  }
-   return p;
- }
- 
- /*
--** Deallocate all chunks from a RowSet.  This frees all memory that
--** the RowSet has allocated over its lifetime.  This routine is
--** the destructor for the RowSet.
-+** Free an allocated buffer obtained from pcache1Alloc().
- */
--SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
--  struct RowSetChunk *pChunk, *pNextChunk;
--  for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
--    pNextChunk = pChunk->pNextChunk;
--    sqlite3DbFree(p->db, pChunk);
-+static int pcache1Free(void *p){
-+  int nFreed = 0;
-+  if( p==0 ) return 0;
-+  if( p>=pcache1.pStart && p<pcache1.pEnd ){
-+    PgFreeslot *pSlot;
-+    sqlite3_mutex_enter(pcache1.mutex);
-+    sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1);
-+    pSlot = (PgFreeslot*)p;
-+    pSlot->pNext = pcache1.pFree;
-+    pcache1.pFree = pSlot;
-+    pcache1.nFreeSlot++;
-+    pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
-+    assert( pcache1.nFreeSlot<=pcache1.nSlot );
-+    sqlite3_mutex_leave(pcache1.mutex);
-+  }else{
-+    assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
-+    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
-+    nFreed = sqlite3MallocSize(p);
-+#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
-+    sqlite3_mutex_enter(pcache1.mutex);
-+    sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
-+    sqlite3_mutex_leave(pcache1.mutex);
-+#endif
-+    sqlite3_free(p);
-   }
--  p->pChunk = 0;
--  p->nFresh = 0;
--  p->pEntry = 0;
--  p->pLast = 0;
--  p->pForest = 0;
--  p->rsFlags = ROWSET_SORTED;
-+  return nFreed;
- }
- 
-+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- /*
--** Allocate a new RowSetEntry object that is associated with the
--** given RowSet.  Return a pointer to the new and completely uninitialized
--** objected.
--**
--** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
--** routine returns NULL.
-+** Return the size of a pcache allocation
- */
--static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
--  assert( p!=0 );
--  if( p->nFresh==0 ){
--    struct RowSetChunk *pNew;
--    pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew));
--    if( pNew==0 ){
--      return 0;
--    }
--    pNew->pNextChunk = p->pChunk;
--    p->pChunk = pNew;
--    p->pFresh = pNew->aEntry;
--    p->nFresh = ROWSET_ENTRY_PER_CHUNK;
-+static int pcache1MemSize(void *p){
-+  if( p>=pcache1.pStart && p<pcache1.pEnd ){
-+    return pcache1.szSlot;
++  assert( (p->nAlloc - p->nData) >= (9 + 4 + 1 + 3 + 5) );
++
++  pPtr = (u8*)p;
++
++  /* If this is a new rowid, append the 4-byte size field for the previous
++  ** entry, and the new rowid for this entry.  */
++  if( iRowid!=p->iRowid ){
++    fts5HashAddPoslistSize(pHash, p);
++    p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid);
++    p->iRowid = iRowid;
++    bNew = 1;
++    p->iSzPoslist = p->nData;
++    if( pHash->eDetail!=FTS5_DETAIL_NONE ){
++      p->nData += 1;
++      p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
++      p->iPos = 0;
++    }
++  }
++
++  if( iCol>=0 ){
++    if( pHash->eDetail==FTS5_DETAIL_NONE ){
++      p->bContent = 1;
++    }else{
++      /* Append a new column value, if necessary */
++      assert( iCol>=p->iCol );
++      if( iCol!=p->iCol ){
++        if( pHash->eDetail==FTS5_DETAIL_FULL ){
++          pPtr[p->nData++] = 0x01;
++          p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol);
++          p->iCol = (i16)iCol;
++          p->iPos = 0;
++        }else{
++          bNew = 1;
++          p->iCol = (i16)(iPos = iCol);
++        }
++      }
++
++      /* Append the new position offset, if necessary */
++      if( bNew ){
++        p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iPos - p->iPos + 2);
++        p->iPos = iPos;
++      }
++    }
 +  }else{
-+    int iSize;
-+    assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
-+    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
-+    iSize = sqlite3MallocSize(p);
-+    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
-+    return iSize;
-   }
--  p->nFresh--;
--  return p->pFresh++;
- }
-+#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
- 
- /*
--** Insert a new value into a RowSet.
--**
--** The mallocFailed flag of the database connection is set if a
--** memory allocation fails.
-+** Allocate a new page object initially associated with cache pCache.
- */
--SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){
--  struct RowSetEntry *pEntry;  /* The new entry */
--  struct RowSetEntry *pLast;   /* The last prior entry */
-+static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
-+  PgHdr1 *p = 0;
-+  void *pPg;
- 
--  /* This routine is never called after sqlite3RowSetNext() */
--  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
-+  /* The group mutex must be released before pcache1Alloc() is called. This
-+  ** is because it may call sqlite3_release_memory(), which assumes that 
-+  ** this mutex is not held. */
-+  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
-+  pcache1LeaveMutex(pCache->pGroup);
-+#ifdef SQLITE_PCACHE_SEPARATE_HEADER
-+  pPg = pcache1Alloc(pCache->szPage);
-+  p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
-+  if( !pPg || !p ){
-+    pcache1Free(pPg);
-+    sqlite3_free(p);
-+    pPg = 0;
++    /* This is a delete. Set the delete flag. */
++    p->bDel = 1;
 +  }
-+#else
-+  pPg = pcache1Alloc(ROUND8(sizeof(PgHdr1)) + pCache->szPage + pCache->szExtra);
-+  p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
-+#endif
-+  pcache1EnterMutex(pCache->pGroup);
- 
--  pEntry = rowSetEntryAlloc(p);
--  if( pEntry==0 ) return;
--  pEntry->v = rowid;
--  pEntry->pRight = 0;
--  pLast = p->pLast;
--  if( pLast ){
--    if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){
--      p->rsFlags &= ~ROWSET_SORTED;
-+  if( pPg ){
-+    p->page.pBuf = pPg;
-+    p->page.pExtra = &p[1];
-+    if( pCache->bPurgeable ){
-+      pCache->pGroup->nCurrentPage++;
-     }
--    pLast->pRight = pEntry;
--  }else{
--    p->pEntry = pEntry;
-+    return p;
-   }
--  p->pLast = pEntry;
-+  return 0;
- }
- 
- /*
--** Merge two lists of RowSetEntry objects.  Remove duplicates.
-+** Free a page object allocated by pcache1AllocPage().
- **
--** The input lists are connected via pRight pointers and are 
--** assumed to each already be in sorted order.
-+** The pointer is allowed to be NULL, which is prudent.  But it turns out
-+** that the current implementation happens to never call this routine
-+** with a NULL pointer, so we mark the NULL test with ALWAYS().
- */
--static struct RowSetEntry *rowSetEntryMerge(
--  struct RowSetEntry *pA,    /* First sorted list to be merged */
--  struct RowSetEntry *pB     /* Second sorted list to be merged */
--){
--  struct RowSetEntry head;
--  struct RowSetEntry *pTail;
--
--  pTail = &head;
--  while( pA && pB ){
--    assert( pA->pRight==0 || pA->v<=pA->pRight->v );
--    assert( pB->pRight==0 || pB->v<=pB->pRight->v );
--    if( pA->v<pB->v ){
--      pTail->pRight = pA;
--      pA = pA->pRight;
--      pTail = pTail->pRight;
--    }else if( pB->v<pA->v ){
--      pTail->pRight = pB;
--      pB = pB->pRight;
--      pTail = pTail->pRight;
--    }else{
--      pA = pA->pRight;
-+static void pcache1FreePage(PgHdr1 *p){
-+  if( ALWAYS(p) ){
-+    PCache1 *pCache = p->pCache;
-+    assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
-+    pcache1Free(p->page.pBuf);
-+#ifdef SQLITE_PCACHE_SEPARATE_HEADER
-+    sqlite3_free(p);
-+#endif
-+    if( pCache->bPurgeable ){
-+      pCache->pGroup->nCurrentPage--;
-     }
-   }
--  if( pA ){
--    assert( pA->pRight==0 || pA->v<=pA->pRight->v );
--    pTail->pRight = pA;
--  }else{
--    assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v );
--    pTail->pRight = pB;
--  }
--  return head.pRight;
- }
- 
- /*
--** Sort all elements on the list of RowSetEntry objects into order of
--** increasing v.
--*/ 
--static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){
--  unsigned int i;
--  struct RowSetEntry *pNext, *aBucket[40];
--
--  memset(aBucket, 0, sizeof(aBucket));
--  while( pIn ){
--    pNext = pIn->pRight;
--    pIn->pRight = 0;
--    for(i=0; aBucket[i]; i++){
--      pIn = rowSetEntryMerge(aBucket[i], pIn);
--      aBucket[i] = 0;
--    }
--    aBucket[i] = pIn;
--    pIn = pNext;
--  }
--  pIn = 0;
--  for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
--    pIn = rowSetEntryMerge(pIn, aBucket[i]);
--  }
--  return pIn;
-+** Malloc function used by SQLite to obtain space from the buffer configured
-+** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer
-+** exists, this function falls back to sqlite3Malloc().
++
++  nIncr += p->nData;
++  *pHash->pnByte += nIncr;
++  return SQLITE_OK;
++}
++
++
++/*
++** Arguments pLeft and pRight point to linked-lists of hash-entry objects,
++** each sorted in key order. This function merges the two lists into a
++** single list and returns a pointer to its first element.
 +*/
-+SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){
-+  return pcache1Alloc(sz);
- }
- 
--
- /*
--** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects.
--** Convert this tree into a linked list connected by the pRight pointers
--** and return pointers to the first and last elements of the new list.
-+** Free an allocated buffer obtained from sqlite3PageMalloc().
- */
--static void rowSetTreeToList(
--  struct RowSetEntry *pIn,         /* Root of the input tree */
--  struct RowSetEntry **ppFirst,    /* Write head of the output list here */
--  struct RowSetEntry **ppLast      /* Write tail of the output list here */
--){
--  assert( pIn!=0 );
--  if( pIn->pLeft ){
--    struct RowSetEntry *p;
--    rowSetTreeToList(pIn->pLeft, ppFirst, &p);
--    p->pRight = pIn;
--  }else{
--    *ppFirst = pIn;
--  }
--  if( pIn->pRight ){
--    rowSetTreeToList(pIn->pRight, &pIn->pRight, ppLast);
--  }else{
--    *ppLast = pIn;
--  }
--  assert( (*ppLast)->pRight==0 );
-+SQLITE_PRIVATE void sqlite3PageFree(void *p){
-+  pcache1Free(p);
- }
- 
- 
- /*
--** Convert a sorted list of elements (connected by pRight) into a binary
--** tree with depth of iDepth.  A depth of 1 means the tree contains a single
--** node taken from the head of *ppList.  A depth of 2 means a tree with
--** three nodes.  And so forth.
-+** Return true if it desirable to avoid allocating a new page cache
-+** entry.
- **
--** Use as many entries from the input list as required and update the
--** *ppList to point to the unused elements of the list.  If the input
--** list contains too few elements, then construct an incomplete tree
--** and leave *ppList set to NULL.
-+** If memory was allocated specifically to the page cache using
-+** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then
-+** it is desirable to avoid allocating a new page cache entry because
-+** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient
-+** for all page cache needs and we should not need to spill the
-+** allocation onto the heap.
- **
--** Return a pointer to the root of the constructed binary tree.
-+** Or, the heap is used for all page cache memory but the heap is
-+** under memory pressure, then again it is desirable to avoid
-+** allocating a new page cache entry in order to avoid stressing
-+** the heap even further.
- */
--static struct RowSetEntry *rowSetNDeepTree(
--  struct RowSetEntry **ppList,
--  int iDepth
--){
--  struct RowSetEntry *p;         /* Root of the new tree */
--  struct RowSetEntry *pLeft;     /* Left subtree */
--  if( *ppList==0 ){
--    return 0;
--  }
--  if( iDepth==1 ){
--    p = *ppList;
--    *ppList = p->pRight;
--    p->pLeft = p->pRight = 0;
--    return p;
--  }
--  pLeft = rowSetNDeepTree(ppList, iDepth-1);
--  p = *ppList;
--  if( p==0 ){
--    return pLeft;
-+static int pcache1UnderMemoryPressure(PCache1 *pCache){
-+  if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){
-+    return pcache1.bUnderPressure;
-+  }else{
-+    return sqlite3HeapNearlyFull();
-   }
--  p->pLeft = pLeft;
--  *ppList = p->pRight;
--  p->pRight = rowSetNDeepTree(ppList, iDepth-1);
--  return p;
- }
- 
--/*
--** Convert a sorted list of elements into a binary tree. Make the tree
--** as deep as it needs to be in order to contain the entire list.
--*/
--static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
--  int iDepth;           /* Depth of the tree so far */
--  struct RowSetEntry *p;       /* Current tree root */
--  struct RowSetEntry *pLeft;   /* Left subtree */
--
--  assert( pList!=0 );
--  p = pList;
--  pList = p->pRight;
--  p->pLeft = p->pRight = 0;
--  for(iDepth=1; pList; iDepth++){
--    pLeft = p;
--    p = pList;
--    pList = p->pRight;
--    p->pLeft = pLeft;
--    p->pRight = rowSetNDeepTree(&pList, iDepth);
--  }
--  return p;
--}
-+/******************************************************************************/
-+/******** General Implementation Functions ************************************/
- 
- /*
--** Take all the entries on p->pEntry and on the trees in p->pForest and
--** sort them all together into one big ordered list on p->pEntry.
-+** This function is used to resize the hash table used by the cache passed
-+** as the first argument.
- **
--** This routine should only be called once in the life of a RowSet.
-+** The PCache mutex must be held when this function is called.
- */
--static void rowSetToList(RowSet *p){
-+static void pcache1ResizeHash(PCache1 *p){
-+  PgHdr1 **apNew;
-+  unsigned int nNew;
-+  unsigned int i;
- 
--  /* This routine is called only once */
--  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
-+  assert( sqlite3_mutex_held(p->pGroup->mutex) );
- 
--  if( (p->rsFlags & ROWSET_SORTED)==0 ){
--    p->pEntry = rowSetEntrySort(p->pEntry);
-+  nNew = p->nHash*2;
-+  if( nNew<256 ){
-+    nNew = 256;
-   }
- 
--  /* While this module could theoretically support it, sqlite3RowSetNext()
--  ** is never called after sqlite3RowSetText() for the same RowSet.  So
--  ** there is never a forest to deal with.  Should this change, simply
--  ** remove the assert() and the #if 0. */
--  assert( p->pForest==0 );
--#if 0
--  while( p->pForest ){
--    struct RowSetEntry *pTree = p->pForest->pLeft;
--    if( pTree ){
--      struct RowSetEntry *pHead, *pTail;
--      rowSetTreeToList(pTree, &pHead, &pTail);
--      p->pEntry = rowSetEntryMerge(p->pEntry, pHead);
-+  pcache1LeaveMutex(p->pGroup);
-+  if( p->nHash ){ sqlite3BeginBenignMalloc(); }
-+  apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew);
-+  if( p->nHash ){ sqlite3EndBenignMalloc(); }
-+  pcache1EnterMutex(p->pGroup);
-+  if( apNew ){
-+    for(i=0; i<p->nHash; i++){
-+      PgHdr1 *pPage;
-+      PgHdr1 *pNext = p->apHash[i];
-+      while( (pPage = pNext)!=0 ){
-+        unsigned int h = pPage->iKey % nNew;
-+        pNext = pPage->pNext;
-+        pPage->pNext = apNew[h];
-+        apNew[h] = pPage;
++static Fts5HashEntry *fts5HashEntryMerge(
++  Fts5HashEntry *pLeft,
++  Fts5HashEntry *pRight
++){
++  Fts5HashEntry *p1 = pLeft;
++  Fts5HashEntry *p2 = pRight;
++  Fts5HashEntry *pRet = 0;
++  Fts5HashEntry **ppOut = &pRet;
++
++  while( p1 || p2 ){
++    if( p1==0 ){
++      *ppOut = p2;
++      p2 = 0;
++    }else if( p2==0 ){
++      *ppOut = p1;
++      p1 = 0;
++    }else{
++      int i = 0;
++      char *zKey1 = fts5EntryKey(p1);
++      char *zKey2 = fts5EntryKey(p2);
++      while( zKey1[i]==zKey2[i] ) i++;
++
++      if( ((u8)zKey1[i])>((u8)zKey2[i]) ){
++        /* p2 is smaller */
++        *ppOut = p2;
++        ppOut = &p2->pScanNext;
++        p2 = p2->pScanNext;
++      }else{
++        /* p1 is smaller */
++        *ppOut = p1;
++        ppOut = &p1->pScanNext;
++        p1 = p1->pScanNext;
 +      }
-     }
--    p->pForest = p->pForest->pRight;
-+    sqlite3_free(p->apHash);
-+    p->apHash = apNew;
-+    p->nHash = nNew;
-   }
--#endif
--  p->rsFlags |= ROWSET_NEXT;  /* Verify this routine is never called again */
- }
- 
- /*
--** Extract the smallest element from the RowSet.
--** Write the element into *pRowid.  Return 1 on success.  Return
--** 0 if the RowSet is already empty.
-+** This function is used internally to remove the page pPage from the 
-+** PGroup LRU list, if is part of it. If pPage is not part of the PGroup
-+** LRU list, then this function is a no-op.
- **
--** After this routine has been called, the sqlite3RowSetInsert()
--** routine may not be called again.  
-+** The PGroup mutex must be held when this function is called.
- */
--SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
--  assert( p!=0 );
--
--  /* Merge the forest into a single sorted list on first call */
--  if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p);
-+static void pcache1PinPage(PgHdr1 *pPage){
-+  PCache1 *pCache;
-+  PGroup *pGroup;
- 
--  /* Return the next entry on the list */
--  if( p->pEntry ){
--    *pRowid = p->pEntry->v;
--    p->pEntry = p->pEntry->pRight;
--    if( p->pEntry==0 ){
--      sqlite3RowSetClear(p);
--    }
--    return 1;
-+  assert( pPage!=0 );
-+  assert( pPage->isPinned==0 );
-+  pCache = pPage->pCache;
-+  pGroup = pCache->pGroup;
-+  assert( pPage->pLruNext || pPage==pGroup->pLruTail );
-+  assert( pPage->pLruPrev || pPage==pGroup->pLruHead );
-+  assert( sqlite3_mutex_held(pGroup->mutex) );
-+  if( pPage->pLruPrev ){
-+    pPage->pLruPrev->pLruNext = pPage->pLruNext;
-   }else{
--    return 0;
-+    pGroup->pLruHead = pPage->pLruNext;
++      *ppOut = 0;
++    }
++  }
++
++  return pRet;
++}
++
++/*
++** Extract all tokens from hash table iHash and link them into a list
++** in sorted order. The hash table is cleared before returning. It is
++** the responsibility of the caller to free the elements of the returned
++** list.
++*/
++static int fts5HashEntrySort(
++  Fts5Hash *pHash, 
++  const char *pTerm, int nTerm,   /* Query prefix, if any */
++  Fts5HashEntry **ppSorted
++){
++  const int nMergeSlot = 32;
++  Fts5HashEntry **ap;
++  Fts5HashEntry *pList;
++  int iSlot;
++  int i;
++
++  *ppSorted = 0;
++  ap = sqlite3_malloc(sizeof(Fts5HashEntry*) * nMergeSlot);
++  if( !ap ) return SQLITE_NOMEM;
++  memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot);
++
++  for(iSlot=0; iSlot<pHash->nSlot; iSlot++){
++    Fts5HashEntry *pIter;
++    for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
++      if( pTerm==0 || 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm) ){
++        Fts5HashEntry *pEntry = pIter;
++        pEntry->pScanNext = 0;
++        for(i=0; ap[i]; i++){
++          pEntry = fts5HashEntryMerge(pEntry, ap[i]);
++          ap[i] = 0;
++        }
++        ap[i] = pEntry;
++      }
++    }
++  }
++
++  pList = 0;
++  for(i=0; i<nMergeSlot; i++){
++    pList = fts5HashEntryMerge(pList, ap[i]);
++  }
++
++  pHash->nEntry = 0;
++  sqlite3_free(ap);
++  *ppSorted = pList;
++  return SQLITE_OK;
++}
++
++/*
++** Query the hash table for a doclist associated with term pTerm/nTerm.
++*/
++static int sqlite3Fts5HashQuery(
++  Fts5Hash *pHash,                /* Hash table to query */
++  const char *pTerm, int nTerm,   /* Query term */
++  const u8 **ppDoclist,           /* OUT: Pointer to doclist for pTerm */
++  int *pnDoclist                  /* OUT: Size of doclist in bytes */
++){
++  unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm);
++  char *zKey = 0;
++  Fts5HashEntry *p;
++
++  for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
++    zKey = fts5EntryKey(p);
++    if( memcmp(zKey, pTerm, nTerm)==0 && zKey[nTerm]==0 ) break;
 +  }
-+  if( pPage->pLruNext ){
-+    pPage->pLruNext->pLruPrev = pPage->pLruPrev;
++
++  if( p ){
++    fts5HashAddPoslistSize(pHash, p);
++    *ppDoclist = (const u8*)&zKey[nTerm+1];
++    *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
 +  }else{
-+    pGroup->pLruTail = pPage->pLruPrev;
-   }
-+  pPage->pLruNext = 0;
-+  pPage->pLruPrev = 0;
-+  pPage->isPinned = 1;
-+  pCache->nRecyclable--;
- }
- 
++    *ppDoclist = 0;
++    *pnDoclist = 0;
++  }
 +
- /*
--** Check to see if element iRowid was inserted into the rowset as
--** part of any insert batch prior to iBatch.  Return 1 or 0.
-+** Remove the page supplied as an argument from the hash table 
-+** (PCache1.apHash structure) that it is currently stored in.
- **
--** If this is the first test of a new batch and if there exist entries
--** on pRowSet->pEntry, then sort those entries into the forest at
--** pRowSet->pForest so that they can be tested.
-+** The PGroup mutex must be held when this function is called.
- */
--SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){
--  struct RowSetEntry *p, *pTree;
-+static void pcache1RemoveFromHash(PgHdr1 *pPage){
-+  unsigned int h;
-+  PCache1 *pCache = pPage->pCache;
-+  PgHdr1 **pp;
- 
--  /* This routine is never called after sqlite3RowSetNext() */
--  assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
-+  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
-+  h = pPage->iKey % pCache->nHash;
-+  for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext);
-+  *pp = (*pp)->pNext;
- 
--  /* Sort entries into the forest on the first test of a new batch 
--  */
--  if( iBatch!=pRowSet->iBatch ){
--    p = pRowSet->pEntry;
--    if( p ){
--      struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
--      if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){
--        p = rowSetEntrySort(p);
--      }
--      for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
--        ppPrevTree = &pTree->pRight;
--        if( pTree->pLeft==0 ){
--          pTree->pLeft = rowSetListToTree(p);
--          break;
--        }else{
--          struct RowSetEntry *pAux, *pTail;
--          rowSetTreeToList(pTree->pLeft, &pAux, &pTail);
--          pTree->pLeft = 0;
--          p = rowSetEntryMerge(pAux, p);
--        }
--      }
--      if( pTree==0 ){
--        *ppPrevTree = pTree = rowSetEntryAlloc(pRowSet);
--        if( pTree ){
--          pTree->v = 0;
--          pTree->pRight = 0;
--          pTree->pLeft = rowSetListToTree(p);
--        }
--      }
--      pRowSet->pEntry = 0;
--      pRowSet->pLast = 0;
--      pRowSet->rsFlags |= ROWSET_SORTED;
--    }
--    pRowSet->iBatch = iBatch;
-+  pCache->nPage--;
++  return SQLITE_OK;
 +}
 +
-+/*
-+** If there are currently more than nMaxPage pages allocated, try
-+** to recycle pages to reduce the number allocated to nMaxPage.
-+*/
-+static void pcache1EnforceMaxPage(PGroup *pGroup){
-+  assert( sqlite3_mutex_held(pGroup->mutex) );
-+  while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){
-+    PgHdr1 *p = pGroup->pLruTail;
-+    assert( p->pCache->pGroup==pGroup );
-+    assert( p->isPinned==0 );
-+    pcache1PinPage(p);
-+    pcache1RemoveFromHash(p);
-+    pcache1FreePage(p);
-   }
++static int sqlite3Fts5HashScanInit(
++  Fts5Hash *p,                    /* Hash table to query */
++  const char *pTerm, int nTerm    /* Query prefix */
++){
++  return fts5HashEntrySort(p, pTerm, nTerm, &p->pScan);
 +}
- 
--  /* Test to see if the iRowid value appears anywhere in the forest.
--  ** Return 1 if it does and 0 if not.
--  */
--  for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
--    p = pTree->pLeft;
--    while( p ){
--      if( p->v<iRowid ){
--        p = p->pRight;
--      }else if( p->v>iRowid ){
--        p = p->pLeft;
-+/*
-+** Discard all pages from cache pCache with a page number (key value) 
-+** greater than or equal to iLimit. Any pinned pages that meet this 
-+** criteria are unpinned before they are discarded.
-+**
-+** The PCache mutex must be held when this function is called.
-+*/
-+static void pcache1TruncateUnsafe(
-+  PCache1 *pCache,             /* The cache to truncate */
-+  unsigned int iLimit          /* Drop pages with this pgno or larger */
-+){
-+  TESTONLY( unsigned int nPage = 0; )  /* To assert pCache->nPage is correct */
-+  unsigned int h;
-+  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
-+  for(h=0; h<pCache->nHash; h++){
-+    PgHdr1 **pp = &pCache->apHash[h]; 
-+    PgHdr1 *pPage;
-+    while( (pPage = *pp)!=0 ){
-+      if( pPage->iKey>=iLimit ){
-+        pCache->nPage--;
-+        *pp = pPage->pNext;
-+        if( !pPage->isPinned ) pcache1PinPage(pPage);
-+        pcache1FreePage(pPage);
-       }else{
--        return 1;
-+        pp = &pPage->pNext;
-+        TESTONLY( nPage++; )
-       }
-     }
-   }
--  return 0;
-+  assert( pCache->nPage==nPage );
- }
- 
--/************** End of rowset.c **********************************************/
--/************** Begin file pager.c *******************************************/
-+/******************************************************************************/
-+/******** sqlite3_pcache Methods **********************************************/
 +
- /*
--** 2001 September 15
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
--**
--**    May you do good and not evil.
--**    May you find forgiveness for yourself and forgive others.
--**    May you share freely, never taking more than you give.
--**
--*************************************************************************
--** This is the implementation of the page cache subsystem or "pager".
--** 
--** The pager is used to access a database disk file.  It implements
--** atomic commit and rollback through the use of a journal file that
--** is separate from the database file.  The pager also implements file
--** locking to prevent two processes from writing the same database
--** file simultaneously, or one process from reading the database while
--** another is writing.
-+** Implementation of the sqlite3_pcache.xInit method.
- */
--#ifndef SQLITE_OMIT_DISKIO
--/************** Include wal.h in the middle of pager.c ***********************/
--/************** Begin file wal.h *********************************************/
-+static int pcache1Init(void *NotUsed){
-+  UNUSED_PARAMETER(NotUsed);
-+  assert( pcache1.isInit==0 );
-+  memset(&pcache1, 0, sizeof(pcache1));
-+  if( sqlite3GlobalConfig.bCoreMutex ){
-+    pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
-+    pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
-+  }
-+  pcache1.grp.mxPinned = 10;
-+  pcache1.isInit = 1;
-+  return SQLITE_OK;
++static void sqlite3Fts5HashScanNext(Fts5Hash *p){
++  assert( !sqlite3Fts5HashScanEof(p) );
++  p->pScan = p->pScan->pScanNext;
 +}
 +
- /*
--** 2010 February 1
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
--**
--**    May you do good and not evil.
--**    May you find forgiveness for yourself and forgive others.
--**    May you share freely, never taking more than you give.
--**
--*************************************************************************
--** This header file defines the interface to the write-ahead logging 
--** system. Refer to the comments below and the header comment attached to 
--** the implementation of each function in log.c for further details.
-+** Implementation of the sqlite3_pcache.xShutdown method.
-+** Note that the static mutex allocated in xInit does 
-+** not need to be freed.
- */
-+static void pcache1Shutdown(void *NotUsed){
-+  UNUSED_PARAMETER(NotUsed);
-+  assert( pcache1.isInit!=0 );
-+  memset(&pcache1, 0, sizeof(pcache1));
++static int sqlite3Fts5HashScanEof(Fts5Hash *p){
++  return (p->pScan==0);
 +}
- 
--#ifndef _WAL_H_
--#define _WAL_H_
--
-+/* forward declaration */
-+static void pcache1Destroy(sqlite3_pcache *p);
- 
--/* Additional values that can be added to the sync_flags argument of
--** sqlite3WalFrames():
++
++static void sqlite3Fts5HashScanEntry(
++  Fts5Hash *pHash,
++  const char **pzTerm,            /* OUT: term (nul-terminated) */
++  const u8 **ppDoclist,           /* OUT: pointer to doclist */
++  int *pnDoclist                  /* OUT: size of doclist in bytes */
++){
++  Fts5HashEntry *p;
++  if( (p = pHash->pScan) ){
++    char *zKey = fts5EntryKey(p);
++    int nTerm = (int)strlen(zKey);
++    fts5HashAddPoslistSize(pHash, p);
++    *pzTerm = zKey;
++    *ppDoclist = (const u8*)&zKey[nTerm+1];
++    *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
++  }else{
++    *pzTerm = 0;
++    *ppDoclist = 0;
++    *pnDoclist = 0;
++  }
++}
++
++
 +/*
-+** Implementation of the sqlite3_pcache.xCreate method.
++** 2014 May 31
 +**
-+** Allocate a new cache.
- */
--#define WAL_SYNC_TRANSACTIONS  0x20   /* Sync at the end of each transaction */
--#define SQLITE_SYNC_MASK       0x13   /* Mask off the SQLITE_SYNC_* values */
-+static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
-+  PCache1 *pCache;      /* The newly created page cache */
-+  PGroup *pGroup;       /* The group the new page cache will belong to */
-+  int sz;               /* Bytes of memory required to allocate the new cache */
- 
--#ifdef SQLITE_OMIT_WAL
--# define sqlite3WalOpen(x,y,z)                   0
--# define sqlite3WalLimit(x,y)
--# define sqlite3WalClose(w,x,y,z)                0
--# define sqlite3WalBeginReadTransaction(y,z)     0
--# define sqlite3WalEndReadTransaction(z)
--# define sqlite3WalDbsize(y)                     0
--# define sqlite3WalBeginWriteTransaction(y)      0
--# define sqlite3WalEndWriteTransaction(x)        0
--# define sqlite3WalUndo(x,y,z)                   0
--# define sqlite3WalSavepoint(y,z)
--# define sqlite3WalSavepointUndo(y,z)            0
--# define sqlite3WalFrames(u,v,w,x,y,z)           0
--# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0
--# define sqlite3WalCallback(z)                   0
--# define sqlite3WalExclusiveMode(y,z)            0
--# define sqlite3WalHeapMemory(z)                 0
--# define sqlite3WalFramesize(z)                  0
--# define sqlite3WalFindFrame(x,y,z)              0
-+  /*
-+  ** The separateCache variable is true if each PCache has its own private
-+  ** PGroup.  In other words, separateCache is true for mode (1) where no
-+  ** mutexing is required.
-+  **
-+  **   *  Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
-+  **
-+  **   *  Always use a unified cache in single-threaded applications
-+  **
-+  **   *  Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off)
-+  **      use separate caches (mode-1)
-+  */
-+#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
-+  const int separateCache = 0;
- #else
-+  int separateCache = sqlite3GlobalConfig.bCoreMutex>0;
++** 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.
++**
++******************************************************************************
++**
++** Low level access to the FTS index stored in the database file. The 
++** routines in this file file implement all read and write access to the
++** %_data table. Other parts of the system access this functionality via
++** the interface defined in fts5Int.h.
++*/
++
++
++/* #include "fts5Int.h" */
++
++/*
++** Overview:
++**
++** The %_data table contains all the FTS indexes for an FTS5 virtual table.
++** As well as the main term index, there may be up to 31 prefix indexes.
++** The format is similar to FTS3/4, except that:
++**
++**   * all segment b-tree leaf data is stored in fixed size page records 
++**     (e.g. 1000 bytes). A single doclist may span multiple pages. Care is 
++**     taken to ensure it is possible to iterate in either direction through 
++**     the entries in a doclist, or to seek to a specific entry within a 
++**     doclist, without loading it into memory.
++**
++**   * large doclists that span many pages have associated "doclist index"
++**     records that contain a copy of the first rowid on each page spanned by
++**     the doclist. This is used to speed up seek operations, and merges of
++**     large doclists with very small doclists.
++**
++**   * extra fields in the "structure record" record the state of ongoing
++**     incremental merge operations.
++**
++*/
++
++
++#define FTS5_OPT_WORK_UNIT  1000  /* Number of leaf pages per optimize step */
++#define FTS5_WORK_UNIT      64    /* Number of leaf pages in unit of work */
++
++#define FTS5_MIN_DLIDX_SIZE 4     /* Add dlidx if this many empty pages */
++
++#define FTS5_MAIN_PREFIX '0'
++
++#if FTS5_MAX_PREFIX_INDEXES > 31
++# error "FTS5_MAX_PREFIX_INDEXES is too large"
 +#endif
- 
--#define WAL_SAVEPOINT_NDATA 4
--
--/* Connection to a write-ahead log (WAL) file. 
--** There is one object of this type for each pager. 
--*/
--typedef struct Wal Wal;
--
--/* Open and close a connection to a write-ahead log. */
--SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
--SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
-+  assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
-+  assert( szExtra < 300 );
- 
--/* Set the limiting size of a WAL file. */
--SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
-+  sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
-+  pCache = (PCache1 *)sqlite3MallocZero(sz);
-+  if( pCache ){
-+    if( separateCache ){
-+      pGroup = (PGroup*)&pCache[1];
-+      pGroup->mxPinned = 10;
-+    }else{
-+      pGroup = &pcache1.grp;
-+    }
-+    pCache->pGroup = pGroup;
-+    pCache->szPage = szPage;
-+    pCache->szExtra = szExtra;
-+    pCache->bPurgeable = (bPurgeable ? 1 : 0);
-+    pcache1EnterMutex(pGroup);
-+    pcache1ResizeHash(pCache);
-+    if( bPurgeable ){
-+      pCache->nMin = 10;
-+      pGroup->nMinPage += pCache->nMin;
-+      pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
-+    }
-+    pcache1LeaveMutex(pGroup);
-+    if( pCache->nHash==0 ){
-+      pcache1Destroy((sqlite3_pcache*)pCache);
-+      pCache = 0;
-+    }
-+  }
-+  return (sqlite3_pcache *)pCache;
-+}
- 
--/* Used by readers to open (lock) and close (unlock) a snapshot.  A 
--** snapshot is like a read-transaction.  It is the state of the database
--** at an instant in time.  sqlite3WalOpenSnapshot gets a read lock and
--** preserves the current state even if the other threads or processes
--** write to or checkpoint the WAL.  sqlite3WalCloseSnapshot() closes the
--** transaction and releases the lock.
-+/*
-+** Implementation of the sqlite3_pcache.xCachesize method. 
-+**
-+** Configure the cache_size limit for a cache.
- */
--SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *);
--SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal);
--
--/* Read a page from the write-ahead log, if it is present. */
--SQLITE_PRIVATE int sqlite3WalFindFrame(Wal *, Pgno, u32 *);
--SQLITE_PRIVATE int sqlite3WalReadFrame(Wal *, u32, int, u8 *);
--
--/* If the WAL is not empty, return the size of the database. */
--SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal);
--
--/* Obtain or release the WRITER lock. */
--SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal);
--SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal);
--
--/* Undo any frames written (but not committed) to the log */
--SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx);
--
--/* Return an integer that records the current (uncommitted) write
--** position in the WAL */
--SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData);
--
--/* Move the write position of the WAL back to iFrame.  Called in
--** response to a ROLLBACK TO command. */
--SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData);
--
--/* Write a frame or frames to the log. */
--SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
--
--/* Copy pages from the log to the database file */ 
--SQLITE_PRIVATE int sqlite3WalCheckpoint(
--  Wal *pWal,                      /* Write-ahead log connection */
--  int eMode,                      /* One of PASSIVE, FULL and RESTART */
--  int (*xBusy)(void*),            /* Function to call when busy */
--  void *pBusyArg,                 /* Context argument for xBusyHandler */
--  int sync_flags,                 /* Flags to sync db file with (or 0) */
--  int nBuf,                       /* Size of buffer nBuf */
--  u8 *zBuf,                       /* Temporary buffer to use */
--  int *pnLog,                     /* OUT: Number of frames in WAL */
--  int *pnCkpt                     /* OUT: Number of backfilled frames in WAL */
--);
-+static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
-+  PCache1 *pCache = (PCache1 *)p;
-+  if( pCache->bPurgeable ){
-+    PGroup *pGroup = pCache->pGroup;
-+    pcache1EnterMutex(pGroup);
-+    pGroup->nMaxPage += (nMax - pCache->nMax);
-+    pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
-+    pCache->nMax = nMax;
-+    pCache->n90pct = pCache->nMax*9/10;
-+    pcache1EnforceMaxPage(pGroup);
-+    pcache1LeaveMutex(pGroup);
-+  }
-+}
- 
--/* Return the value to pass to a sqlite3_wal_hook callback, the
--** number of frames in the WAL at the point of the last commit since
--** sqlite3WalCallback() was called.  If no commits have occurred since
--** the last call, then return 0.
++
 +/*
-+** Implementation of the sqlite3_pcache.xShrink method. 
++** Details:
 +**
-+** Free up as much memory as possible.
- */
--SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal);
-+static void pcache1Shrink(sqlite3_pcache *p){
-+  PCache1 *pCache = (PCache1*)p;
-+  if( pCache->bPurgeable ){
-+    PGroup *pGroup = pCache->pGroup;
-+    int savedMaxPage;
-+    pcache1EnterMutex(pGroup);
-+    savedMaxPage = pGroup->nMaxPage;
-+    pGroup->nMaxPage = 0;
-+    pcache1EnforceMaxPage(pGroup);
-+    pGroup->nMaxPage = savedMaxPage;
-+    pcache1LeaveMutex(pGroup);
-+  }
-+}
- 
--/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released)
--** by the pager layer on the database file.
++** The %_data table managed by this module,
++**
++**     CREATE TABLE %_data(id INTEGER PRIMARY KEY, block BLOB);
++**
++** , contains the following 5 types of records. See the comments surrounding
++** the FTS5_*_ROWID macros below for a description of how %_data rowids are 
++** assigned to each fo them.
++**
++** 1. Structure Records:
++**
++**   The set of segments that make up an index - the index structure - are
++**   recorded in a single record within the %_data table. The record consists
++**   of a single 32-bit configuration cookie value followed by a list of 
++**   SQLite varints. If the FTS table features more than one index (because
++**   there are one or more prefix indexes), it is guaranteed that all share
++**   the same cookie value.
++**
++**   Immediately following the configuration cookie, the record begins with
++**   three varints:
++**
++**     + number of levels,
++**     + total number of segments on all levels,
++**     + value of write counter.
++**
++**   Then, for each level from 0 to nMax:
++**
++**     + number of input segments in ongoing merge.
++**     + total number of segments in level.
++**     + for each segment from oldest to newest:
++**         + segment id (always > 0)
++**         + first leaf page number (often 1, always greater than 0)
++**         + final leaf page number
++**
++** 2. The Averages Record:
++**
++**   A single record within the %_data table. The data is a list of varints.
++**   The first value is the number of rows in the index. Then, for each column
++**   from left to right, the total number of tokens in the column for all
++**   rows of the table.
++**
++** 3. Segment leaves:
++**
++**   TERM/DOCLIST FORMAT:
++**
++**     Most of each segment leaf is taken up by term/doclist data. The 
++**     general format of term/doclist, starting with the first term
++**     on the leaf page, is:
++**
++**         varint : size of first term
++**         blob:    first term data
++**         doclist: first doclist
++**         zero-or-more {
++**           varint:  number of bytes in common with previous term
++**           varint:  number of bytes of new term data (nNew)
++**           blob:    nNew bytes of new term data
++**           doclist: next doclist
++**         }
++**
++**     doclist format:
++**
++**         varint:  first rowid
++**         poslist: first poslist
++**         zero-or-more {
++**           varint:  rowid delta (always > 0)
++**           poslist: next poslist
++**         }
++**
++**     poslist format:
++**
++**         varint: size of poslist in bytes multiplied by 2, not including
++**                 this field. Plus 1 if this entry carries the "delete" flag.
++**         collist: collist for column 0
++**         zero-or-more {
++**           0x01 byte
++**           varint: column number (I)
++**           collist: collist for column I
++**         }
++**
++**     collist format:
++**
++**         varint: first offset + 2
++**         zero-or-more {
++**           varint: offset delta + 2
++**         }
++**
++**   PAGE FORMAT
++**
++**     Each leaf page begins with a 4-byte header containing 2 16-bit 
++**     unsigned integer fields in big-endian format. They are:
++**
++**       * The byte offset of the first rowid on the page, if it exists
++**         and occurs before the first term (otherwise 0).
++**
++**       * The byte offset of the start of the page footer. If the page
++**         footer is 0 bytes in size, then this field is the same as the
++**         size of the leaf page in bytes.
++**
++**     The page footer consists of a single varint for each term located
++**     on the page. Each varint is the byte offset of the current term
++**     within the page, delta-compressed against the previous value. In
++**     other words, the first varint in the footer is the byte offset of
++**     the first term, the second is the byte offset of the second less that
++**     of the first, and so on.
++**
++**     The term/doclist format described above is accurate if the entire
++**     term/doclist data fits on a single leaf page. If this is not the case,
++**     the format is changed in two ways:
++**
++**       + if the first rowid on a page occurs before the first term, it
++**         is stored as a literal value:
++**
++**             varint:  first rowid
++**
++**       + the first term on each page is stored in the same way as the
++**         very first term of the segment:
++**
++**             varint : size of first term
++**             blob:    first term data
++**
++** 5. Segment doclist indexes:
++**
++**   Doclist indexes are themselves b-trees, however they usually consist of
++**   a single leaf record only. The format of each doclist index leaf page 
++**   is:
++**
++**     * Flags byte. Bits are:
++**         0x01: Clear if leaf is also the root page, otherwise set.
++**
++**     * Page number of fts index leaf page. As a varint.
++**
++**     * First rowid on page indicated by previous field. As a varint.
++**
++**     * A list of varints, one for each subsequent termless page. A 
++**       positive delta if the termless page contains at least one rowid, 
++**       or an 0x00 byte otherwise.
++**
++**   Internal doclist index nodes are:
++**
++**     * Flags byte. Bits are:
++**         0x01: Clear for root page, otherwise set.
++**
++**     * Page number of first child page. As a varint.
++**
++**     * Copy of first rowid on page indicated by previous field. As a varint.
++**
++**     * A list of delta-encoded varints - the first rowid on each subsequent
++**       child page. 
++**
++*/
++
 +/*
-+** Implementation of the sqlite3_pcache.xPagecount method. 
- */
--SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op);
-+static int pcache1Pagecount(sqlite3_pcache *p){
-+  int n;
-+  PCache1 *pCache = (PCache1*)p;
-+  pcache1EnterMutex(pCache->pGroup);
-+  n = pCache->nPage;
-+  pcache1LeaveMutex(pCache->pGroup);
-+  return n;
-+}
- 
--/* Return true if the argument is non-NULL and the WAL module is using
--** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
--** WAL module is using shared-memory, return false. 
--*/
--SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
- 
--#ifdef SQLITE_ENABLE_ZIPVFS
--/* If the WAL file is not empty, return the number of bytes of content
--** stored in each frame (i.e. the db page-size when the WAL was created).
++** Rowids for the averages and structure records in the %_data table.
++*/
++#define FTS5_AVERAGES_ROWID     1    /* Rowid used for the averages record */
++#define FTS5_STRUCTURE_ROWID   10    /* The structure record */
++
 +/*
-+** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described
-+** in the header of the pcache1Fetch() procedure.
++** Macros determining the rowids used by segment leaves and dlidx leaves
++** and nodes. All nodes and leaves are stored in the %_data table with large
++** positive rowids.
 +**
-+** This steps are broken out into a separate procedure because they are
-+** usually not needed, and by avoiding the stack initialization required
-+** for these steps, the main pcache1Fetch() procedure can run faster.
- */
--SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
--#endif
-+static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
-+  PCache1 *pCache, 
-+  unsigned int iKey, 
-+  int createFlag
-+){
-+  unsigned int nPinned;
-+  PGroup *pGroup = pCache->pGroup;
-+  PgHdr1 *pPage = 0;
- 
--#endif /* ifndef SQLITE_OMIT_WAL */
--#endif /* _WAL_H_ */
-+  /* Step 3: Abort if createFlag is 1 but the cache is nearly full */
-+  assert( pCache->nPage >= pCache->nRecyclable );
-+  nPinned = pCache->nPage - pCache->nRecyclable;
-+  assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
-+  assert( pCache->n90pct == pCache->nMax*9/10 );
-+  if( createFlag==1 && (
-+        nPinned>=pGroup->mxPinned
-+     || nPinned>=pCache->n90pct
-+     || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
-+  )){
-+    return 0;
-+  }
- 
--/************** End of wal.h *************************************************/
--/************** Continuing where we left off in pager.c **********************/
-+  if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
-+  assert( pCache->nHash>0 && pCache->apHash );
- 
-+  /* Step 4. Try to recycle a page. */
-+  if( pCache->bPurgeable && pGroup->pLruTail && (
-+         (pCache->nPage+1>=pCache->nMax)
-+      || pGroup->nCurrentPage>=pGroup->nMaxPage
-+      || pcache1UnderMemoryPressure(pCache)
-+  )){
-+    PCache1 *pOther;
-+    pPage = pGroup->pLruTail;
-+    assert( pPage->isPinned==0 );
-+    pcache1RemoveFromHash(pPage);
-+    pcache1PinPage(pPage);
-+    pOther = pPage->pCache;
- 
--/******************* NOTES ON THE DESIGN OF THE PAGER ************************
--**
--** This comment block describes invariants that hold when using a rollback
--** journal.  These invariants do not apply for journal_mode=WAL,
--** journal_mode=MEMORY, or journal_mode=OFF.
--**
--** Within this comment block, a page is deemed to have been synced
--** automatically as soon as it is written when PRAGMA synchronous=OFF.
--** Otherwise, the page is not synced until the xSync method of the VFS
--** is called successfully on the file containing the page.
--**
--** Definition:  A page of the database file is said to be "overwriteable" if
--** one or more of the following are true about the page:
--** 
--**     (a)  The original content of the page as it was at the beginning of
--**          the transaction has been written into the rollback journal and
--**          synced.
--** 
--**     (b)  The page was a freelist leaf page at the start of the transaction.
--** 
--**     (c)  The page number is greater than the largest page that existed in
--**          the database file at the start of the transaction.
--** 
--** (1) A page of the database file is never overwritten unless one of the
--**     following are true:
--** 
--**     (a) The page and all other pages on the same sector are overwriteable.
--** 
--**     (b) The atomic page write optimization is enabled, and the entire
--**         transaction other than the update of the transaction sequence
--**         number consists of a single page change.
--** 
--** (2) The content of a page written into the rollback journal exactly matches
--**     both the content in the database when the rollback journal was written
--**     and the content in the database at the beginning of the current
--**     transaction.
--** 
--** (3) Writes to the database file are an integer multiple of the page size
--**     in length and are aligned on a page boundary.
--** 
--** (4) Reads from the database file are either aligned on a page boundary and
--**     an integer multiple of the page size in length or are taken from the
--**     first 100 bytes of the database file.
--** 
--** (5) All writes to the database file are synced prior to the rollback journal
--**     being deleted, truncated, or zeroed.
--** 
--** (6) If a master journal file is used, then all writes to the database file
--**     are synced prior to the master journal being deleted.
--** 
--** Definition: Two databases (or the same database at two points it time)
--** are said to be "logically equivalent" if they give the same answer to
--** all queries.  Note in particular the content of freelist leaf
--** pages can be changed arbitrarily without affecting the logical equivalence
--** of the database.
--** 
--** (7) At any time, if any subset, including the empty set and the total set,
--**     of the unsynced changes to a rollback journal are removed and the 
--**     journal is rolled back, the resulting database file will be logically
--**     equivalent to the database file at the beginning of the transaction.
--** 
--** (8) When a transaction is rolled back, the xTruncate method of the VFS
--**     is called to restore the database file to the same size it was at
--**     the beginning of the transaction.  (In some VFSes, the xTruncate
--**     method is a no-op, but that does not change the fact the SQLite will
--**     invoke it.)
--** 
--** (9) Whenever the database file is modified, at least one bit in the range
--**     of bytes from 24 through 39 inclusive will be changed prior to releasing
--**     the EXCLUSIVE lock, thus signaling other connections on the same
--**     database to flush their caches.
--**
--** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less
--**      than one billion transactions.
--**
--** (11) A database file is well-formed at the beginning and at the conclusion
--**      of every transaction.
--**
--** (12) An EXCLUSIVE lock is held on the database file when writing to
--**      the database file.
--**
--** (13) A SHARED lock is held on the database file while reading any
--**      content out of the database file.
--**
--******************************************************************************/
-+    /* We want to verify that szPage and szExtra are the same for pOther
-+    ** and pCache.  Assert that we can verify this by comparing sums. */
-+    assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 );
-+    assert( pCache->szExtra<512 );
-+    assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 );
-+    assert( pOther->szExtra<512 );
- 
--/*
--** Macros for troubleshooting.  Normally turned off
--*/
--#if 0
--int sqlite3PagerTrace=1;  /* True to enable tracing */
--#define sqlite3DebugPrintf printf
--#define PAGERTRACE(X)     if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; }
--#else
--#define PAGERTRACE(X)
--#endif
-+    if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
-+      pcache1FreePage(pPage);
-+      pPage = 0;
-+    }else{
-+      pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
-+    }
-+  }
- 
--/*
--** The following two macros are used within the PAGERTRACE() macros above
--** to print out file-descriptors. 
--**
--** PAGERID() takes a pointer to a Pager struct as its argument. The
--** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file
--** struct as its argument.
--*/
--#define PAGERID(p) ((int)(p->fd))
--#define FILEHANDLEID(fd) ((int)fd)
-+  /* Step 5. If a usable page buffer has still not been found, 
-+  ** attempt to allocate a new one. 
++** Each segment has a unique non-zero 16-bit id.
++**
++** The rowid for each segment leaf is found by passing the segment id and 
++** the leaf page number to the FTS5_SEGMENT_ROWID macro. Leaves are numbered
++** sequentially starting from 1.
++*/
++#define FTS5_DATA_ID_B     16     /* Max seg id number 65535 */
++#define FTS5_DATA_DLI_B     1     /* Doclist-index flag (1 bit) */
++#define FTS5_DATA_HEIGHT_B  5     /* Max dlidx tree height of 32 */
++#define FTS5_DATA_PAGE_B   31     /* Max page number of 2147483648 */
++
++#define fts5_dri(segid, dlidx, height, pgno) (                                 \
++ ((i64)(segid)  << (FTS5_DATA_PAGE_B+FTS5_DATA_HEIGHT_B+FTS5_DATA_DLI_B)) +    \
++ ((i64)(dlidx)  << (FTS5_DATA_PAGE_B + FTS5_DATA_HEIGHT_B)) +                  \
++ ((i64)(height) << (FTS5_DATA_PAGE_B)) +                                       \
++ ((i64)(pgno))                                                                 \
++)
++
++#define FTS5_SEGMENT_ROWID(segid, pgno)       fts5_dri(segid, 0, 0, pgno)
++#define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno)
++
++/*
++** Maximum segments permitted in a single index 
++*/
++#define FTS5_MAX_SEGMENT 2000
++
++#ifdef SQLITE_DEBUG
++static int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; }
++#endif
++
++
++/*
++** Each time a blob is read from the %_data table, it is padded with this
++** many zero bytes. This makes it easier to decode the various record formats
++** without overreading if the records are corrupt.
++*/
++#define FTS5_DATA_ZERO_PADDING 8
++#define FTS5_DATA_PADDING 20
++
++typedef struct Fts5Data Fts5Data;
++typedef struct Fts5DlidxIter Fts5DlidxIter;
++typedef struct Fts5DlidxLvl Fts5DlidxLvl;
++typedef struct Fts5DlidxWriter Fts5DlidxWriter;
++typedef struct Fts5Iter Fts5Iter;
++typedef struct Fts5PageWriter Fts5PageWriter;
++typedef struct Fts5SegIter Fts5SegIter;
++typedef struct Fts5DoclistIter Fts5DoclistIter;
++typedef struct Fts5SegWriter Fts5SegWriter;
++typedef struct Fts5Structure Fts5Structure;
++typedef struct Fts5StructureLevel Fts5StructureLevel;
++typedef struct Fts5StructureSegment Fts5StructureSegment;
++
++struct Fts5Data {
++  u8 *p;                          /* Pointer to buffer containing record */
++  int nn;                         /* Size of record in bytes */
++  int szLeaf;                     /* Size of leaf without page-index */
++};
++
++/*
++** One object per %_data table.
++*/
++struct Fts5Index {
++  Fts5Config *pConfig;            /* Virtual table configuration */
++  char *zDataTbl;                 /* Name of %_data table */
++  int nWorkUnit;                  /* Leaf pages in a "unit" of work */
++
++  /*
++  ** Variables related to the accumulation of tokens and doclists within the
++  ** in-memory hash tables before they are flushed to disk.
 +  */
-+  if( !pPage ){
-+    if( createFlag==1 ) sqlite3BeginBenignMalloc();
-+    pPage = pcache1AllocPage(pCache);
-+    if( createFlag==1 ) sqlite3EndBenignMalloc();
-+  }
-+
-+  if( pPage ){
-+    unsigned int h = iKey % pCache->nHash;
-+    pCache->nPage++;
-+    pPage->iKey = iKey;
-+    pPage->pNext = pCache->apHash[h];
-+    pPage->pCache = pCache;
-+    pPage->pLruPrev = 0;
-+    pPage->pLruNext = 0;
-+    pPage->isPinned = 1;
-+    *(void **)pPage->page.pExtra = 0;
-+    pCache->apHash[h] = pPage;
-+    if( iKey>pCache->iMaxKey ){
-+      pCache->iMaxKey = iKey;
-+    }
-+  }
-+  return pPage;
++  Fts5Hash *pHash;                /* Hash table for in-memory data */
++  int nPendingData;               /* Current bytes of pending data */
++  i64 iWriteRowid;                /* Rowid for current doc being written */
++  int bDelete;                    /* Current write is a delete */
++
++  /* Error state. */
++  int rc;                         /* Current error code */
++
++  /* State used by the fts5DataXXX() functions. */
++  sqlite3_blob *pReader;          /* RO incr-blob open on %_data table */
++  sqlite3_stmt *pWriter;          /* "INSERT ... %_data VALUES(?,?)" */
++  sqlite3_stmt *pDeleter;         /* "DELETE FROM %_data ... id>=? AND id<=?" */
++  sqlite3_stmt *pIdxWriter;       /* "INSERT ... %_idx VALUES(?,?,?,?)" */
++  sqlite3_stmt *pIdxDeleter;      /* "DELETE FROM %_idx WHERE segid=? */
++  sqlite3_stmt *pIdxSelect;
++  int nRead;                      /* Total number of blocks read */
++
++  sqlite3_stmt *pDataVersion;
++  i64 iStructVersion;             /* data_version when pStruct read */
++  Fts5Structure *pStruct;         /* Current db structure (or NULL) */
++};
++
++struct Fts5DoclistIter {
++  u8 *aEof;                       /* Pointer to 1 byte past end of doclist */
++
++  /* Output variables. aPoslist==0 at EOF */
++  i64 iRowid;
++  u8 *aPoslist;
++  int nPoslist;
++  int nSize;
++};
++
++/*
++** The contents of the "structure" record for each index are represented
++** using an Fts5Structure record in memory. Which uses instances of the 
++** other Fts5StructureXXX types as components.
++*/
++struct Fts5StructureSegment {
++  int iSegid;                     /* Segment id */
++  int pgnoFirst;                  /* First leaf page number in segment */
++  int pgnoLast;                   /* Last leaf page number in segment */
++};
++struct Fts5StructureLevel {
++  int nMerge;                     /* Number of segments in incr-merge */
++  int nSeg;                       /* Total number of segments on level */
++  Fts5StructureSegment *aSeg;     /* Array of segments. aSeg[0] is oldest. */
++};
++struct Fts5Structure {
++  int nRef;                       /* Object reference count */
++  u64 nWriteCounter;              /* Total leaves written to level 0 */
++  int nSegment;                   /* Total segments in this structure */
++  int nLevel;                     /* Number of levels in this index */
++  Fts5StructureLevel aLevel[1];   /* Array of nLevel level objects */
++};
++
++/*
++** An object of type Fts5SegWriter is used to write to segments.
++*/
++struct Fts5PageWriter {
++  int pgno;                       /* Page number for this page */
++  int iPrevPgidx;                 /* Previous value written into pgidx */
++  Fts5Buffer buf;                 /* Buffer containing leaf data */
++  Fts5Buffer pgidx;               /* Buffer containing page-index */
++  Fts5Buffer term;                /* Buffer containing previous term on page */
++};
++struct Fts5DlidxWriter {
++  int pgno;                       /* Page number for this page */
++  int bPrevValid;                 /* True if iPrev is valid */
++  i64 iPrev;                      /* Previous rowid value written to page */
++  Fts5Buffer buf;                 /* Buffer containing page data */
++};
++struct Fts5SegWriter {
++  int iSegid;                     /* Segid to write to */
++  Fts5PageWriter writer;          /* PageWriter object */
++  i64 iPrevRowid;                 /* Previous rowid written to current leaf */
++  u8 bFirstRowidInDoclist;        /* True if next rowid is first in doclist */
++  u8 bFirstRowidInPage;           /* True if next rowid is first in page */
++  /* TODO1: Can use (writer.pgidx.n==0) instead of bFirstTermInPage */
++  u8 bFirstTermInPage;            /* True if next term will be first in leaf */
++  int nLeafWritten;               /* Number of leaf pages written */
++  int nEmpty;                     /* Number of contiguous term-less nodes */
++
++  int nDlidx;                     /* Allocated size of aDlidx[] array */
++  Fts5DlidxWriter *aDlidx;        /* Array of Fts5DlidxWriter objects */
++
++  /* Values to insert into the %_idx table */
++  Fts5Buffer btterm;              /* Next term to insert into %_idx table */
++  int iBtPage;                    /* Page number corresponding to btterm */
++};
++
++typedef struct Fts5CResult Fts5CResult;
++struct Fts5CResult {
++  u16 iFirst;                     /* aSeg[] index of firstest iterator */
++  u8 bTermEq;                     /* True if the terms are equal */
++};
++
++/*
++** Object for iterating through a single segment, visiting each term/rowid
++** pair in the segment.
++**
++** pSeg:
++**   The segment to iterate through.
++**
++** iLeafPgno:
++**   Current leaf page number within segment.
++**
++** iLeafOffset:
++**   Byte offset within the current leaf that is the first byte of the 
++**   position list data (one byte passed the position-list size field).
++**   rowid field of the current entry. Usually this is the size field of the
++**   position list data. The exception is if the rowid for the current entry 
++**   is the last thing on the leaf page.
++**
++** pLeaf:
++**   Buffer containing current leaf page data. Set to NULL at EOF.
++**
++** iTermLeafPgno, iTermLeafOffset:
++**   Leaf page number containing the last term read from the segment. And
++**   the offset immediately following the term data.
++**
++** flags:
++**   Mask of FTS5_SEGITER_XXX values. Interpreted as follows:
++**
++**   FTS5_SEGITER_ONETERM:
++**     If set, set the iterator to point to EOF after the current doclist 
++**     has been exhausted. Do not proceed to the next term in the segment.
++**
++**   FTS5_SEGITER_REVERSE:
++**     This flag is only ever set if FTS5_SEGITER_ONETERM is also set. If
++**     it is set, iterate through rowid in descending order instead of the
++**     default ascending order.
++**
++** iRowidOffset/nRowidOffset/aRowidOffset:
++**     These are used if the FTS5_SEGITER_REVERSE flag is set.
++**
++**     For each rowid on the page corresponding to the current term, the
++**     corresponding aRowidOffset[] entry is set to the byte offset of the
++**     start of the "position-list-size" field within the page.
++**
++** iTermIdx:
++**     Index of current term on iTermLeafPgno.
++*/
++struct Fts5SegIter {
++  Fts5StructureSegment *pSeg;     /* Segment to iterate through */
++  int flags;                      /* Mask of configuration flags */
++  int iLeafPgno;                  /* Current leaf page number */
++  Fts5Data *pLeaf;                /* Current leaf data */
++  Fts5Data *pNextLeaf;            /* Leaf page (iLeafPgno+1) */
++  int iLeafOffset;                /* Byte offset within current leaf */
++
++  /* Next method */
++  void (*xNext)(Fts5Index*, Fts5SegIter*, int*);
++
++  /* The page and offset from which the current term was read. The offset 
++  ** is the offset of the first rowid in the current doclist.  */
++  int iTermLeafPgno;
++  int iTermLeafOffset;
++
++  int iPgidxOff;                  /* Next offset in pgidx */
++  int iEndofDoclist;
++
++  /* The following are only used if the FTS5_SEGITER_REVERSE flag is set. */
++  int iRowidOffset;               /* Current entry in aRowidOffset[] */
++  int nRowidOffset;               /* Allocated size of aRowidOffset[] array */
++  int *aRowidOffset;              /* Array of offset to rowid fields */
++
++  Fts5DlidxIter *pDlidx;          /* If there is a doclist-index */
++
++  /* Variables populated based on current entry. */
++  Fts5Buffer term;                /* Current term */
++  i64 iRowid;                     /* Current rowid */
++  int nPos;                       /* Number of bytes in current position list */
++  u8 bDel;                        /* True if the delete flag is set */
++};
++
++/*
++** Argument is a pointer to an Fts5Data structure that contains a 
++** leaf page.
++*/
++#define ASSERT_SZLEAF_OK(x) assert( \
++    (x)->szLeaf==(x)->nn || (x)->szLeaf==fts5GetU16(&(x)->p[2]) \
++)
++
++#define FTS5_SEGITER_ONETERM 0x01
++#define FTS5_SEGITER_REVERSE 0x02
++
++/* 
++** Argument is a pointer to an Fts5Data structure that contains a leaf
++** page. This macro evaluates to true if the leaf contains no terms, or
++** false if it contains at least one term.
++*/
++#define fts5LeafIsTermless(x) ((x)->szLeaf >= (x)->nn)
++
++#define fts5LeafTermOff(x, i) (fts5GetU16(&(x)->p[(x)->szLeaf + (i)*2]))
++
++#define fts5LeafFirstRowidOff(x) (fts5GetU16((x)->p))
++
++/*
++** Object for iterating through the merged results of one or more segments,
++** visiting each term/rowid pair in the merged data.
++**
++** nSeg is always a power of two greater than or equal to the number of
++** segments that this object is merging data from. Both the aSeg[] and
++** aFirst[] arrays are sized at nSeg entries. The aSeg[] array is padded
++** with zeroed objects - these are handled as if they were iterators opened
++** on empty segments.
++**
++** The results of comparing segments aSeg[N] and aSeg[N+1], where N is an
++** even number, is stored in aFirst[(nSeg+N)/2]. The "result" of the 
++** comparison in this context is the index of the iterator that currently
++** points to the smaller term/rowid combination. Iterators at EOF are
++** considered to be greater than all other iterators.
++**
++** aFirst[1] contains the index in aSeg[] of the iterator that points to
++** the smallest key overall. aFirst[0] is unused. 
++**
++** poslist:
++**   Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
++**   There is no way to tell if this is populated or not.
++*/
++struct Fts5Iter {
++  Fts5IndexIter base;             /* Base class containing output vars */
++
++  Fts5Index *pIndex;              /* Index that owns this iterator */
++  Fts5Structure *pStruct;         /* Database structure for this iterator */
++  Fts5Buffer poslist;             /* Buffer containing current poslist */
++  Fts5Colset *pColset;            /* Restrict matches to these columns */
++
++  /* Invoked to set output variables. */
++  void (*xSetOutputs)(Fts5Iter*, Fts5SegIter*);
++
++  int nSeg;                       /* Size of aSeg[] array */
++  int bRev;                       /* True to iterate in reverse order */
++  u8 bSkipEmpty;                  /* True to skip deleted entries */
++
++  i64 iSwitchRowid;               /* Firstest rowid of other than aFirst[1] */
++  Fts5CResult *aFirst;            /* Current merge state (see above) */
++  Fts5SegIter aSeg[1];            /* Array of segment iterators */
++};
++
++
++/*
++** An instance of the following type is used to iterate through the contents
++** of a doclist-index record.
++**
++** pData:
++**   Record containing the doclist-index data.
++**
++** bEof:
++**   Set to true once iterator has reached EOF.
++**
++** iOff:
++**   Set to the current offset within record pData.
++*/
++struct Fts5DlidxLvl {
++  Fts5Data *pData;              /* Data for current page of this level */
++  int iOff;                     /* Current offset into pData */
++  int bEof;                     /* At EOF already */
++  int iFirstOff;                /* Used by reverse iterators */
++
++  /* Output variables */
++  int iLeafPgno;                /* Page number of current leaf page */
++  i64 iRowid;                   /* First rowid on leaf iLeafPgno */
++};
++struct Fts5DlidxIter {
++  int nLvl;
++  int iSegid;
++  Fts5DlidxLvl aLvl[1];
++};
++
++static void fts5PutU16(u8 *aOut, u16 iVal){
++  aOut[0] = (iVal>>8);
++  aOut[1] = (iVal&0xFF);
 +}
- 
- /*
--** The Pager.eState variable stores the current 'state' of a pager. A
--** pager may be in any one of the seven states shown in the following
--** state diagram.
--**
--**                            OPEN <------+------+
--**                              |         |      |
--**                              V         |      |
--**               +---------> READER-------+      |
--**               |              |                |
--**               |              V                |
--**               |<-------WRITER_LOCKED------> ERROR
--**               |              |                ^  
--**               |              V                |
--**               |<------WRITER_CACHEMOD-------->|
--**               |              |                |
--**               |              V                |
--**               |<-------WRITER_DBMOD---------->|
--**               |              |                |
--**               |              V                |
--**               +<------WRITER_FINISHED-------->+
--**
--**
--** List of state transitions and the C [function] that performs each:
--** 
--**   OPEN              -> READER              [sqlite3PagerSharedLock]
--**   READER            -> OPEN                [pager_unlock]
--**
--**   READER            -> WRITER_LOCKED       [sqlite3PagerBegin]
--**   WRITER_LOCKED     -> WRITER_CACHEMOD     [pager_open_journal]
--**   WRITER_CACHEMOD   -> WRITER_DBMOD        [syncJournal]
--**   WRITER_DBMOD      -> WRITER_FINISHED     [sqlite3PagerCommitPhaseOne]
--**   WRITER_***        -> READER              [pager_end_transaction]
--**
--**   WRITER_***        -> ERROR               [pager_error]
--**   ERROR             -> OPEN                [pager_unlock]
--** 
--**
--**  OPEN:
--**
--**    The pager starts up in this state. Nothing is guaranteed in this
--**    state - the file may or may not be locked and the database size is
--**    unknown. The database may not be read or written.
--**
--**    * No read or write transaction is active.
--**    * Any lock, or no lock at all, may be held on the database file.
--**    * The dbSize, dbOrigSize and dbFileSize variables may not be trusted.
--**
--**  READER:
--**
--**    In this state all the requirements for reading the database in 
--**    rollback (non-WAL) mode are met. Unless the pager is (or recently
--**    was) in exclusive-locking mode, a user-level read transaction is 
--**    open. The database size is known in this state.
--**
--**    A connection running with locking_mode=normal enters this state when
--**    it opens a read-transaction on the database and returns to state
--**    OPEN after the read-transaction is completed. However a connection
--**    running in locking_mode=exclusive (including temp databases) remains in
--**    this state even after the read-transaction is closed. The only way
--**    a locking_mode=exclusive connection can transition from READER to OPEN
--**    is via the ERROR state (see below).
--** 
--**    * A read transaction may be active (but a write-transaction cannot).
--**    * A SHARED or greater lock is held on the database file.
--**    * The dbSize variable may be trusted (even if a user-level read 
--**      transaction is not active). The dbOrigSize and dbFileSize variables
--**      may not be trusted at this point.
--**    * If the database is a WAL database, then the WAL connection is open.
--**    * Even if a read-transaction is not open, it is guaranteed that 
--**      there is no hot-journal in the file-system.
--**
--**  WRITER_LOCKED:
--**
--**    The pager moves to this state from READER when a write-transaction
--**    is first opened on the database. In WRITER_LOCKED state, all locks 
--**    required to start a write-transaction are held, but no actual 
--**    modifications to the cache or database have taken place.
--**
--**    In rollback mode, a RESERVED or (if the transaction was opened with 
--**    BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when
--**    moving to this state, but the journal file is not written to or opened 
--**    to in this state. If the transaction is committed or rolled back while 
--**    in WRITER_LOCKED state, all that is required is to unlock the database 
--**    file.
--**
--**    IN WAL mode, WalBeginWriteTransaction() is called to lock the log file.
--**    If the connection is running with locking_mode=exclusive, an attempt
--**    is made to obtain an EXCLUSIVE lock on the database file.
--**
--**    * A write transaction is active.
--**    * If the connection is open in rollback-mode, a RESERVED or greater 
--**      lock is held on the database file.
--**    * If the connection is open in WAL-mode, a WAL write transaction
--**      is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully
--**      called).
--**    * The dbSize, dbOrigSize and dbFileSize variables are all valid.
--**    * The contents of the pager cache have not been modified.
--**    * The journal file may or may not be open.
--**    * Nothing (not even the first header) has been written to the journal.
--**
--**  WRITER_CACHEMOD:
--**
--**    A pager moves from WRITER_LOCKED state to this state when a page is
--**    first modified by the upper layer. In rollback mode the journal file
--**    is opened (if it is not already open) and a header written to the
--**    start of it. The database file on disk has not been modified.
--**
--**    * A write transaction is active.
--**    * A RESERVED or greater lock is held on the database file.
--**    * The journal file is open and the first header has been written 
--**      to it, but the header has not been synced to disk.
--**    * The contents of the page cache have been modified.
--**
--**  WRITER_DBMOD:
--**
--**    The pager transitions from WRITER_CACHEMOD into WRITER_DBMOD state
--**    when it modifies the contents of the database file. WAL connections
--**    never enter this state (since they do not modify the database file,
--**    just the log file).
--**
--**    * A write transaction is active.
--**    * An EXCLUSIVE or greater lock is held on the database file.
--**    * The journal file is open and the first header has been written 
--**      and synced to disk.
--**    * The contents of the page cache have been modified (and possibly
--**      written to disk).
--**
--**  WRITER_FINISHED:
--**
--**    It is not possible for a WAL connection to enter this state.
--**
--**    A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD
--**    state after the entire transaction has been successfully written into the
--**    database file. In this state the transaction may be committed simply
--**    by finalizing the journal file. Once in WRITER_FINISHED state, it is 
--**    not possible to modify the database further. At this point, the upper 
--**    layer must either commit or rollback the transaction.
--**
--**    * A write transaction is active.
--**    * An EXCLUSIVE or greater lock is held on the database file.
--**    * All writing and syncing of journal and database data has finished.
--**      If no error occurred, all that remains is to finalize the journal to
--**      commit the transaction. If an error did occur, the caller will need
--**      to rollback the transaction. 
--**
--**  ERROR:
-+** Implementation of the sqlite3_pcache.xFetch method. 
- **
--**    The ERROR state is entered when an IO or disk-full error (including
--**    SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it 
--**    difficult to be sure that the in-memory pager state (cache contents, 
--**    db size etc.) are consistent with the contents of the file-system.
-+** Fetch a page by key value.
- **
--**    Temporary pager files may enter the ERROR state, but in-memory pagers
--**    cannot.
-+** Whether or not a new page may be allocated by this function depends on
-+** the value of the createFlag argument.  0 means do not allocate a new
-+** page.  1 means allocate a new page if space is easily available.  2 
-+** means to try really hard to allocate a new page.
- **
--**    For example, if an IO error occurs while performing a rollback, 
--**    the contents of the page-cache may be left in an inconsistent state.
--**    At this point it would be dangerous to change back to READER state
--**    (as usually happens after a rollback). Any subsequent readers might
--**    report database corruption (due to the inconsistent cache), and if
--**    they upgrade to writers, they may inadvertently corrupt the database
--**    file. To avoid this hazard, the pager switches into the ERROR state
--**    instead of READER following such an error.
-+** For a non-purgeable cache (a cache used as the storage for an in-memory
-+** database) there is really no difference between createFlag 1 and 2.  So
-+** the calling function (pcache.c) will never have a createFlag of 1 on
-+** a non-purgeable cache.
- **
--**    Once it has entered the ERROR state, any attempt to use the pager
--**    to read or write data returns an error. Eventually, once all 
--**    outstanding transactions have been abandoned, the pager is able to
--**    transition back to OPEN state, discarding the contents of the 
--**    page-cache and any other in-memory state at the same time. Everything
--**    is reloaded from disk (and, if necessary, hot-journal rollback peformed)
--**    when a read-transaction is next opened on the pager (transitioning
--**    the pager into READER state). At that point the system has recovered 
--**    from the error.
-+** There are three different approaches to obtaining space for a page,
-+** depending on the value of parameter createFlag (which may be 0, 1 or 2).
- **
--**    Specifically, the pager jumps into the ERROR state if:
-+**   1. Regardless of the value of createFlag, the cache is searched for a 
-+**      copy of the requested page. If one is found, it is returned.
- **
--**      1. An error occurs while attempting a rollback. This happens in
--**         function sqlite3PagerRollback().
-+**   2. If createFlag==0 and the page is not already in the cache, NULL is
-+**      returned.
- **
--**      2. An error occurs while attempting to finalize a journal file
--**         following a commit in function sqlite3PagerCommitPhaseTwo().
-+**   3. If createFlag is 1, and the page is not already in the cache, then
-+**      return NULL (do not allocate a new page) if any of the following
-+**      conditions are true:
- **
--**      3. An error occurs while attempting to write to the journal or
--**         database file in function pagerStress() in order to free up
--**         memory.
-+**       (a) the number of pages pinned by the cache is greater than
-+**           PCache1.nMax, or
- **
--**    In other cases, the error is returned to the b-tree layer. The b-tree
--**    layer then attempts a rollback operation. If the error condition 
--**    persists, the pager enters the ERROR state via condition (1) above.
-+**       (b) the number of pages pinned by the cache is greater than
-+**           the sum of nMax for all purgeable caches, less the sum of 
-+**           nMin for all other purgeable caches, or
- **
--**    Condition (3) is necessary because it can be triggered by a read-only
--**    statement executed within a transaction. In this case, if the error
--**    code were simply returned to the user, the b-tree layer would not
--**    automatically attempt a rollback, as it assumes that an error in a
--**    read-only statement cannot leave the pager in an internally inconsistent 
--**    state.
-+**   4. If none of the first three conditions apply and the cache is marked
-+**      as purgeable, and if one of the following is true:
- **
--**    * The Pager.errCode variable is set to something other than SQLITE_OK.
--**    * There are one or more outstanding references to pages (after the
--**      last reference is dropped the pager should move back to OPEN state).
--**    * The pager is not an in-memory pager.
--**    
-+**       (a) The number of pages allocated for the cache is already 
-+**           PCache1.nMax, or
- **
--** Notes:
-+**       (b) The number of pages allocated for all purgeable caches is
-+**           already equal to or greater than the sum of nMax for all
-+**           purgeable caches,
- **
--**   * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the
--**     connection is open in WAL mode. A WAL connection is always in one
--**     of the first four states.
-+**       (c) The system is under memory pressure and wants to avoid
-+**           unnecessary pages cache entry allocations
- **
--**   * Normally, a connection open in exclusive mode is never in PAGER_OPEN
--**     state. There are two exceptions: immediately after exclusive-mode has
--**     been turned on (and before any read or write transactions are 
--**     executed), and when the pager is leaving the "error state".
-+**      then attempt to recycle a page from the LRU list. If it is the right
-+**      size, return the recycled buffer. Otherwise, free the buffer and
-+**      proceed to step 5. 
- **
--**   * See also: assert_pager_state().
-+**   5. Otherwise, allocate and return a new page buffer.
- */
--#define PAGER_OPEN                  0
--#define PAGER_READER                1
--#define PAGER_WRITER_LOCKED         2
--#define PAGER_WRITER_CACHEMOD       3
--#define PAGER_WRITER_DBMOD          4
--#define PAGER_WRITER_FINISHED       5
--#define PAGER_ERROR                 6
-+static sqlite3_pcache_page *pcache1Fetch(
-+  sqlite3_pcache *p, 
-+  unsigned int iKey, 
-+  int createFlag
++
++static u16 fts5GetU16(const u8 *aIn){
++  return ((u16)aIn[0] << 8) + aIn[1];
++} 
++
++/*
++** Allocate and return a buffer at least nByte bytes in size.
++**
++** If an OOM error is encountered, return NULL and set the error code in
++** the Fts5Index handle passed as the first argument.
++*/
++static void *fts5IdxMalloc(Fts5Index *p, int nByte){
++  return sqlite3Fts5MallocZero(&p->rc, nByte);
++}
++
++/*
++** Compare the contents of the pLeft buffer with the pRight/nRight blob.
++**
++** Return -ve if pLeft is smaller than pRight, 0 if they are equal or
++** +ve if pRight is smaller than pLeft. In other words:
++**
++**     res = *pLeft - *pRight
++*/
++#ifdef SQLITE_DEBUG
++static int fts5BufferCompareBlob(
++  Fts5Buffer *pLeft,              /* Left hand side of comparison */
++  const u8 *pRight, int nRight    /* Right hand side of comparison */
 +){
-+  PCache1 *pCache = (PCache1 *)p;
-+  PgHdr1 *pPage = 0;
++  int nCmp = MIN(pLeft->n, nRight);
++  int res = memcmp(pLeft->p, pRight, nCmp);
++  return (res==0 ? (pLeft->n - nRight) : res);
++}
++#endif
 +
-+  assert( offsetof(PgHdr1,page)==0 );
-+  assert( pCache->bPurgeable || createFlag!=1 );
-+  assert( pCache->bPurgeable || pCache->nMin==0 );
-+  assert( pCache->bPurgeable==0 || pCache->nMin==10 );
-+  assert( pCache->nMin==0 || pCache->bPurgeable );
-+  assert( pCache->nHash>0 );
-+  pcache1EnterMutex(pCache->pGroup);
++/*
++** Compare the contents of the two buffers using memcmp(). If one buffer
++** is a prefix of the other, it is considered the lesser.
++**
++** Return -ve if pLeft is smaller than pRight, 0 if they are equal or
++** +ve if pRight is smaller than pLeft. In other words:
++**
++**     res = *pLeft - *pRight
++*/
++static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){
++  int nCmp = MIN(pLeft->n, pRight->n);
++  int res = memcmp(pLeft->p, pRight->p, nCmp);
++  return (res==0 ? (pLeft->n - pRight->n) : res);
++}
 +
-+  /* Step 1: Search the hash table for an existing entry. */
-+  pPage = pCache->apHash[iKey % pCache->nHash];
-+  while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; }
++static int fts5LeafFirstTermOff(Fts5Data *pLeaf){
++  int ret;
++  fts5GetVarint32(&pLeaf->p[pLeaf->szLeaf], ret);
++  return ret;
++}
 +
-+  /* Step 2: Abort if no existing page is found and createFlag is 0 */
-+  if( pPage ){
-+    if( !pPage->isPinned ) pcache1PinPage(pPage);
-+  }else if( createFlag ){
-+    /* Steps 3, 4, and 5 implemented by this subroutine */
-+    pPage = pcache1FetchStage2(pCache, iKey, createFlag);
++/*
++** Close the read-only blob handle, if it is open.
++*/
++static void fts5CloseReader(Fts5Index *p){
++  if( p->pReader ){
++    sqlite3_blob *pReader = p->pReader;
++    p->pReader = 0;
++    sqlite3_blob_close(pReader);
 +  }
-+  assert( pPage==0 || pCache->iMaxKey>=iKey );
-+  pcache1LeaveMutex(pCache->pGroup);
-+  return (sqlite3_pcache_page*)pPage;
 +}
 +
- 
- /*
--** The Pager.eLock variable is almost always set to one of the 
--** following locking-states, according to the lock currently held on
--** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
--** This variable is kept up to date as locks are taken and released by
--** the pagerLockDb() and pagerUnlockDb() wrappers.
--**
--** If the VFS xLock() or xUnlock() returns an error other than SQLITE_BUSY
--** (i.e. one of the SQLITE_IOERR subtypes), it is not clear whether or not
--** the operation was successful. In these circumstances pagerLockDb() and
--** pagerUnlockDb() take a conservative approach - eLock is always updated
--** when unlocking the file, and only updated when locking the file if the
--** VFS call is successful. This way, the Pager.eLock variable may be set
--** to a less exclusive (lower) value than the lock that is actually held
--** at the system level, but it is never set to a more exclusive value.
--**
--** This is usually safe. If an xUnlock fails or appears to fail, there may 
--** be a few redundant xLock() calls or a lock may be held for longer than
--** required, but nothing really goes wrong.
--**
--** The exception is when the database file is unlocked as the pager moves
--** from ERROR to OPEN state. At this point there may be a hot-journal file 
--** in the file-system that needs to be rolled back (as part of an OPEN->SHARED
--** transition, by the same pager or any other). If the call to xUnlock()
--** fails at this point and the pager is left holding an EXCLUSIVE lock, this
--** can confuse the call to xCheckReservedLock() call made later as part
--** of hot-journal detection.
-+** Implementation of the sqlite3_pcache.xUnpin method.
- **
--** xCheckReservedLock() is defined as returning true "if there is a RESERVED 
--** lock held by this process or any others". So xCheckReservedLock may 
--** return true because the caller itself is holding an EXCLUSIVE lock (but
--** doesn't know it because of a previous error in xUnlock). If this happens
--** a hot-journal may be mistaken for a journal being created by an active
--** transaction in another process, causing SQLite to read from the database
--** without rolling it back.
-+** Mark a page as unpinned (eligible for asynchronous recycling).
-+*/
-+static void pcache1Unpin(
-+  sqlite3_pcache *p, 
-+  sqlite3_pcache_page *pPg, 
-+  int reuseUnlikely
-+){
-+  PCache1 *pCache = (PCache1 *)p;
-+  PgHdr1 *pPage = (PgHdr1 *)pPg;
-+  PGroup *pGroup = pCache->pGroup;
-+ 
-+  assert( pPage->pCache==pCache );
-+  pcache1EnterMutex(pGroup);
++/*
++** Retrieve a record from the %_data table.
++**
++** If an error occurs, NULL is returned and an error left in the 
++** Fts5Index object.
++*/
++static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
++  Fts5Data *pRet = 0;
++  if( p->rc==SQLITE_OK ){
++    int rc = SQLITE_OK;
++
++    if( p->pReader ){
++      /* This call may return SQLITE_ABORT if there has been a savepoint
++      ** rollback since it was last used. In this case a new blob handle
++      ** is required.  */
++      sqlite3_blob *pBlob = p->pReader;
++      p->pReader = 0;
++      rc = sqlite3_blob_reopen(pBlob, iRowid);
++      assert( p->pReader==0 );
++      p->pReader = pBlob;
++      if( rc!=SQLITE_OK ){
++        fts5CloseReader(p);
++      }
++      if( rc==SQLITE_ABORT ) rc = SQLITE_OK;
++    }
 +
-+  /* It is an error to call this function if the page is already 
-+  ** part of the PGroup LRU list.
-+  */
-+  assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
-+  assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage );
-+  assert( pPage->isPinned==1 );
++    /* If the blob handle is not open at this point, open it and seek 
++    ** to the requested entry.  */
++    if( p->pReader==0 && rc==SQLITE_OK ){
++      Fts5Config *pConfig = p->pConfig;
++      rc = sqlite3_blob_open(pConfig->db, 
++          pConfig->zDb, p->zDataTbl, "block", iRowid, 0, &p->pReader
++      );
++    }
 +
-+  if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
-+    pcache1RemoveFromHash(pPage);
-+    pcache1FreePage(pPage);
-+  }else{
-+    /* Add the page to the PGroup LRU list. */
-+    if( pGroup->pLruHead ){
-+      pGroup->pLruHead->pLruPrev = pPage;
-+      pPage->pLruNext = pGroup->pLruHead;
-+      pGroup->pLruHead = pPage;
-+    }else{
-+      pGroup->pLruTail = pPage;
-+      pGroup->pLruHead = pPage;
++    /* If either of the sqlite3_blob_open() or sqlite3_blob_reopen() calls
++    ** above returned SQLITE_ERROR, return SQLITE_CORRUPT_VTAB instead.
++    ** All the reasons those functions might return SQLITE_ERROR - missing
++    ** table, missing row, non-blob/text in block column - indicate 
++    ** backing store corruption.  */
++    if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT;
++
++    if( rc==SQLITE_OK ){
++      u8 *aOut = 0;               /* Read blob data into this buffer */
++      int nByte = sqlite3_blob_bytes(p->pReader);
++      int nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING;
++      pRet = (Fts5Data*)sqlite3_malloc(nAlloc);
++      if( pRet ){
++        pRet->nn = nByte;
++        aOut = pRet->p = (u8*)&pRet[1];
++      }else{
++        rc = SQLITE_NOMEM;
++      }
++
++      if( rc==SQLITE_OK ){
++        rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0);
++      }
++      if( rc!=SQLITE_OK ){
++        sqlite3_free(pRet);
++        pRet = 0;
++      }else{
++        /* TODO1: Fix this */
++        pRet->szLeaf = fts5GetU16(&pRet->p[2]);
++      }
 +    }
-+    pCache->nRecyclable++;
-+    pPage->isPinned = 0;
++    p->rc = rc;
++    p->nRead++;
 +  }
 +
-+  pcache1LeaveMutex(pCache->pGroup);
++  assert( (pRet==0)==(p->rc!=SQLITE_OK) );
++  return pRet;
 +}
 +
 +/*
-+** Implementation of the sqlite3_pcache.xRekey method. 
++** Release a reference to data record returned by an earlier call to
++** fts5DataRead().
 +*/
-+static void pcache1Rekey(
-+  sqlite3_pcache *p,
-+  sqlite3_pcache_page *pPg,
-+  unsigned int iOld,
-+  unsigned int iNew
-+){
-+  PCache1 *pCache = (PCache1 *)p;
-+  PgHdr1 *pPage = (PgHdr1 *)pPg;
-+  PgHdr1 **pp;
-+  unsigned int h; 
-+  assert( pPage->iKey==iOld );
-+  assert( pPage->pCache==pCache );
++static void fts5DataRelease(Fts5Data *pData){
++  sqlite3_free(pData);
++}
 +
-+  pcache1EnterMutex(pCache->pGroup);
++static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
++  Fts5Data *pRet = fts5DataRead(p, iRowid);
++  if( pRet ){
++    if( pRet->szLeaf>pRet->nn ){
++      p->rc = FTS5_CORRUPT;
++      fts5DataRelease(pRet);
++      pRet = 0;
++    }
++  }
++  return pRet;
++}
 +
-+  h = iOld%pCache->nHash;
-+  pp = &pCache->apHash[h];
-+  while( (*pp)!=pPage ){
-+    pp = &(*pp)->pNext;
++static int fts5IndexPrepareStmt(
++  Fts5Index *p,
++  sqlite3_stmt **ppStmt,
++  char *zSql
++){
++  if( p->rc==SQLITE_OK ){
++    if( zSql ){
++      p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
++                                 SQLITE_PREPARE_PERSISTENT, ppStmt, 0);
++    }else{
++      p->rc = SQLITE_NOMEM;
++    }
 +  }
-+  *pp = pPage->pNext;
++  sqlite3_free(zSql);
++  return p->rc;
++}
++
 +
-+  h = iNew%pCache->nHash;
-+  pPage->iKey = iNew;
-+  pPage->pNext = pCache->apHash[h];
-+  pCache->apHash[h] = pPage;
-+  if( iNew>pCache->iMaxKey ){
-+    pCache->iMaxKey = iNew;
++/*
++** INSERT OR REPLACE a record into the %_data table.
++*/
++static void fts5DataWrite(Fts5Index *p, i64 iRowid, const u8 *pData, int nData){
++  if( p->rc!=SQLITE_OK ) return;
++
++  if( p->pWriter==0 ){
++    Fts5Config *pConfig = p->pConfig;
++    fts5IndexPrepareStmt(p, &p->pWriter, sqlite3_mprintf(
++          "REPLACE INTO '%q'.'%q_data'(id, block) VALUES(?,?)", 
++          pConfig->zDb, pConfig->zName
++    ));
++    if( p->rc ) return;
 +  }
 +
-+  pcache1LeaveMutex(pCache->pGroup);
++  sqlite3_bind_int64(p->pWriter, 1, iRowid);
++  sqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC);
++  sqlite3_step(p->pWriter);
++  p->rc = sqlite3_reset(p->pWriter);
 +}
 +
 +/*
-+** Implementation of the sqlite3_pcache.xTruncate method. 
- **
--** To work around this, if a call to xUnlock() fails when unlocking the
--** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It
--** is only changed back to a real locking state after a successful call
--** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition
--** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK 
--** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE
--** lock on the database file before attempting to roll it back. See function
--** PagerSharedLock() for more detail.
-+** Discard all unpinned pages in the cache with a page number equal to
-+** or greater than parameter iLimit. Any pinned pages with a page number
-+** equal to or greater than iLimit are implicitly unpinned.
++** Execute the following SQL:
++**
++**     DELETE FROM %_data WHERE id BETWEEN $iFirst AND $iLast
 +*/
-+static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){
-+  PCache1 *pCache = (PCache1 *)p;
-+  pcache1EnterMutex(pCache->pGroup);
-+  if( iLimit<=pCache->iMaxKey ){
-+    pcache1TruncateUnsafe(pCache, iLimit);
-+    pCache->iMaxKey = iLimit-1;
++static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){
++  if( p->rc!=SQLITE_OK ) return;
++
++  if( p->pDeleter==0 ){
++    int rc;
++    Fts5Config *pConfig = p->pConfig;
++    char *zSql = sqlite3_mprintf(
++        "DELETE FROM '%q'.'%q_data' WHERE id>=? AND id<=?", 
++          pConfig->zDb, pConfig->zName
++    );
++    if( zSql==0 ){
++      rc = SQLITE_NOMEM;
++    }else{
++      rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
++                              SQLITE_PREPARE_PERSISTENT, &p->pDeleter, 0);
++      sqlite3_free(zSql);
++    }
++    if( rc!=SQLITE_OK ){
++      p->rc = rc;
++      return;
++    }
 +  }
-+  pcache1LeaveMutex(pCache->pGroup);
++
++  sqlite3_bind_int64(p->pDeleter, 1, iFirst);
++  sqlite3_bind_int64(p->pDeleter, 2, iLast);
++  sqlite3_step(p->pDeleter);
++  p->rc = sqlite3_reset(p->pDeleter);
 +}
 +
 +/*
-+** Implementation of the sqlite3_pcache.xDestroy method. 
- **
--** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in 
--** PAGER_OPEN state.
-+** Destroy a cache allocated using pcache1Create().
- */
--#define UNKNOWN_LOCK                (EXCLUSIVE_LOCK+1)
-+static void pcache1Destroy(sqlite3_pcache *p){
-+  PCache1 *pCache = (PCache1 *)p;
-+  PGroup *pGroup = pCache->pGroup;
-+  assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
-+  pcache1EnterMutex(pGroup);
-+  pcache1TruncateUnsafe(pCache, 0);
-+  assert( pGroup->nMaxPage >= pCache->nMax );
-+  pGroup->nMaxPage -= pCache->nMax;
-+  assert( pGroup->nMinPage >= pCache->nMin );
-+  pGroup->nMinPage -= pCache->nMin;
-+  pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
-+  pcache1EnforceMaxPage(pGroup);
-+  pcache1LeaveMutex(pGroup);
-+  sqlite3_free(pCache->apHash);
-+  sqlite3_free(pCache);
-+}
- 
- /*
--** A macro used for invoking the codec if there is one
-+** This function is called during initialization (sqlite3_initialize()) to
-+** install the default pluggable cache module, assuming the user has not
-+** already provided an alternative.
-+*/
-+SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){
-+  static const sqlite3_pcache_methods2 defaultMethods = {
-+    1,                       /* iVersion */
-+    0,                       /* pArg */
-+    pcache1Init,             /* xInit */
-+    pcache1Shutdown,         /* xShutdown */
-+    pcache1Create,           /* xCreate */
-+    pcache1Cachesize,        /* xCachesize */
-+    pcache1Pagecount,        /* xPagecount */
-+    pcache1Fetch,            /* xFetch */
-+    pcache1Unpin,            /* xUnpin */
-+    pcache1Rekey,            /* xRekey */
-+    pcache1Truncate,         /* xTruncate */
-+    pcache1Destroy,          /* xDestroy */
-+    pcache1Shrink            /* xShrink */
-+  };
-+  sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
++** Remove all records associated with segment iSegid.
++*/
++static void fts5DataRemoveSegment(Fts5Index *p, int iSegid){
++  i64 iFirst = FTS5_SEGMENT_ROWID(iSegid, 0);
++  i64 iLast = FTS5_SEGMENT_ROWID(iSegid+1, 0)-1;
++  fts5DataDelete(p, iFirst, iLast);
++  if( p->pIdxDeleter==0 ){
++    Fts5Config *pConfig = p->pConfig;
++    fts5IndexPrepareStmt(p, &p->pIdxDeleter, sqlite3_mprintf(
++          "DELETE FROM '%q'.'%q_idx' WHERE segid=?",
++          pConfig->zDb, pConfig->zName
++    ));
++  }
++  if( p->rc==SQLITE_OK ){
++    sqlite3_bind_int(p->pIdxDeleter, 1, iSegid);
++    sqlite3_step(p->pIdxDeleter);
++    p->rc = sqlite3_reset(p->pIdxDeleter);
++  }
 +}
 +
 +/*
-+** Return the size of the header on each page of this PCACHE implementation.
- */
--#ifdef SQLITE_HAS_CODEC
--# define CODEC1(P,D,N,X,E) \
--    if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; }
--# define CODEC2(P,D,N,X,E,O) \
--    if( P->xCodec==0 ){ O=(char*)D; }else \
--    if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; }
--#else
--# define CODEC1(P,D,N,X,E)   /* NO-OP */
--# define CODEC2(P,D,N,X,E,O) O=(char*)D
--#endif
-+SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); }
- 
- /*
--** The maximum allowed sector size. 64KiB. If the xSectorsize() method 
--** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
--** This could conceivably cause corruption following a power failure on
--** such a system. This is currently an undocumented limit.
-+** Return the global mutex used by this PCACHE implementation.  The
-+** sqlite3_status() routine needs access to this mutex.
- */
--#define MAX_SECTOR_SIZE 0x10000
-+SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){
-+  return pcache1.mutex;
-+}
- 
-+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- /*
--** An instance of the following structure is allocated for each active
--** savepoint and statement transaction in the system. All such structures
--** are stored in the Pager.aSavepoint[] array, which is allocated and
--** resized using sqlite3Realloc().
-+** This function is called to free superfluous dynamically allocated memory
-+** held by the pager system. Memory in use by any SQLite pager allocated
-+** by the current thread may be sqlite3_free()ed.
- **
--** When a savepoint is created, the PagerSavepoint.iHdrOffset field is
--** set to 0. If a journal-header is written into the main journal while
--** the savepoint is active, then iHdrOffset is set to the byte offset 
--** immediately following the last journal record written into the main
--** journal before the journal-header. This is required during savepoint
--** rollback (see pagerPlaybackSavepoint()).
-+** nReq is the number of bytes of memory required. Once this much has
-+** been released, the function returns. The return value is the total number 
-+** of bytes of memory released.
- */
--typedef struct PagerSavepoint PagerSavepoint;
--struct PagerSavepoint {
--  i64 iOffset;                 /* Starting offset in main journal */
--  i64 iHdrOffset;              /* See above */
--  Bitvec *pInSavepoint;        /* Set of pages in this savepoint */
--  Pgno nOrig;                  /* Original number of pages in file */
--  Pgno iSubRec;                /* Index of first record in sub-journal */
--#ifndef SQLITE_OMIT_WAL
--  u32 aWalData[WAL_SAVEPOINT_NDATA];        /* WAL savepoint context */
-+SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
-+  int nFree = 0;
-+  assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
-+  assert( sqlite3_mutex_notheld(pcache1.mutex) );
-+  if( pcache1.pStart==0 ){
-+    PgHdr1 *p;
-+    pcache1EnterMutex(&pcache1.grp);
-+    while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
-+      nFree += pcache1MemSize(p->page.pBuf);
-+#ifdef SQLITE_PCACHE_SEPARATE_HEADER
-+      nFree += sqlite3MemSize(p);
- #endif
--};
-+      assert( p->isPinned==0 );
-+      pcache1PinPage(p);
-+      pcache1RemoveFromHash(p);
-+      pcache1FreePage(p);
++** Release a reference to an Fts5Structure object returned by an earlier 
++** call to fts5StructureRead() or fts5StructureDecode().
++*/
++static void fts5StructureRelease(Fts5Structure *pStruct){
++  if( pStruct && 0>=(--pStruct->nRef) ){
++    int i;
++    assert( pStruct->nRef==0 );
++    for(i=0; i<pStruct->nLevel; i++){
++      sqlite3_free(pStruct->aLevel[i].aSeg);
 +    }
-+    pcache1LeaveMutex(&pcache1.grp);
++    sqlite3_free(pStruct);
 +  }
-+  return nFree;
 +}
-+#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
- 
-+#ifdef SQLITE_TEST
- /*
--** Bits of the Pager.doNotSpill flag.  See further description below.
-+** This function is used by test procedures to inspect the internal state
-+** of the global cache.
- */
--#define SPILLFLAG_OFF         0x01      /* Never spill cache.  Set via pragma */
--#define SPILLFLAG_ROLLBACK    0x02      /* Current rolling back, so do not spill */
--#define SPILLFLAG_NOSYNC      0x04      /* Spill is ok, but do not sync */
-+SQLITE_PRIVATE void sqlite3PcacheStats(
-+  int *pnCurrent,      /* OUT: Total number of pages cached */
-+  int *pnMax,          /* OUT: Global maximum cache size */
-+  int *pnMin,          /* OUT: Sum of PCache1.nMin for purgeable caches */
-+  int *pnRecyclable    /* OUT: Total number of pages available for recycling */
-+){
-+  PgHdr1 *p;
-+  int nRecyclable = 0;
-+  for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){
-+    assert( p->isPinned==0 );
-+    nRecyclable++;
-+  }
-+  *pnCurrent = pcache1.grp.nCurrentPage;
-+  *pnMax = (int)pcache1.grp.nMaxPage;
-+  *pnMin = (int)pcache1.grp.nMinPage;
-+  *pnRecyclable = nRecyclable;
++
++static void fts5StructureRef(Fts5Structure *pStruct){
++  pStruct->nRef++;
 +}
-+#endif
- 
-+/************** End of pcache1.c *********************************************/
-+/************** Begin file rowset.c ******************************************/
- /*
--** An open page cache is an instance of struct Pager. A description of
--** some of the more important member variables follows:
--**
--** eState
--**
--**   The current 'state' of the pager object. See the comment and state
--**   diagram above for a description of the pager state.
--**
--** eLock
--**
--**   For a real on-disk database, the current lock held on the database file -
--**   NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
--**
--**   For a temporary or in-memory database (neither of which require any
--**   locks), this variable is always set to EXCLUSIVE_LOCK. Since such
--**   databases always have Pager.exclusiveMode==1, this tricks the pager
--**   logic into thinking that it already has all the locks it will ever
--**   need (and no reason to release them).
--**
--**   In some (obscure) circumstances, this variable may also be set to
--**   UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for
--**   details.
--**
--** changeCountDone
--**
--**   This boolean variable is used to make sure that the change-counter 
--**   (the 4-byte header field at byte offset 24 of the database file) is 
--**   not updated more often than necessary. 
--**
--**   It is set to true when the change-counter field is updated, which 
--**   can only happen if an exclusive lock is held on the database file.
--**   It is cleared (set to false) whenever an exclusive lock is 
--**   relinquished on the database file. Each time a transaction is committed,
--**   The changeCountDone flag is inspected. If it is true, the work of
--**   updating the change-counter is omitted for the current transaction.
--**
--**   This mechanism means that when running in exclusive mode, a connection 
--**   need only update the change-counter once, for the first transaction
--**   committed.
--**
--** setMaster
--**
--**   When PagerCommitPhaseOne() is called to commit a transaction, it may
--**   (or may not) specify a master-journal name to be written into the 
--**   journal file before it is synced to disk.
--**
--**   Whether or not a journal file contains a master-journal pointer affects 
--**   the way in which the journal file is finalized after the transaction is 
--**   committed or rolled back when running in "journal_mode=PERSIST" mode.
--**   If a journal file does not contain a master-journal pointer, it is
--**   finalized by overwriting the first journal header with zeroes. If
--**   it does contain a master-journal pointer the journal file is finalized 
--**   by truncating it to zero bytes, just as if the connection were 
--**   running in "journal_mode=truncate" mode.
--**
--**   Journal files that contain master journal pointers cannot be finalized
--**   simply by overwriting the first journal-header with zeroes, as the
--**   master journal pointer could interfere with hot-journal rollback of any
--**   subsequently interrupted transaction that reuses the journal file.
--**
--**   The flag is cleared as soon as the journal file is finalized (either
--**   by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the
--**   journal file from being successfully finalized, the setMaster flag
--**   is cleared anyway (and the pager will move to ERROR state).
--**
--** doNotSpill
--**
--**   This variables control the behavior of cache-spills  (calls made by
--**   the pcache module to the pagerStress() routine to write cached data
--**   to the file-system in order to free up memory).
-+** 2008 December 3
- **
--**   When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set,
--**   writing to the database from pagerStress() is disabled altogether.
--**   The SPILLFLAG_ROLLBACK case is done in a very obscure case that
--**   comes up during savepoint rollback that requires the pcache module
--**   to allocate a new page to prevent the journal file from being written
--**   while it is being traversed by code in pager_playback().  The SPILLFLAG_OFF
--**   case is a user preference.
--** 
--**   If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStress()
--**   is permitted, but syncing the journal file is not. This flag is set
--**   by sqlite3PagerWrite() when the file-system sector-size is larger than
--**   the database page-size in order to prevent a journal sync from happening 
--**   in between the journalling of two pages on the same sector. 
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
- **
--** subjInMemory
-+**    May you do good and not evil.
-+**    May you find forgiveness for yourself and forgive others.
-+**    May you share freely, never taking more than you give.
- **
--**   This is a boolean variable. If true, then any required sub-journal
--**   is opened as an in-memory journal file. If false, then in-memory
--**   sub-journals are only used for in-memory pager files.
-+*************************************************************************
- **
--**   This variable is updated by the upper layer each time a new 
--**   write-transaction is opened.
-+** This module implements an object we call a "RowSet".
- **
--** dbSize, dbOrigSize, dbFileSize
-+** The RowSet object is a collection of rowids.  Rowids
-+** are inserted into the RowSet in an arbitrary order.  Inserts
-+** can be intermixed with tests to see if a given rowid has been
-+** previously inserted into the RowSet.
- **
--**   Variable dbSize is set to the number of pages in the database file.
--**   It is valid in PAGER_READER and higher states (all states except for
--**   OPEN and ERROR). 
-+** After all inserts are finished, it is possible to extract the
-+** elements of the RowSet in sorted order.  Once this extraction
-+** process has started, no new elements may be inserted.
- **
--**   dbSize is set based on the size of the database file, which may be 
--**   larger than the size of the database (the value stored at offset
--**   28 of the database header by the btree). If the size of the file
--**   is not an integer multiple of the page-size, the value stored in
--**   dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2).
--**   Except, any file that is greater than 0 bytes in size is considered
--**   to have at least one page. (i.e. a 1KB file with 2K page-size leads
--**   to dbSize==1).
-+** Hence, the primitive operations for a RowSet are:
- **
--**   During a write-transaction, if pages with page-numbers greater than
--**   dbSize are modified in the cache, dbSize is updated accordingly.
--**   Similarly, if the database is truncated using PagerTruncateImage(), 
--**   dbSize is updated.
-+**    CREATE
-+**    INSERT
-+**    TEST
-+**    SMALLEST
-+**    DESTROY
- **
--**   Variables dbOrigSize and dbFileSize are valid in states 
--**   PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize
--**   variable at the start of the transaction. It is used during rollback,
--**   and to determine whether or not pages need to be journalled before
--**   being modified.
-+** The CREATE and DESTROY primitives are the constructor and destructor,
-+** obviously.  The INSERT primitive adds a new element to the RowSet.
-+** TEST checks to see if an element is already in the RowSet.  SMALLEST
-+** extracts the least value from the RowSet.
- **
--**   Throughout a write-transaction, dbFileSize contains the size of
--**   the file on disk in pages. It is set to a copy of dbSize when the
--**   write-transaction is first opened, and updated when VFS calls are made
--**   to write or truncate the database file on disk. 
-+** The INSERT primitive might allocate additional memory.  Memory is
-+** allocated in chunks so most INSERTs do no allocation.  There is an 
-+** upper bound on the size of allocated memory.  No memory is freed
-+** until DESTROY.
- **
--**   The only reason the dbFileSize variable is required is to suppress 
--**   unnecessary calls to xTruncate() after committing a transaction. If, 
--**   when a transaction is committed, the dbFileSize variable indicates 
--**   that the database file is larger than the database image (Pager.dbSize), 
--**   pager_truncate() is called. The pager_truncate() call uses xFilesize()
--**   to measure the database file on disk, and then truncates it if required.
--**   dbFileSize is not used when rolling back a transaction. In this case
--**   pager_truncate() is called unconditionally (which means there may be
--**   a call to xFilesize() that is not strictly required). In either case,
--**   pager_truncate() may cause the file to become smaller or larger.
-+** The TEST primitive includes a "batch" number.  The TEST primitive
-+** will only see elements that were inserted before the last change
-+** in the batch number.  In other words, if an INSERT occurs between
-+** two TESTs where the TESTs have the same batch nubmer, then the
-+** value added by the INSERT will not be visible to the second TEST.
-+** The initial batch number is zero, so if the very first TEST contains
-+** a non-zero batch number, it will see all prior INSERTs.
- **
--** dbHintSize
-+** No INSERTs may occurs after a SMALLEST.  An assertion will fail if
-+** that is attempted.
- **
--**   The dbHintSize variable is used to limit the number of calls made to
--**   the VFS xFileControl(FCNTL_SIZE_HINT) method. 
-+** The cost of an INSERT is roughly constant.  (Sometimes new memory
-+** has to be allocated on an INSERT.)  The cost of a TEST with a new
-+** batch number is O(NlogN) where N is the number of elements in the RowSet.
-+** The cost of a TEST using the same batch number is O(logN).  The cost
-+** of the first SMALLEST is O(NlogN).  Second and subsequent SMALLEST
-+** primitives are constant time.  The cost of DESTROY is O(N).
- **
--**   dbHintSize is set to a copy of the dbSize variable when a
--**   write-transaction is opened (at the same time as dbFileSize and
--**   dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called,
--**   dbHintSize is increased to the number of pages that correspond to the
--**   size-hint passed to the method call. See pager_write_pagelist() for 
--**   details.
-+** There is an added cost of O(N) when switching between TEST and
-+** SMALLEST primitives.
-+*/
-+
-+
-+/*
-+** Target size for allocation chunks.
-+*/
-+#define ROWSET_ALLOCATION_SIZE 1024
-+
-+/*
-+** The number of rowset entries per allocation chunk.
-+*/
-+#define ROWSET_ENTRY_PER_CHUNK  \
-+                       ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry))
-+
-+/*
-+** Each entry in a RowSet is an instance of the following object.
- **
--** errCode
-+** This same object is reused to store a linked list of trees of RowSetEntry
-+** objects.  In that alternative use, pRight points to the next entry
-+** in the list, pLeft points to the tree, and v is unused.  The
-+** RowSet.pForest value points to the head of this forest list.
-+*/
-+struct RowSetEntry {            
-+  i64 v;                        /* ROWID value for this entry */
-+  struct RowSetEntry *pRight;   /* Right subtree (larger entries) or list */
-+  struct RowSetEntry *pLeft;    /* Left subtree (smaller entries) */
-+};
 +
-+/*
-+** RowSetEntry objects are allocated in large chunks (instances of the
-+** following structure) to reduce memory allocation overhead.  The
-+** chunks are kept on a linked list so that they can be deallocated
-+** when the RowSet is destroyed.
-+*/
-+struct RowSetChunk {
-+  struct RowSetChunk *pNextChunk;        /* Next chunk on list of them all */
-+  struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */
-+};
++/*
++** Deserialize and return the structure record currently stored in serialized
++** form within buffer pData/nData.
++**
++** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array
++** are over-allocated by one slot. This allows the structure contents
++** to be more easily edited.
++**
++** If an error occurs, *ppOut is set to NULL and an SQLite error code
++** returned. Otherwise, *ppOut is set to point to the new object and
++** SQLITE_OK returned.
++*/
++static int fts5StructureDecode(
++  const u8 *pData,                /* Buffer containing serialized structure */
++  int nData,                      /* Size of buffer pData in bytes */
++  int *piCookie,                  /* Configuration cookie value */
++  Fts5Structure **ppOut           /* OUT: Deserialized object */
++){
++  int rc = SQLITE_OK;
++  int i = 0;
++  int iLvl;
++  int nLevel = 0;
++  int nSegment = 0;
++  int nByte;                      /* Bytes of space to allocate at pRet */
++  Fts5Structure *pRet = 0;        /* Structure object to return */
++
++  /* Grab the cookie value */
++  if( piCookie ) *piCookie = sqlite3Fts5Get32(pData);
++  i = 4;
++
++  /* Read the total number of levels and segments from the start of the
++  ** structure record.  */
++  i += fts5GetVarint32(&pData[i], nLevel);
++  i += fts5GetVarint32(&pData[i], nSegment);
++  nByte = (
++      sizeof(Fts5Structure) +                    /* Main structure */
++      sizeof(Fts5StructureLevel) * (nLevel-1)    /* aLevel[] array */
++  );
++  pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte);
++
++  if( pRet ){
++    pRet->nRef = 1;
++    pRet->nLevel = nLevel;
++    pRet->nSegment = nSegment;
++    i += sqlite3Fts5GetVarint(&pData[i], &pRet->nWriteCounter);
++
++    for(iLvl=0; rc==SQLITE_OK && iLvl<nLevel; iLvl++){
++      Fts5StructureLevel *pLvl = &pRet->aLevel[iLvl];
++      int nTotal = 0;
++      int iSeg;
++
++      if( i>=nData ){
++        rc = FTS5_CORRUPT;
++      }else{
++        i += fts5GetVarint32(&pData[i], pLvl->nMerge);
++        i += fts5GetVarint32(&pData[i], nTotal);
++        assert( nTotal>=pLvl->nMerge );
++        pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc, 
++            nTotal * sizeof(Fts5StructureSegment)
++        );
++      }
++
++      if( rc==SQLITE_OK ){
++        pLvl->nSeg = nTotal;
++        for(iSeg=0; iSeg<nTotal; iSeg++){
++          if( i>=nData ){
++            rc = FTS5_CORRUPT;
++            break;
++          }
++          i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].iSegid);
++          i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoFirst);
++          i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoLast);
++        }
++      }
++    }
++    if( rc!=SQLITE_OK ){
++      fts5StructureRelease(pRet);
++      pRet = 0;
++    }
++  }
++
++  *ppOut = pRet;
++  return rc;
++}
 +
 +/*
-+** A RowSet in an instance of the following structure.
- **
--**   The Pager.errCode variable is only ever used in PAGER_ERROR state. It
--**   is set to zero in all other states. In PAGER_ERROR state, Pager.errCode 
--**   is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX 
--**   sub-codes.
-+** A typedef of this structure if found in sqliteInt.h.
- */
--struct Pager {
--  sqlite3_vfs *pVfs;          /* OS functions to use for IO */
--  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
--  u8 journalMode;             /* One of the PAGER_JOURNALMODE_* values */
--  u8 useJournal;              /* Use a rollback journal on this file */
--  u8 noSync;                  /* Do not sync the journal if true */
--  u8 fullSync;                /* Do extra syncs of the journal for robustness */
--  u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
--  u8 walSyncFlags;            /* SYNC_NORMAL or SYNC_FULL for wal writes */
--  u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
--  u8 tempFile;                /* zFilename is a temporary or immutable file */
--  u8 noLock;                  /* Do not lock (except in WAL mode) */
--  u8 readOnly;                /* True for a read-only database */
--  u8 memDb;                   /* True to inhibit all file I/O */
-+struct RowSet {
-+  struct RowSetChunk *pChunk;    /* List of all chunk allocations */
-+  sqlite3 *db;                   /* The database connection */
-+  struct RowSetEntry *pEntry;    /* List of entries using pRight */
-+  struct RowSetEntry *pLast;     /* Last entry on the pEntry list */
-+  struct RowSetEntry *pFresh;    /* Source of new entry objects */
-+  struct RowSetEntry *pForest;   /* List of binary trees of entries */
-+  u16 nFresh;                    /* Number of objects on pFresh */
-+  u16 rsFlags;                   /* Various flags */
-+  int iBatch;                    /* Current insert batch */
-+};
- 
--  /**************************************************************************
--  ** The following block contains those class members that change during
--  ** routine operation.  Class members not in this block are either fixed
--  ** when the pager is first created or else only change when there is a
--  ** significant mode change (such as changing the page_size, locking_mode,
--  ** or the journal_mode).  From another view, these class members describe
--  ** the "state" of the pager, while other class members describe the
--  ** "configuration" of the pager.
--  */
--  u8 eState;                  /* Pager state (OPEN, READER, WRITER_LOCKED..) */
--  u8 eLock;                   /* Current lock held on database file */
--  u8 changeCountDone;         /* Set after incrementing the change-counter */
--  u8 setMaster;               /* True if a m-j name has been written to jrnl */
--  u8 doNotSpill;              /* Do not spill the cache when non-zero */
--  u8 subjInMemory;            /* True to use in-memory sub-journals */
--  u8 bUseFetch;               /* True to use xFetch() */
--  u8 hasBeenUsed;             /* True if any content previously read from this pager*/
--  Pgno dbSize;                /* Number of pages in the database */
--  Pgno dbOrigSize;            /* dbSize before the current transaction */
--  Pgno dbFileSize;            /* Number of pages in the database file */
--  Pgno dbHintSize;            /* Value passed to FCNTL_SIZE_HINT call */
--  int errCode;                /* One of several kinds of errors */
--  int nRec;                   /* Pages journalled since last j-header written */
--  u32 cksumInit;              /* Quasi-random value added to every checksum */
--  u32 nSubRec;                /* Number of records written to sub-journal */
--  Bitvec *pInJournal;         /* One bit for each page in the database file */
--  sqlite3_file *fd;           /* File descriptor for database */
--  sqlite3_file *jfd;          /* File descriptor for main journal */
--  sqlite3_file *sjfd;         /* File descriptor for sub-journal */
--  i64 journalOff;             /* Current write offset in the journal file */
--  i64 journalHdr;             /* Byte offset to previous journal header */
--  sqlite3_backup *pBackup;    /* Pointer to list of ongoing backup processes */
--  PagerSavepoint *aSavepoint; /* Array of active savepoints */
--  int nSavepoint;             /* Number of elements in aSavepoint[] */
--  u32 iDataVersion;           /* Changes whenever database content changes */
--  char dbFileVers[16];        /* Changes whenever database file changes */
-+/*
-+** Allowed values for RowSet.rsFlags
-+*/
-+#define ROWSET_SORTED  0x01   /* True if RowSet.pEntry is sorted */
-+#define ROWSET_NEXT    0x02   /* True if sqlite3RowSetNext() has been called */
- 
--  int nMmapOut;               /* Number of mmap pages currently outstanding */
--  sqlite3_int64 szMmap;       /* Desired maximum mmap size */
--  PgHdr *pMmapFreelist;       /* List of free mmap page headers (pDirty) */
--  /*
--  ** End of the routinely-changing class members
--  ***************************************************************************/
-+/*
-+** Turn bulk memory into a RowSet object.  N bytes of memory
-+** are available at pSpace.  The db pointer is used as a memory context
-+** for any subsequent allocations that need to occur.
-+** Return a pointer to the new RowSet object.
 +**
-+** It must be the case that N is sufficient to make a Rowset.  If not
-+** an assertion fault occurs.
-+** 
-+** If N is larger than the minimum, use the surplus as an initial
-+** allocation of entries available to be filled.
-+*/
-+SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
-+  RowSet *p;
-+  assert( N >= ROUND8(sizeof(*p)) );
-+  p = pSpace;
-+  p->pChunk = 0;
-+  p->db = db;
-+  p->pEntry = 0;
-+  p->pLast = 0;
-+  p->pForest = 0;
-+  p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
-+  p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
-+  p->rsFlags = ROWSET_SORTED;
-+  p->iBatch = 0;
-+  return p;
++*/
++static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
++  if( *pRc==SQLITE_OK ){
++    Fts5Structure *pStruct = *ppStruct;
++    int nLevel = pStruct->nLevel;
++    int nByte = (
++        sizeof(Fts5Structure) +                  /* Main structure */
++        sizeof(Fts5StructureLevel) * (nLevel+1)  /* aLevel[] array */
++    );
++
++    pStruct = sqlite3_realloc(pStruct, nByte);
++    if( pStruct ){
++      memset(&pStruct->aLevel[nLevel], 0, sizeof(Fts5StructureLevel));
++      pStruct->nLevel++;
++      *ppStruct = pStruct;
++    }else{
++      *pRc = SQLITE_NOMEM;
++    }
++  }
 +}
- 
--  u16 nExtra;                 /* Add this many bytes to each in-memory page */
--  i16 nReserve;               /* Number of unused bytes at end of each page */
--  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
--  u32 sectorSize;             /* Assumed sector size during rollback */
--  int pageSize;               /* Number of bytes in a page */
--  Pgno mxPgno;                /* Maximum allowed size of the database */
--  i64 journalSizeLimit;       /* Size limit for persistent journal files */
--  char *zFilename;            /* Name of the database file */
--  char *zJournal;             /* Name of the journal file */
--  int (*xBusyHandler)(void*); /* Function to call when busy */
--  void *pBusyHandlerArg;      /* Context argument for xBusyHandler */
--  int aStat[3];               /* Total cache hits, misses and writes */
--#ifdef SQLITE_TEST
--  int nRead;                  /* Database pages read */
--#endif
--  void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
--#ifdef SQLITE_HAS_CODEC
--  void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
--  void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
--  void (*xCodecFree)(void*);             /* Destructor for the codec */
--  void *pCodec;               /* First argument to xCodec... methods */
--#endif
--  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
--  PCache *pPCache;            /* Pointer to page cache object */
--#ifndef SQLITE_OMIT_WAL
--  Wal *pWal;                  /* Write-ahead log used by "journal_mode=wal" */
--  char *zWal;                 /* File name for write-ahead log */
--#endif
--};
++
 +/*
-+** Deallocate all chunks from a RowSet.  This frees all memory that
-+** the RowSet has allocated over its lifetime.  This routine is
-+** the destructor for the RowSet.
++** Extend level iLvl so that there is room for at least nExtra more
++** segments.
 +*/
-+SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
-+  struct RowSetChunk *pChunk, *pNextChunk;
-+  for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
-+    pNextChunk = pChunk->pNextChunk;
-+    sqlite3DbFree(p->db, pChunk);
++static void fts5StructureExtendLevel(
++  int *pRc, 
++  Fts5Structure *pStruct, 
++  int iLvl, 
++  int nExtra, 
++  int bInsert
++){
++  if( *pRc==SQLITE_OK ){
++    Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
++    Fts5StructureSegment *aNew;
++    int nByte;
++
++    nByte = (pLvl->nSeg + nExtra) * sizeof(Fts5StructureSegment);
++    aNew = sqlite3_realloc(pLvl->aSeg, nByte);
++    if( aNew ){
++      if( bInsert==0 ){
++        memset(&aNew[pLvl->nSeg], 0, sizeof(Fts5StructureSegment) * nExtra);
++      }else{
++        int nMove = pLvl->nSeg * sizeof(Fts5StructureSegment);
++        memmove(&aNew[nExtra], aNew, nMove);
++        memset(aNew, 0, sizeof(Fts5StructureSegment) * nExtra);
++      }
++      pLvl->aSeg = aNew;
++    }else{
++      *pRc = SQLITE_NOMEM;
++    }
 +  }
-+  p->pChunk = 0;
-+  p->nFresh = 0;
-+  p->pEntry = 0;
-+  p->pLast = 0;
-+  p->pForest = 0;
-+  p->rsFlags = ROWSET_SORTED;
 +}
- 
- /*
--** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains
--** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS 
--** or CACHE_WRITE to sqlite3_db_status().
-+** Allocate a new RowSetEntry object that is associated with the
-+** given RowSet.  Return a pointer to the new and completely uninitialized
-+** objected.
-+**
-+** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
-+** routine returns NULL.
- */
--#define PAGER_STAT_HIT   0
--#define PAGER_STAT_MISS  1
--#define PAGER_STAT_WRITE 2
-+static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
-+  assert( p!=0 );
-+  if( p->nFresh==0 ){
-+    struct RowSetChunk *pNew;
-+    pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew));
-+    if( pNew==0 ){
-+      return 0;
++
++static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){
++  Fts5Structure *pRet = 0;
++  Fts5Config *pConfig = p->pConfig;
++  int iCookie;                    /* Configuration cookie */
++  Fts5Data *pData;
++
++  pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
++  if( p->rc==SQLITE_OK ){
++    /* TODO: Do we need this if the leaf-index is appended? Probably... */
++    memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
++    p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
++    if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){
++      p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
++    }
++    fts5DataRelease(pData);
++    if( p->rc!=SQLITE_OK ){
++      fts5StructureRelease(pRet);
++      pRet = 0;
 +    }
-+    pNew->pNextChunk = p->pChunk;
-+    p->pChunk = pNew;
-+    p->pFresh = pNew->aEntry;
-+    p->nFresh = ROWSET_ENTRY_PER_CHUNK;
 +  }
-+  p->nFresh--;
-+  return p->pFresh++;
++
++  return pRet;
 +}
- 
- /*
--** The following global variables hold counters used for
--** testing purposes only.  These variables do not exist in
--** a non-testing build.  These variables are not thread-safe.
-+** Insert a new value into a RowSet.
-+**
-+** The mallocFailed flag of the database connection is set if a
-+** memory allocation fails.
- */
--#ifdef SQLITE_TEST
--SQLITE_API int sqlite3_pager_readdb_count = 0;    /* Number of full pages read from DB */
--SQLITE_API int sqlite3_pager_writedb_count = 0;   /* Number of full pages written to DB */
--SQLITE_API int sqlite3_pager_writej_count = 0;    /* Number of pages written to journal */
--# define PAGER_INCR(v)  v++
--#else
--# define PAGER_INCR(v)
--#endif
-+SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){
-+  struct RowSetEntry *pEntry;  /* The new entry */
-+  struct RowSetEntry *pLast;   /* The last prior entry */
- 
-+  /* This routine is never called after sqlite3RowSetNext() */
-+  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
- 
-+  pEntry = rowSetEntryAlloc(p);
-+  if( pEntry==0 ) return;
-+  pEntry->v = rowid;
-+  pEntry->pRight = 0;
-+  pLast = p->pLast;
-+  if( pLast ){
-+    if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){
-+      p->rsFlags &= ~ROWSET_SORTED;
++
++static i64 fts5IndexDataVersion(Fts5Index *p){
++  i64 iVersion = 0;
++
++  if( p->rc==SQLITE_OK ){
++    if( p->pDataVersion==0 ){
++      p->rc = fts5IndexPrepareStmt(p, &p->pDataVersion, 
++          sqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb)
++          );
++      if( p->rc ) return 0;
 +    }
-+    pLast->pRight = pEntry;
-+  }else{
-+    p->pEntry = pEntry;
++
++    if( SQLITE_ROW==sqlite3_step(p->pDataVersion) ){
++      iVersion = sqlite3_column_int64(p->pDataVersion, 0);
++    }
++    p->rc = sqlite3_reset(p->pDataVersion);
 +  }
-+  p->pLast = pEntry;
++
++  return iVersion;
 +}
- 
- /*
--** Journal files begin with the following magic string.  The data
--** was obtained from /dev/random.  It is used only as a sanity check.
--**
--** Since version 2.8.0, the journal format contains additional sanity
--** checking information.  If the power fails while the journal is being
--** written, semi-random garbage data might appear in the journal
--** file after power is restored.  If an attempt is then made
--** to roll the journal back, the database could be corrupted.  The additional
--** sanity checking data is an attempt to discover the garbage in the
--** journal and ignore it.
-+** Merge two lists of RowSetEntry objects.  Remove duplicates.
- **
--** The sanity checking information for the new journal format consists
--** of a 32-bit checksum on each page of data.  The checksum covers both
--** the page number and the pPager->pageSize bytes of data for the page.
--** This cksum is initialized to a 32-bit random value that appears in the
--** journal file right after the header.  The random initializer is important,
--** because garbage data that appears at the end of a journal is likely
--** data that was once in other files that have now been deleted.  If the
--** garbage data came from an obsolete journal file, the checksums might
--** be correct.  But by initializing the checksum to random value which
--** is different for every journal, we minimize that risk.
-+** The input lists are connected via pRight pointers and are 
-+** assumed to each already be in sorted order.
- */
--static const unsigned char aJournalMagic[] = {
--  0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,
--};
-+static struct RowSetEntry *rowSetEntryMerge(
-+  struct RowSetEntry *pA,    /* First sorted list to be merged */
-+  struct RowSetEntry *pB     /* Second sorted list to be merged */
-+){
-+  struct RowSetEntry head;
-+  struct RowSetEntry *pTail;
- 
--/*
--** The size of the of each page record in the journal is given by
--** the following macro.
--*/
--#define JOURNAL_PG_SZ(pPager)  ((pPager->pageSize) + 8)
-+  pTail = &head;
-+  while( pA && pB ){
-+    assert( pA->pRight==0 || pA->v<=pA->pRight->v );
-+    assert( pB->pRight==0 || pB->v<=pB->pRight->v );
-+    if( pA->v<pB->v ){
-+      pTail->pRight = pA;
-+      pA = pA->pRight;
-+      pTail = pTail->pRight;
-+    }else if( pB->v<pA->v ){
-+      pTail->pRight = pB;
-+      pB = pB->pRight;
-+      pTail = pTail->pRight;
-+    }else{
-+      pA = pA->pRight;
++
++/*
++** Read, deserialize and return the structure record.
++**
++** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array
++** are over-allocated as described for function fts5StructureDecode() 
++** above.
++**
++** If an error occurs, NULL is returned and an error code left in the
++** Fts5Index handle. If an error has already occurred when this function
++** is called, it is a no-op.
++*/
++static Fts5Structure *fts5StructureRead(Fts5Index *p){
++
++  if( p->pStruct==0 ){
++    p->iStructVersion = fts5IndexDataVersion(p);
++    if( p->rc==SQLITE_OK ){
++      p->pStruct = fts5StructureReadUncached(p);
 +    }
 +  }
-+  if( pA ){
-+    assert( pA->pRight==0 || pA->v<=pA->pRight->v );
-+    pTail->pRight = pA;
-+  }else{
-+    assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v );
-+    pTail->pRight = pB;
++
++#if 0
++  else{
++    Fts5Structure *pTest = fts5StructureReadUncached(p);
++    if( pTest ){
++      int i, j;
++      assert_nc( p->pStruct->nSegment==pTest->nSegment );
++      assert_nc( p->pStruct->nLevel==pTest->nLevel );
++      for(i=0; i<pTest->nLevel; i++){
++        assert_nc( p->pStruct->aLevel[i].nMerge==pTest->aLevel[i].nMerge );
++        assert_nc( p->pStruct->aLevel[i].nSeg==pTest->aLevel[i].nSeg );
++        for(j=0; j<pTest->aLevel[i].nSeg; j++){
++          Fts5StructureSegment *p1 = &pTest->aLevel[i].aSeg[j];
++          Fts5StructureSegment *p2 = &p->pStruct->aLevel[i].aSeg[j];
++          assert_nc( p1->iSegid==p2->iSegid );
++          assert_nc( p1->pgnoFirst==p2->pgnoFirst );
++          assert_nc( p1->pgnoLast==p2->pgnoLast );
++        }
++      }
++      fts5StructureRelease(pTest);
++    }
 +  }
-+  return head.pRight;
++#endif
++
++  if( p->rc!=SQLITE_OK ) return 0;
++  assert( p->iStructVersion!=0 );
++  assert( p->pStruct!=0 );
++  fts5StructureRef(p->pStruct);
++  return p->pStruct;
 +}
- 
- /*
--** The journal header size for this pager. This is usually the same 
--** size as a single disk sector. See also setSectorSize().
--*/
--#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize)
-+** Sort all elements on the list of RowSetEntry objects into order of
-+** increasing v.
-+*/ 
-+static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){
-+  unsigned int i;
-+  struct RowSetEntry *pNext, *aBucket[40];
- 
--/*
--** The macro MEMDB is true if we are dealing with an in-memory database.
--** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set,
--** the value of MEMDB will be a constant and the compiler will optimize
--** out code that would never execute.
--*/
--#ifdef SQLITE_OMIT_MEMORYDB
--# define MEMDB 0
--#else
--# define MEMDB pPager->memDb
--#endif
-+  memset(aBucket, 0, sizeof(aBucket));
-+  while( pIn ){
-+    pNext = pIn->pRight;
-+    pIn->pRight = 0;
-+    for(i=0; aBucket[i]; i++){
-+      pIn = rowSetEntryMerge(aBucket[i], pIn);
-+      aBucket[i] = 0;
++
++static void fts5StructureInvalidate(Fts5Index *p){
++  if( p->pStruct ){
++    fts5StructureRelease(p->pStruct);
++    p->pStruct = 0;
++  }
++}
++
++/*
++** Return the total number of segments in index structure pStruct. This
++** function is only ever used as part of assert() conditions.
++*/
++#ifdef SQLITE_DEBUG
++static int fts5StructureCountSegments(Fts5Structure *pStruct){
++  int nSegment = 0;               /* Total number of segments */
++  if( pStruct ){
++    int iLvl;                     /* Used to iterate through levels */
++    for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
++      nSegment += pStruct->aLevel[iLvl].nSeg;
 +    }
-+    aBucket[i] = pIn;
-+    pIn = pNext;
 +  }
-+  pIn = 0;
-+  for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
-+    pIn = rowSetEntryMerge(pIn, aBucket[i]);
++
++  return nSegment;
++}
++#endif
++
++#define fts5BufferSafeAppendBlob(pBuf, pBlob, nBlob) {     \
++  assert( (pBuf)->nSpace>=((pBuf)->n+nBlob) );             \
++  memcpy(&(pBuf)->p[(pBuf)->n], pBlob, nBlob);             \
++  (pBuf)->n += nBlob;                                      \
++}
++
++#define fts5BufferSafeAppendVarint(pBuf, iVal) {                \
++  (pBuf)->n += sqlite3Fts5PutVarint(&(pBuf)->p[(pBuf)->n], (iVal));  \
++  assert( (pBuf)->nSpace>=(pBuf)->n );                          \
++}
++
++
++/*
++** Serialize and store the "structure" record.
++**
++** If an error occurs, leave an error code in the Fts5Index object. If an
++** error has already occurred, this function is a no-op.
++*/
++static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){
++  if( p->rc==SQLITE_OK ){
++    Fts5Buffer buf;               /* Buffer to serialize record into */
++    int iLvl;                     /* Used to iterate through levels */
++    int iCookie;                  /* Cookie value to store */
++
++    assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
++    memset(&buf, 0, sizeof(Fts5Buffer));
++
++    /* Append the current configuration cookie */
++    iCookie = p->pConfig->iCookie;
++    if( iCookie<0 ) iCookie = 0;
++
++    if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){
++      sqlite3Fts5Put32(buf.p, iCookie);
++      buf.n = 4;
++      fts5BufferSafeAppendVarint(&buf, pStruct->nLevel);
++      fts5BufferSafeAppendVarint(&buf, pStruct->nSegment);
++      fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter);
++    }
++
++    for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
++      int iSeg;                     /* Used to iterate through segments */
++      Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
++      fts5BufferAppendVarint(&p->rc, &buf, pLvl->nMerge);
++      fts5BufferAppendVarint(&p->rc, &buf, pLvl->nSeg);
++      assert( pLvl->nMerge<=pLvl->nSeg );
++
++      for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
++        fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].iSegid);
++        fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoFirst);
++        fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoLast);
++      }
++    }
++
++    fts5DataWrite(p, FTS5_STRUCTURE_ROWID, buf.p, buf.n);
++    fts5BufferFree(&buf);
 +  }
-+  return pIn;
 +}
- 
--/*
--** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch
--** interfaces to access the database using memory-mapped I/O.
--*/
--#if SQLITE_MAX_MMAP_SIZE>0
--# define USEFETCH(x) ((x)->bUseFetch)
--#else
--# define USEFETCH(x) 0
--#endif
- 
- /*
--** The maximum legal page number is (2^31 - 1).
-+** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects.
-+** Convert this tree into a linked list connected by the pRight pointers
-+** and return pointers to the first and last elements of the new list.
- */
--#define PAGER_MAX_PGNO 2147483647
-+static void rowSetTreeToList(
-+  struct RowSetEntry *pIn,         /* Root of the input tree */
-+  struct RowSetEntry **ppFirst,    /* Write head of the output list here */
-+  struct RowSetEntry **ppLast      /* Write tail of the output list here */
++
++#if 0
++static void fts5DebugStructure(int*,Fts5Buffer*,Fts5Structure*);
++static void fts5PrintStructure(const char *zCaption, Fts5Structure *pStruct){
++  int rc = SQLITE_OK;
++  Fts5Buffer buf;
++  memset(&buf, 0, sizeof(buf));
++  fts5DebugStructure(&rc, &buf, pStruct);
++  fprintf(stdout, "%s: %s\n", zCaption, buf.p);
++  fflush(stdout);
++  fts5BufferFree(&buf);
++}
++#else
++# define fts5PrintStructure(x,y)
++#endif
++
++static int fts5SegmentSize(Fts5StructureSegment *pSeg){
++  return 1 + pSeg->pgnoLast - pSeg->pgnoFirst;
++}
++
++/*
++** Return a copy of index structure pStruct. Except, promote as many 
++** segments as possible to level iPromote. If an OOM occurs, NULL is 
++** returned.
++*/
++static void fts5StructurePromoteTo(
++  Fts5Index *p,
++  int iPromote,
++  int szPromote,
++  Fts5Structure *pStruct
 +){
-+  assert( pIn!=0 );
-+  if( pIn->pLeft ){
-+    struct RowSetEntry *p;
-+    rowSetTreeToList(pIn->pLeft, ppFirst, &p);
-+    p->pRight = pIn;
-+  }else{
-+    *ppFirst = pIn;
-+  }
-+  if( pIn->pRight ){
-+    rowSetTreeToList(pIn->pRight, &pIn->pRight, ppLast);
-+  }else{
-+    *ppLast = pIn;
++  int il, is;
++  Fts5StructureLevel *pOut = &pStruct->aLevel[iPromote];
++
++  if( pOut->nMerge==0 ){
++    for(il=iPromote+1; il<pStruct->nLevel; il++){
++      Fts5StructureLevel *pLvl = &pStruct->aLevel[il];
++      if( pLvl->nMerge ) return;
++      for(is=pLvl->nSeg-1; is>=0; is--){
++        int sz = fts5SegmentSize(&pLvl->aSeg[is]);
++        if( sz>szPromote ) return;
++        fts5StructureExtendLevel(&p->rc, pStruct, iPromote, 1, 1);
++        if( p->rc ) return;
++        memcpy(pOut->aSeg, &pLvl->aSeg[is], sizeof(Fts5StructureSegment));
++        pOut->nSeg++;
++        pLvl->nSeg--;
++      }
++    }
 +  }
-+  assert( (*ppLast)->pRight==0 );
 +}
 +
- 
- /*
--** The argument to this macro is a file descriptor (type sqlite3_file*).
--** Return 0 if it is not open, or non-zero (but not 1) if it is.
--**
--** This is so that expressions can be written as:
--**
--**   if( isOpen(pPager->jfd) ){ ...
-+** Convert a sorted list of elements (connected by pRight) into a binary
-+** tree with depth of iDepth.  A depth of 1 means the tree contains a single
-+** node taken from the head of *ppList.  A depth of 2 means a tree with
-+** three nodes.  And so forth.
- **
--** instead of
-+** Use as many entries from the input list as required and update the
-+** *ppList to point to the unused elements of the list.  If the input
-+** list contains too few elements, then construct an incomplete tree
-+** and leave *ppList set to NULL.
- **
--**   if( pPager->jfd->pMethods ){ ...
-+** Return a pointer to the root of the constructed binary tree.
- */
--#define isOpen(pFd) ((pFd)->pMethods)
-+static struct RowSetEntry *rowSetNDeepTree(
-+  struct RowSetEntry **ppList,
-+  int iDepth
++/*
++** A new segment has just been written to level iLvl of index structure
++** pStruct. This function determines if any segments should be promoted
++** as a result. Segments are promoted in two scenarios:
++**
++**   a) If the segment just written is smaller than one or more segments
++**      within the previous populated level, it is promoted to the previous
++**      populated level.
++**
++**   b) If the segment just written is larger than the newest segment on
++**      the next populated level, then that segment, and any other adjacent
++**      segments that are also smaller than the one just written, are 
++**      promoted. 
++**
++** If one or more segments are promoted, the structure object is updated
++** to reflect this.
++*/
++static void fts5StructurePromote(
++  Fts5Index *p,                   /* FTS5 backend object */
++  int iLvl,                       /* Index level just updated */
++  Fts5Structure *pStruct          /* Index structure */
 +){
-+  struct RowSetEntry *p;         /* Root of the new tree */
-+  struct RowSetEntry *pLeft;     /* Left subtree */
-+  if( *ppList==0 ){
-+    return 0;
-+  }
-+  if( iDepth==1 ){
-+    p = *ppList;
-+    *ppList = p->pRight;
-+    p->pLeft = p->pRight = 0;
-+    return p;
-+  }
-+  pLeft = rowSetNDeepTree(ppList, iDepth-1);
-+  p = *ppList;
-+  if( p==0 ){
-+    return pLeft;
++  if( p->rc==SQLITE_OK ){
++    int iTst;
++    int iPromote = -1;
++    int szPromote = 0;            /* Promote anything this size or smaller */
++    Fts5StructureSegment *pSeg;   /* Segment just written */
++    int szSeg;                    /* Size of segment just written */
++    int nSeg = pStruct->aLevel[iLvl].nSeg;
++
++    if( nSeg==0 ) return;
++    pSeg = &pStruct->aLevel[iLvl].aSeg[pStruct->aLevel[iLvl].nSeg-1];
++    szSeg = (1 + pSeg->pgnoLast - pSeg->pgnoFirst);
++
++    /* Check for condition (a) */
++    for(iTst=iLvl-1; iTst>=0 && pStruct->aLevel[iTst].nSeg==0; iTst--);
++    if( iTst>=0 ){
++      int i;
++      int szMax = 0;
++      Fts5StructureLevel *pTst = &pStruct->aLevel[iTst];
++      assert( pTst->nMerge==0 );
++      for(i=0; i<pTst->nSeg; i++){
++        int sz = pTst->aSeg[i].pgnoLast - pTst->aSeg[i].pgnoFirst + 1;
++        if( sz>szMax ) szMax = sz;
++      }
++      if( szMax>=szSeg ){
++        /* Condition (a) is true. Promote the newest segment on level 
++        ** iLvl to level iTst.  */
++        iPromote = iTst;
++        szPromote = szMax;
++      }
++    }
++
++    /* If condition (a) is not met, assume (b) is true. StructurePromoteTo()
++    ** is a no-op if it is not.  */
++    if( iPromote<0 ){
++      iPromote = iLvl;
++      szPromote = szSeg;
++    }
++    fts5StructurePromoteTo(p, iPromote, szPromote, pStruct);
 +  }
-+  p->pLeft = pLeft;
-+  *ppList = p->pRight;
-+  p->pRight = rowSetNDeepTree(ppList, iDepth-1);
-+  return p;
 +}
- 
- /*
--** Return true if this pager uses a write-ahead log instead of the usual
--** rollback journal. Otherwise false.
-+** Convert a sorted list of elements into a binary tree. Make the tree
-+** as deep as it needs to be in order to contain the entire list.
- */
--#ifndef SQLITE_OMIT_WAL
--static int pagerUseWal(Pager *pPager){
--  return (pPager->pWal!=0);
-+static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
-+  int iDepth;           /* Depth of the tree so far */
-+  struct RowSetEntry *p;       /* Current tree root */
-+  struct RowSetEntry *pLeft;   /* Left subtree */
-+
-+  assert( pList!=0 );
-+  p = pList;
-+  pList = p->pRight;
-+  p->pLeft = p->pRight = 0;
-+  for(iDepth=1; pList; iDepth++){
-+    pLeft = p;
-+    p = pList;
-+    pList = p->pRight;
-+    p->pLeft = pLeft;
-+    p->pRight = rowSetNDeepTree(&pList, iDepth);
-+  }
-+  return p;
- }
--#else
--# define pagerUseWal(x) 0
--# define pagerRollbackWal(x) 0
--# define pagerWalFrames(v,w,x,y) 0
--# define pagerOpenWalIfPresent(z) SQLITE_OK
--# define pagerBeginReadTransaction(z) SQLITE_OK
--#endif
- 
--#ifndef NDEBUG 
- /*
--** Usage:
--**
--**   assert( assert_pager_state(pPager) );
-+** Take all the entries on p->pEntry and on the trees in p->pForest and
-+** sort them all together into one big ordered list on p->pEntry.
- **
--** This function runs many asserts to try to find inconsistencies in
--** the internal state of the Pager object.
-+** This routine should only be called once in the life of a RowSet.
- */
--static int assert_pager_state(Pager *p){
--  Pager *pPager = p;
--
--  /* State must be valid. */
--  assert( p->eState==PAGER_OPEN
--       || p->eState==PAGER_READER
--       || p->eState==PAGER_WRITER_LOCKED
--       || p->eState==PAGER_WRITER_CACHEMOD
--       || p->eState==PAGER_WRITER_DBMOD
--       || p->eState==PAGER_WRITER_FINISHED
--       || p->eState==PAGER_ERROR
--  );
--
--  /* Regardless of the current state, a temp-file connection always behaves
--  ** as if it has an exclusive lock on the database file. It never updates
--  ** the change-counter field, so the changeCountDone flag is always set.
--  */
--  assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK );
--  assert( p->tempFile==0 || pPager->changeCountDone );
-+static void rowSetToList(RowSet *p){
- 
--  /* If the useJournal flag is clear, the journal-mode must be "OFF". 
--  ** And if the journal-mode is "OFF", the journal file must not be open.
--  */
--  assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal );
--  assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) );
-+  /* This routine is called only once */
-+  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
- 
--  /* Check that MEMDB implies noSync. And an in-memory journal. Since 
--  ** this means an in-memory pager performs no IO at all, it cannot encounter 
--  ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing 
--  ** a journal file. (although the in-memory journal implementation may 
--  ** return SQLITE_IOERR_NOMEM while the journal file is being written). It 
--  ** is therefore not possible for an in-memory pager to enter the ERROR 
--  ** state.
--  */
--  if( MEMDB ){
--    assert( p->noSync );
--    assert( p->journalMode==PAGER_JOURNALMODE_OFF 
--         || p->journalMode==PAGER_JOURNALMODE_MEMORY 
--    );
--    assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN );
--    assert( pagerUseWal(p)==0 );
-+  if( (p->rsFlags & ROWSET_SORTED)==0 ){
-+    p->pEntry = rowSetEntrySort(p->pEntry);
-   }
- 
--  /* If changeCountDone is set, a RESERVED lock or greater must be held
--  ** on the file.
--  */
--  assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK );
--  assert( p->eLock!=PENDING_LOCK );
--
--  switch( p->eState ){
--    case PAGER_OPEN:
--      assert( !MEMDB );
--      assert( pPager->errCode==SQLITE_OK );
--      assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile );
--      break;
--
--    case PAGER_READER:
--      assert( pPager->errCode==SQLITE_OK );
--      assert( p->eLock!=UNKNOWN_LOCK );
--      assert( p->eLock>=SHARED_LOCK );
--      break;
--
--    case PAGER_WRITER_LOCKED:
--      assert( p->eLock!=UNKNOWN_LOCK );
--      assert( pPager->errCode==SQLITE_OK );
--      if( !pagerUseWal(pPager) ){
--        assert( p->eLock>=RESERVED_LOCK );
--      }
--      assert( pPager->dbSize==pPager->dbOrigSize );
--      assert( pPager->dbOrigSize==pPager->dbFileSize );
--      assert( pPager->dbOrigSize==pPager->dbHintSize );
--      assert( pPager->setMaster==0 );
--      break;
--
--    case PAGER_WRITER_CACHEMOD:
--      assert( p->eLock!=UNKNOWN_LOCK );
--      assert( pPager->errCode==SQLITE_OK );
--      if( !pagerUseWal(pPager) ){
--        /* It is possible that if journal_mode=wal here that neither the
--        ** journal file nor the WAL file are open. This happens during
--        ** a rollback transaction that switches from journal_mode=off
--        ** to journal_mode=wal.
--        */
--        assert( p->eLock>=RESERVED_LOCK );
--        assert( isOpen(p->jfd) 
--             || p->journalMode==PAGER_JOURNALMODE_OFF 
--             || p->journalMode==PAGER_JOURNALMODE_WAL 
--        );
--      }
--      assert( pPager->dbOrigSize==pPager->dbFileSize );
--      assert( pPager->dbOrigSize==pPager->dbHintSize );
--      break;
--
--    case PAGER_WRITER_DBMOD:
--      assert( p->eLock==EXCLUSIVE_LOCK );
--      assert( pPager->errCode==SQLITE_OK );
--      assert( !pagerUseWal(pPager) );
--      assert( p->eLock>=EXCLUSIVE_LOCK );
--      assert( isOpen(p->jfd) 
--           || p->journalMode==PAGER_JOURNALMODE_OFF 
--           || p->journalMode==PAGER_JOURNALMODE_WAL 
--      );
--      assert( pPager->dbOrigSize<=pPager->dbHintSize );
--      break;
--
--    case PAGER_WRITER_FINISHED:
--      assert( p->eLock==EXCLUSIVE_LOCK );
--      assert( pPager->errCode==SQLITE_OK );
--      assert( !pagerUseWal(pPager) );
--      assert( isOpen(p->jfd) 
--           || p->journalMode==PAGER_JOURNALMODE_OFF 
--           || p->journalMode==PAGER_JOURNALMODE_WAL 
--      );
--      break;
--
--    case PAGER_ERROR:
--      /* There must be at least one outstanding reference to the pager if
--      ** in ERROR state. Otherwise the pager should have already dropped
--      ** back to OPEN state.
--      */
--      assert( pPager->errCode!=SQLITE_OK );
--      assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
--      break;
-+  /* While this module could theoretically support it, sqlite3RowSetNext()
-+  ** is never called after sqlite3RowSetText() for the same RowSet.  So
-+  ** there is never a forest to deal with.  Should this change, simply
-+  ** remove the assert() and the #if 0. */
-+  assert( p->pForest==0 );
-+#if 0
-+  while( p->pForest ){
-+    struct RowSetEntry *pTree = p->pForest->pLeft;
-+    if( pTree ){
-+      struct RowSetEntry *pHead, *pTail;
-+      rowSetTreeToList(pTree, &pHead, &pTail);
-+      p->pEntry = rowSetEntryMerge(p->pEntry, pHead);
++
++
++/*
++** Advance the iterator passed as the only argument. If the end of the 
++** doclist-index page is reached, return non-zero.
++*/
++static int fts5DlidxLvlNext(Fts5DlidxLvl *pLvl){
++  Fts5Data *pData = pLvl->pData;
++
++  if( pLvl->iOff==0 ){
++    assert( pLvl->bEof==0 );
++    pLvl->iOff = 1;
++    pLvl->iOff += fts5GetVarint32(&pData->p[1], pLvl->iLeafPgno);
++    pLvl->iOff += fts5GetVarint(&pData->p[pLvl->iOff], (u64*)&pLvl->iRowid);
++    pLvl->iFirstOff = pLvl->iOff;
++  }else{
++    int iOff;
++    for(iOff=pLvl->iOff; iOff<pData->nn; iOff++){
++      if( pData->p[iOff] ) break; 
 +    }
-+    p->pForest = p->pForest->pRight;
-   }
--
--  return 1;
-+#endif
-+  p->rsFlags |= ROWSET_NEXT;  /* Verify this routine is never called again */
- }
--#endif /* ifndef NDEBUG */
- 
--#ifdef SQLITE_DEBUG 
- /*
--** Return a pointer to a human readable string in a static buffer
--** containing the state of the Pager object passed as an argument. This
--** is intended to be used within debuggers. For example, as an alternative
--** to "print *pPager" in gdb:
-+** Extract the smallest element from the RowSet.
-+** Write the element into *pRowid.  Return 1 on success.  Return
-+** 0 if the RowSet is already empty.
- **
--** (gdb) printf "%s", print_pager_state(pPager)
-+** After this routine has been called, the sqlite3RowSetInsert()
-+** routine may not be called again.  
- */
--static char *print_pager_state(Pager *p){
--  static char zRet[1024];
-+SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
-+  assert( p!=0 );
- 
--  sqlite3_snprintf(1024, zRet,
--      "Filename:      %s\n"
--      "State:         %s errCode=%d\n"
--      "Lock:          %s\n"
--      "Locking mode:  locking_mode=%s\n"
--      "Journal mode:  journal_mode=%s\n"
--      "Backing store: tempFile=%d memDb=%d useJournal=%d\n"
--      "Journal:       journalOff=%lld journalHdr=%lld\n"
--      "Size:          dbsize=%d dbOrigSize=%d dbFileSize=%d\n"
--      , p->zFilename
--      , p->eState==PAGER_OPEN            ? "OPEN" :
--        p->eState==PAGER_READER          ? "READER" :
--        p->eState==PAGER_WRITER_LOCKED   ? "WRITER_LOCKED" :
--        p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" :
--        p->eState==PAGER_WRITER_DBMOD    ? "WRITER_DBMOD" :
--        p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" :
--        p->eState==PAGER_ERROR           ? "ERROR" : "?error?"
--      , (int)p->errCode
--      , p->eLock==NO_LOCK         ? "NO_LOCK" :
--        p->eLock==RESERVED_LOCK   ? "RESERVED" :
--        p->eLock==EXCLUSIVE_LOCK  ? "EXCLUSIVE" :
--        p->eLock==SHARED_LOCK     ? "SHARED" :
--        p->eLock==UNKNOWN_LOCK    ? "UNKNOWN" : "?error?"
--      , p->exclusiveMode ? "exclusive" : "normal"
--      , p->journalMode==PAGER_JOURNALMODE_MEMORY   ? "memory" :
--        p->journalMode==PAGER_JOURNALMODE_OFF      ? "off" :
--        p->journalMode==PAGER_JOURNALMODE_DELETE   ? "delete" :
--        p->journalMode==PAGER_JOURNALMODE_PERSIST  ? "persist" :
--        p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" :
--        p->journalMode==PAGER_JOURNALMODE_WAL      ? "wal" : "?error?"
--      , (int)p->tempFile, (int)p->memDb, (int)p->useJournal
--      , p->journalOff, p->journalHdr
--      , (int)p->dbSize, (int)p->dbOrigSize, (int)p->dbFileSize
--  );
-+  /* Merge the forest into a single sorted list on first call */
-+  if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p);
- 
--  return zRet;
-+  /* Return the next entry on the list */
-+  if( p->pEntry ){
-+    *pRowid = p->pEntry->v;
-+    p->pEntry = p->pEntry->pRight;
-+    if( p->pEntry==0 ){
-+      sqlite3RowSetClear(p);
++
++    if( iOff<pData->nn ){
++      i64 iVal;
++      pLvl->iLeafPgno += (iOff - pLvl->iOff) + 1;
++      iOff += fts5GetVarint(&pData->p[iOff], (u64*)&iVal);
++      pLvl->iRowid += iVal;
++      pLvl->iOff = iOff;
++    }else{
++      pLvl->bEof = 1;
++    }
++  }
++
++  return pLvl->bEof;
++}
++
++/*
++** Advance the iterator passed as the only argument.
++*/
++static int fts5DlidxIterNextR(Fts5Index *p, Fts5DlidxIter *pIter, int iLvl){
++  Fts5DlidxLvl *pLvl = &pIter->aLvl[iLvl];
++
++  assert( iLvl<pIter->nLvl );
++  if( fts5DlidxLvlNext(pLvl) ){
++    if( (iLvl+1) < pIter->nLvl ){
++      fts5DlidxIterNextR(p, pIter, iLvl+1);
++      if( pLvl[1].bEof==0 ){
++        fts5DataRelease(pLvl->pData);
++        memset(pLvl, 0, sizeof(Fts5DlidxLvl));
++        pLvl->pData = fts5DataRead(p, 
++            FTS5_DLIDX_ROWID(pIter->iSegid, iLvl, pLvl[1].iLeafPgno)
++        );
++        if( pLvl->pData ) fts5DlidxLvlNext(pLvl);
++      }
 +    }
-+    return 1;
-+  }else{
-+    return 0;
 +  }
- }
--#endif
- 
- /*
--** Return true if it is necessary to write page *pPg into the sub-journal.
--** A page needs to be written into the sub-journal if there exists one
--** or more open savepoints for which:
-+** Check to see if element iRowid was inserted into the rowset as
-+** part of any insert batch prior to iBatch.  Return 1 or 0.
- **
--**   * The page-number is less than or equal to PagerSavepoint.nOrig, and
--**   * The bit corresponding to the page-number is not set in
--**     PagerSavepoint.pInSavepoint.
-+** If this is the first test of a new batch and if there exist entries
-+** on pRowSet->pEntry, then sort those entries into the forest at
-+** pRowSet->pForest so that they can be tested.
- */
--static int subjRequiresPage(PgHdr *pPg){
--  Pager *pPager = pPg->pPager;
--  PagerSavepoint *p;
--  Pgno pgno = pPg->pgno;
--  int i;
--  for(i=0; i<pPager->nSavepoint; i++){
--    p = &pPager->aSavepoint[i];
--    if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
--      return 1;
-+SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){
-+  struct RowSetEntry *p, *pTree;
 +
-+  /* This routine is never called after sqlite3RowSetNext() */
-+  assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
++  return pIter->aLvl[0].bEof;
++}
++static int fts5DlidxIterNext(Fts5Index *p, Fts5DlidxIter *pIter){
++  return fts5DlidxIterNextR(p, pIter, 0);
++}
++
++/*
++** The iterator passed as the first argument has the following fields set
++** as follows. This function sets up the rest of the iterator so that it
++** points to the first rowid in the doclist-index.
++**
++**   pData:
++**     pointer to doclist-index record, 
++**
++** When this function is called pIter->iLeafPgno is the page number the
++** doclist is associated with (the one featuring the term).
++*/
++static int fts5DlidxIterFirst(Fts5DlidxIter *pIter){
++  int i;
++  for(i=0; i<pIter->nLvl; i++){
++    fts5DlidxLvlNext(&pIter->aLvl[i]);
++  }
++  return pIter->aLvl[0].bEof;
++}
++
 +
-+  /* Sort entries into the forest on the first test of a new batch 
-+  */
-+  if( iBatch!=pRowSet->iBatch ){
-+    p = pRowSet->pEntry;
-+    if( p ){
-+      struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
-+      if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){
-+        p = rowSetEntrySort(p);
-+      }
-+      for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
-+        ppPrevTree = &pTree->pRight;
-+        if( pTree->pLeft==0 ){
-+          pTree->pLeft = rowSetListToTree(p);
-+          break;
-+        }else{
-+          struct RowSetEntry *pAux, *pTail;
-+          rowSetTreeToList(pTree->pLeft, &pAux, &pTail);
-+          pTree->pLeft = 0;
-+          p = rowSetEntryMerge(pAux, p);
-+        }
++static int fts5DlidxIterEof(Fts5Index *p, Fts5DlidxIter *pIter){
++  return p->rc!=SQLITE_OK || pIter->aLvl[0].bEof;
++}
++
++static void fts5DlidxIterLast(Fts5Index *p, Fts5DlidxIter *pIter){
++  int i;
++
++  /* Advance each level to the last entry on the last page */
++  for(i=pIter->nLvl-1; p->rc==SQLITE_OK && i>=0; i--){
++    Fts5DlidxLvl *pLvl = &pIter->aLvl[i];
++    while( fts5DlidxLvlNext(pLvl)==0 );
++    pLvl->bEof = 0;
++
++    if( i>0 ){
++      Fts5DlidxLvl *pChild = &pLvl[-1];
++      fts5DataRelease(pChild->pData);
++      memset(pChild, 0, sizeof(Fts5DlidxLvl));
++      pChild->pData = fts5DataRead(p, 
++          FTS5_DLIDX_ROWID(pIter->iSegid, i-1, pLvl->iLeafPgno)
++      );
++    }
++  }
++}
++
++/*
++** Move the iterator passed as the only argument to the previous entry.
++*/
++static int fts5DlidxLvlPrev(Fts5DlidxLvl *pLvl){
++  int iOff = pLvl->iOff;
++
++  assert( pLvl->bEof==0 );
++  if( iOff<=pLvl->iFirstOff ){
++    pLvl->bEof = 1;
++  }else{
++    u8 *a = pLvl->pData->p;
++    i64 iVal;
++    int iLimit;
++    int ii;
++    int nZero = 0;
++
++    /* Currently iOff points to the first byte of a varint. This block 
++    ** decrements iOff until it points to the first byte of the previous 
++    ** varint. Taking care not to read any memory locations that occur
++    ** before the buffer in memory.  */
++    iLimit = (iOff>9 ? iOff-9 : 0);
++    for(iOff--; iOff>iLimit; iOff--){
++      if( (a[iOff-1] & 0x80)==0 ) break;
++    }
++
++    fts5GetVarint(&a[iOff], (u64*)&iVal);
++    pLvl->iRowid -= iVal;
++    pLvl->iLeafPgno--;
++
++    /* Skip backwards past any 0x00 varints. */
++    for(ii=iOff-1; ii>=pLvl->iFirstOff && a[ii]==0x00; ii--){
++      nZero++;
++    }
++    if( ii>=pLvl->iFirstOff && (a[ii] & 0x80) ){
++      /* The byte immediately before the last 0x00 byte has the 0x80 bit
++      ** set. So the last 0x00 is only a varint 0 if there are 8 more 0x80
++      ** bytes before a[ii]. */
++      int bZero = 0;              /* True if last 0x00 counts */
++      if( (ii-8)>=pLvl->iFirstOff ){
++        int j;
++        for(j=1; j<=8 && (a[ii-j] & 0x80); j++);
++        bZero = (j>8);
 +      }
-+      if( pTree==0 ){
-+        *ppPrevTree = pTree = rowSetEntryAlloc(pRowSet);
-+        if( pTree ){
-+          pTree->v = 0;
-+          pTree->pRight = 0;
-+          pTree->pLeft = rowSetListToTree(p);
++      if( bZero==0 ) nZero--;
++    }
++    pLvl->iLeafPgno -= nZero;
++    pLvl->iOff = iOff - nZero;
++  }
++
++  return pLvl->bEof;
++}
++
++static int fts5DlidxIterPrevR(Fts5Index *p, Fts5DlidxIter *pIter, int iLvl){
++  Fts5DlidxLvl *pLvl = &pIter->aLvl[iLvl];
++
++  assert( iLvl<pIter->nLvl );
++  if( fts5DlidxLvlPrev(pLvl) ){
++    if( (iLvl+1) < pIter->nLvl ){
++      fts5DlidxIterPrevR(p, pIter, iLvl+1);
++      if( pLvl[1].bEof==0 ){
++        fts5DataRelease(pLvl->pData);
++        memset(pLvl, 0, sizeof(Fts5DlidxLvl));
++        pLvl->pData = fts5DataRead(p, 
++            FTS5_DLIDX_ROWID(pIter->iSegid, iLvl, pLvl[1].iLeafPgno)
++        );
++        if( pLvl->pData ){
++          while( fts5DlidxLvlNext(pLvl)==0 );
++          pLvl->bEof = 0;
 +        }
 +      }
-+      pRowSet->pEntry = 0;
-+      pRowSet->pLast = 0;
-+      pRowSet->rsFlags |= ROWSET_SORTED;
 +    }
-+    pRowSet->iBatch = iBatch;
 +  }
 +
-+  /* Test to see if the iRowid value appears anywhere in the forest.
-+  ** Return 1 if it does and 0 if not.
-+  */
-+  for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
-+    p = pTree->pLeft;
-+    while( p ){
-+      if( p->v<iRowid ){
-+        p = p->pRight;
-+      }else if( p->v>iRowid ){
-+        p = p->pLeft;
-+      }else{
-+        return 1;
++  return pIter->aLvl[0].bEof;
++}
++static int fts5DlidxIterPrev(Fts5Index *p, Fts5DlidxIter *pIter){
++  return fts5DlidxIterPrevR(p, pIter, 0);
++}
++
++/*
++** Free a doclist-index iterator object allocated by fts5DlidxIterInit().
++*/
++static void fts5DlidxIterFree(Fts5DlidxIter *pIter){
++  if( pIter ){
++    int i;
++    for(i=0; i<pIter->nLvl; i++){
++      fts5DataRelease(pIter->aLvl[i].pData);
++    }
++    sqlite3_free(pIter);
++  }
++}
++
++static Fts5DlidxIter *fts5DlidxIterInit(
++  Fts5Index *p,                   /* Fts5 Backend to iterate within */
++  int bRev,                       /* True for ORDER BY ASC */
++  int iSegid,                     /* Segment id */
++  int iLeafPg                     /* Leaf page number to load dlidx for */
++){
++  Fts5DlidxIter *pIter = 0;
++  int i;
++  int bDone = 0;
++
++  for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
++    int nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl);
++    Fts5DlidxIter *pNew;
++
++    pNew = (Fts5DlidxIter*)sqlite3_realloc(pIter, nByte);
++    if( pNew==0 ){
++      p->rc = SQLITE_NOMEM;
++    }else{
++      i64 iRowid = FTS5_DLIDX_ROWID(iSegid, i, iLeafPg);
++      Fts5DlidxLvl *pLvl = &pNew->aLvl[i];
++      pIter = pNew;
++      memset(pLvl, 0, sizeof(Fts5DlidxLvl));
++      pLvl->pData = fts5DataRead(p, iRowid);
++      if( pLvl->pData && (pLvl->pData->p[0] & 0x0001)==0 ){
++        bDone = 1;
 +      }
-     }
-   }
-   return 0;
- }
- 
-+/************** End of rowset.c **********************************************/
-+/************** Begin file pager.c *******************************************/
- /*
--** Return true if the page is already in the journal file.
-+** 2001 September 15
-+**
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
-+**
-+**    May you do good and not evil.
-+**    May you find forgiveness for yourself and forgive others.
-+**    May you share freely, never taking more than you give.
-+**
-+*************************************************************************
-+** This is the implementation of the page cache subsystem or "pager".
-+** 
-+** The pager is used to access a database disk file.  It implements
-+** atomic commit and rollback through the use of a journal file that
-+** is separate from the database file.  The pager also implements file
-+** locking to prevent two processes from writing the same database
-+** file simultaneously, or one process from reading the database while
-+** another is writing.
- */
--static int pageInJournal(Pager *pPager, PgHdr *pPg){
--  return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno);
--}
--
-+#ifndef SQLITE_OMIT_DISKIO
-+/************** Include wal.h in the middle of pager.c ***********************/
-+/************** Begin file wal.h *********************************************/
- /*
--** Read a 32-bit integer from the given file descriptor.  Store the integer
--** that is read in *pRes.  Return SQLITE_OK if everything worked, or an
--** error code is something goes wrong.
-+** 2010 February 1
- **
--** All values are stored on disk as big-endian.
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
-+**
-+**    May you do good and not evil.
-+**    May you find forgiveness for yourself and forgive others.
-+**    May you share freely, never taking more than you give.
-+**
-+*************************************************************************
-+** This header file defines the interface to the write-ahead logging 
-+** system. Refer to the comments below and the header comment attached to 
-+** the implementation of each function in log.c for further details.
- */
--static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){
--  unsigned char ac[4];
--  int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset);
--  if( rc==SQLITE_OK ){
--    *pRes = sqlite3Get4byte(ac);
--  }
--  return rc;
--}
- 
--/*
--** Write a 32-bit integer into a string buffer in big-endian byte order.
--*/
--#define put32bits(A,B)  sqlite3Put4byte((u8*)A,B)
-+#ifndef _WAL_H_
-+#define _WAL_H_
- 
- 
--/*
--** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
--** on success or an error code is something goes wrong.
-+/* Additional values that can be added to the sync_flags argument of
-+** sqlite3WalFrames():
- */
--static int write32bits(sqlite3_file *fd, i64 offset, u32 val){
--  char ac[4];
--  put32bits(ac, val);
--  return sqlite3OsWrite(fd, ac, 4, offset);
--}
-+#define WAL_SYNC_TRANSACTIONS  0x20   /* Sync at the end of each transaction */
-+#define SQLITE_SYNC_MASK       0x13   /* Mask off the SQLITE_SYNC_* values */
- 
--/*
--** Unlock the database file to level eLock, which must be either NO_LOCK
--** or SHARED_LOCK. Regardless of whether or not the call to xUnlock()
--** succeeds, set the Pager.eLock variable to match the (attempted) new lock.
--**
--** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is
--** called, do not modify it. See the comment above the #define of 
--** UNKNOWN_LOCK for an explanation of this.
-+#ifdef SQLITE_OMIT_WAL
-+# define sqlite3WalOpen(x,y,z)                   0
-+# define sqlite3WalLimit(x,y)
-+# define sqlite3WalClose(w,x,y,z)                0
-+# define sqlite3WalBeginReadTransaction(y,z)     0
-+# define sqlite3WalEndReadTransaction(z)
-+# define sqlite3WalDbsize(y)                     0
-+# define sqlite3WalBeginWriteTransaction(y)      0
-+# define sqlite3WalEndWriteTransaction(x)        0
-+# define sqlite3WalUndo(x,y,z)                   0
-+# define sqlite3WalSavepoint(y,z)
-+# define sqlite3WalSavepointUndo(y,z)            0
-+# define sqlite3WalFrames(u,v,w,x,y,z)           0
-+# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0
-+# define sqlite3WalCallback(z)                   0
-+# define sqlite3WalExclusiveMode(y,z)            0
-+# define sqlite3WalHeapMemory(z)                 0
-+# define sqlite3WalFramesize(z)                  0
-+# define sqlite3WalFindFrame(x,y,z)              0
-+#else
++      pIter->nLvl = i+1;
++    }
++  }
 +
-+#define WAL_SAVEPOINT_NDATA 4
++  if( p->rc==SQLITE_OK ){
++    pIter->iSegid = iSegid;
++    if( bRev==0 ){
++      fts5DlidxIterFirst(pIter);
++    }else{
++      fts5DlidxIterLast(p, pIter);
++    }
++  }
 +
-+/* Connection to a write-ahead log (WAL) file. 
-+** There is one object of this type for each pager. 
- */
--static int pagerUnlockDb(Pager *pPager, int eLock){
--  int rc = SQLITE_OK;
-+typedef struct Wal Wal;
- 
--  assert( !pPager->exclusiveMode || pPager->eLock==eLock );
--  assert( eLock==NO_LOCK || eLock==SHARED_LOCK );
--  assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
--  if( isOpen(pPager->fd) ){
--    assert( pPager->eLock>=eLock );
--    rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock);
--    if( pPager->eLock!=UNKNOWN_LOCK ){
--      pPager->eLock = (u8)eLock;
--    }
--    IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
--  }
--  return rc;
--}
-+/* Open and close a connection to a write-ahead log. */
-+SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
-+SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
- 
--/*
--** Lock the database file to level eLock, which must be either SHARED_LOCK,
--** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the
--** Pager.eLock variable to the new locking state. 
--**
--** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is 
--** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. 
--** See the comment above the #define of UNKNOWN_LOCK for an explanation 
--** of this.
-+/* Set the limiting size of a WAL file. */
-+SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
-+
-+/* Used by readers to open (lock) and close (unlock) a snapshot.  A 
-+** snapshot is like a read-transaction.  It is the state of the database
-+** at an instant in time.  sqlite3WalOpenSnapshot gets a read lock and
-+** preserves the current state even if the other threads or processes
-+** write to or checkpoint the WAL.  sqlite3WalCloseSnapshot() closes the
-+** transaction and releases the lock.
- */
--static int pagerLockDb(Pager *pPager, int eLock){
--  int rc = SQLITE_OK;
-+SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *);
-+SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal);
- 
--  assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK );
--  if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){
--    rc = pPager->noLock ? SQLITE_OK : sqlite3OsLock(pPager->fd, eLock);
--    if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){
--      pPager->eLock = (u8)eLock;
--      IOTRACE(("LOCK %p %d\n", pPager, eLock))
--    }
--  }
--  return rc;
--}
-+/* Read a page from the write-ahead log, if it is present. */
-+SQLITE_PRIVATE int sqlite3WalFindFrame(Wal *, Pgno, u32 *);
-+SQLITE_PRIVATE int sqlite3WalReadFrame(Wal *, u32, int, u8 *);
- 
--/*
--** This function determines whether or not the atomic-write optimization
--** can be used with this pager. The optimization can be used if:
--**
--**  (a) the value returned by OsDeviceCharacteristics() indicates that
--**      a database page may be written atomically, and
--**  (b) the value returned by OsSectorSize() is less than or equal
--**      to the page size.
--**
--** The optimization is also always enabled for temporary files. It is
--** an error to call this function if pPager is opened on an in-memory
--** database.
--**
--** If the optimization cannot be used, 0 is returned. If it can be used,
--** then the value returned is the size of the journal file when it
--** contains rollback data for exactly one page.
-+/* If the WAL is not empty, return the size of the database. */
-+SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal);
-+
-+/* Obtain or release the WRITER lock. */
-+SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal);
-+SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal);
-+
-+/* Undo any frames written (but not committed) to the log */
-+SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx);
-+
-+/* Return an integer that records the current (uncommitted) write
-+** position in the WAL */
-+SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData);
-+
-+/* Move the write position of the WAL back to iFrame.  Called in
-+** response to a ROLLBACK TO command. */
-+SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData);
-+
-+/* Write a frame or frames to the log. */
-+SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
-+
-+/* Copy pages from the log to the database file */ 
-+SQLITE_PRIVATE int sqlite3WalCheckpoint(
-+  Wal *pWal,                      /* Write-ahead log connection */
-+  int eMode,                      /* One of PASSIVE, FULL and RESTART */
-+  int (*xBusy)(void*),            /* Function to call when busy */
-+  void *pBusyArg,                 /* Context argument for xBusyHandler */
-+  int sync_flags,                 /* Flags to sync db file with (or 0) */
-+  int nBuf,                       /* Size of buffer nBuf */
-+  u8 *zBuf,                       /* Temporary buffer to use */
-+  int *pnLog,                     /* OUT: Number of frames in WAL */
-+  int *pnCkpt                     /* OUT: Number of backfilled frames in WAL */
-+);
++  if( p->rc!=SQLITE_OK ){
++    fts5DlidxIterFree(pIter);
++    pIter = 0;
++  }
 +
-+/* Return the value to pass to a sqlite3_wal_hook callback, the
-+** number of frames in the WAL at the point of the last commit since
-+** sqlite3WalCallback() was called.  If no commits have occurred since
-+** the last call, then return 0.
- */
--#ifdef SQLITE_ENABLE_ATOMIC_WRITE
--static int jrnlBufferSize(Pager *pPager){
--  assert( !MEMDB );
--  if( !pPager->tempFile ){
--    int dc;                           /* Device characteristics */
--    int nSector;                      /* Sector size */
--    int szPage;                       /* Page size */
-+SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal);
- 
--    assert( isOpen(pPager->fd) );
--    dc = sqlite3OsDeviceCharacteristics(pPager->fd);
--    nSector = pPager->sectorSize;
--    szPage = pPager->pageSize;
-+/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released)
-+** by the pager layer on the database file.
-+*/
-+SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op);
- 
--    assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
--    assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
--    if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){
--      return 0;
--    }
--  }
-+/* Return true if the argument is non-NULL and the WAL module is using
-+** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
-+** WAL module is using shared-memory, return false. 
-+*/
-+SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
- 
--  return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
--}
-+#ifdef SQLITE_ENABLE_ZIPVFS
-+/* If the WAL file is not empty, return the number of bytes of content
-+** stored in each frame (i.e. the db page-size when the WAL was created).
++  return pIter;
++}
++
++static i64 fts5DlidxIterRowid(Fts5DlidxIter *pIter){
++  return pIter->aLvl[0].iRowid;
++}
++static int fts5DlidxIterPgno(Fts5DlidxIter *pIter){
++  return pIter->aLvl[0].iLeafPgno;
++}
++
++/*
++** Load the next leaf page into the segment iterator.
 +*/
-+SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
- #endif
- 
-+#endif /* ifndef SQLITE_OMIT_WAL */
-+#endif /* _WAL_H_ */
++static void fts5SegIterNextPage(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5SegIter *pIter              /* Iterator to advance to next page */
++){
++  Fts5Data *pLeaf;
++  Fts5StructureSegment *pSeg = pIter->pSeg;
++  fts5DataRelease(pIter->pLeaf);
++  pIter->iLeafPgno++;
++  if( pIter->pNextLeaf ){
++    pIter->pLeaf = pIter->pNextLeaf;
++    pIter->pNextLeaf = 0;
++  }else if( pIter->iLeafPgno<=pSeg->pgnoLast ){
++    pIter->pLeaf = fts5LeafRead(p, 
++        FTS5_SEGMENT_ROWID(pSeg->iSegid, pIter->iLeafPgno)
++    );
++  }else{
++    pIter->pLeaf = 0;
++  }
++  pLeaf = pIter->pLeaf;
 +
-+/************** End of wal.h *************************************************/
-+/************** Continuing where we left off in pager.c **********************/
++  if( pLeaf ){
++    pIter->iPgidxOff = pLeaf->szLeaf;
++    if( fts5LeafIsTermless(pLeaf) ){
++      pIter->iEndofDoclist = pLeaf->nn+1;
++    }else{
++      pIter->iPgidxOff += fts5GetVarint32(&pLeaf->p[pIter->iPgidxOff],
++          pIter->iEndofDoclist
++      );
++    }
++  }
++}
 +
++/*
++** Argument p points to a buffer containing a varint to be interpreted as a
++** position list size field. Read the varint and return the number of bytes
++** read. Before returning, set *pnSz to the number of bytes in the position
++** list, and *pbDel to true if the delete flag is set, or false otherwise.
++*/
++static int fts5GetPoslistSize(const u8 *p, int *pnSz, int *pbDel){
++  int nSz;
++  int n = 0;
++  fts5FastGetVarint32(p, n, nSz);
++  assert_nc( nSz>=0 );
++  *pnSz = nSz/2;
++  *pbDel = nSz & 0x0001;
++  return n;
++}
 +
-+/******************* NOTES ON THE DESIGN OF THE PAGER ************************
-+**
-+** This comment block describes invariants that hold when using a rollback
-+** journal.  These invariants do not apply for journal_mode=WAL,
-+** journal_mode=MEMORY, or journal_mode=OFF.
-+**
-+** Within this comment block, a page is deemed to have been synced
-+** automatically as soon as it is written when PRAGMA synchronous=OFF.
-+** Otherwise, the page is not synced until the xSync method of the VFS
-+** is called successfully on the file containing the page.
-+**
-+** Definition:  A page of the database file is said to be "overwriteable" if
-+** one or more of the following are true about the page:
-+** 
-+**     (a)  The original content of the page as it was at the beginning of
-+**          the transaction has been written into the rollback journal and
-+**          synced.
-+** 
-+**     (b)  The page was a freelist leaf page at the start of the transaction.
-+** 
-+**     (c)  The page number is greater than the largest page that existed in
-+**          the database file at the start of the transaction.
-+** 
-+** (1) A page of the database file is never overwritten unless one of the
-+**     following are true:
-+** 
-+**     (a) The page and all other pages on the same sector are overwriteable.
-+** 
-+**     (b) The atomic page write optimization is enabled, and the entire
-+**         transaction other than the update of the transaction sequence
-+**         number consists of a single page change.
-+** 
-+** (2) The content of a page written into the rollback journal exactly matches
-+**     both the content in the database when the rollback journal was written
-+**     and the content in the database at the beginning of the current
-+**     transaction.
-+** 
-+** (3) Writes to the database file are an integer multiple of the page size
-+**     in length and are aligned on a page boundary.
-+** 
-+** (4) Reads from the database file are either aligned on a page boundary and
-+**     an integer multiple of the page size in length or are taken from the
-+**     first 100 bytes of the database file.
-+** 
-+** (5) All writes to the database file are synced prior to the rollback journal
-+**     being deleted, truncated, or zeroed.
-+** 
-+** (6) If a master journal file is used, then all writes to the database file
-+**     are synced prior to the master journal being deleted.
-+** 
-+** Definition: Two databases (or the same database at two points it time)
-+** are said to be "logically equivalent" if they give the same answer to
-+** all queries.  Note in particular the content of freelist leaf
-+** pages can be changed arbitrarily without affecting the logical equivalence
-+** of the database.
-+** 
-+** (7) At any time, if any subset, including the empty set and the total set,
-+**     of the unsynced changes to a rollback journal are removed and the 
-+**     journal is rolled back, the resulting database file will be logically
-+**     equivalent to the database file at the beginning of the transaction.
-+** 
-+** (8) When a transaction is rolled back, the xTruncate method of the VFS
-+**     is called to restore the database file to the same size it was at
-+**     the beginning of the transaction.  (In some VFSes, the xTruncate
-+**     method is a no-op, but that does not change the fact the SQLite will
-+**     invoke it.)
-+** 
-+** (9) Whenever the database file is modified, at least one bit in the range
-+**     of bytes from 24 through 39 inclusive will be changed prior to releasing
-+**     the EXCLUSIVE lock, thus signaling other connections on the same
-+**     database to flush their caches.
-+**
-+** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less
-+**      than one billion transactions.
-+**
-+** (11) A database file is well-formed at the beginning and at the conclusion
-+**      of every transaction.
-+**
-+** (12) An EXCLUSIVE lock is held on the database file when writing to
-+**      the database file.
++/*
++** Fts5SegIter.iLeafOffset currently points to the first byte of a
++** position-list size field. Read the value of the field and store it
++** in the following variables:
 +**
-+** (13) A SHARED lock is held on the database file while reading any
-+**      content out of the database file.
++**   Fts5SegIter.nPos
++**   Fts5SegIter.bDel
 +**
-+******************************************************************************/
++** Leave Fts5SegIter.iLeafOffset pointing to the first byte of the 
++** position list content (if any).
++*/
++static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){
++  if( p->rc==SQLITE_OK ){
++    int iOff = pIter->iLeafOffset;  /* Offset to read at */
++    ASSERT_SZLEAF_OK(pIter->pLeaf);
++    if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
++      int iEod = MIN(pIter->iEndofDoclist, pIter->pLeaf->szLeaf);
++      pIter->bDel = 0;
++      pIter->nPos = 1;
++      if( iOff<iEod && pIter->pLeaf->p[iOff]==0 ){
++        pIter->bDel = 1;
++        iOff++;
++        if( iOff<iEod && pIter->pLeaf->p[iOff]==0 ){
++          pIter->nPos = 1;
++          iOff++;
++        }else{
++          pIter->nPos = 0;
++        }
++      }
++    }else{
++      int nSz;
++      fts5FastGetVarint32(pIter->pLeaf->p, iOff, nSz);
++      pIter->bDel = (nSz & 0x0001);
++      pIter->nPos = nSz>>1;
++      assert_nc( pIter->nPos>=0 );
++    }
++    pIter->iLeafOffset = iOff;
++  }
++}
 +
- /*
--** If SQLITE_CHECK_PAGES is defined then we do some sanity checking
--** on the cache using a hash function.  This is used for testing
--** and debugging only.
--*/
--#ifdef SQLITE_CHECK_PAGES
--/*
--** Return a 32-bit hash of the page data for pPage.
-+** Macros for troubleshooting.  Normally turned off
- */
--static u32 pager_datahash(int nByte, unsigned char *pData){
--  u32 hash = 0;
--  int i;
--  for(i=0; i<nByte; i++){
--    hash = (hash*1039) + pData[i];
--  }
--  return hash;
--}
--static u32 pager_pagehash(PgHdr *pPage){
--  return pager_datahash(pPage->pPager->pageSize, (unsigned char *)pPage->pData);
--}
--static void pager_set_pagehash(PgHdr *pPage){
--  pPage->pageHash = pager_pagehash(pPage);
--}
-+#if 0
-+int sqlite3PagerTrace=1;  /* True to enable tracing */
-+#define sqlite3DebugPrintf printf
-+#define PAGERTRACE(X)     if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; }
-+#else
-+#define PAGERTRACE(X)
-+#endif
- 
- /*
--** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
--** is defined, and NDEBUG is not defined, an assert() statement checks
--** that the page is either dirty or still matches the calculated page-hash.
-+** The following two macros are used within the PAGERTRACE() macros above
-+** to print out file-descriptors. 
-+**
-+** PAGERID() takes a pointer to a Pager struct as its argument. The
-+** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file
-+** struct as its argument.
- */
--#define CHECK_PAGE(x) checkPage(x)
--static void checkPage(PgHdr *pPg){
--  Pager *pPager = pPg->pPager;
--  assert( pPager->eState!=PAGER_ERROR );
--  assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) );
--}
--
--#else
--#define pager_datahash(X,Y)  0
--#define pager_pagehash(X)  0
--#define pager_set_pagehash(X)
--#define CHECK_PAGE(x)
--#endif  /* SQLITE_CHECK_PAGES */
-+#define PAGERID(p) ((int)(p->fd))
-+#define FILEHANDLEID(fd) ((int)fd)
- 
- /*
--** When this is called the journal file for pager pPager must be open.
--** This function attempts to read a master journal file name from the 
--** end of the file and, if successful, copies it into memory supplied 
--** by the caller. See comments above writeMasterJournal() for the format
--** used to store a master journal file name at the end of a journal file.
-+** The Pager.eState variable stores the current 'state' of a pager. A
-+** pager may be in any one of the seven states shown in the following
-+** state diagram.
-+**
-+**                            OPEN <------+------+
-+**                              |         |      |
-+**                              V         |      |
-+**               +---------> READER-------+      |
-+**               |              |                |
-+**               |              V                |
-+**               |<-------WRITER_LOCKED------> ERROR
-+**               |              |                ^  
-+**               |              V                |
-+**               |<------WRITER_CACHEMOD-------->|
-+**               |              |                |
-+**               |              V                |
-+**               |<-------WRITER_DBMOD---------->|
-+**               |              |                |
-+**               |              V                |
-+**               +<------WRITER_FINISHED-------->+
-+**
-+**
-+** List of state transitions and the C [function] that performs each:
-+** 
-+**   OPEN              -> READER              [sqlite3PagerSharedLock]
-+**   READER            -> OPEN                [pager_unlock]
-+**
-+**   READER            -> WRITER_LOCKED       [sqlite3PagerBegin]
-+**   WRITER_LOCKED     -> WRITER_CACHEMOD     [pager_open_journal]
-+**   WRITER_CACHEMOD   -> WRITER_DBMOD        [syncJournal]
-+**   WRITER_DBMOD      -> WRITER_FINISHED     [sqlite3PagerCommitPhaseOne]
-+**   WRITER_***        -> READER              [pager_end_transaction]
-+**
-+**   WRITER_***        -> ERROR               [pager_error]
-+**   ERROR             -> OPEN                [pager_unlock]
-+** 
++static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
++  u8 *a = pIter->pLeaf->p;        /* Buffer to read data from */
++  int iOff = pIter->iLeafOffset;
++
++  ASSERT_SZLEAF_OK(pIter->pLeaf);
++  if( iOff>=pIter->pLeaf->szLeaf ){
++    fts5SegIterNextPage(p, pIter);
++    if( pIter->pLeaf==0 ){
++      if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
++      return;
++    }
++    iOff = 4;
++    a = pIter->pLeaf->p;
++  }
++  iOff += sqlite3Fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
++  pIter->iLeafOffset = iOff;
++}
++
++/*
++** Fts5SegIter.iLeafOffset currently points to the first byte of the 
++** "nSuffix" field of a term. Function parameter nKeep contains the value
++** of the "nPrefix" field (if there was one - it is passed 0 if this is
++** the first term in the segment).
 +**
-+**  OPEN:
++** This function populates:
 +**
-+**    The pager starts up in this state. Nothing is guaranteed in this
-+**    state - the file may or may not be locked and the database size is
-+**    unknown. The database may not be read or written.
++**   Fts5SegIter.term
++**   Fts5SegIter.rowid
 +**
-+**    * No read or write transaction is active.
-+**    * Any lock, or no lock at all, may be held on the database file.
-+**    * The dbSize, dbOrigSize and dbFileSize variables may not be trusted.
++** accordingly and leaves (Fts5SegIter.iLeafOffset) set to the content of
++** the first position list. The position list belonging to document 
++** (Fts5SegIter.iRowid).
++*/
++static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
++  u8 *a = pIter->pLeaf->p;        /* Buffer to read data from */
++  int iOff = pIter->iLeafOffset;  /* Offset to read at */
++  int nNew;                       /* Bytes of new data */
++
++  iOff += fts5GetVarint32(&a[iOff], nNew);
++  if( iOff+nNew>pIter->pLeaf->nn ){
++    p->rc = FTS5_CORRUPT;
++    return;
++  }
++  pIter->term.n = nKeep;
++  fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
++  iOff += nNew;
++  pIter->iTermLeafOffset = iOff;
++  pIter->iTermLeafPgno = pIter->iLeafPgno;
++  pIter->iLeafOffset = iOff;
++
++  if( pIter->iPgidxOff>=pIter->pLeaf->nn ){
++    pIter->iEndofDoclist = pIter->pLeaf->nn+1;
++  }else{
++    int nExtra;
++    pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], nExtra);
++    pIter->iEndofDoclist += nExtra;
++  }
++
++  fts5SegIterLoadRowid(p, pIter);
++}
++
++static void fts5SegIterNext(Fts5Index*, Fts5SegIter*, int*);
++static void fts5SegIterNext_Reverse(Fts5Index*, Fts5SegIter*, int*);
++static void fts5SegIterNext_None(Fts5Index*, Fts5SegIter*, int*);
++
++static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){
++  if( pIter->flags & FTS5_SEGITER_REVERSE ){
++    pIter->xNext = fts5SegIterNext_Reverse;
++  }else if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
++    pIter->xNext = fts5SegIterNext_None;
++  }else{
++    pIter->xNext = fts5SegIterNext;
++  }
++}
++
++/*
++** Initialize the iterator object pIter to iterate through the entries in
++** segment pSeg. The iterator is left pointing to the first entry when 
++** this function returns.
 +**
-+**  READER:
++** If an error occurs, Fts5Index.rc is set to an appropriate error code. If 
++** an error has already occurred when this function is called, it is a no-op.
++*/
++static void fts5SegIterInit(
++  Fts5Index *p,                   /* FTS index object */
++  Fts5StructureSegment *pSeg,     /* Description of segment */
++  Fts5SegIter *pIter              /* Object to populate */
++){
++  if( pSeg->pgnoFirst==0 ){
++    /* This happens if the segment is being used as an input to an incremental
++    ** merge and all data has already been "trimmed". See function
++    ** fts5TrimSegments() for details. In this case leave the iterator empty.
++    ** The caller will see the (pIter->pLeaf==0) and assume the iterator is
++    ** at EOF already. */
++    assert( pIter->pLeaf==0 );
++    return;
++  }
++
++  if( p->rc==SQLITE_OK ){
++    memset(pIter, 0, sizeof(*pIter));
++    fts5SegIterSetNext(p, pIter);
++    pIter->pSeg = pSeg;
++    pIter->iLeafPgno = pSeg->pgnoFirst-1;
++    fts5SegIterNextPage(p, pIter);
++  }
++
++  if( p->rc==SQLITE_OK ){
++    pIter->iLeafOffset = 4;
++    assert_nc( pIter->pLeaf->nn>4 );
++    assert( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
++    pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
++    fts5SegIterLoadTerm(p, pIter, 0);
++    fts5SegIterLoadNPos(p, pIter);
++  }
++}
++
++/*
++** This function is only ever called on iterators created by calls to
++** Fts5IndexQuery() with the FTS5INDEX_QUERY_DESC flag set.
 +**
-+**    In this state all the requirements for reading the database in 
-+**    rollback (non-WAL) mode are met. Unless the pager is (or recently
-+**    was) in exclusive-locking mode, a user-level read transaction is 
-+**    open. The database size is known in this state.
++** The iterator is in an unusual state when this function is called: the
++** Fts5SegIter.iLeafOffset variable is set to the offset of the start of
++** the position-list size field for the first relevant rowid on the page.
++** Fts5SegIter.rowid is set, but nPos and bDel are not.
 +**
-+**    A connection running with locking_mode=normal enters this state when
-+**    it opens a read-transaction on the database and returns to state
-+**    OPEN after the read-transaction is completed. However a connection
-+**    running in locking_mode=exclusive (including temp databases) remains in
-+**    this state even after the read-transaction is closed. The only way
-+**    a locking_mode=exclusive connection can transition from READER to OPEN
-+**    is via the ERROR state (see below).
-+** 
-+**    * A read transaction may be active (but a write-transaction cannot).
-+**    * A SHARED or greater lock is held on the database file.
-+**    * The dbSize variable may be trusted (even if a user-level read 
-+**      transaction is not active). The dbOrigSize and dbFileSize variables
-+**      may not be trusted at this point.
-+**    * If the database is a WAL database, then the WAL connection is open.
-+**    * Even if a read-transaction is not open, it is guaranteed that 
-+**      there is no hot-journal in the file-system.
-+**
-+**  WRITER_LOCKED:
-+**
-+**    The pager moves to this state from READER when a write-transaction
-+**    is first opened on the database. In WRITER_LOCKED state, all locks 
-+**    required to start a write-transaction are held, but no actual 
-+**    modifications to the cache or database have taken place.
-+**
-+**    In rollback mode, a RESERVED or (if the transaction was opened with 
-+**    BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when
-+**    moving to this state, but the journal file is not written to or opened 
-+**    to in this state. If the transaction is committed or rolled back while 
-+**    in WRITER_LOCKED state, all that is required is to unlock the database 
-+**    file.
-+**
-+**    IN WAL mode, WalBeginWriteTransaction() is called to lock the log file.
-+**    If the connection is running with locking_mode=exclusive, an attempt
-+**    is made to obtain an EXCLUSIVE lock on the database file.
-+**
-+**    * A write transaction is active.
-+**    * If the connection is open in rollback-mode, a RESERVED or greater 
-+**      lock is held on the database file.
-+**    * If the connection is open in WAL-mode, a WAL write transaction
-+**      is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully
-+**      called).
-+**    * The dbSize, dbOrigSize and dbFileSize variables are all valid.
-+**    * The contents of the pager cache have not been modified.
-+**    * The journal file may or may not be open.
-+**    * Nothing (not even the first header) has been written to the journal.
-+**
-+**  WRITER_CACHEMOD:
-+**
-+**    A pager moves from WRITER_LOCKED state to this state when a page is
-+**    first modified by the upper layer. In rollback mode the journal file
-+**    is opened (if it is not already open) and a header written to the
-+**    start of it. The database file on disk has not been modified.
-+**
-+**    * A write transaction is active.
-+**    * A RESERVED or greater lock is held on the database file.
-+**    * The journal file is open and the first header has been written 
-+**      to it, but the header has not been synced to disk.
-+**    * The contents of the page cache have been modified.
- **
--** zMaster must point to a buffer of at least nMaster bytes allocated by
--** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is
--** enough space to write the master journal name). If the master journal
--** name in the journal is longer than nMaster bytes (including a
--** nul-terminator), then this is handled as if no master journal name
--** were present in the journal.
-+**  WRITER_DBMOD:
- **
--** If a master journal file name is present at the end of the journal
--** file, then it is copied into the buffer pointed to by zMaster. A
--** nul-terminator byte is appended to the buffer following the master
--** journal file name.
-+**    The pager transitions from WRITER_CACHEMOD into WRITER_DBMOD state
-+**    when it modifies the contents of the database file. WAL connections
-+**    never enter this state (since they do not modify the database file,
-+**    just the log file).
- **
--** If it is determined that no master journal file name is present 
--** zMaster[0] is set to 0 and SQLITE_OK returned.
-+**    * A write transaction is active.
-+**    * An EXCLUSIVE or greater lock is held on the database file.
-+**    * The journal file is open and the first header has been written 
-+**      and synced to disk.
-+**    * The contents of the page cache have been modified (and possibly
-+**      written to disk).
- **
--** If an error occurs while reading from the journal file, an SQLite
--** error code is returned.
--*/
--static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
--  int rc;                    /* Return code */
--  u32 len;                   /* Length in bytes of master journal name */
--  i64 szJ;                   /* Total size in bytes of journal file pJrnl */
--  u32 cksum;                 /* MJ checksum value read from journal */
--  u32 u;                     /* Unsigned loop counter */
--  unsigned char aMagic[8];   /* A buffer to hold the magic header */
--  zMaster[0] = '\0';
--
--  if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ))
--   || szJ<16
--   || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
--   || len>=nMaster 
--   || len==0 
--   || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
--   || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
--   || memcmp(aMagic, aJournalMagic, 8)
--   || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len))
--  ){
--    return rc;
--  }
--
--  /* See if the checksum matches the master journal name */
--  for(u=0; u<len; u++){
--    cksum -= zMaster[u];
--  }
--  if( cksum ){
--    /* If the checksum doesn't add up, then one or more of the disk sectors
--    ** containing the master journal filename is corrupted. This means
--    ** definitely roll back, so just return SQLITE_OK and report a (nul)
--    ** master-journal filename.
--    */
--    len = 0;
--  }
--  zMaster[len] = '\0';
--   
--  return SQLITE_OK;
--}
--
--/*
--** Return the offset of the sector boundary at or immediately 
--** following the value in pPager->journalOff, assuming a sector 
--** size of pPager->sectorSize bytes.
-+**  WRITER_FINISHED:
- **
--** i.e for a sector size of 512:
-+**    It is not possible for a WAL connection to enter this state.
- **
--**   Pager.journalOff          Return value
--**   ---------------------------------------
--**   0                         0
--**   512                       512
--**   100                       512
--**   2000                      2048
--** 
--*/
--static i64 journalHdrOffset(Pager *pPager){
--  i64 offset = 0;
--  i64 c = pPager->journalOff;
--  if( c ){
--    offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager);
--  }
--  assert( offset%JOURNAL_HDR_SZ(pPager)==0 );
--  assert( offset>=c );
--  assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
--  return offset;
--}
--
--/*
--** The journal file must be open when this function is called.
-+**    A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD
-+**    state after the entire transaction has been successfully written into the
-+**    database file. In this state the transaction may be committed simply
-+**    by finalizing the journal file. Once in WRITER_FINISHED state, it is 
-+**    not possible to modify the database further. At this point, the upper 
-+**    layer must either commit or rollback the transaction.
- **
--** This function is a no-op if the journal file has not been written to
--** within the current transaction (i.e. if Pager.journalOff==0).
-+**    * A write transaction is active.
-+**    * An EXCLUSIVE or greater lock is held on the database file.
-+**    * All writing and syncing of journal and database data has finished.
-+**      If no error occurred, all that remains is to finalize the journal to
-+**      commit the transaction. If an error did occur, the caller will need
-+**      to rollback the transaction. 
- **
--** If doTruncate is non-zero or the Pager.journalSizeLimit variable is
--** set to 0, then truncate the journal file to zero bytes in size. Otherwise,
--** zero the 28-byte header at the start of the journal file. In either case, 
--** if the pager is not in no-sync mode, sync the journal file immediately 
--** after writing or truncating it.
-+**  ERROR:
- **
--** If Pager.journalSizeLimit is set to a positive, non-zero value, and
--** following the truncation or zeroing described above the size of the 
--** journal file in bytes is larger than this value, then truncate the
--** journal file to Pager.journalSizeLimit bytes. The journal file does
--** not need to be synced following this operation.
-+**    The ERROR state is entered when an IO or disk-full error (including
-+**    SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it 
-+**    difficult to be sure that the in-memory pager state (cache contents, 
-+**    db size etc.) are consistent with the contents of the file-system.
- **
--** If an IO error occurs, abandon processing and return the IO error code.
--** Otherwise, return SQLITE_OK.
--*/
--static int zeroJournalHdr(Pager *pPager, int doTruncate){
--  int rc = SQLITE_OK;                               /* Return code */
--  assert( isOpen(pPager->jfd) );
--  if( pPager->journalOff ){
--    const i64 iLimit = pPager->journalSizeLimit;    /* Local cache of jsl */
--
--    IOTRACE(("JZEROHDR %p\n", pPager))
--    if( doTruncate || iLimit==0 ){
--      rc = sqlite3OsTruncate(pPager->jfd, 0);
--    }else{
--      static const char zeroHdr[28] = {0};
--      rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0);
--    }
--    if( rc==SQLITE_OK && !pPager->noSync ){
--      rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags);
--    }
--
--    /* At this point the transaction is committed but the write lock 
--    ** is still held on the file. If there is a size limit configured for 
--    ** the persistent journal and the journal file currently consumes more
--    ** space than that limit allows for, truncate it now. There is no need
--    ** to sync the file following this operation.
--    */
--    if( rc==SQLITE_OK && iLimit>0 ){
--      i64 sz;
--      rc = sqlite3OsFileSize(pPager->jfd, &sz);
--      if( rc==SQLITE_OK && sz>iLimit ){
--        rc = sqlite3OsTruncate(pPager->jfd, iLimit);
--      }
--    }
--  }
--  return rc;
--}
--
--/*
--** The journal file must be open when this routine is called. A journal
--** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the
--** current location.
-+**    Temporary pager files may enter the ERROR state, but in-memory pagers
-+**    cannot.
- **
--** The format for the journal header is as follows:
--** - 8 bytes: Magic identifying journal format.
--** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.
--** - 4 bytes: Random number used for page hash.
--** - 4 bytes: Initial database page count.
--** - 4 bytes: Sector size used by the process that wrote this journal.
--** - 4 bytes: Database page size.
--** 
--** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space.
--*/
--static int writeJournalHdr(Pager *pPager){
--  int rc = SQLITE_OK;                 /* Return code */
--  char *zHeader = pPager->pTmpSpace;  /* Temporary space used to build header */
--  u32 nHeader = (u32)pPager->pageSize;/* Size of buffer pointed to by zHeader */
--  u32 nWrite;                         /* Bytes of header sector written */
--  int ii;                             /* Loop counter */
--
--  assert( isOpen(pPager->jfd) );      /* Journal file must be open. */
--
--  if( nHeader>JOURNAL_HDR_SZ(pPager) ){
--    nHeader = JOURNAL_HDR_SZ(pPager);
--  }
--
--  /* If there are active savepoints and any of them were created 
--  ** since the most recent journal header was written, update the 
--  ** PagerSavepoint.iHdrOffset fields now.
--  */
--  for(ii=0; ii<pPager->nSavepoint; ii++){
--    if( pPager->aSavepoint[ii].iHdrOffset==0 ){
--      pPager->aSavepoint[ii].iHdrOffset = pPager->journalOff;
--    }
--  }
--
--  pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager);
--
--  /* 
--  ** Write the nRec Field - the number of page records that follow this
--  ** journal header. Normally, zero is written to this value at this time.
--  ** After the records are added to the journal (and the journal synced, 
--  ** if in full-sync mode), the zero is overwritten with the true number
--  ** of records (see syncJournal()).
--  **
--  ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When
--  ** reading the journal this value tells SQLite to assume that the
--  ** rest of the journal file contains valid page records. This assumption
--  ** is dangerous, as if a failure occurred whilst writing to the journal
--  ** file it may contain some garbage data. There are two scenarios
--  ** where this risk can be ignored:
--  **
--  **   * When the pager is in no-sync mode. Corruption can follow a
--  **     power failure in this case anyway.
--  **
--  **   * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees
--  **     that garbage data is never appended to the journal file.
--  */
--  assert( isOpen(pPager->fd) || pPager->noSync );
--  if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY)
--   || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) 
--  ){
--    memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
--    put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
--  }else{
--    memset(zHeader, 0, sizeof(aJournalMagic)+4);
--  }
--
--  /* The random check-hash initializer */ 
--  sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
--  put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);
--  /* The initial database size */
--  put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize);
--  /* The assumed sector size for this process */
--  put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
--
--  /* The page size */
--  put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize);
--
--  /* Initializing the tail of the buffer is not necessary.  Everything
--  ** works find if the following memset() is omitted.  But initializing
--  ** the memory prevents valgrind from complaining, so we are willing to
--  ** take the performance hit.
--  */
--  memset(&zHeader[sizeof(aJournalMagic)+20], 0,
--         nHeader-(sizeof(aJournalMagic)+20));
--
--  /* In theory, it is only necessary to write the 28 bytes that the 
--  ** journal header consumes to the journal file here. Then increment the 
--  ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next 
--  ** record is written to the following sector (leaving a gap in the file
--  ** that will be implicitly filled in by the OS).
--  **
--  ** However it has been discovered that on some systems this pattern can 
--  ** be significantly slower than contiguously writing data to the file,
--  ** even if that means explicitly writing data to the block of 
--  ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what
--  ** is done. 
--  **
--  ** The loop is required here in case the sector-size is larger than the 
--  ** database page size. Since the zHeader buffer is only Pager.pageSize
--  ** bytes in size, more than one call to sqlite3OsWrite() may be required
--  ** to populate the entire journal header sector.
--  */ 
--  for(nWrite=0; rc==SQLITE_OK&&nWrite<JOURNAL_HDR_SZ(pPager); nWrite+=nHeader){
--    IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, nHeader))
--    rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff);
--    assert( pPager->journalHdr <= pPager->journalOff );
--    pPager->journalOff += nHeader;
--  }
--
--  return rc;
--}
--
--/*
--** The journal file must be open when this is called. A journal header file
--** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal
--** file. The current location in the journal file is given by
--** pPager->journalOff. See comments above function writeJournalHdr() for
--** a description of the journal header format.
-+**    For example, if an IO error occurs while performing a rollback, 
-+**    the contents of the page-cache may be left in an inconsistent state.
-+**    At this point it would be dangerous to change back to READER state
-+**    (as usually happens after a rollback). Any subsequent readers might
-+**    report database corruption (due to the inconsistent cache), and if
-+**    they upgrade to writers, they may inadvertently corrupt the database
-+**    file. To avoid this hazard, the pager switches into the ERROR state
-+**    instead of READER following such an error.
- **
--** If the header is read successfully, *pNRec is set to the number of
--** page records following this header and *pDbSize is set to the size of the
--** database before the transaction began, in pages. Also, pPager->cksumInit
--** is set to the value read from the journal header. SQLITE_OK is returned
--** in this case.
-+**    Once it has entered the ERROR state, any attempt to use the pager
-+**    to read or write data returns an error. Eventually, once all 
-+**    outstanding transactions have been abandoned, the pager is able to
-+**    transition back to OPEN state, discarding the contents of the 
-+**    page-cache and any other in-memory state at the same time. Everything
-+**    is reloaded from disk (and, if necessary, hot-journal rollback peformed)
-+**    when a read-transaction is next opened on the pager (transitioning
-+**    the pager into READER state). At that point the system has recovered 
-+**    from the error.
- **
--** If the journal header file appears to be corrupted, SQLITE_DONE is
--** returned and *pNRec and *PDbSize are undefined.  If JOURNAL_HDR_SZ bytes
--** cannot be read from the journal file an error code is returned.
-+**    Specifically, the pager jumps into the ERROR state if:
-+**
-+**      1. An error occurs while attempting a rollback. This happens in
-+**         function sqlite3PagerRollback().
-+**
-+**      2. An error occurs while attempting to finalize a journal file
-+**         following a commit in function sqlite3PagerCommitPhaseTwo().
-+**
-+**      3. An error occurs while attempting to write to the journal or
-+**         database file in function pagerStress() in order to free up
-+**         memory.
-+**
-+**    In other cases, the error is returned to the b-tree layer. The b-tree
-+**    layer then attempts a rollback operation. If the error condition 
-+**    persists, the pager enters the ERROR state via condition (1) above.
-+**
-+**    Condition (3) is necessary because it can be triggered by a read-only
-+**    statement executed within a transaction. In this case, if the error
-+**    code were simply returned to the user, the b-tree layer would not
-+**    automatically attempt a rollback, as it assumes that an error in a
-+**    read-only statement cannot leave the pager in an internally inconsistent 
-+**    state.
-+**
-+**    * The Pager.errCode variable is set to something other than SQLITE_OK.
-+**    * There are one or more outstanding references to pages (after the
-+**      last reference is dropped the pager should move back to OPEN state).
-+**    * The pager is not an in-memory pager.
-+**    
-+**
-+** Notes:
-+**
-+**   * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the
-+**     connection is open in WAL mode. A WAL connection is always in one
-+**     of the first four states.
-+**
-+**   * Normally, a connection open in exclusive mode is never in PAGER_OPEN
-+**     state. There are two exceptions: immediately after exclusive-mode has
-+**     been turned on (and before any read or write transactions are 
-+**     executed), and when the pager is leaving the "error state".
-+**
-+**   * See also: assert_pager_state().
- */
--static int readJournalHdr(
--  Pager *pPager,               /* Pager object */
--  int isHot,
--  i64 journalSize,             /* Size of the open journal file in bytes */
--  u32 *pNRec,                  /* OUT: Value read from the nRec field */
--  u32 *pDbSize                 /* OUT: Value of original database size field */
--){
--  int rc;                      /* Return code */
--  unsigned char aMagic[8];     /* A buffer to hold the magic header */
--  i64 iHdrOff;                 /* Offset of journal header being read */
--
--  assert( isOpen(pPager->jfd) );      /* Journal file must be open. */
--
--  /* Advance Pager.journalOff to the start of the next sector. If the
--  ** journal file is too small for there to be a header stored at this
--  ** point, return SQLITE_DONE.
--  */
--  pPager->journalOff = journalHdrOffset(pPager);
--  if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
--    return SQLITE_DONE;
--  }
--  iHdrOff = pPager->journalOff;
--
--  /* Read in the first 8 bytes of the journal header. If they do not match
--  ** the  magic string found at the start of each journal header, return
--  ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise,
--  ** proceed.
--  */
--  if( isHot || iHdrOff!=pPager->journalHdr ){
--    rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff);
--    if( rc ){
--      return rc;
--    }
--    if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
--      return SQLITE_DONE;
--    }
--  }
--
--  /* Read the first three 32-bit fields of the journal header: The nRec
--  ** field, the checksum-initializer and the database size at the start
--  ** of the transaction. Return an error code if anything goes wrong.
--  */
--  if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+8, pNRec))
--   || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+12, &pPager->cksumInit))
--   || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+16, pDbSize))
--  ){
--    return rc;
--  }
--
--  if( pPager->journalOff==0 ){
--    u32 iPageSize;               /* Page-size field of journal header */
--    u32 iSectorSize;             /* Sector-size field of journal header */
--
--    /* Read the page-size and sector-size journal header fields. */
--    if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize))
--     || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize))
--    ){
--      return rc;
--    }
--
--    /* Versions of SQLite prior to 3.5.8 set the page-size field of the
--    ** journal header to zero. In this case, assume that the Pager.pageSize
--    ** variable is already set to the correct page size.
--    */
--    if( iPageSize==0 ){
--      iPageSize = pPager->pageSize;
--    }
--
--    /* Check that the values read from the page-size and sector-size fields
--    ** are within range. To be 'in range', both values need to be a power
--    ** of two greater than or equal to 512 or 32, and not greater than their 
--    ** respective compile time maximum limits.
--    */
--    if( iPageSize<512                  || iSectorSize<32
--     || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE
--     || ((iPageSize-1)&iPageSize)!=0   || ((iSectorSize-1)&iSectorSize)!=0 
--    ){
--      /* If the either the page-size or sector-size in the journal-header is 
--      ** invalid, then the process that wrote the journal-header must have 
--      ** crashed before the header was synced. In this case stop reading 
--      ** the journal file here.
--      */
--      return SQLITE_DONE;
--    }
--
--    /* Update the page-size to match the value read from the journal. 
--    ** Use a testcase() macro to make sure that malloc failure within 
--    ** PagerSetPagesize() is tested.
--    */
--    rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1);
--    testcase( rc!=SQLITE_OK );
--
--    /* Update the assumed sector-size to match the value used by 
--    ** the process that created this journal. If this journal was
--    ** created by a process other than this one, then this routine
--    ** is being called from within pager_playback(). The local value
--    ** of Pager.sectorSize is restored at the end of that routine.
--    */
--    pPager->sectorSize = iSectorSize;
--  }
--
--  pPager->journalOff += JOURNAL_HDR_SZ(pPager);
--  return rc;
--}
--
-+#define PAGER_OPEN                  0
-+#define PAGER_READER                1
-+#define PAGER_WRITER_LOCKED         2
-+#define PAGER_WRITER_CACHEMOD       3
-+#define PAGER_WRITER_DBMOD          4
-+#define PAGER_WRITER_FINISHED       5
-+#define PAGER_ERROR                 6
- 
- /*
--** Write the supplied master journal name into the journal file for pager
--** pPager at the current location. The master journal name must be the last
--** thing written to a journal file. If the pager is in full-sync mode, the
--** journal file descriptor is advanced to the next sector boundary before
--** anything is written. The format is:
-+** The Pager.eLock variable is almost always set to one of the 
-+** following locking-states, according to the lock currently held on
-+** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
-+** This variable is kept up to date as locks are taken and released by
-+** the pagerLockDb() and pagerUnlockDb() wrappers.
- **
--**   + 4 bytes: PAGER_MJ_PGNO.
--**   + N bytes: Master journal filename in utf-8.
--**   + 4 bytes: N (length of master journal name in bytes, no nul-terminator).
--**   + 4 bytes: Master journal name checksum.
--**   + 8 bytes: aJournalMagic[].
-+** If the VFS xLock() or xUnlock() returns an error other than SQLITE_BUSY
-+** (i.e. one of the SQLITE_IOERR subtypes), it is not clear whether or not
-+** the operation was successful. In these circumstances pagerLockDb() and
-+** pagerUnlockDb() take a conservative approach - eLock is always updated
-+** when unlocking the file, and only updated when locking the file if the
-+** VFS call is successful. This way, the Pager.eLock variable may be set
-+** to a less exclusive (lower) value than the lock that is actually held
-+** at the system level, but it is never set to a more exclusive value.
- **
--** The master journal page checksum is the sum of the bytes in the master
--** journal name, where each byte is interpreted as a signed 8-bit integer.
-+** This is usually safe. If an xUnlock fails or appears to fail, there may 
-+** be a few redundant xLock() calls or a lock may be held for longer than
-+** required, but nothing really goes wrong.
-+**
-+** The exception is when the database file is unlocked as the pager moves
-+** from ERROR to OPEN state. At this point there may be a hot-journal file 
-+** in the file-system that needs to be rolled back (as part of an OPEN->SHARED
-+** transition, by the same pager or any other). If the call to xUnlock()
-+** fails at this point and the pager is left holding an EXCLUSIVE lock, this
-+** can confuse the call to xCheckReservedLock() call made later as part
-+** of hot-journal detection.
-+**
-+** xCheckReservedLock() is defined as returning true "if there is a RESERVED 
-+** lock held by this process or any others". So xCheckReservedLock may 
-+** return true because the caller itself is holding an EXCLUSIVE lock (but
-+** doesn't know it because of a previous error in xUnlock). If this happens
-+** a hot-journal may be mistaken for a journal being created by an active
-+** transaction in another process, causing SQLite to read from the database
-+** without rolling it back.
-+**
-+** To work around this, if a call to xUnlock() fails when unlocking the
-+** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It
-+** is only changed back to a real locking state after a successful call
-+** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition
-+** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK 
-+** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE
-+** lock on the database file before attempting to roll it back. See function
-+** PagerSharedLock() for more detail.
- **
--** If zMaster is a NULL pointer (occurs for a single database transaction), 
--** this call is a no-op.
-+** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in 
-+** PAGER_OPEN state.
- */
--static int writeMasterJournal(Pager *pPager, const char *zMaster){
--  int rc;                          /* Return code */
--  int nMaster;                     /* Length of string zMaster */
--  i64 iHdrOff;                     /* Offset of header in journal file */
--  i64 jrnlSize;                    /* Size of journal file on disk */
--  u32 cksum = 0;                   /* Checksum of string zMaster */
--
--  assert( pPager->setMaster==0 );
--  assert( !pagerUseWal(pPager) );
--
--  if( !zMaster 
--   || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
--   || !isOpen(pPager->jfd)
--  ){
--    return SQLITE_OK;
--  }
--  pPager->setMaster = 1;
--  assert( pPager->journalHdr <= pPager->journalOff );
--
--  /* Calculate the length in bytes and the checksum of zMaster */
--  for(nMaster=0; zMaster[nMaster]; nMaster++){
--    cksum += zMaster[nMaster];
--  }
--
--  /* If in full-sync mode, advance to the next disk sector before writing
--  ** the master journal name. This is in case the previous page written to
--  ** the journal has already been synced.
--  */
--  if( pPager->fullSync ){
--    pPager->journalOff = journalHdrOffset(pPager);
--  }
--  iHdrOff = pPager->journalOff;
--
--  /* Write the master journal data to the end of the journal file. If
--  ** an error occurs, return the error code to the caller.
--  */
--  if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
--   || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4)))
--   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster)))
--   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum)))
--   || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8)))
--  ){
--    return rc;
--  }
--  pPager->journalOff += (nMaster+20);
--
--  /* If the pager is in peristent-journal mode, then the physical 
--  ** journal-file may extend past the end of the master-journal name
--  ** and 8 bytes of magic data just written to the file. This is 
--  ** dangerous because the code to rollback a hot-journal file
--  ** will not be able to find the master-journal name to determine 
--  ** whether or not the journal is hot. 
--  **
--  ** Easiest thing to do in this scenario is to truncate the journal 
--  ** file to the required size.
--  */ 
--  if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize))
--   && jrnlSize>pPager->journalOff
--  ){
--    rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff);
--  }
--  return rc;
--}
-+#define UNKNOWN_LOCK                (EXCLUSIVE_LOCK+1)
- 
- /*
--** Discard the entire contents of the in-memory page-cache.
-+** A macro used for invoking the codec if there is one
- */
--static void pager_reset(Pager *pPager){
--  pPager->iDataVersion++;
--  sqlite3BackupRestart(pPager->pBackup);
--  sqlite3PcacheClear(pPager->pPCache);
--}
-+#ifdef SQLITE_HAS_CODEC
-+# define CODEC1(P,D,N,X,E) \
-+    if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; }
-+# define CODEC2(P,D,N,X,E,O) \
-+    if( P->xCodec==0 ){ O=(char*)D; }else \
-+    if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; }
-+#else
-+# define CODEC1(P,D,N,X,E)   /* NO-OP */
-+# define CODEC2(P,D,N,X,E,O) O=(char*)D
-+#endif
- 
- /*
--** Return the pPager->iDataVersion value
-+** The maximum allowed sector size. 64KiB. If the xSectorsize() method 
-+** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
-+** This could conceivably cause corruption following a power failure on
-+** such a system. This is currently an undocumented limit.
- */
--SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){
--  assert( pPager->eState>PAGER_OPEN );
--  return pPager->iDataVersion;
--}
-+#define MAX_SECTOR_SIZE 0x10000
- 
- /*
--** Free all structures in the Pager.aSavepoint[] array and set both
--** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
--** if it is open and the pager is not in exclusive mode.
-+** An instance of the following structure is allocated for each active
-+** savepoint and statement transaction in the system. All such structures
-+** are stored in the Pager.aSavepoint[] array, which is allocated and
-+** resized using sqlite3Realloc().
-+**
-+** When a savepoint is created, the PagerSavepoint.iHdrOffset field is
-+** set to 0. If a journal-header is written into the main journal while
-+** the savepoint is active, then iHdrOffset is set to the byte offset 
-+** immediately following the last journal record written into the main
-+** journal before the journal-header. This is required during savepoint
-+** rollback (see pagerPlaybackSavepoint()).
- */
--static void releaseAllSavepoints(Pager *pPager){
--  int ii;               /* Iterator for looping through Pager.aSavepoint */
--  for(ii=0; ii<pPager->nSavepoint; ii++){
--    sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
--  }
--  if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){
--    sqlite3OsClose(pPager->sjfd);
--  }
--  sqlite3_free(pPager->aSavepoint);
--  pPager->aSavepoint = 0;
--  pPager->nSavepoint = 0;
--  pPager->nSubRec = 0;
--}
-+typedef struct PagerSavepoint PagerSavepoint;
-+struct PagerSavepoint {
-+  i64 iOffset;                 /* Starting offset in main journal */
-+  i64 iHdrOffset;              /* See above */
-+  Bitvec *pInSavepoint;        /* Set of pages in this savepoint */
-+  Pgno nOrig;                  /* Original number of pages in file */
-+  Pgno iSubRec;                /* Index of first record in sub-journal */
-+#ifndef SQLITE_OMIT_WAL
-+  u32 aWalData[WAL_SAVEPOINT_NDATA];        /* WAL savepoint context */
-+#endif
-+};
- 
- /*
--** Set the bit number pgno in the PagerSavepoint.pInSavepoint 
--** bitvecs of all open savepoints. Return SQLITE_OK if successful
--** or SQLITE_NOMEM if a malloc failure occurs.
-+** Bits of the Pager.doNotSpill flag.  See further description below.
- */
--static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){
--  int ii;                   /* Loop counter */
--  int rc = SQLITE_OK;       /* Result code */
--
--  for(ii=0; ii<pPager->nSavepoint; ii++){
--    PagerSavepoint *p = &pPager->aSavepoint[ii];
--    if( pgno<=p->nOrig ){
--      rc |= sqlite3BitvecSet(p->pInSavepoint, pgno);
--      testcase( rc==SQLITE_NOMEM );
--      assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
--    }
--  }
--  return rc;
--}
-+#define SPILLFLAG_OFF         0x01      /* Never spill cache.  Set via pragma */
-+#define SPILLFLAG_ROLLBACK    0x02      /* Current rolling back, so do not spill */
-+#define SPILLFLAG_NOSYNC      0x04      /* Spill is ok, but do not sync */
- 
- /*
--** This function is a no-op if the pager is in exclusive mode and not
--** in the ERROR state. Otherwise, it switches the pager to PAGER_OPEN
--** state.
-+** An open page cache is an instance of struct Pager. A description of
-+** some of the more important member variables follows:
- **
--** If the pager is not in exclusive-access mode, the database file is
--** completely unlocked. If the file is unlocked and the file-system does
--** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is
--** closed (if it is open).
-+** eState
- **
--** If the pager is in ERROR state when this function is called, the 
--** contents of the pager cache are discarded before switching back to 
--** the OPEN state. Regardless of whether the pager is in exclusive-mode
--** or not, any journal file left in the file-system will be treated
--** as a hot-journal and rolled back the next time a read-transaction
--** is opened (by this or by any other connection).
--*/
--static void pager_unlock(Pager *pPager){
--
--  assert( pPager->eState==PAGER_READER 
--       || pPager->eState==PAGER_OPEN 
--       || pPager->eState==PAGER_ERROR 
--  );
--
--  sqlite3BitvecDestroy(pPager->pInJournal);
--  pPager->pInJournal = 0;
--  releaseAllSavepoints(pPager);
--
--  if( pagerUseWal(pPager) ){
--    assert( !isOpen(pPager->jfd) );
--    sqlite3WalEndReadTransaction(pPager->pWal);
--    pPager->eState = PAGER_OPEN;
--  }else if( !pPager->exclusiveMode ){
--    int rc;                       /* Error code returned by pagerUnlockDb() */
--    int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0;
--
--    /* If the operating system support deletion of open files, then
--    ** close the journal file when dropping the database lock.  Otherwise
--    ** another connection with journal_mode=delete might delete the file
--    ** out from under us.
--    */
--    assert( (PAGER_JOURNALMODE_MEMORY   & 5)!=1 );
--    assert( (PAGER_JOURNALMODE_OFF      & 5)!=1 );
--    assert( (PAGER_JOURNALMODE_WAL      & 5)!=1 );
--    assert( (PAGER_JOURNALMODE_DELETE   & 5)!=1 );
--    assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
--    assert( (PAGER_JOURNALMODE_PERSIST  & 5)==1 );
--    if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN)
--     || 1!=(pPager->journalMode & 5)
--    ){
--      sqlite3OsClose(pPager->jfd);
--    }
--
--    /* If the pager is in the ERROR state and the call to unlock the database
--    ** file fails, set the current lock to UNKNOWN_LOCK. See the comment
--    ** above the #define for UNKNOWN_LOCK for an explanation of why this
--    ** is necessary.
--    */
--    rc = pagerUnlockDb(pPager, NO_LOCK);
--    if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){
--      pPager->eLock = UNKNOWN_LOCK;
--    }
--
--    /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here
--    ** without clearing the error code. This is intentional - the error
--    ** code is cleared and the cache reset in the block below.
--    */
--    assert( pPager->errCode || pPager->eState!=PAGER_ERROR );
--    pPager->changeCountDone = 0;
--    pPager->eState = PAGER_OPEN;
--  }
--
--  /* If Pager.errCode is set, the contents of the pager cache cannot be
--  ** trusted. Now that there are no outstanding references to the pager,
--  ** it can safely move back to PAGER_OPEN state. This happens in both
--  ** normal and exclusive-locking mode.
--  */
--  if( pPager->errCode ){
--    assert( !MEMDB );
--    pager_reset(pPager);
--    pPager->changeCountDone = pPager->tempFile;
--    pPager->eState = PAGER_OPEN;
--    pPager->errCode = SQLITE_OK;
--    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
--  }
--
--  pPager->journalOff = 0;
--  pPager->journalHdr = 0;
--  pPager->setMaster = 0;
--}
--
--/*
--** This function is called whenever an IOERR or FULL error that requires
--** the pager to transition into the ERROR state may ahve occurred.
--** The first argument is a pointer to the pager structure, the second 
--** the error-code about to be returned by a pager API function. The 
--** value returned is a copy of the second argument to this function. 
-+**   The current 'state' of the pager object. See the comment and state
-+**   diagram above for a description of the pager state.
- **
--** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the
--** IOERR sub-codes, the pager enters the ERROR state and the error code
--** is stored in Pager.errCode. While the pager remains in the ERROR state,
--** all major API calls on the Pager will immediately return Pager.errCode.
-+** eLock
- **
--** The ERROR state indicates that the contents of the pager-cache 
--** cannot be trusted. This state can be cleared by completely discarding 
--** the contents of the pager-cache. If a transaction was active when
--** the persistent error occurred, then the rollback journal may need
--** to be replayed to restore the contents of the database file (as if
--** it were a hot-journal).
--*/
--static int pager_error(Pager *pPager, int rc){
--  int rc2 = rc & 0xff;
--  assert( rc==SQLITE_OK || !MEMDB );
--  assert(
--       pPager->errCode==SQLITE_FULL ||
--       pPager->errCode==SQLITE_OK ||
--       (pPager->errCode & 0xff)==SQLITE_IOERR
--  );
--  if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
--    pPager->errCode = rc;
--    pPager->eState = PAGER_ERROR;
--  }
--  return rc;
--}
--
--static int pager_truncate(Pager *pPager, Pgno nPage);
--
--/*
--** This routine ends a transaction. A transaction is usually ended by 
--** either a COMMIT or a ROLLBACK operation. This routine may be called 
--** after rollback of a hot-journal, or if an error occurs while opening
--** the journal file or writing the very first journal-header of a
--** database transaction.
--** 
--** This routine is never called in PAGER_ERROR state. If it is called
--** in PAGER_NONE or PAGER_SHARED state and the lock held is less
--** exclusive than a RESERVED lock, it is a no-op.
-+**   For a real on-disk database, the current lock held on the database file -
-+**   NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
- **
--** Otherwise, any active savepoints are released.
-+**   For a temporary or in-memory database (neither of which require any
-+**   locks), this variable is always set to EXCLUSIVE_LOCK. Since such
-+**   databases always have Pager.exclusiveMode==1, this tricks the pager
-+**   logic into thinking that it already has all the locks it will ever
-+**   need (and no reason to release them).
- **
--** If the journal file is open, then it is "finalized". Once a journal 
--** file has been finalized it is not possible to use it to roll back a 
--** transaction. Nor will it be considered to be a hot-journal by this
--** or any other database connection. Exactly how a journal is finalized
--** depends on whether or not the pager is running in exclusive mode and
--** the current journal-mode (Pager.journalMode value), as follows:
-+**   In some (obscure) circumstances, this variable may also be set to
-+**   UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for
-+**   details.
- **
--**   journalMode==MEMORY
--**     Journal file descriptor is simply closed. This destroys an 
--**     in-memory journal.
-+** changeCountDone
- **
--**   journalMode==TRUNCATE
--**     Journal file is truncated to zero bytes in size.
-+**   This boolean variable is used to make sure that the change-counter 
-+**   (the 4-byte header field at byte offset 24 of the database file) is 
-+**   not updated more often than necessary. 
- **
--**   journalMode==PERSIST
--**     The first 28 bytes of the journal file are zeroed. This invalidates
--**     the first journal header in the file, and hence the entire journal
--**     file. An invalid journal file cannot be rolled back.
-+**   It is set to true when the change-counter field is updated, which 
-+**   can only happen if an exclusive lock is held on the database file.
-+**   It is cleared (set to false) whenever an exclusive lock is 
-+**   relinquished on the database file. Each time a transaction is committed,
-+**   The changeCountDone flag is inspected. If it is true, the work of
-+**   updating the change-counter is omitted for the current transaction.
- **
--**   journalMode==DELETE
--**     The journal file is closed and deleted using sqlite3OsDelete().
-+**   This mechanism means that when running in exclusive mode, a connection 
-+**   need only update the change-counter once, for the first transaction
-+**   committed.
- **
--**     If the pager is running in exclusive mode, this method of finalizing
--**     the journal file is never used. Instead, if the journalMode is
--**     DELETE and the pager is in exclusive mode, the method described under
--**     journalMode==PERSIST is used instead.
-+** setMaster
- **
--** After the journal is finalized, the pager moves to PAGER_READER state.
--** If running in non-exclusive rollback mode, the lock on the file is 
--** downgraded to a SHARED_LOCK.
-+**   When PagerCommitPhaseOne() is called to commit a transaction, it may
-+**   (or may not) specify a master-journal name to be written into the 
-+**   journal file before it is synced to disk.
- **
--** SQLITE_OK is returned if no error occurs. If an error occurs during
--** any of the IO operations to finalize the journal file or unlock the
--** database then the IO error code is returned to the user. If the 
--** operation to finalize the journal file fails, then the code still
--** tries to unlock the database file if not in exclusive mode. If the
--** unlock operation fails as well, then the first error code related
--** to the first error encountered (the journal finalization one) is
--** returned.
--*/
--static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
--  int rc = SQLITE_OK;      /* Error code from journal finalization operation */
--  int rc2 = SQLITE_OK;     /* Error code from db file unlock operation */
--
--  /* Do nothing if the pager does not have an open write transaction
--  ** or at least a RESERVED lock. This function may be called when there
--  ** is no write-transaction active but a RESERVED or greater lock is
--  ** held under two circumstances:
--  **
--  **   1. After a successful hot-journal rollback, it is called with
--  **      eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK.
--  **
--  **   2. If a connection with locking_mode=exclusive holding an EXCLUSIVE 
--  **      lock switches back to locking_mode=normal and then executes a
--  **      read-transaction, this function is called with eState==PAGER_READER 
--  **      and eLock==EXCLUSIVE_LOCK when the read-transaction is closed.
--  */
--  assert( assert_pager_state(pPager) );
--  assert( pPager->eState!=PAGER_ERROR );
--  if( pPager->eState<PAGER_WRITER_LOCKED && pPager->eLock<RESERVED_LOCK ){
--    return SQLITE_OK;
--  }
--
--  releaseAllSavepoints(pPager);
--  assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
--  if( isOpen(pPager->jfd) ){
--    assert( !pagerUseWal(pPager) );
--
--    /* Finalize the journal file. */
--    if( sqlite3IsMemJournal(pPager->jfd) ){
--      assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
--      sqlite3OsClose(pPager->jfd);
--    }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
--      if( pPager->journalOff==0 ){
--        rc = SQLITE_OK;
--      }else{
--        rc = sqlite3OsTruncate(pPager->jfd, 0);
--        if( rc==SQLITE_OK && pPager->fullSync ){
--          /* Make sure the new file size is written into the inode right away.
--          ** Otherwise the journal might resurrect following a power loss and
--          ** cause the last transaction to roll back.  See
--          ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
--          */
--          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
--        }
--      }
--      pPager->journalOff = 0;
--    }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
--      || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
--    ){
--      rc = zeroJournalHdr(pPager, hasMaster);
--      pPager->journalOff = 0;
--    }else{
--      /* This branch may be executed with Pager.journalMode==MEMORY if
--      ** a hot-journal was just rolled back. In this case the journal
--      ** file should be closed and deleted. If this connection writes to
--      ** the database file, it will do so using an in-memory journal. 
--      */
--      int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
--      assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE 
--           || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
--           || pPager->journalMode==PAGER_JOURNALMODE_WAL 
--      );
--      sqlite3OsClose(pPager->jfd);
--      if( bDelete ){
--        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
--      }
--    }
--  }
--
--#ifdef SQLITE_CHECK_PAGES
--  sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
--  if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
--    PgHdr *p = sqlite3PagerLookup(pPager, 1);
--    if( p ){
--      p->pageHash = 0;
--      sqlite3PagerUnrefNotNull(p);
--    }
--  }
--#endif
--
--  sqlite3BitvecDestroy(pPager->pInJournal);
--  pPager->pInJournal = 0;
--  pPager->nRec = 0;
--  sqlite3PcacheCleanAll(pPager->pPCache);
--  sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
--
--  if( pagerUseWal(pPager) ){
--    /* Drop the WAL write-lock, if any. Also, if the connection was in 
--    ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE 
--    ** lock held on the database file.
--    */
--    rc2 = sqlite3WalEndWriteTransaction(pPager->pWal);
--    assert( rc2==SQLITE_OK );
--  }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){
--    /* This branch is taken when committing a transaction in rollback-journal
--    ** mode if the database file on disk is larger than the database image.
--    ** At this point the journal has been finalized and the transaction 
--    ** successfully committed, but the EXCLUSIVE lock is still held on the
--    ** file. So it is safe to truncate the database file to its minimum
--    ** required size.  */
--    assert( pPager->eLock==EXCLUSIVE_LOCK );
--    rc = pager_truncate(pPager, pPager->dbSize);
--  }
--
--  if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){
--    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0);
--    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
--  }
--
--  if( !pPager->exclusiveMode 
--   && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
--  ){
--    rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
--    pPager->changeCountDone = 0;
--  }
--  pPager->eState = PAGER_READER;
--  pPager->setMaster = 0;
--
--  return (rc==SQLITE_OK?rc2:rc);
--}
--
--/*
--** Execute a rollback if a transaction is active and unlock the 
--** database file. 
-+**   Whether or not a journal file contains a master-journal pointer affects 
-+**   the way in which the journal file is finalized after the transaction is 
-+**   committed or rolled back when running in "journal_mode=PERSIST" mode.
-+**   If a journal file does not contain a master-journal pointer, it is
-+**   finalized by overwriting the first journal header with zeroes. If
-+**   it does contain a master-journal pointer the journal file is finalized 
-+**   by truncating it to zero bytes, just as if the connection were 
-+**   running in "journal_mode=truncate" mode.
-+**
-+**   Journal files that contain master journal pointers cannot be finalized
-+**   simply by overwriting the first journal-header with zeroes, as the
-+**   master journal pointer could interfere with hot-journal rollback of any
-+**   subsequently interrupted transaction that reuses the journal file.
-+**
-+**   The flag is cleared as soon as the journal file is finalized (either
-+**   by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the
-+**   journal file from being successfully finalized, the setMaster flag
-+**   is cleared anyway (and the pager will move to ERROR state).
-+**
-+** doNotSpill
-+**
-+**   This variables control the behavior of cache-spills  (calls made by
-+**   the pcache module to the pagerStress() routine to write cached data
-+**   to the file-system in order to free up memory).
-+**
-+**   When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set,
-+**   writing to the database from pagerStress() is disabled altogether.
-+**   The SPILLFLAG_ROLLBACK case is done in a very obscure case that
-+**   comes up during savepoint rollback that requires the pcache module
-+**   to allocate a new page to prevent the journal file from being written
-+**   while it is being traversed by code in pager_playback().  The SPILLFLAG_OFF
-+**   case is a user preference.
-+** 
-+**   If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStress()
-+**   is permitted, but syncing the journal file is not. This flag is set
-+**   by sqlite3PagerWrite() when the file-system sector-size is larger than
-+**   the database page-size in order to prevent a journal sync from happening 
-+**   in between the journalling of two pages on the same sector. 
- **
--** If the pager has already entered the ERROR state, do not attempt 
--** the rollback at this time. Instead, pager_unlock() is called. The
--** call to pager_unlock() will discard all in-memory pages, unlock
--** the database file and move the pager back to OPEN state. If this 
--** means that there is a hot-journal left in the file-system, the next 
--** connection to obtain a shared lock on the pager (which may be this one) 
--** will roll it back.
-+** subjInMemory
- **
--** If the pager has not already entered the ERROR state, but an IO or
--** malloc error occurs during a rollback, then this will itself cause 
--** the pager to enter the ERROR state. Which will be cleared by the
--** call to pager_unlock(), as described above.
--*/
--static void pagerUnlockAndRollback(Pager *pPager){
--  if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){
--    assert( assert_pager_state(pPager) );
--    if( pPager->eState>=PAGER_WRITER_LOCKED ){
--      sqlite3BeginBenignMalloc();
--      sqlite3PagerRollback(pPager);
--      sqlite3EndBenignMalloc();
--    }else if( !pPager->exclusiveMode ){
--      assert( pPager->eState==PAGER_READER );
--      pager_end_transaction(pPager, 0, 0);
--    }
--  }
--  pager_unlock(pPager);
--}
--
--/*
--** Parameter aData must point to a buffer of pPager->pageSize bytes
--** of data. Compute and return a checksum based ont the contents of the 
--** page of data and the current value of pPager->cksumInit.
-+**   This is a boolean variable. If true, then any required sub-journal
-+**   is opened as an in-memory journal file. If false, then in-memory
-+**   sub-journals are only used for in-memory pager files.
- **
--** This is not a real checksum. It is really just the sum of the 
--** random initial value (pPager->cksumInit) and every 200th byte
--** of the page data, starting with byte offset (pPager->pageSize%200).
--** Each byte is interpreted as an 8-bit unsigned integer.
-+**   This variable is updated by the upper layer each time a new 
-+**   write-transaction is opened.
- **
--** Changing the formula used to compute this checksum results in an
--** incompatible journal file format.
-+** dbSize, dbOrigSize, dbFileSize
- **
--** If journal corruption occurs due to a power failure, the most likely 
--** scenario is that one end or the other of the record will be changed. 
--** It is much less likely that the two ends of the journal record will be
--** correct and the middle be corrupt.  Thus, this "checksum" scheme,
--** though fast and simple, catches the mostly likely kind of corruption.
--*/
--static u32 pager_cksum(Pager *pPager, const u8 *aData){
--  u32 cksum = pPager->cksumInit;         /* Checksum value to return */
--  int i = pPager->pageSize-200;          /* Loop counter */
--  while( i>0 ){
--    cksum += aData[i];
--    i -= 200;
--  }
--  return cksum;
--}
--
--/*
--** Report the current page size and number of reserved bytes back
--** to the codec.
--*/
--#ifdef SQLITE_HAS_CODEC
--static void pagerReportSize(Pager *pPager){
--  if( pPager->xCodecSizeChng ){
--    pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
--                           (int)pPager->nReserve);
--  }
--}
--#else
--# define pagerReportSize(X)     /* No-op if we do not support a codec */
--#endif
--
--/*
--** Read a single page from either the journal file (if isMainJrnl==1) or
--** from the sub-journal (if isMainJrnl==0) and playback that page.
--** The page begins at offset *pOffset into the file. The *pOffset
--** value is increased to the start of the next page in the journal.
-+**   Variable dbSize is set to the number of pages in the database file.
-+**   It is valid in PAGER_READER and higher states (all states except for
-+**   OPEN and ERROR). 
- **
--** The main rollback journal uses checksums - the statement journal does 
--** not.
-+**   dbSize is set based on the size of the database file, which may be 
-+**   larger than the size of the database (the value stored at offset
-+**   28 of the database header by the btree). If the size of the file
-+**   is not an integer multiple of the page-size, the value stored in
-+**   dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2).
-+**   Except, any file that is greater than 0 bytes in size is considered
-+**   to have at least one page. (i.e. a 1KB file with 2K page-size leads
-+**   to dbSize==1).
- **
--** If the page number of the page record read from the (sub-)journal file
--** is greater than the current value of Pager.dbSize, then playback is
--** skipped and SQLITE_OK is returned.
-+**   During a write-transaction, if pages with page-numbers greater than
-+**   dbSize are modified in the cache, dbSize is updated accordingly.
-+**   Similarly, if the database is truncated using PagerTruncateImage(), 
-+**   dbSize is updated.
- **
--** If pDone is not NULL, then it is a record of pages that have already
--** been played back.  If the page at *pOffset has already been played back
--** (if the corresponding pDone bit is set) then skip the playback.
--** Make sure the pDone bit corresponding to the *pOffset page is set
--** prior to returning.
-+**   Variables dbOrigSize and dbFileSize are valid in states 
-+**   PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize
-+**   variable at the start of the transaction. It is used during rollback,
-+**   and to determine whether or not pages need to be journalled before
-+**   being modified.
- **
--** If the page record is successfully read from the (sub-)journal file
--** and played back, then SQLITE_OK is returned. If an IO error occurs
--** while reading the record from the (sub-)journal file or while writing
--** to the database file, then the IO error code is returned. If data
--** is successfully read from the (sub-)journal file but appears to be
--** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
--** two circumstances:
--** 
--**   * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or
--**   * If the record is being rolled back from the main journal file
--**     and the checksum field does not match the record content.
-+**   Throughout a write-transaction, dbFileSize contains the size of
-+**   the file on disk in pages. It is set to a copy of dbSize when the
-+**   write-transaction is first opened, and updated when VFS calls are made
-+**   to write or truncate the database file on disk. 
- **
--** Neither of these two scenarios are possible during a savepoint rollback.
-+**   The only reason the dbFileSize variable is required is to suppress 
-+**   unnecessary calls to xTruncate() after committing a transaction. If, 
-+**   when a transaction is committed, the dbFileSize variable indicates 
-+**   that the database file is larger than the database image (Pager.dbSize), 
-+**   pager_truncate() is called. The pager_truncate() call uses xFilesize()
-+**   to measure the database file on disk, and then truncates it if required.
-+**   dbFileSize is not used when rolling back a transaction. In this case
-+**   pager_truncate() is called unconditionally (which means there may be
-+**   a call to xFilesize() that is not strictly required). In either case,
-+**   pager_truncate() may cause the file to become smaller or larger.
- **
--** If this is a savepoint rollback, then memory may have to be dynamically
--** allocated by this function. If this is the case and an allocation fails,
--** SQLITE_NOMEM is returned.
-+** dbHintSize
-+**
-+**   The dbHintSize variable is used to limit the number of calls made to
-+**   the VFS xFileControl(FCNTL_SIZE_HINT) method. 
-+**
-+**   dbHintSize is set to a copy of the dbSize variable when a
-+**   write-transaction is opened (at the same time as dbFileSize and
-+**   dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called,
-+**   dbHintSize is increased to the number of pages that correspond to the
-+**   size-hint passed to the method call. See pager_write_pagelist() for 
-+**   details.
-+**
-+** errCode
-+**
-+**   The Pager.errCode variable is only ever used in PAGER_ERROR state. It
-+**   is set to zero in all other states. In PAGER_ERROR state, Pager.errCode 
-+**   is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX 
-+**   sub-codes.
- */
--static int pager_playback_one_page(
--  Pager *pPager,                /* The pager being played back */
--  i64 *pOffset,                 /* Offset of record to playback */
--  Bitvec *pDone,                /* Bitvec of pages already played back */
--  int isMainJrnl,               /* 1 -> main journal. 0 -> sub-journal. */
--  int isSavepnt                 /* True for a savepoint rollback */
--){
--  int rc;
--  PgHdr *pPg;                   /* An existing page in the cache */
--  Pgno pgno;                    /* The page number of a page in journal */
--  u32 cksum;                    /* Checksum used for sanity checking */
--  char *aData;                  /* Temporary storage for the page */
--  sqlite3_file *jfd;            /* The file descriptor for the journal file */
--  int isSynced;                 /* True if journal page is synced */
-+struct Pager {
-+  sqlite3_vfs *pVfs;          /* OS functions to use for IO */
-+  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
-+  u8 journalMode;             /* One of the PAGER_JOURNALMODE_* values */
-+  u8 useJournal;              /* Use a rollback journal on this file */
-+  u8 noSync;                  /* Do not sync the journal if true */
-+  u8 fullSync;                /* Do extra syncs of the journal for robustness */
-+  u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
-+  u8 walSyncFlags;            /* SYNC_NORMAL or SYNC_FULL for wal writes */
-+  u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
-+  u8 tempFile;                /* zFilename is a temporary or immutable file */
-+  u8 noLock;                  /* Do not lock (except in WAL mode) */
-+  u8 readOnly;                /* True for a read-only database */
-+  u8 memDb;                   /* True to inhibit all file I/O */
- 
--  assert( (isMainJrnl&~1)==0 );      /* isMainJrnl is 0 or 1 */
--  assert( (isSavepnt&~1)==0 );       /* isSavepnt is 0 or 1 */
--  assert( isMainJrnl || pDone );     /* pDone always used on sub-journals */
--  assert( isSavepnt || pDone==0 );   /* pDone never used on non-savepoint */
-+  /**************************************************************************
-+  ** The following block contains those class members that change during
-+  ** routine operation.  Class members not in this block are either fixed
-+  ** when the pager is first created or else only change when there is a
-+  ** significant mode change (such as changing the page_size, locking_mode,
-+  ** or the journal_mode).  From another view, these class members describe
-+  ** the "state" of the pager, while other class members describe the
-+  ** "configuration" of the pager.
++** This function advances the iterator so that it points to the last 
++** relevant rowid on the page and, if necessary, initializes the 
++** aRowidOffset[] and iRowidOffset variables. At this point the iterator
++** is in its regular state - Fts5SegIter.iLeafOffset points to the first
++** byte of the position list content associated with said rowid.
++*/
++static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
++  int eDetail = p->pConfig->eDetail;
++  int n = pIter->pLeaf->szLeaf;
++  int i = pIter->iLeafOffset;
++  u8 *a = pIter->pLeaf->p;
++  int iRowidOffset = 0;
++
++  if( n>pIter->iEndofDoclist ){
++    n = pIter->iEndofDoclist;
++  }
++
++  ASSERT_SZLEAF_OK(pIter->pLeaf);
++  while( 1 ){
++    i64 iDelta = 0;
++
++    if( eDetail==FTS5_DETAIL_NONE ){
++      /* todo */
++      if( i<n && a[i]==0 ){
++        i++;
++        if( i<n && a[i]==0 ) i++;
++      }
++    }else{
++      int nPos;
++      int bDummy;
++      i += fts5GetPoslistSize(&a[i], &nPos, &bDummy);
++      i += nPos;
++    }
++    if( i>=n ) break;
++    i += fts5GetVarint(&a[i], (u64*)&iDelta);
++    pIter->iRowid += iDelta;
++
++    /* If necessary, grow the pIter->aRowidOffset[] array. */
++    if( iRowidOffset>=pIter->nRowidOffset ){
++      int nNew = pIter->nRowidOffset + 8;
++      int *aNew = (int*)sqlite3_realloc(pIter->aRowidOffset, nNew*sizeof(int));
++      if( aNew==0 ){
++        p->rc = SQLITE_NOMEM;
++        break;
++      }
++      pIter->aRowidOffset = aNew;
++      pIter->nRowidOffset = nNew;
++    }
++
++    pIter->aRowidOffset[iRowidOffset++] = pIter->iLeafOffset;
++    pIter->iLeafOffset = i;
++  }
++  pIter->iRowidOffset = iRowidOffset;
++  fts5SegIterLoadNPos(p, pIter);
++}
++
++/*
++**
++*/
++static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){
++  assert( pIter->flags & FTS5_SEGITER_REVERSE );
++  assert( pIter->flags & FTS5_SEGITER_ONETERM );
++
++  fts5DataRelease(pIter->pLeaf);
++  pIter->pLeaf = 0;
++  while( p->rc==SQLITE_OK && pIter->iLeafPgno>pIter->iTermLeafPgno ){
++    Fts5Data *pNew;
++    pIter->iLeafPgno--;
++    pNew = fts5DataRead(p, FTS5_SEGMENT_ROWID(
++          pIter->pSeg->iSegid, pIter->iLeafPgno
++    ));
++    if( pNew ){
++      /* iTermLeafOffset may be equal to szLeaf if the term is the last
++      ** thing on the page - i.e. the first rowid is on the following page.
++      ** In this case leave pIter->pLeaf==0, this iterator is at EOF. */
++      if( pIter->iLeafPgno==pIter->iTermLeafPgno ){
++        assert( pIter->pLeaf==0 );
++        if( pIter->iTermLeafOffset<pNew->szLeaf ){
++          pIter->pLeaf = pNew;
++          pIter->iLeafOffset = pIter->iTermLeafOffset;
++        }
++      }else{
++        int iRowidOff;
++        iRowidOff = fts5LeafFirstRowidOff(pNew);
++        if( iRowidOff ){
++          pIter->pLeaf = pNew;
++          pIter->iLeafOffset = iRowidOff;
++        }
++      }
++
++      if( pIter->pLeaf ){
++        u8 *a = &pIter->pLeaf->p[pIter->iLeafOffset];
++        pIter->iLeafOffset += fts5GetVarint(a, (u64*)&pIter->iRowid);
++        break;
++      }else{
++        fts5DataRelease(pNew);
++      }
++    }
++  }
++
++  if( pIter->pLeaf ){
++    pIter->iEndofDoclist = pIter->pLeaf->nn+1;
++    fts5SegIterReverseInitPage(p, pIter);
++  }
++}
++
++/*
++** Return true if the iterator passed as the second argument currently
++** points to a delete marker. A delete marker is an entry with a 0 byte
++** position-list.
++*/
++static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5Iter *pIter){
++  Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
++  return (p->rc==SQLITE_OK && pSeg->pLeaf && pSeg->nPos==0);
++}
++
++/*
++** Advance iterator pIter to the next entry.
++**
++** This version of fts5SegIterNext() is only used by reverse iterators.
++*/
++static void fts5SegIterNext_Reverse(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5SegIter *pIter,             /* Iterator to advance */
++  int *pbUnused                   /* Unused */
++){
++  assert( pIter->flags & FTS5_SEGITER_REVERSE );
++  assert( pIter->pNextLeaf==0 );
++  UNUSED_PARAM(pbUnused);
++
++  if( pIter->iRowidOffset>0 ){
++    u8 *a = pIter->pLeaf->p;
++    int iOff;
++    i64 iDelta;
++
++    pIter->iRowidOffset--;
++    pIter->iLeafOffset = pIter->aRowidOffset[pIter->iRowidOffset];
++    fts5SegIterLoadNPos(p, pIter);
++    iOff = pIter->iLeafOffset;
++    if( p->pConfig->eDetail!=FTS5_DETAIL_NONE ){
++      iOff += pIter->nPos;
++    }
++    fts5GetVarint(&a[iOff], (u64*)&iDelta);
++    pIter->iRowid -= iDelta;
++  }else{
++    fts5SegIterReverseNewPage(p, pIter);
++  }
++}
++
++/*
++** Advance iterator pIter to the next entry.
++**
++** This version of fts5SegIterNext() is only used if detail=none and the
++** iterator is not a reverse direction iterator.
++*/
++static void fts5SegIterNext_None(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5SegIter *pIter,             /* Iterator to advance */
++  int *pbNewTerm                  /* OUT: Set for new term */
++){
++  int iOff;
++
++  assert( p->rc==SQLITE_OK );
++  assert( (pIter->flags & FTS5_SEGITER_REVERSE)==0 );
++  assert( p->pConfig->eDetail==FTS5_DETAIL_NONE );
++
++  ASSERT_SZLEAF_OK(pIter->pLeaf);
++  iOff = pIter->iLeafOffset;
++
++  /* Next entry is on the next page */
++  if( pIter->pSeg && iOff>=pIter->pLeaf->szLeaf ){
++    fts5SegIterNextPage(p, pIter);
++    if( p->rc || pIter->pLeaf==0 ) return;
++    pIter->iRowid = 0;
++    iOff = 4;
++  }
++
++  if( iOff<pIter->iEndofDoclist ){
++    /* Next entry is on the current page */
++    i64 iDelta;
++    iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta);
++    pIter->iLeafOffset = iOff;
++    pIter->iRowid += iDelta;
++  }else if( (pIter->flags & FTS5_SEGITER_ONETERM)==0 ){
++    if( pIter->pSeg ){
++      int nKeep = 0;
++      if( iOff!=fts5LeafFirstTermOff(pIter->pLeaf) ){
++        iOff += fts5GetVarint32(&pIter->pLeaf->p[iOff], nKeep);
++      }
++      pIter->iLeafOffset = iOff;
++      fts5SegIterLoadTerm(p, pIter, nKeep);
++    }else{
++      const u8 *pList = 0;
++      const char *zTerm = 0;
++      int nList;
++      sqlite3Fts5HashScanNext(p->pHash);
++      sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList);
++      if( pList==0 ) goto next_none_eof;
++      pIter->pLeaf->p = (u8*)pList;
++      pIter->pLeaf->nn = nList;
++      pIter->pLeaf->szLeaf = nList;
++      pIter->iEndofDoclist = nList;
++      sqlite3Fts5BufferSet(&p->rc,&pIter->term, (int)strlen(zTerm), (u8*)zTerm);
++      pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
++    }
++
++    if( pbNewTerm ) *pbNewTerm = 1;
++  }else{
++    goto next_none_eof;
++  }
++
++  fts5SegIterLoadNPos(p, pIter);
++
++  return;
++ next_none_eof:
++  fts5DataRelease(pIter->pLeaf);
++  pIter->pLeaf = 0;
++}
++
++
++/*
++** Advance iterator pIter to the next entry. 
++**
++** If an error occurs, Fts5Index.rc is set to an appropriate error code. It 
++** is not considered an error if the iterator reaches EOF. If an error has 
++** already occurred when this function is called, it is a no-op.
++*/
++static void fts5SegIterNext(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5SegIter *pIter,             /* Iterator to advance */
++  int *pbNewTerm                  /* OUT: Set for new term */
++){
++  Fts5Data *pLeaf = pIter->pLeaf;
++  int iOff;
++  int bNewTerm = 0;
++  int nKeep = 0;
++  u8 *a;
++  int n;
++
++  assert( pbNewTerm==0 || *pbNewTerm==0 );
++  assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE );
++
++  /* Search for the end of the position list within the current page. */
++  a = pLeaf->p;
++  n = pLeaf->szLeaf;
++
++  ASSERT_SZLEAF_OK(pLeaf);
++  iOff = pIter->iLeafOffset + pIter->nPos;
++
++  if( iOff<n ){
++    /* The next entry is on the current page. */
++    assert_nc( iOff<=pIter->iEndofDoclist );
++    if( iOff>=pIter->iEndofDoclist ){
++      bNewTerm = 1;
++      if( iOff!=fts5LeafFirstTermOff(pLeaf) ){
++        iOff += fts5GetVarint32(&a[iOff], nKeep);
++      }
++    }else{
++      u64 iDelta;
++      iOff += sqlite3Fts5GetVarint(&a[iOff], &iDelta);
++      pIter->iRowid += iDelta;
++      assert_nc( iDelta>0 );
++    }
++    pIter->iLeafOffset = iOff;
++
++  }else if( pIter->pSeg==0 ){
++    const u8 *pList = 0;
++    const char *zTerm = 0;
++    int nList = 0;
++    assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm );
++    if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){
++      sqlite3Fts5HashScanNext(p->pHash);
++      sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList);
++    }
++    if( pList==0 ){
++      fts5DataRelease(pIter->pLeaf);
++      pIter->pLeaf = 0;
++    }else{
++      pIter->pLeaf->p = (u8*)pList;
++      pIter->pLeaf->nn = nList;
++      pIter->pLeaf->szLeaf = nList;
++      pIter->iEndofDoclist = nList+1;
++      sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm),
++          (u8*)zTerm);
++      pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
++      *pbNewTerm = 1;
++    }
++  }else{
++    iOff = 0;
++    /* Next entry is not on the current page */
++    while( iOff==0 ){
++      fts5SegIterNextPage(p, pIter);
++      pLeaf = pIter->pLeaf;
++      if( pLeaf==0 ) break;
++      ASSERT_SZLEAF_OK(pLeaf);
++      if( (iOff = fts5LeafFirstRowidOff(pLeaf)) && iOff<pLeaf->szLeaf ){
++        iOff += sqlite3Fts5GetVarint(&pLeaf->p[iOff], (u64*)&pIter->iRowid);
++        pIter->iLeafOffset = iOff;
++
++        if( pLeaf->nn>pLeaf->szLeaf ){
++          pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
++              &pLeaf->p[pLeaf->szLeaf], pIter->iEndofDoclist
++          );
++        }
++      }
++      else if( pLeaf->nn>pLeaf->szLeaf ){
++        pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
++            &pLeaf->p[pLeaf->szLeaf], iOff
++        );
++        pIter->iLeafOffset = iOff;
++        pIter->iEndofDoclist = iOff;
++        bNewTerm = 1;
++      }
++      assert_nc( iOff<pLeaf->szLeaf );
++      if( iOff>pLeaf->szLeaf ){
++        p->rc = FTS5_CORRUPT;
++        return;
++      }
++    }
++  }
++
++  /* Check if the iterator is now at EOF. If so, return early. */
++  if( pIter->pLeaf ){
++    if( bNewTerm ){
++      if( pIter->flags & FTS5_SEGITER_ONETERM ){
++        fts5DataRelease(pIter->pLeaf);
++        pIter->pLeaf = 0;
++      }else{
++        fts5SegIterLoadTerm(p, pIter, nKeep);
++        fts5SegIterLoadNPos(p, pIter);
++        if( pbNewTerm ) *pbNewTerm = 1;
++      }
++    }else{
++      /* The following could be done by calling fts5SegIterLoadNPos(). But
++      ** this block is particularly performance critical, so equivalent
++      ** code is inlined. 
++      **
++      ** Later: Switched back to fts5SegIterLoadNPos() because it supports
++      ** detail=none mode. Not ideal.
++      */
++      int nSz;
++      assert( p->rc==SQLITE_OK );
++      assert( pIter->iLeafOffset<=pIter->pLeaf->nn );
++      fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz);
++      pIter->bDel = (nSz & 0x0001);
++      pIter->nPos = nSz>>1;
++      assert_nc( pIter->nPos>=0 );
++    }
++  }
++}
++
++#define SWAPVAL(T, a, b) { T tmp; tmp=a; a=b; b=tmp; }
++
++#define fts5IndexSkipVarint(a, iOff) {            \
++  int iEnd = iOff+9;                              \
++  while( (a[iOff++] & 0x80) && iOff<iEnd );       \
++}
++
++/*
++** Iterator pIter currently points to the first rowid in a doclist. This
++** function sets the iterator up so that iterates in reverse order through
++** the doclist.
++*/
++static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){
++  Fts5DlidxIter *pDlidx = pIter->pDlidx;
++  Fts5Data *pLast = 0;
++  int pgnoLast = 0;
++
++  if( pDlidx ){
++    int iSegid = pIter->pSeg->iSegid;
++    pgnoLast = fts5DlidxIterPgno(pDlidx);
++    pLast = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast));
++  }else{
++    Fts5Data *pLeaf = pIter->pLeaf;         /* Current leaf data */
++
++    /* Currently, Fts5SegIter.iLeafOffset points to the first byte of
++    ** position-list content for the current rowid. Back it up so that it
++    ** points to the start of the position-list size field. */
++    int iPoslist;
++    if( pIter->iTermLeafPgno==pIter->iLeafPgno ){
++      iPoslist = pIter->iTermLeafOffset;
++    }else{
++      iPoslist = 4;
++    }
++    fts5IndexSkipVarint(pLeaf->p, iPoslist);
++    pIter->iLeafOffset = iPoslist;
++
++    /* If this condition is true then the largest rowid for the current
++    ** term may not be stored on the current page. So search forward to
++    ** see where said rowid really is.  */
++    if( pIter->iEndofDoclist>=pLeaf->szLeaf ){
++      int pgno;
++      Fts5StructureSegment *pSeg = pIter->pSeg;
++
++      /* The last rowid in the doclist may not be on the current page. Search
++      ** forward to find the page containing the last rowid.  */
++      for(pgno=pIter->iLeafPgno+1; !p->rc && pgno<=pSeg->pgnoLast; pgno++){
++        i64 iAbs = FTS5_SEGMENT_ROWID(pSeg->iSegid, pgno);
++        Fts5Data *pNew = fts5DataRead(p, iAbs);
++        if( pNew ){
++          int iRowid, bTermless;
++          iRowid = fts5LeafFirstRowidOff(pNew);
++          bTermless = fts5LeafIsTermless(pNew);
++          if( iRowid ){
++            SWAPVAL(Fts5Data*, pNew, pLast);
++            pgnoLast = pgno;
++          }
++          fts5DataRelease(pNew);
++          if( bTermless==0 ) break;
++        }
++      }
++    }
++  }
++
++  /* If pLast is NULL at this point, then the last rowid for this doclist
++  ** lies on the page currently indicated by the iterator. In this case 
++  ** pIter->iLeafOffset is already set to point to the position-list size
++  ** field associated with the first relevant rowid on the page.
++  **
++  ** Or, if pLast is non-NULL, then it is the page that contains the last
++  ** rowid. In this case configure the iterator so that it points to the
++  ** first rowid on this page.
 +  */
-+  u8 eState;                  /* Pager state (OPEN, READER, WRITER_LOCKED..) */
-+  u8 eLock;                   /* Current lock held on database file */
-+  u8 changeCountDone;         /* Set after incrementing the change-counter */
-+  u8 setMaster;               /* True if a m-j name has been written to jrnl */
-+  u8 doNotSpill;              /* Do not spill the cache when non-zero */
-+  u8 subjInMemory;            /* True to use in-memory sub-journals */
-+  u8 bUseFetch;               /* True to use xFetch() */
-+  u8 hasBeenUsed;             /* True if any content previously read from this pager*/
-+  Pgno dbSize;                /* Number of pages in the database */
-+  Pgno dbOrigSize;            /* dbSize before the current transaction */
-+  Pgno dbFileSize;            /* Number of pages in the database file */
-+  Pgno dbHintSize;            /* Value passed to FCNTL_SIZE_HINT call */
-+  int errCode;                /* One of several kinds of errors */
-+  int nRec;                   /* Pages journalled since last j-header written */
-+  u32 cksumInit;              /* Quasi-random value added to every checksum */
-+  u32 nSubRec;                /* Number of records written to sub-journal */
-+  Bitvec *pInJournal;         /* One bit for each page in the database file */
-+  sqlite3_file *fd;           /* File descriptor for database */
-+  sqlite3_file *jfd;          /* File descriptor for main journal */
-+  sqlite3_file *sjfd;         /* File descriptor for sub-journal */
-+  i64 journalOff;             /* Current write offset in the journal file */
-+  i64 journalHdr;             /* Byte offset to previous journal header */
-+  sqlite3_backup *pBackup;    /* Pointer to list of ongoing backup processes */
-+  PagerSavepoint *aSavepoint; /* Array of active savepoints */
-+  int nSavepoint;             /* Number of elements in aSavepoint[] */
-+  u32 iDataVersion;           /* Changes whenever database content changes */
-+  char dbFileVers[16];        /* Changes whenever database file changes */
- 
--  aData = pPager->pTmpSpace;
--  assert( aData );         /* Temp storage must have already been allocated */
--  assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) );
-+  int nMmapOut;               /* Number of mmap pages currently outstanding */
-+  sqlite3_int64 szMmap;       /* Desired maximum mmap size */
-+  PgHdr *pMmapFreelist;       /* List of free mmap page headers (pDirty) */
-+  /*
-+  ** End of the routinely-changing class members
-+  ***************************************************************************/
- 
--  /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction 
--  ** or savepoint rollback done at the request of the caller) or this is
--  ** a hot-journal rollback. If it is a hot-journal rollback, the pager
--  ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback
--  ** only reads from the main journal, not the sub-journal.
--  */
--  assert( pPager->eState>=PAGER_WRITER_CACHEMOD
--       || (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK)
--  );
--  assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl );
-+  u16 nExtra;                 /* Add this many bytes to each in-memory page */
-+  i16 nReserve;               /* Number of unused bytes at end of each page */
-+  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
-+  u32 sectorSize;             /* Assumed sector size during rollback */
-+  int pageSize;               /* Number of bytes in a page */
-+  Pgno mxPgno;                /* Maximum allowed size of the database */
-+  i64 journalSizeLimit;       /* Size limit for persistent journal files */
-+  char *zFilename;            /* Name of the database file */
-+  char *zJournal;             /* Name of the journal file */
-+  int (*xBusyHandler)(void*); /* Function to call when busy */
-+  void *pBusyHandlerArg;      /* Context argument for xBusyHandler */
-+  int aStat[3];               /* Total cache hits, misses and writes */
-+#ifdef SQLITE_TEST
-+  int nRead;                  /* Database pages read */
-+#endif
-+  void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
-+#ifdef SQLITE_HAS_CODEC
-+  void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
-+  void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
-+  void (*xCodecFree)(void*);             /* Destructor for the codec */
-+  void *pCodec;               /* First argument to xCodec... methods */
-+#endif
-+  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
-+  PCache *pPCache;            /* Pointer to page cache object */
-+#ifndef SQLITE_OMIT_WAL
-+  Wal *pWal;                  /* Write-ahead log used by "journal_mode=wal" */
-+  char *zWal;                 /* File name for write-ahead log */
-+#endif
-+};
- 
--  /* Read the page number and page data from the journal or sub-journal
--  ** file. Return an error code to the caller if an IO error occurs.
--  */
--  jfd = isMainJrnl ? pPager->jfd : pPager->sjfd;
--  rc = read32bits(jfd, *pOffset, &pgno);
--  if( rc!=SQLITE_OK ) return rc;
--  rc = sqlite3OsRead(jfd, (u8*)aData, pPager->pageSize, (*pOffset)+4);
--  if( rc!=SQLITE_OK ) return rc;
--  *pOffset += pPager->pageSize + 4 + isMainJrnl*4;
++  if( pLast ){
++    int iOff;
++    fts5DataRelease(pIter->pLeaf);
++    pIter->pLeaf = pLast;
++    pIter->iLeafPgno = pgnoLast;
++    iOff = fts5LeafFirstRowidOff(pLast);
++    iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid);
++    pIter->iLeafOffset = iOff;
++
++    if( fts5LeafIsTermless(pLast) ){
++      pIter->iEndofDoclist = pLast->nn+1;
++    }else{
++      pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast);
++    }
++
++  }
++
++  fts5SegIterReverseInitPage(p, pIter);
++}
++
 +/*
-+** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains
-+** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS 
-+** or CACHE_WRITE to sqlite3_db_status().
++** Iterator pIter currently points to the first rowid of a doclist.
++** There is a doclist-index associated with the final term on the current 
++** page. If the current term is the last term on the page, load the 
++** doclist-index from disk and initialize an iterator at (pIter->pDlidx).
 +*/
-+#define PAGER_STAT_HIT   0
-+#define PAGER_STAT_MISS  1
-+#define PAGER_STAT_WRITE 2
- 
--  /* Sanity checking on the page.  This is more important that I originally
--  ** thought.  If a power failure occurs while the journal is being written,
--  ** it could cause invalid data to be written into the journal.  We need to
--  ** detect this invalid data (with high probability) and ignore it.
--  */
--  if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
--    assert( !isSavepnt );
--    return SQLITE_DONE;
--  }
--  if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
--    return SQLITE_OK;
--  }
--  if( isMainJrnl ){
--    rc = read32bits(jfd, (*pOffset)-4, &cksum);
--    if( rc ) return rc;
--    if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){
--      return SQLITE_DONE;
--    }
--  }
++static void fts5SegIterLoadDlidx(Fts5Index *p, Fts5SegIter *pIter){
++  int iSeg = pIter->pSeg->iSegid;
++  int bRev = (pIter->flags & FTS5_SEGITER_REVERSE);
++  Fts5Data *pLeaf = pIter->pLeaf; /* Current leaf data */
++
++  assert( pIter->flags & FTS5_SEGITER_ONETERM );
++  assert( pIter->pDlidx==0 );
++
++  /* Check if the current doclist ends on this page. If it does, return
++  ** early without loading the doclist-index (as it belongs to a different
++  ** term. */
++  if( pIter->iTermLeafPgno==pIter->iLeafPgno 
++   && pIter->iEndofDoclist<pLeaf->szLeaf 
++  ){
++    return;
++  }
++
++  pIter->pDlidx = fts5DlidxIterInit(p, bRev, iSeg, pIter->iTermLeafPgno);
++}
++
++/*
++** The iterator object passed as the second argument currently contains
++** no valid values except for the Fts5SegIter.pLeaf member variable. This
++** function searches the leaf page for a term matching (pTerm/nTerm).
++**
++** If the specified term is found on the page, then the iterator is left
++** pointing to it. If argument bGe is zero and the term is not found,
++** the iterator is left pointing at EOF.
++**
++** If bGe is non-zero and the specified term is not found, then the
++** iterator is left pointing to the smallest term in the segment that
++** is larger than the specified term, even if this term is not on the
++** current page.
++*/
++static void fts5LeafSeek(
++  Fts5Index *p,                   /* Leave any error code here */
++  int bGe,                        /* True for a >= search */
++  Fts5SegIter *pIter,             /* Iterator to seek */
++  const u8 *pTerm, int nTerm      /* Term to search for */
++){
++  int iOff;
++  const u8 *a = pIter->pLeaf->p;
++  int szLeaf = pIter->pLeaf->szLeaf;
++  int n = pIter->pLeaf->nn;
++
++  int nMatch = 0;
++  int nKeep = 0;
++  int nNew = 0;
++  int iTermOff;
++  int iPgidx;                     /* Current offset in pgidx */
++  int bEndOfPage = 0;
++
++  assert( p->rc==SQLITE_OK );
++
++  iPgidx = szLeaf;
++  iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
++  iOff = iTermOff;
++  if( iOff>n ){
++    p->rc = FTS5_CORRUPT;
++    return;
++  }
++
++  while( 1 ){
++
++    /* Figure out how many new bytes are in this term */
++    fts5FastGetVarint32(a, iOff, nNew);
++    if( nKeep<nMatch ){
++      goto search_failed;
++    }
++
++    assert( nKeep>=nMatch );
++    if( nKeep==nMatch ){
++      int nCmp;
++      int i;
++      nCmp = MIN(nNew, nTerm-nMatch);
++      for(i=0; i<nCmp; i++){
++        if( a[iOff+i]!=pTerm[nMatch+i] ) break;
++      }
++      nMatch += i;
++
++      if( nTerm==nMatch ){
++        if( i==nNew ){
++          goto search_success;
++        }else{
++          goto search_failed;
++        }
++      }else if( i<nNew && a[iOff+i]>pTerm[nMatch] ){
++        goto search_failed;
++      }
++    }
++
++    if( iPgidx>=n ){
++      bEndOfPage = 1;
++      break;
++    }
++
++    iPgidx += fts5GetVarint32(&a[iPgidx], nKeep);
++    iTermOff += nKeep;
++    iOff = iTermOff;
++
++    if( iOff>=n ){
++      p->rc = FTS5_CORRUPT;
++      return;
++    }
++
++    /* Read the nKeep field of the next term. */
++    fts5FastGetVarint32(a, iOff, nKeep);
++  }
++
++ search_failed:
++  if( bGe==0 ){
++    fts5DataRelease(pIter->pLeaf);
++    pIter->pLeaf = 0;
++    return;
++  }else if( bEndOfPage ){
++    do {
++      fts5SegIterNextPage(p, pIter);
++      if( pIter->pLeaf==0 ) return;
++      a = pIter->pLeaf->p;
++      if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
++        iPgidx = pIter->pLeaf->szLeaf;
++        iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
++        if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){
++          p->rc = FTS5_CORRUPT;
++        }else{
++          nKeep = 0;
++          iTermOff = iOff;
++          n = pIter->pLeaf->nn;
++          iOff += fts5GetVarint32(&a[iOff], nNew);
++          break;
++        }
++      }
++    }while( 1 );
++  }
++
++ search_success:
++
++  pIter->iLeafOffset = iOff + nNew;
++  pIter->iTermLeafOffset = pIter->iLeafOffset;
++  pIter->iTermLeafPgno = pIter->iLeafPgno;
++
++  fts5BufferSet(&p->rc, &pIter->term, nKeep, pTerm);
++  fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
++
++  if( iPgidx>=n ){
++    pIter->iEndofDoclist = pIter->pLeaf->nn+1;
++  }else{
++    int nExtra;
++    iPgidx += fts5GetVarint32(&a[iPgidx], nExtra);
++    pIter->iEndofDoclist = iTermOff + nExtra;
++  }
++  pIter->iPgidxOff = iPgidx;
++
++  fts5SegIterLoadRowid(p, pIter);
++  fts5SegIterLoadNPos(p, pIter);
++}
++
++static sqlite3_stmt *fts5IdxSelectStmt(Fts5Index *p){
++  if( p->pIdxSelect==0 ){
++    Fts5Config *pConfig = p->pConfig;
++    fts5IndexPrepareStmt(p, &p->pIdxSelect, sqlite3_mprintf(
++          "SELECT pgno FROM '%q'.'%q_idx' WHERE "
++          "segid=? AND term<=? ORDER BY term DESC LIMIT 1",
++          pConfig->zDb, pConfig->zName
++    ));
++  }
++  return p->pIdxSelect;
++}
++
++/*
++** Initialize the object pIter to point to term pTerm/nTerm within segment
++** pSeg. If there is no such term in the index, the iterator is set to EOF.
++**
++** If an error occurs, Fts5Index.rc is set to an appropriate error code. If 
++** an error has already occurred when this function is called, it is a no-op.
++*/
++static void fts5SegIterSeekInit(
++  Fts5Index *p,                   /* FTS5 backend */
++  const u8 *pTerm, int nTerm,     /* Term to seek to */
++  int flags,                      /* Mask of FTS5INDEX_XXX flags */
++  Fts5StructureSegment *pSeg,     /* Description of segment */
++  Fts5SegIter *pIter              /* Object to populate */
++){
++  int iPg = 1;
++  int bGe = (flags & FTS5INDEX_QUERY_SCAN);
++  int bDlidx = 0;                 /* True if there is a doclist-index */
++  sqlite3_stmt *pIdxSelect = 0;
++
++  assert( bGe==0 || (flags & FTS5INDEX_QUERY_DESC)==0 );
++  assert( pTerm && nTerm );
++  memset(pIter, 0, sizeof(*pIter));
++  pIter->pSeg = pSeg;
++
++  /* This block sets stack variable iPg to the leaf page number that may
++  ** contain term (pTerm/nTerm), if it is present in the segment. */
++  pIdxSelect = fts5IdxSelectStmt(p);
++  if( p->rc ) return;
++  sqlite3_bind_int(pIdxSelect, 1, pSeg->iSegid);
++  sqlite3_bind_blob(pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC);
++  if( SQLITE_ROW==sqlite3_step(pIdxSelect) ){
++    i64 val = sqlite3_column_int(pIdxSelect, 0);
++    iPg = (int)(val>>1);
++    bDlidx = (val & 0x0001);
++  }
++  p->rc = sqlite3_reset(pIdxSelect);
++
++  if( iPg<pSeg->pgnoFirst ){
++    iPg = pSeg->pgnoFirst;
++    bDlidx = 0;
++  }
++
++  pIter->iLeafPgno = iPg - 1;
++  fts5SegIterNextPage(p, pIter);
++
++  if( pIter->pLeaf ){
++    fts5LeafSeek(p, bGe, pIter, pTerm, nTerm);
++  }
++
++  if( p->rc==SQLITE_OK && bGe==0 ){
++    pIter->flags |= FTS5_SEGITER_ONETERM;
++    if( pIter->pLeaf ){
++      if( flags & FTS5INDEX_QUERY_DESC ){
++        pIter->flags |= FTS5_SEGITER_REVERSE;
++      }
++      if( bDlidx ){
++        fts5SegIterLoadDlidx(p, pIter);
++      }
++      if( flags & FTS5INDEX_QUERY_DESC ){
++        fts5SegIterReverse(p, pIter);
++      }
++    }
++  }
++
++  fts5SegIterSetNext(p, pIter);
++
++  /* Either:
++  **
++  **   1) an error has occurred, or
++  **   2) the iterator points to EOF, or
++  **   3) the iterator points to an entry with term (pTerm/nTerm), or
++  **   4) the FTS5INDEX_QUERY_SCAN flag was set and the iterator points
++  **      to an entry with a term greater than or equal to (pTerm/nTerm).
++  */
++  assert( p->rc!=SQLITE_OK                                          /* 1 */
++   || pIter->pLeaf==0                                               /* 2 */
++   || fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)==0          /* 3 */
++   || (bGe && fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)>0)  /* 4 */
++  );
++}
++
++/*
++** Initialize the object pIter to point to term pTerm/nTerm within the
++** in-memory hash table. If there is no such term in the hash-table, the 
++** iterator is set to EOF.
++**
++** If an error occurs, Fts5Index.rc is set to an appropriate error code. If 
++** an error has already occurred when this function is called, it is a no-op.
++*/
++static void fts5SegIterHashInit(
++  Fts5Index *p,                   /* FTS5 backend */
++  const u8 *pTerm, int nTerm,     /* Term to seek to */
++  int flags,                      /* Mask of FTS5INDEX_XXX flags */
++  Fts5SegIter *pIter              /* Object to populate */
++){
++  const u8 *pList = 0;
++  int nList = 0;
++  const u8 *z = 0;
++  int n = 0;
++
++  assert( p->pHash );
++  assert( p->rc==SQLITE_OK );
++
++  if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){
++    p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm);
++    sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList);
++    n = (z ? (int)strlen((const char*)z) : 0);
++  }else{
++    pIter->flags |= FTS5_SEGITER_ONETERM;
++    sqlite3Fts5HashQuery(p->pHash, (const char*)pTerm, nTerm, &pList, &nList);
++    z = pTerm;
++    n = nTerm;
++  }
++
++  if( pList ){
++    Fts5Data *pLeaf;
++    sqlite3Fts5BufferSet(&p->rc, &pIter->term, n, z);
++    pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data));
++    if( pLeaf==0 ) return;
++    pLeaf->p = (u8*)pList;
++    pLeaf->nn = pLeaf->szLeaf = nList;
++    pIter->pLeaf = pLeaf;
++    pIter->iLeafOffset = fts5GetVarint(pLeaf->p, (u64*)&pIter->iRowid);
++    pIter->iEndofDoclist = pLeaf->nn;
++
++    if( flags & FTS5INDEX_QUERY_DESC ){
++      pIter->flags |= FTS5_SEGITER_REVERSE;
++      fts5SegIterReverseInitPage(p, pIter);
++    }else{
++      fts5SegIterLoadNPos(p, pIter);
++    }
++  }
++
++  fts5SegIterSetNext(p, pIter);
++}
++
++/*
++** Zero the iterator passed as the only argument.
++*/
++static void fts5SegIterClear(Fts5SegIter *pIter){
++  fts5BufferFree(&pIter->term);
++  fts5DataRelease(pIter->pLeaf);
++  fts5DataRelease(pIter->pNextLeaf);
++  fts5DlidxIterFree(pIter->pDlidx);
++  sqlite3_free(pIter->aRowidOffset);
++  memset(pIter, 0, sizeof(Fts5SegIter));
++}
++
++#ifdef SQLITE_DEBUG
++
++/*
++** This function is used as part of the big assert() procedure implemented by
++** fts5AssertMultiIterSetup(). It ensures that the result currently stored
++** in *pRes is the correct result of comparing the current positions of the
++** two iterators.
++*/
++static void fts5AssertComparisonResult(
++  Fts5Iter *pIter, 
++  Fts5SegIter *p1,
++  Fts5SegIter *p2,
++  Fts5CResult *pRes
++){
++  int i1 = p1 - pIter->aSeg;
++  int i2 = p2 - pIter->aSeg;
++
++  if( p1->pLeaf || p2->pLeaf ){
++    if( p1->pLeaf==0 ){
++      assert( pRes->iFirst==i2 );
++    }else if( p2->pLeaf==0 ){
++      assert( pRes->iFirst==i1 );
++    }else{
++      int nMin = MIN(p1->term.n, p2->term.n);
++      int res = memcmp(p1->term.p, p2->term.p, nMin);
++      if( res==0 ) res = p1->term.n - p2->term.n;
++
++      if( res==0 ){
++        assert( pRes->bTermEq==1 );
++        assert( p1->iRowid!=p2->iRowid );
++        res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : 1;
++      }else{
++        assert( pRes->bTermEq==0 );
++      }
++
++      if( res<0 ){
++        assert( pRes->iFirst==i1 );
++      }else{
++        assert( pRes->iFirst==i2 );
++      }
++    }
++  }
++}
++
 +/*
-+** The following global variables hold counters used for
-+** testing purposes only.  These variables do not exist in
-+** a non-testing build.  These variables are not thread-safe.
++** This function is a no-op unless SQLITE_DEBUG is defined when this module
++** is compiled. In that case, this function is essentially an assert() 
++** statement used to verify that the contents of the pIter->aFirst[] array
++** are correct.
 +*/
-+#ifdef SQLITE_TEST
-+SQLITE_API int sqlite3_pager_readdb_count = 0;    /* Number of full pages read from DB */
-+SQLITE_API int sqlite3_pager_writedb_count = 0;   /* Number of full pages written to DB */
-+SQLITE_API int sqlite3_pager_writej_count = 0;    /* Number of pages written to journal */
-+# define PAGER_INCR(v)  v++
++static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5Iter *pIter){
++  if( p->rc==SQLITE_OK ){
++    Fts5SegIter *pFirst = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
++    int i;
++
++    assert( (pFirst->pLeaf==0)==pIter->base.bEof );
++
++    /* Check that pIter->iSwitchRowid is set correctly. */
++    for(i=0; i<pIter->nSeg; i++){
++      Fts5SegIter *p1 = &pIter->aSeg[i];
++      assert( p1==pFirst 
++           || p1->pLeaf==0 
++           || fts5BufferCompare(&pFirst->term, &p1->term) 
++           || p1->iRowid==pIter->iSwitchRowid
++           || (p1->iRowid<pIter->iSwitchRowid)==pIter->bRev
++      );
++    }
++
++    for(i=0; i<pIter->nSeg; i+=2){
++      Fts5SegIter *p1 = &pIter->aSeg[i];
++      Fts5SegIter *p2 = &pIter->aSeg[i+1];
++      Fts5CResult *pRes = &pIter->aFirst[(pIter->nSeg + i) / 2];
++      fts5AssertComparisonResult(pIter, p1, p2, pRes);
++    }
++
++    for(i=1; i<(pIter->nSeg / 2); i+=2){
++      Fts5SegIter *p1 = &pIter->aSeg[ pIter->aFirst[i*2].iFirst ];
++      Fts5SegIter *p2 = &pIter->aSeg[ pIter->aFirst[i*2+1].iFirst ];
++      Fts5CResult *pRes = &pIter->aFirst[i];
++      fts5AssertComparisonResult(pIter, p1, p2, pRes);
++    }
++  }
++}
 +#else
-+# define PAGER_INCR(v)
++# define fts5AssertMultiIterSetup(x,y)
 +#endif
- 
--  /* If this page has already been played by before during the current
--  ** rollback, then don't bother to play it back again.
--  */
--  if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
--    return rc;
--  }
- 
--  /* When playing back page 1, restore the nReserve setting
--  */
--  if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){
--    pPager->nReserve = ((u8*)aData)[20];
--    pagerReportSize(pPager);
--  }
- 
--  /* If the pager is in CACHEMOD state, then there must be a copy of this
--  ** page in the pager cache. In this case just update the pager cache,
--  ** not the database file. The page is left marked dirty in this case.
--  **
--  ** An exception to the above rule: If the database is in no-sync mode
--  ** and a page is moved during an incremental vacuum then the page may
--  ** not be in the pager cache. Later: if a malloc() or IO error occurs
--  ** during a Movepage() call, then the page may not be in the cache
--  ** either. So the condition described in the above paragraph is not
--  ** assert()able.
--  **
--  ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the
--  ** pager cache if it exists and the main file. The page is then marked 
--  ** not dirty. Since this code is only executed in PAGER_OPEN state for
--  ** a hot-journal rollback, it is guaranteed that the page-cache is empty
--  ** if the pager is in OPEN state.
--  **
--  ** Ticket #1171:  The statement journal might contain page content that is
--  ** different from the page content at the start of the transaction.
--  ** This occurs when a page is changed prior to the start of a statement
--  ** then changed again within the statement.  When rolling back such a
--  ** statement we must not write to the original database unless we know
--  ** for certain that original page contents are synced into the main rollback
--  ** journal.  Otherwise, a power loss might leave modified data in the
--  ** database file without an entry in the rollback journal that can
--  ** restore the database to its original form.  Two conditions must be
--  ** met before writing to the database files. (1) the database must be
--  ** locked.  (2) we know that the original page content is fully synced
--  ** in the main journal either because the page is not in cache or else
--  ** the page is marked as needSync==0.
--  **
--  ** 2008-04-14:  When attempting to vacuum a corrupt database file, it
--  ** is possible to fail a statement on a database that does not yet exist.
--  ** Do not attempt to write if database file has never been opened.
--  */
--  if( pagerUseWal(pPager) ){
--    pPg = 0;
--  }else{
--    pPg = sqlite3PagerLookup(pPager, pgno);
--  }
--  assert( pPg || !MEMDB );
--  assert( pPager->eState!=PAGER_OPEN || pPg==0 );
--  PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
--           PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData),
--           (isMainJrnl?"main-journal":"sub-journal")
--  ));
--  if( isMainJrnl ){
--    isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr);
--  }else{
--    isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC));
--  }
--  if( isOpen(pPager->fd)
--   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
--   && isSynced
--  ){
--    i64 ofst = (pgno-1)*(i64)pPager->pageSize;
--    testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
--    assert( !pagerUseWal(pPager) );
--    rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
--    if( pgno>pPager->dbFileSize ){
--      pPager->dbFileSize = pgno;
--    }
--    if( pPager->pBackup ){
--      CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM);
--      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
--      CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData);
--    }
--  }else if( !isMainJrnl && pPg==0 ){
--    /* If this is a rollback of a savepoint and data was not written to
--    ** the database and the page is not in-memory, there is a potential
--    ** problem. When the page is next fetched by the b-tree layer, it 
--    ** will be read from the database file, which may or may not be 
--    ** current. 
--    **
--    ** There are a couple of different ways this can happen. All are quite
--    ** obscure. When running in synchronous mode, this can only happen 
--    ** if the page is on the free-list at the start of the transaction, then
--    ** populated, then moved using sqlite3PagerMovepage().
--    **
--    ** The solution is to add an in-memory page to the cache containing
--    ** the data just read from the sub-journal. Mark the page as dirty 
--    ** and if the pager requires a journal-sync, then mark the page as 
--    ** requiring a journal-sync before it is written.
--    */
--    assert( isSavepnt );
--    assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
--    pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
--    rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
--    assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
--    pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
--    if( rc!=SQLITE_OK ) return rc;
--    pPg->flags &= ~PGHDR_NEED_READ;
--    sqlite3PcacheMakeDirty(pPg);
--  }
--  if( pPg ){
--    /* No page should ever be explicitly rolled back that is in use, except
--    ** for page 1 which is held in use in order to keep the lock on the
--    ** database active. However such a page may be rolled back as a result
--    ** of an internal error resulting in an automatic call to
--    ** sqlite3PagerRollback().
--    */
--    void *pData;
--    pData = pPg->pData;
--    memcpy(pData, (u8*)aData, pPager->pageSize);
--    pPager->xReiniter(pPg);
--    if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){
--      /* If the contents of this page were just restored from the main 
--      ** journal file, then its content must be as they were when the 
--      ** transaction was first opened. In this case we can mark the page
--      ** as clean, since there will be no need to write it out to the
--      ** database.
--      **
--      ** There is one exception to this rule. If the page is being rolled
--      ** back as part of a savepoint (or statement) rollback from an 
--      ** unsynced portion of the main journal file, then it is not safe
--      ** to mark the page as clean. This is because marking the page as
--      ** clean will clear the PGHDR_NEED_SYNC flag. Since the page is
--      ** already in the journal file (recorded in Pager.pInJournal) and
--      ** the PGHDR_NEED_SYNC flag is cleared, if the page is written to
--      ** again within this transaction, it will be marked as dirty but
--      ** the PGHDR_NEED_SYNC flag will not be set. It could then potentially
--      ** be written out into the database file before its journal file
--      ** segment is synced. If a crash occurs during or following this,
--      ** database corruption may ensue.
--      */
--      assert( !pagerUseWal(pPager) );
--      sqlite3PcacheMakeClean(pPg);
--    }
--    pager_set_pagehash(pPg);
-+/*
-+** Journal files begin with the following magic string.  The data
-+** was obtained from /dev/random.  It is used only as a sanity check.
-+**
-+** Since version 2.8.0, the journal format contains additional sanity
-+** checking information.  If the power fails while the journal is being
-+** written, semi-random garbage data might appear in the journal
-+** file after power is restored.  If an attempt is then made
-+** to roll the journal back, the database could be corrupted.  The additional
-+** sanity checking data is an attempt to discover the garbage in the
-+** journal and ignore it.
-+**
-+** The sanity checking information for the new journal format consists
-+** of a 32-bit checksum on each page of data.  The checksum covers both
-+** the page number and the pPager->pageSize bytes of data for the page.
-+** This cksum is initialized to a 32-bit random value that appears in the
-+** journal file right after the header.  The random initializer is important,
-+** because garbage data that appears at the end of a journal is likely
-+** data that was once in other files that have now been deleted.  If the
-+** garbage data came from an obsolete journal file, the checksums might
-+** be correct.  But by initializing the checksum to random value which
-+** is different for every journal, we minimize that risk.
-+*/
-+static const unsigned char aJournalMagic[] = {
-+  0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,
-+};
 +
 +/*
-+** The size of the of each page record in the journal is given by
-+** the following macro.
++** Do the comparison necessary to populate pIter->aFirst[iOut].
++**
++** If the returned value is non-zero, then it is the index of an entry
++** in the pIter->aSeg[] array that is (a) not at EOF, and (b) pointing
++** to a key that is a duplicate of another, higher priority, 
++** segment-iterator in the pSeg->aSeg[] array.
 +*/
-+#define JOURNAL_PG_SZ(pPager)  ((pPager->pageSize) + 8)
++static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){
++  int i1;                         /* Index of left-hand Fts5SegIter */
++  int i2;                         /* Index of right-hand Fts5SegIter */
++  int iRes;
++  Fts5SegIter *p1;                /* Left-hand Fts5SegIter */
++  Fts5SegIter *p2;                /* Right-hand Fts5SegIter */
++  Fts5CResult *pRes = &pIter->aFirst[iOut];
++
++  assert( iOut<pIter->nSeg && iOut>0 );
++  assert( pIter->bRev==0 || pIter->bRev==1 );
++
++  if( iOut>=(pIter->nSeg/2) ){
++    i1 = (iOut - pIter->nSeg/2) * 2;
++    i2 = i1 + 1;
++  }else{
++    i1 = pIter->aFirst[iOut*2].iFirst;
++    i2 = pIter->aFirst[iOut*2+1].iFirst;
++  }
++  p1 = &pIter->aSeg[i1];
++  p2 = &pIter->aSeg[i2];
++
++  pRes->bTermEq = 0;
++  if( p1->pLeaf==0 ){           /* If p1 is at EOF */
++    iRes = i2;
++  }else if( p2->pLeaf==0 ){     /* If p2 is at EOF */
++    iRes = i1;
++  }else{
++    int res = fts5BufferCompare(&p1->term, &p2->term);
++    if( res==0 ){
++      assert( i2>i1 );
++      assert( i2!=0 );
++      pRes->bTermEq = 1;
++      if( p1->iRowid==p2->iRowid ){
++        p1->bDel = p2->bDel;
++        return i2;
++      }
++      res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : +1;
++    }
++    assert( res!=0 );
++    if( res<0 ){
++      iRes = i1;
++    }else{
++      iRes = i2;
++    }
++  }
++
++  pRes->iFirst = (u16)iRes;
++  return 0;
++}
 +
 +/*
-+** The journal header size for this pager. This is usually the same 
-+** size as a single disk sector. See also setSectorSize().
++** Move the seg-iter so that it points to the first rowid on page iLeafPgno.
++** It is an error if leaf iLeafPgno does not exist or contains no rowids.
 +*/
-+#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize)
++static void fts5SegIterGotoPage(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5SegIter *pIter,             /* Iterator to advance */
++  int iLeafPgno
++){
++  assert( iLeafPgno>pIter->iLeafPgno );
++
++  if( iLeafPgno>pIter->pSeg->pgnoLast ){
++    p->rc = FTS5_CORRUPT;
++  }else{
++    fts5DataRelease(pIter->pNextLeaf);
++    pIter->pNextLeaf = 0;
++    pIter->iLeafPgno = iLeafPgno-1;
++    fts5SegIterNextPage(p, pIter);
++    assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno );
++
++    if( p->rc==SQLITE_OK ){
++      int iOff;
++      u8 *a = pIter->pLeaf->p;
++      int n = pIter->pLeaf->szLeaf;
++
++      iOff = fts5LeafFirstRowidOff(pIter->pLeaf);
++      if( iOff<4 || iOff>=n ){
++        p->rc = FTS5_CORRUPT;
++      }else{
++        iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
++        pIter->iLeafOffset = iOff;
++        fts5SegIterLoadNPos(p, pIter);
++      }
++    }
++  }
++}
 +
 +/*
-+** The macro MEMDB is true if we are dealing with an in-memory database.
-+** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set,
-+** the value of MEMDB will be a constant and the compiler will optimize
-+** out code that would never execute.
++** Advance the iterator passed as the second argument until it is at or 
++** past rowid iFrom. Regardless of the value of iFrom, the iterator is
++** always advanced at least once.
 +*/
-+#ifdef SQLITE_OMIT_MEMORYDB
-+# define MEMDB 0
-+#else
-+# define MEMDB pPager->memDb
-+#endif
- 
--    /* If this was page 1, then restore the value of Pager.dbFileVers.
--    ** Do this before any decoding. */
--    if( pgno==1 ){
--      memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
--    }
++static void fts5SegIterNextFrom(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5SegIter *pIter,             /* Iterator to advance */
++  i64 iMatch                      /* Advance iterator at least this far */
++){
++  int bRev = (pIter->flags & FTS5_SEGITER_REVERSE);
++  Fts5DlidxIter *pDlidx = pIter->pDlidx;
++  int iLeafPgno = pIter->iLeafPgno;
++  int bMove = 1;
++
++  assert( pIter->flags & FTS5_SEGITER_ONETERM );
++  assert( pIter->pDlidx );
++  assert( pIter->pLeaf );
++
++  if( bRev==0 ){
++    while( !fts5DlidxIterEof(p, pDlidx) && iMatch>fts5DlidxIterRowid(pDlidx) ){
++      iLeafPgno = fts5DlidxIterPgno(pDlidx);
++      fts5DlidxIterNext(p, pDlidx);
++    }
++    assert_nc( iLeafPgno>=pIter->iLeafPgno || p->rc );
++    if( iLeafPgno>pIter->iLeafPgno ){
++      fts5SegIterGotoPage(p, pIter, iLeafPgno);
++      bMove = 0;
++    }
++  }else{
++    assert( pIter->pNextLeaf==0 );
++    assert( iMatch<pIter->iRowid );
++    while( !fts5DlidxIterEof(p, pDlidx) && iMatch<fts5DlidxIterRowid(pDlidx) ){
++      fts5DlidxIterPrev(p, pDlidx);
++    }
++    iLeafPgno = fts5DlidxIterPgno(pDlidx);
++
++    assert( fts5DlidxIterEof(p, pDlidx) || iLeafPgno<=pIter->iLeafPgno );
++
++    if( iLeafPgno<pIter->iLeafPgno ){
++      pIter->iLeafPgno = iLeafPgno+1;
++      fts5SegIterReverseNewPage(p, pIter);
++      bMove = 0;
++    }
++  }
++
++  do{
++    if( bMove && p->rc==SQLITE_OK ) pIter->xNext(p, pIter, 0);
++    if( pIter->pLeaf==0 ) break;
++    if( bRev==0 && pIter->iRowid>=iMatch ) break;
++    if( bRev!=0 && pIter->iRowid<=iMatch ) break;
++    bMove = 1;
++  }while( p->rc==SQLITE_OK );
++}
++
++
 +/*
-+** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch
-+** interfaces to access the database using memory-mapped I/O.
++** Free the iterator object passed as the second argument.
 +*/
-+#if SQLITE_MAX_MMAP_SIZE>0
-+# define USEFETCH(x) ((x)->bUseFetch)
-+#else
-+# define USEFETCH(x) 0
-+#endif
- 
--    /* Decode the page just read from disk */
--    CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
--    sqlite3PcacheRelease(pPg);
--  }
--  return rc;
--}
++static void fts5MultiIterFree(Fts5Iter *pIter){
++  if( pIter ){
++    int i;
++    for(i=0; i<pIter->nSeg; i++){
++      fts5SegIterClear(&pIter->aSeg[i]);
++    }
++    fts5StructureRelease(pIter->pStruct);
++    fts5BufferFree(&pIter->poslist);
++    sqlite3_free(pIter);
++  }
++}
++
++static void fts5MultiIterAdvanced(
++  Fts5Index *p,                   /* FTS5 backend to iterate within */
++  Fts5Iter *pIter,                /* Iterator to update aFirst[] array for */
++  int iChanged,                   /* Index of sub-iterator just advanced */
++  int iMinset                     /* Minimum entry in aFirst[] to set */
++){
++  int i;
++  for(i=(pIter->nSeg+iChanged)/2; i>=iMinset && p->rc==SQLITE_OK; i=i/2){
++    int iEq;
++    if( (iEq = fts5MultiIterDoCompare(pIter, i)) ){
++      Fts5SegIter *pSeg = &pIter->aSeg[iEq];
++      assert( p->rc==SQLITE_OK );
++      pSeg->xNext(p, pSeg, 0);
++      i = pIter->nSeg + iEq;
++    }
++  }
++}
++
 +/*
-+** The maximum legal page number is (2^31 - 1).
-+*/
-+#define PAGER_MAX_PGNO 2147483647
- 
- /*
--** Parameter zMaster is the name of a master journal file. A single journal
--** file that referred to the master journal file has just been rolled back.
--** This routine checks if it is possible to delete the master journal file,
--** and does so if it is.
--**
--** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not 
--** available for use within this function.
--**
--** When a master journal file is created, it is populated with the names 
--** of all of its child journals, one after another, formatted as utf-8 
--** encoded text. The end of each child journal file is marked with a 
--** nul-terminator byte (0x00). i.e. the entire contents of a master journal
--** file for a transaction involving two databases might be:
--**
--**   "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00"
-+** The argument to this macro is a file descriptor (type sqlite3_file*).
-+** Return 0 if it is not open, or non-zero (but not 1) if it is.
- **
--** A master journal file may only be deleted once all of its child 
--** journals have been rolled back.
-+** This is so that expressions can be written as:
- **
--** This function reads the contents of the master-journal file into 
--** memory and loops through each of the child journal names. For
--** each child journal, it checks if:
-+**   if( isOpen(pPager->jfd) ){ ...
- **
--**   * if the child journal exists, and if so
--**   * if the child journal contains a reference to master journal 
--**     file zMaster
-+** instead of
- **
--** If a child journal can be found that matches both of the criteria
--** above, this function returns without doing anything. Otherwise, if
--** no such child journal can be found, file zMaster is deleted from
--** the file-system using sqlite3OsDelete().
-+**   if( pPager->jfd->pMethods ){ ...
++** Sub-iterator iChanged of iterator pIter has just been advanced. It still
++** points to the same term though - just a different rowid. This function
++** attempts to update the contents of the pIter->aFirst[] accordingly.
++** If it does so successfully, 0 is returned. Otherwise 1.
++**
++** If non-zero is returned, the caller should call fts5MultiIterAdvanced()
++** on the iterator instead. That function does the same as this one, except
++** that it deals with more complicated cases as well.
++*/ 
++static int fts5MultiIterAdvanceRowid(
++  Fts5Iter *pIter,                /* Iterator to update aFirst[] array for */
++  int iChanged,                   /* Index of sub-iterator just advanced */
++  Fts5SegIter **ppFirst
++){
++  Fts5SegIter *pNew = &pIter->aSeg[iChanged];
++
++  if( pNew->iRowid==pIter->iSwitchRowid
++   || (pNew->iRowid<pIter->iSwitchRowid)==pIter->bRev
++  ){
++    int i;
++    Fts5SegIter *pOther = &pIter->aSeg[iChanged ^ 0x0001];
++    pIter->iSwitchRowid = pIter->bRev ? SMALLEST_INT64 : LARGEST_INT64;
++    for(i=(pIter->nSeg+iChanged)/2; 1; i=i/2){
++      Fts5CResult *pRes = &pIter->aFirst[i];
++
++      assert( pNew->pLeaf );
++      assert( pRes->bTermEq==0 || pOther->pLeaf );
++
++      if( pRes->bTermEq ){
++        if( pNew->iRowid==pOther->iRowid ){
++          return 1;
++        }else if( (pOther->iRowid>pNew->iRowid)==pIter->bRev ){
++          pIter->iSwitchRowid = pOther->iRowid;
++          pNew = pOther;
++        }else if( (pOther->iRowid>pIter->iSwitchRowid)==pIter->bRev ){
++          pIter->iSwitchRowid = pOther->iRowid;
++        }
++      }
++      pRes->iFirst = (u16)(pNew - pIter->aSeg);
++      if( i==1 ) break;
++
++      pOther = &pIter->aSeg[ pIter->aFirst[i ^ 0x0001].iFirst ];
++    }
++  }
++
++  *ppFirst = pNew;
++  return 0;
++}
++
++/*
++** Set the pIter->bEof variable based on the state of the sub-iterators.
 +*/
-+#define isOpen(pFd) ((pFd)->pMethods)
++static void fts5MultiIterSetEof(Fts5Iter *pIter){
++  Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
++  pIter->base.bEof = pSeg->pLeaf==0;
++  pIter->iSwitchRowid = pSeg->iRowid;
++}
 +
 +/*
-+** Return true if this pager uses a write-ahead log instead of the usual
-+** rollback journal. Otherwise false.
++** Move the iterator to the next entry. 
++**
++** If an error occurs, an error code is left in Fts5Index.rc. It is not 
++** considered an error if the iterator reaches EOF, or if it is already at 
++** EOF when this function is called.
 +*/
-+#ifndef SQLITE_OMIT_WAL
-+static int pagerUseWal(Pager *pPager){
-+  return (pPager->pWal!=0);
++static void fts5MultiIterNext(
++  Fts5Index *p, 
++  Fts5Iter *pIter,
++  int bFrom,                      /* True if argument iFrom is valid */
++  i64 iFrom                       /* Advance at least as far as this */
++){
++  int bUseFrom = bFrom;
++  assert( pIter->base.bEof==0 );
++  while( p->rc==SQLITE_OK ){
++    int iFirst = pIter->aFirst[1].iFirst;
++    int bNewTerm = 0;
++    Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
++    assert( p->rc==SQLITE_OK );
++    if( bUseFrom && pSeg->pDlidx ){
++      fts5SegIterNextFrom(p, pSeg, iFrom);
++    }else{
++      pSeg->xNext(p, pSeg, &bNewTerm);
++    }
++
++    if( pSeg->pLeaf==0 || bNewTerm 
++     || fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg)
++    ){
++      fts5MultiIterAdvanced(p, pIter, iFirst, 1);
++      fts5MultiIterSetEof(pIter);
++      pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
++      if( pSeg->pLeaf==0 ) return;
++    }
++
++    fts5AssertMultiIterSetup(p, pIter);
++    assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf );
++    if( pIter->bSkipEmpty==0 || pSeg->nPos ){
++      pIter->xSetOutputs(pIter, pSeg);
++      return;
++    }
++    bUseFrom = 0;
++  }
 +}
-+#else
-+# define pagerUseWal(x) 0
-+# define pagerRollbackWal(x) 0
-+# define pagerWalFrames(v,w,x,y) 0
-+# define pagerOpenWalIfPresent(z) SQLITE_OK
-+# define pagerBeginReadTransaction(z) SQLITE_OK
-+#endif
-+
-+#ifndef NDEBUG 
-+/*
-+** Usage:
- **
--** If an IO error within this function, an error code is returned. This
--** function allocates memory by calling sqlite3Malloc(). If an allocation
--** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors 
--** occur, SQLITE_OK is returned.
-+**   assert( assert_pager_state(pPager) );
- **
--** TODO: This function allocates a single block of memory to load
--** the entire contents of the master journal file. This could be
--** a couple of kilobytes or so - potentially larger than the page 
--** size.
-+** This function runs many asserts to try to find inconsistencies in
-+** the internal state of the Pager object.
- */
--static int pager_delmaster(Pager *pPager, const char *zMaster){
--  sqlite3_vfs *pVfs = pPager->pVfs;
--  int rc;                   /* Return code */
--  sqlite3_file *pMaster;    /* Malloc'd master-journal file descriptor */
--  sqlite3_file *pJournal;   /* Malloc'd child-journal file descriptor */
--  char *zMasterJournal = 0; /* Contents of master journal file */
--  i64 nMasterJournal;       /* Size of master journal file */
--  char *zJournal;           /* Pointer to one journal within MJ file */
--  char *zMasterPtr;         /* Space to hold MJ filename from a journal file */
--  int nMasterPtr;           /* Amount of space allocated to zMasterPtr[] */
-+static int assert_pager_state(Pager *p){
-+  Pager *pPager = p;
- 
--  /* Allocate space for both the pJournal and pMaster file descriptors.
--  ** If successful, open the master journal file for reading.
-+  /* State must be valid. */
-+  assert( p->eState==PAGER_OPEN
-+       || p->eState==PAGER_READER
-+       || p->eState==PAGER_WRITER_LOCKED
-+       || p->eState==PAGER_WRITER_CACHEMOD
-+       || p->eState==PAGER_WRITER_DBMOD
-+       || p->eState==PAGER_WRITER_FINISHED
-+       || p->eState==PAGER_ERROR
++
++static void fts5MultiIterNext2(
++  Fts5Index *p, 
++  Fts5Iter *pIter,
++  int *pbNewTerm                  /* OUT: True if *might* be new term */
++){
++  assert( pIter->bSkipEmpty );
++  if( p->rc==SQLITE_OK ){
++    *pbNewTerm = 0;
++    do{
++      int iFirst = pIter->aFirst[1].iFirst;
++      Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
++      int bNewTerm = 0;
++
++      assert( p->rc==SQLITE_OK );
++      pSeg->xNext(p, pSeg, &bNewTerm);
++      if( pSeg->pLeaf==0 || bNewTerm 
++       || fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg)
++      ){
++        fts5MultiIterAdvanced(p, pIter, iFirst, 1);
++        fts5MultiIterSetEof(pIter);
++        *pbNewTerm = 1;
++      }
++      fts5AssertMultiIterSetup(p, pIter);
++
++    }while( fts5MultiIterIsEmpty(p, pIter) );
++  }
++}
++
++static void fts5IterSetOutputs_Noop(Fts5Iter *pUnused1, Fts5SegIter *pUnused2){
++  UNUSED_PARAM2(pUnused1, pUnused2);
++}
++
++static Fts5Iter *fts5MultiIterAlloc(
++  Fts5Index *p,                   /* FTS5 backend to iterate within */
++  int nSeg
++){
++  Fts5Iter *pNew;
++  int nSlot;                      /* Power of two >= nSeg */
++
++  for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2);
++  pNew = fts5IdxMalloc(p, 
++      sizeof(Fts5Iter) +                  /* pNew */
++      sizeof(Fts5SegIter) * (nSlot-1) +   /* pNew->aSeg[] */
++      sizeof(Fts5CResult) * nSlot         /* pNew->aFirst[] */
 +  );
++  if( pNew ){
++    pNew->nSeg = nSlot;
++    pNew->aFirst = (Fts5CResult*)&pNew->aSeg[nSlot];
++    pNew->pIndex = p;
++    pNew->xSetOutputs = fts5IterSetOutputs_Noop;
++  }
++  return pNew;
++}
 +
-+  /* Regardless of the current state, a temp-file connection always behaves
-+  ** as if it has an exclusive lock on the database file. It never updates
-+  ** the change-counter field, so the changeCountDone flag is always set.
-   */
--  pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
--  pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
--  if( !pMaster ){
--    rc = SQLITE_NOMEM;
--  }else{
--    const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
--    rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
--  }
--  if( rc!=SQLITE_OK ) goto delmaster_out;
-+  assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK );
-+  assert( p->tempFile==0 || pPager->changeCountDone );
- 
--  /* Load the entire master journal file into space obtained from
--  ** sqlite3_malloc() and pointed to by zMasterJournal.   Also obtain
--  ** sufficient space (in zMasterPtr) to hold the names of master
--  ** journal files extracted from regular rollback-journals.
-+  /* If the useJournal flag is clear, the journal-mode must be "OFF". 
-+  ** And if the journal-mode is "OFF", the journal file must not be open.
-   */
--  rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
--  if( rc!=SQLITE_OK ) goto delmaster_out;
--  nMasterPtr = pVfs->mxPathname+1;
--  zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
--  if( !zMasterJournal ){
--    rc = SQLITE_NOMEM;
--    goto delmaster_out;
-+  assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal );
-+  assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) );
-+
-+  /* Check that MEMDB implies noSync. And an in-memory journal. Since 
-+  ** this means an in-memory pager performs no IO at all, it cannot encounter 
-+  ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing 
-+  ** a journal file. (although the in-memory journal implementation may 
-+  ** return SQLITE_IOERR_NOMEM while the journal file is being written). It 
-+  ** is therefore not possible for an in-memory pager to enter the ERROR 
-+  ** state.
-+  */
-+  if( MEMDB ){
-+    assert( p->noSync );
-+    assert( p->journalMode==PAGER_JOURNALMODE_OFF 
-+         || p->journalMode==PAGER_JOURNALMODE_MEMORY 
-+    );
-+    assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN );
-+    assert( pagerUseWal(p)==0 );
-   }
--  zMasterPtr = &zMasterJournal[nMasterJournal+1];
--  rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
--  if( rc!=SQLITE_OK ) goto delmaster_out;
--  zMasterJournal[nMasterJournal] = 0;
- 
--  zJournal = zMasterJournal;
--  while( (zJournal-zMasterJournal)<nMasterJournal ){
--    int exists;
--    rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists);
--    if( rc!=SQLITE_OK ){
--      goto delmaster_out;
--    }
--    if( exists ){
--      /* One of the journals pointed to by the master journal exists.
--      ** Open it and check if it points at the master journal. If
--      ** so, return without deleting the master journal file.
--      */
--      int c;
--      int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
--      rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
--      if( rc!=SQLITE_OK ){
--        goto delmaster_out;
--      }
-+  /* If changeCountDone is set, a RESERVED lock or greater must be held
-+  ** on the file.
-+  */
-+  assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK );
-+  assert( p->eLock!=PENDING_LOCK );
- 
--      rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
--      sqlite3OsClose(pJournal);
--      if( rc!=SQLITE_OK ){
--        goto delmaster_out;
-+  switch( p->eState ){
-+    case PAGER_OPEN:
-+      assert( !MEMDB );
-+      assert( pPager->errCode==SQLITE_OK );
-+      assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile );
-+      break;
++static void fts5PoslistCallback(
++  Fts5Index *pUnused, 
++  void *pContext, 
++  const u8 *pChunk, int nChunk
++){
++  UNUSED_PARAM(pUnused);
++  assert_nc( nChunk>=0 );
++  if( nChunk>0 ){
++    fts5BufferSafeAppendBlob((Fts5Buffer*)pContext, pChunk, nChunk);
++  }
++}
 +
-+    case PAGER_READER:
-+      assert( pPager->errCode==SQLITE_OK );
-+      assert( p->eLock!=UNKNOWN_LOCK );
-+      assert( p->eLock>=SHARED_LOCK );
-+      break;
++typedef struct PoslistCallbackCtx PoslistCallbackCtx;
++struct PoslistCallbackCtx {
++  Fts5Buffer *pBuf;               /* Append to this buffer */
++  Fts5Colset *pColset;            /* Restrict matches to this column */
++  int eState;                     /* See above */
++};
 +
-+    case PAGER_WRITER_LOCKED:
-+      assert( p->eLock!=UNKNOWN_LOCK );
-+      assert( pPager->errCode==SQLITE_OK );
-+      if( !pagerUseWal(pPager) ){
-+        assert( p->eLock>=RESERVED_LOCK );
-       }
-+      assert( pPager->dbSize==pPager->dbOrigSize );
-+      assert( pPager->dbOrigSize==pPager->dbFileSize );
-+      assert( pPager->dbOrigSize==pPager->dbHintSize );
-+      assert( pPager->setMaster==0 );
-+      break;
- 
--      c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0;
--      if( c ){
--        /* We have a match. Do not delete the master journal file. */
--        goto delmaster_out;
-+    case PAGER_WRITER_CACHEMOD:
-+      assert( p->eLock!=UNKNOWN_LOCK );
-+      assert( pPager->errCode==SQLITE_OK );
-+      if( !pagerUseWal(pPager) ){
-+        /* It is possible that if journal_mode=wal here that neither the
-+        ** journal file nor the WAL file are open. This happens during
-+        ** a rollback transaction that switches from journal_mode=off
-+        ** to journal_mode=wal.
-+        */
-+        assert( p->eLock>=RESERVED_LOCK );
-+        assert( isOpen(p->jfd) 
-+             || p->journalMode==PAGER_JOURNALMODE_OFF 
-+             || p->journalMode==PAGER_JOURNALMODE_WAL 
-+        );
-       }
-+      assert( pPager->dbOrigSize==pPager->dbFileSize );
-+      assert( pPager->dbOrigSize==pPager->dbHintSize );
-+      break;
++typedef struct PoslistOffsetsCtx PoslistOffsetsCtx;
++struct PoslistOffsetsCtx {
++  Fts5Buffer *pBuf;               /* Append to this buffer */
++  Fts5Colset *pColset;            /* Restrict matches to this column */
++  int iRead;
++  int iWrite;
++};
 +
-+    case PAGER_WRITER_DBMOD:
-+      assert( p->eLock==EXCLUSIVE_LOCK );
-+      assert( pPager->errCode==SQLITE_OK );
-+      assert( !pagerUseWal(pPager) );
-+      assert( p->eLock>=EXCLUSIVE_LOCK );
-+      assert( isOpen(p->jfd) 
-+           || p->journalMode==PAGER_JOURNALMODE_OFF 
-+           || p->journalMode==PAGER_JOURNALMODE_WAL 
-+      );
-+      assert( pPager->dbOrigSize<=pPager->dbHintSize );
++/*
++** TODO: Make this more efficient!
++*/
++static int fts5IndexColsetTest(Fts5Colset *pColset, int iCol){
++  int i;
++  for(i=0; i<pColset->nCol; i++){
++    if( pColset->aiCol[i]==iCol ) return 1;
++  }
++  return 0;
++}
++
++static void fts5PoslistOffsetsCallback(
++  Fts5Index *pUnused, 
++  void *pContext, 
++  const u8 *pChunk, int nChunk
++){
++  PoslistOffsetsCtx *pCtx = (PoslistOffsetsCtx*)pContext;
++  UNUSED_PARAM(pUnused);
++  assert_nc( nChunk>=0 );
++  if( nChunk>0 ){
++    int i = 0;
++    while( i<nChunk ){
++      int iVal;
++      i += fts5GetVarint32(&pChunk[i], iVal);
++      iVal += pCtx->iRead - 2;
++      pCtx->iRead = iVal;
++      if( fts5IndexColsetTest(pCtx->pColset, iVal) ){
++        fts5BufferSafeAppendVarint(pCtx->pBuf, iVal + 2 - pCtx->iWrite);
++        pCtx->iWrite = iVal;
++      }
++    }
++  }
++}
++
++static void fts5PoslistFilterCallback(
++  Fts5Index *pUnused,
++  void *pContext, 
++  const u8 *pChunk, int nChunk
++){
++  PoslistCallbackCtx *pCtx = (PoslistCallbackCtx*)pContext;
++  UNUSED_PARAM(pUnused);
++  assert_nc( nChunk>=0 );
++  if( nChunk>0 ){
++    /* Search through to find the first varint with value 1. This is the
++    ** start of the next columns hits. */
++    int i = 0;
++    int iStart = 0;
++
++    if( pCtx->eState==2 ){
++      int iCol;
++      fts5FastGetVarint32(pChunk, i, iCol);
++      if( fts5IndexColsetTest(pCtx->pColset, iCol) ){
++        pCtx->eState = 1;
++        fts5BufferSafeAppendVarint(pCtx->pBuf, 1);
++      }else{
++        pCtx->eState = 0;
++      }
++    }
++
++    do {
++      while( i<nChunk && pChunk[i]!=0x01 ){
++        while( pChunk[i] & 0x80 ) i++;
++        i++;
++      }
++      if( pCtx->eState ){
++        fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
++      }
++      if( i<nChunk ){
++        int iCol;
++        iStart = i;
++        i++;
++        if( i>=nChunk ){
++          pCtx->eState = 2;
++        }else{
++          fts5FastGetVarint32(pChunk, i, iCol);
++          pCtx->eState = fts5IndexColsetTest(pCtx->pColset, iCol);
++          if( pCtx->eState ){
++            fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
++            iStart = i;
++          }
++        }
++      }
++    }while( i<nChunk );
++  }
++}
++
++static void fts5ChunkIterate(
++  Fts5Index *p,                   /* Index object */
++  Fts5SegIter *pSeg,              /* Poslist of this iterator */
++  void *pCtx,                     /* Context pointer for xChunk callback */
++  void (*xChunk)(Fts5Index*, void*, const u8*, int)
++){
++  int nRem = pSeg->nPos;          /* Number of bytes still to come */
++  Fts5Data *pData = 0;
++  u8 *pChunk = &pSeg->pLeaf->p[pSeg->iLeafOffset];
++  int nChunk = MIN(nRem, pSeg->pLeaf->szLeaf - pSeg->iLeafOffset);
++  int pgno = pSeg->iLeafPgno;
++  int pgnoSave = 0;
++
++  /* This function does notmwork with detail=none databases. */
++  assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE );
++
++  if( (pSeg->flags & FTS5_SEGITER_REVERSE)==0 ){
++    pgnoSave = pgno+1;
++  }
++
++  while( 1 ){
++    xChunk(p, pCtx, pChunk, nChunk);
++    nRem -= nChunk;
++    fts5DataRelease(pData);
++    if( nRem<=0 ){
 +      break;
++    }else{
++      pgno++;
++      pData = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno));
++      if( pData==0 ) break;
++      pChunk = &pData->p[4];
++      nChunk = MIN(nRem, pData->szLeaf - 4);
++      if( pgno==pgnoSave ){
++        assert( pSeg->pNextLeaf==0 );
++        pSeg->pNextLeaf = pData;
++        pData = 0;
++      }
++    }
++  }
++}
++
++/*
++** Iterator pIter currently points to a valid entry (not EOF). This
++** function appends the position list data for the current entry to
++** buffer pBuf. It does not make a copy of the position-list size
++** field.
++*/
++static void fts5SegiterPoslist(
++  Fts5Index *p,
++  Fts5SegIter *pSeg,
++  Fts5Colset *pColset,
++  Fts5Buffer *pBuf
++){
++  if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){
++    if( pColset==0 ){
++      fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
++    }else{
++      if( p->pConfig->eDetail==FTS5_DETAIL_FULL ){
++        PoslistCallbackCtx sCtx;
++        sCtx.pBuf = pBuf;
++        sCtx.pColset = pColset;
++        sCtx.eState = fts5IndexColsetTest(pColset, 0);
++        assert( sCtx.eState==0 || sCtx.eState==1 );
++        fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback);
++      }else{
++        PoslistOffsetsCtx sCtx;
++        memset(&sCtx, 0, sizeof(sCtx));
++        sCtx.pBuf = pBuf;
++        sCtx.pColset = pColset;
++        fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistOffsetsCallback);
++      }
++    }
++  }
++}
 +
-+    case PAGER_WRITER_FINISHED:
-+      assert( p->eLock==EXCLUSIVE_LOCK );
-+      assert( pPager->errCode==SQLITE_OK );
-+      assert( !pagerUseWal(pPager) );
-+      assert( isOpen(p->jfd) 
-+           || p->journalMode==PAGER_JOURNALMODE_OFF 
-+           || p->journalMode==PAGER_JOURNALMODE_WAL 
-+      );
-+      break;
++/*
++** IN/OUT parameter (*pa) points to a position list n bytes in size. If
++** the position list contains entries for column iCol, then (*pa) is set
++** to point to the sub-position-list for that column and the number of
++** bytes in it returned. Or, if the argument position list does not
++** contain any entries for column iCol, return 0.
++*/
++static int fts5IndexExtractCol(
++  const u8 **pa,                  /* IN/OUT: Pointer to poslist */
++  int n,                          /* IN: Size of poslist in bytes */
++  int iCol                        /* Column to extract from poslist */
++){
++  int iCurrent = 0;               /* Anything before the first 0x01 is col 0 */
++  const u8 *p = *pa;
++  const u8 *pEnd = &p[n];         /* One byte past end of position list */
++
++  while( iCol>iCurrent ){
++    /* Advance pointer p until it points to pEnd or an 0x01 byte that is
++    ** not part of a varint. Note that it is not possible for a negative
++    ** or extremely large varint to occur within an uncorrupted position 
++    ** list. So the last byte of each varint may be assumed to have a clear
++    ** 0x80 bit.  */
++    while( *p!=0x01 ){
++      while( *p++ & 0x80 );
++      if( p>=pEnd ) return 0;
++    }
++    *pa = p++;
++    iCurrent = *p++;
++    if( iCurrent & 0x80 ){
++      p--;
++      p += fts5GetVarint32(p, iCurrent);
++    }
++  }
++  if( iCol!=iCurrent ) return 0;
 +
-+    case PAGER_ERROR:
-+      /* There must be at least one outstanding reference to the pager if
-+      ** in ERROR state. Otherwise the pager should have already dropped
-+      ** back to OPEN state.
-+      */
-+      assert( pPager->errCode!=SQLITE_OK );
-+      assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
-+      break;
++  /* Advance pointer p until it points to pEnd or an 0x01 byte that is
++  ** not part of a varint */
++  while( p<pEnd && *p!=0x01 ){
++    while( *p++ & 0x80 );
 +  }
 +
-+  return 1;
++  return p - (*pa);
 +}
-+#endif /* ifndef NDEBUG */
-+
-+#ifdef SQLITE_DEBUG 
-+/*
-+** Return a pointer to a human readable string in a static buffer
-+** containing the state of the Pager object passed as an argument. This
-+** is intended to be used within debuggers. For example, as an alternative
-+** to "print *pPager" in gdb:
-+**
-+** (gdb) printf "%s", print_pager_state(pPager)
-+*/
-+static char *print_pager_state(Pager *p){
-+  static char zRet[1024];
-+
-+  sqlite3_snprintf(1024, zRet,
-+      "Filename:      %s\n"
-+      "State:         %s errCode=%d\n"
-+      "Lock:          %s\n"
-+      "Locking mode:  locking_mode=%s\n"
-+      "Journal mode:  journal_mode=%s\n"
-+      "Backing store: tempFile=%d memDb=%d useJournal=%d\n"
-+      "Journal:       journalOff=%lld journalHdr=%lld\n"
-+      "Size:          dbsize=%d dbOrigSize=%d dbFileSize=%d\n"
-+      , p->zFilename
-+      , p->eState==PAGER_OPEN            ? "OPEN" :
-+        p->eState==PAGER_READER          ? "READER" :
-+        p->eState==PAGER_WRITER_LOCKED   ? "WRITER_LOCKED" :
-+        p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" :
-+        p->eState==PAGER_WRITER_DBMOD    ? "WRITER_DBMOD" :
-+        p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" :
-+        p->eState==PAGER_ERROR           ? "ERROR" : "?error?"
-+      , (int)p->errCode
-+      , p->eLock==NO_LOCK         ? "NO_LOCK" :
-+        p->eLock==RESERVED_LOCK   ? "RESERVED" :
-+        p->eLock==EXCLUSIVE_LOCK  ? "EXCLUSIVE" :
-+        p->eLock==SHARED_LOCK     ? "SHARED" :
-+        p->eLock==UNKNOWN_LOCK    ? "UNKNOWN" : "?error?"
-+      , p->exclusiveMode ? "exclusive" : "normal"
-+      , p->journalMode==PAGER_JOURNALMODE_MEMORY   ? "memory" :
-+        p->journalMode==PAGER_JOURNALMODE_OFF      ? "off" :
-+        p->journalMode==PAGER_JOURNALMODE_DELETE   ? "delete" :
-+        p->journalMode==PAGER_JOURNALMODE_PERSIST  ? "persist" :
-+        p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" :
-+        p->journalMode==PAGER_JOURNALMODE_WAL      ? "wal" : "?error?"
-+      , (int)p->tempFile, (int)p->memDb, (int)p->useJournal
-+      , p->journalOff, p->journalHdr
-+      , (int)p->dbSize, (int)p->dbOrigSize, (int)p->dbFileSize
-+  );
 +
-+  return zRet;
++static void fts5IndexExtractColset(
++  int *pRc,
++  Fts5Colset *pColset,            /* Colset to filter on */
++  const u8 *pPos, int nPos,       /* Position list */
++  Fts5Buffer *pBuf                /* Output buffer */
++){
++  if( *pRc==SQLITE_OK ){
++    int i;
++    fts5BufferZero(pBuf);
++    for(i=0; i<pColset->nCol; i++){
++      const u8 *pSub = pPos;
++      int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
++      if( nSub ){
++        fts5BufferAppendBlob(pRc, pBuf, nSub, pSub);
++      }
++    }
++  }
 +}
-+#endif
 +
 +/*
-+** Return true if it is necessary to write page *pPg into the sub-journal.
-+** A page needs to be written into the sub-journal if there exists one
-+** or more open savepoints for which:
-+**
-+**   * The page-number is less than or equal to PagerSavepoint.nOrig, and
-+**   * The bit corresponding to the page-number is not set in
-+**     PagerSavepoint.pInSavepoint.
-+*/
-+static int subjRequiresPage(PgHdr *pPg){
-+  Pager *pPager = pPg->pPager;
-+  PagerSavepoint *p;
-+  Pgno pgno = pPg->pgno;
-+  int i;
-+  for(i=0; i<pPager->nSavepoint; i++){
-+    p = &pPager->aSavepoint[i];
-+    if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
-+      return 1;
-     }
--    zJournal += (sqlite3Strlen30(zJournal)+1);
-   }
-- 
--  sqlite3OsClose(pMaster);
--  rc = sqlite3OsDelete(pVfs, zMaster, 0);
-+  return 0;
-+}
- 
--delmaster_out:
--  sqlite3_free(zMasterJournal);
--  if( pMaster ){
--    sqlite3OsClose(pMaster);
--    assert( !isOpen(pJournal) );
--    sqlite3_free(pMaster);
-+/*
-+** Return true if the page is already in the journal file.
++** xSetOutputs callback used by detail=none tables.
 +*/
-+static int pageInJournal(Pager *pPager, PgHdr *pPg){
-+  return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno);
++static void fts5IterSetOutputs_None(Fts5Iter *pIter, Fts5SegIter *pSeg){
++  assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_NONE );
++  pIter->base.iRowid = pSeg->iRowid;
++  pIter->base.nData = pSeg->nPos;
 +}
 +
 +/*
-+** Read a 32-bit integer from the given file descriptor.  Store the integer
-+** that is read in *pRes.  Return SQLITE_OK if everything worked, or an
-+** error code is something goes wrong.
-+**
-+** All values are stored on disk as big-endian.
++** xSetOutputs callback used by detail=full and detail=col tables when no
++** column filters are specified.
 +*/
-+static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){
-+  unsigned char ac[4];
-+  int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset);
-+  if( rc==SQLITE_OK ){
-+    *pRes = sqlite3Get4byte(ac);
++static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){
++  pIter->base.iRowid = pSeg->iRowid;
++  pIter->base.nData = pSeg->nPos;
++
++  assert( pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_NONE );
++  assert( pIter->pColset==0 );
++
++  if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
++    /* All data is stored on the current page. Populate the output 
++    ** variables to point into the body of the page object. */
++    pIter->base.pData = &pSeg->pLeaf->p[pSeg->iLeafOffset];
++  }else{
++    /* The data is distributed over two or more pages. Copy it into the
++    ** Fts5Iter.poslist buffer and then set the output pointer to point
++    ** to this buffer.  */
++    fts5BufferZero(&pIter->poslist);
++    fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist);
++    pIter->base.pData = pIter->poslist.p;
 +  }
-+  return rc;
 +}
 +
 +/*
-+** Write a 32-bit integer into a string buffer in big-endian byte order.
++** xSetOutputs callback used when the Fts5Colset object has nCol==0 (match
++** against no columns at all).
 +*/
-+#define put32bits(A,B)  sqlite3Put4byte((u8*)A,B)
-+
++static void fts5IterSetOutputs_ZeroColset(Fts5Iter *pIter, Fts5SegIter *pSeg){
++  UNUSED_PARAM(pSeg);
++  pIter->base.nData = 0;
++}
 +
 +/*
-+** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
-+** on success or an error code is something goes wrong.
++** xSetOutputs callback used by detail=col when there is a column filter
++** and there are 100 or more columns. Also called as a fallback from
++** fts5IterSetOutputs_Col100 if the column-list spans more than one page.
 +*/
-+static int write32bits(sqlite3_file *fd, i64 offset, u32 val){
-+  char ac[4];
-+  put32bits(ac, val);
-+  return sqlite3OsWrite(fd, ac, 4, offset);
++static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){
++  fts5BufferZero(&pIter->poslist);
++  fts5SegiterPoslist(pIter->pIndex, pSeg, pIter->pColset, &pIter->poslist);
++  pIter->base.iRowid = pSeg->iRowid;
++  pIter->base.pData = pIter->poslist.p;
++  pIter->base.nData = pIter->poslist.n;
 +}
 +
 +/*
-+** Unlock the database file to level eLock, which must be either NO_LOCK
-+** or SHARED_LOCK. Regardless of whether or not the call to xUnlock()
-+** succeeds, set the Pager.eLock variable to match the (attempted) new lock.
++** xSetOutputs callback used when: 
 +**
-+** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is
-+** called, do not modify it. See the comment above the #define of 
-+** UNKNOWN_LOCK for an explanation of this.
-+*/
-+static int pagerUnlockDb(Pager *pPager, int eLock){
-+  int rc = SQLITE_OK;
-+
-+  assert( !pPager->exclusiveMode || pPager->eLock==eLock );
-+  assert( eLock==NO_LOCK || eLock==SHARED_LOCK );
-+  assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
-+  if( isOpen(pPager->fd) ){
-+    assert( pPager->eLock>=eLock );
-+    rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock);
-+    if( pPager->eLock!=UNKNOWN_LOCK ){
-+      pPager->eLock = (u8)eLock;
-+    }
-+    IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
-   }
-   return rc;
- }
- 
-+/*
-+** Lock the database file to level eLock, which must be either SHARED_LOCK,
-+** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the
-+** Pager.eLock variable to the new locking state. 
++**   * detail=col,
++**   * there is a column filter, and
++**   * the table contains 100 or fewer columns. 
 +**
-+** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is 
-+** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. 
-+** See the comment above the #define of UNKNOWN_LOCK for an explanation 
-+** of this.
++** The last point is to ensure all column numbers are stored as 
++** single-byte varints.
 +*/
-+static int pagerLockDb(Pager *pPager, int eLock){
-+  int rc = SQLITE_OK;
++static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){
 +
-+  assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK );
-+  if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){
-+    rc = pPager->noLock ? SQLITE_OK : sqlite3OsLock(pPager->fd, eLock);
-+    if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){
-+      pPager->eLock = (u8)eLock;
-+      IOTRACE(("LOCK %p %d\n", pPager, eLock))
++  assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
++  assert( pIter->pColset );
++
++  if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ){
++    fts5IterSetOutputs_Col(pIter, pSeg);
++  }else{
++    u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset];
++    u8 *pEnd = (u8*)&a[pSeg->nPos]; 
++    int iPrev = 0;
++    int *aiCol = pIter->pColset->aiCol;
++    int *aiColEnd = &aiCol[pIter->pColset->nCol];
++
++    u8 *aOut = pIter->poslist.p;
++    int iPrevOut = 0;
++
++    pIter->base.iRowid = pSeg->iRowid;
++
++    while( a<pEnd ){
++      iPrev += (int)a++[0] - 2;
++      while( *aiCol<iPrev ){
++        aiCol++;
++        if( aiCol==aiColEnd ) goto setoutputs_col_out;
++      }
++      if( *aiCol==iPrev ){
++        *aOut++ = (u8)((iPrev - iPrevOut) + 2);
++        iPrevOut = iPrev;
++      }
 +    }
++
++setoutputs_col_out:
++    pIter->base.pData = pIter->poslist.p;
++    pIter->base.nData = aOut - pIter->poslist.p;
 +  }
-+  return rc;
 +}
- 
- /*
--** This function is used to change the actual size of the database 
--** file in the file-system. This only happens when committing a transaction,
--** or rolling back a transaction (including rolling back a hot-journal).
-+** This function determines whether or not the atomic-write optimization
-+** can be used with this pager. The optimization can be used if:
- **
--** If the main database file is not open, or the pager is not in either
--** DBMOD or OPEN state, this function is a no-op. Otherwise, the size 
--** of the file is changed to nPage pages (nPage*pPager->pageSize bytes). 
--** If the file on disk is currently larger than nPage pages, then use the VFS
--** xTruncate() method to truncate it.
-+**  (a) the value returned by OsDeviceCharacteristics() indicates that
-+**      a database page may be written atomically, and
-+**  (b) the value returned by OsSectorSize() is less than or equal
-+**      to the page size.
- **
--** Or, it might be the case that the file on disk is smaller than 
--** nPage pages. Some operating system implementations can get confused if 
--** you try to truncate a file to some size that is larger than it 
--** currently is, so detect this case and write a single zero byte to 
--** the end of the new file instead.
-+** The optimization is also always enabled for temporary files. It is
-+** an error to call this function if pPager is opened on an in-memory
-+** database.
- **
--** If successful, return SQLITE_OK. If an IO error occurs while modifying
--** the database file, return the error code to the caller.
-+** If the optimization cannot be used, 0 is returned. If it can be used,
-+** then the value returned is the size of the journal file when it
-+** contains rollback data for exactly one page.
- */
--static int pager_truncate(Pager *pPager, Pgno nPage){
--  int rc = SQLITE_OK;
--  assert( pPager->eState!=PAGER_ERROR );
--  assert( pPager->eState!=PAGER_READER );
--  
--  if( isOpen(pPager->fd) 
--   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) 
--  ){
--    i64 currentSize, newSize;
--    int szPage = pPager->pageSize;
--    assert( pPager->eLock==EXCLUSIVE_LOCK );
--    /* TODO: Is it safe to use Pager.dbFileSize here? */
--    rc = sqlite3OsFileSize(pPager->fd, &currentSize);
--    newSize = szPage*(i64)nPage;
--    if( rc==SQLITE_OK && currentSize!=newSize ){
--      if( currentSize>newSize ){
--        rc = sqlite3OsTruncate(pPager->fd, newSize);
--      }else if( (currentSize+szPage)<=newSize ){
--        char *pTmp = pPager->pTmpSpace;
--        memset(pTmp, 0, szPage);
--        testcase( (newSize-szPage) == currentSize );
--        testcase( (newSize-szPage) >  currentSize );
--        rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage);
--      }
--      if( rc==SQLITE_OK ){
--        pPager->dbFileSize = nPage;
--      }
-+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-+static int jrnlBufferSize(Pager *pPager){
-+  assert( !MEMDB );
-+  if( !pPager->tempFile ){
-+    int dc;                           /* Device characteristics */
-+    int nSector;                      /* Sector size */
-+    int szPage;                       /* Page size */
-+
-+    assert( isOpen(pPager->fd) );
-+    dc = sqlite3OsDeviceCharacteristics(pPager->fd);
-+    nSector = pPager->sectorSize;
-+    szPage = pPager->pageSize;
-+
-+    assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
-+    assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
-+    if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){
-+      return 0;
-     }
-   }
--  return rc;
 +
-+  return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
- }
-+#endif
- 
- /*
--** Return a sanitized version of the sector-size of OS file pFile. The
--** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE.
-+** If SQLITE_CHECK_PAGES is defined then we do some sanity checking
-+** on the cache using a hash function.  This is used for testing
-+** and debugging only.
- */
--SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){
--  int iRet = sqlite3OsSectorSize(pFile);
--  if( iRet<32 ){
--    iRet = 512;
--  }else if( iRet>MAX_SECTOR_SIZE ){
--    assert( MAX_SECTOR_SIZE>=512 );
--    iRet = MAX_SECTOR_SIZE;
-+#ifdef SQLITE_CHECK_PAGES
 +/*
-+** Return a 32-bit hash of the page data for pPage.
++** xSetOutputs callback used by detail=full when there is a column filter.
 +*/
-+static u32 pager_datahash(int nByte, unsigned char *pData){
-+  u32 hash = 0;
-+  int i;
-+  for(i=0; i<nByte; i++){
-+    hash = (hash*1039) + pData[i];
-   }
--  return iRet;
-+  return hash;
-+}
-+static u32 pager_pagehash(PgHdr *pPage){
-+  return pager_datahash(pPage->pPager->pageSize, (unsigned char *)pPage->pData);
-+}
-+static void pager_set_pagehash(PgHdr *pPage){
-+  pPage->pageHash = pager_pagehash(pPage);
- }
- 
- /*
--** Set the value of the Pager.sectorSize variable for the given
--** pager based on the value returned by the xSectorSize method
--** of the open database file. The sector size will be used 
--** to determine the size and alignment of journal header and 
--** master journal pointers within created journal files.
--**
--** For temporary files the effective sector size is always 512 bytes.
--**
--** Otherwise, for non-temporary files, the effective sector size is
--** the value returned by the xSectorSize() method rounded up to 32 if
--** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it
--** is greater than MAX_SECTOR_SIZE.
--**
--** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set
--** the effective sector size to its minimum value (512).  The purpose of
--** pPager->sectorSize is to define the "blast radius" of bytes that
--** might change if a crash occurs while writing to a single byte in
--** that range.  But with POWERSAFE_OVERWRITE, the blast radius is zero
--** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector
--** size.  For backwards compatibility of the rollback journal file format,
--** we cannot reduce the effective sector size below 512.
-+** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
-+** is defined, and NDEBUG is not defined, an assert() statement checks
-+** that the page is either dirty or still matches the calculated page-hash.
- */
--static void setSectorSize(Pager *pPager){
--  assert( isOpen(pPager->fd) || pPager->tempFile );
--
--  if( pPager->tempFile
--   || (sqlite3OsDeviceCharacteristics(pPager->fd) & 
--              SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0
--  ){
--    /* Sector size doesn't matter for temporary files. Also, the file
--    ** may not have been opened yet, in which case the OsSectorSize()
--    ** call will segfault. */
--    pPager->sectorSize = 512;
--  }else{
--    pPager->sectorSize = sqlite3SectorSize(pPager->fd);
--  }
-+#define CHECK_PAGE(x) checkPage(x)
-+static void checkPage(PgHdr *pPg){
-+  Pager *pPager = pPg->pPager;
-+  assert( pPager->eState!=PAGER_ERROR );
-+  assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) );
- }
- 
-+#else
-+#define pager_datahash(X,Y)  0
-+#define pager_pagehash(X)  0
-+#define pager_set_pagehash(X)
-+#define CHECK_PAGE(x)
-+#endif  /* SQLITE_CHECK_PAGES */
-+
- /*
--** Playback the journal and thus restore the database file to
--** the state it was in before we started making changes.  
--**
--** The journal file format is as follows: 
--**
--**  (1)  8 byte prefix.  A copy of aJournalMagic[].
--**  (2)  4 byte big-endian integer which is the number of valid page records
--**       in the journal.  If this value is 0xffffffff, then compute the
--**       number of page records from the journal size.
--**  (3)  4 byte big-endian integer which is the initial value for the 
--**       sanity checksum.
--**  (4)  4 byte integer which is the number of pages to truncate the
--**       database to during a rollback.
--**  (5)  4 byte big-endian integer which is the sector size.  The header
--**       is this many bytes in size.
--**  (6)  4 byte big-endian integer which is the page size.
--**  (7)  zero padding out to the next sector size.
--**  (8)  Zero or more pages instances, each as follows:
--**        +  4 byte page number.
--**        +  pPager->pageSize bytes of data.
--**        +  4 byte checksum
--**
--** When we speak of the journal header, we mean the first 7 items above.
--** Each entry in the journal is an instance of the 8th item.
--**
--** Call the value from the second bullet "nRec".  nRec is the number of
--** valid page entries in the journal.  In most cases, you can compute the
--** value of nRec from the size of the journal file.  But if a power
--** failure occurred while the journal was being written, it could be the
--** case that the size of the journal file had already been increased but
--** the extra entries had not yet made it safely to disk.  In such a case,
--** the value of nRec computed from the file size would be too large.  For
--** that reason, we always use the nRec value in the header.
-+** When this is called the journal file for pager pPager must be open.
-+** This function attempts to read a master journal file name from the 
-+** end of the file and, if successful, copies it into memory supplied 
-+** by the caller. See comments above writeMasterJournal() for the format
-+** used to store a master journal file name at the end of a journal file.
- **
--** If the nRec value is 0xffffffff it means that nRec should be computed
--** from the file size.  This value is used when the user selects the
--** no-sync option for the journal.  A power failure could lead to corruption
--** in this case.  But for things like temporary table (which will be
--** deleted when the power is restored) we don't care.  
-+** zMaster must point to a buffer of at least nMaster bytes allocated by
-+** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is
-+** enough space to write the master journal name). If the master journal
-+** name in the journal is longer than nMaster bytes (including a
-+** nul-terminator), then this is handled as if no master journal name
-+** were present in the journal.
- **
--** If the file opened as the journal file is not a well-formed
--** journal file then all pages up to the first corrupted page are rolled
--** back (or no pages if the journal header is corrupted). The journal file
--** is then deleted and SQLITE_OK returned, just as if no corruption had
--** been encountered.
-+** If a master journal file name is present at the end of the journal
-+** file, then it is copied into the buffer pointed to by zMaster. A
-+** nul-terminator byte is appended to the buffer following the master
-+** journal file name.
- **
--** If an I/O or malloc() error occurs, the journal-file is not deleted
--** and an error code is returned.
-+** If it is determined that no master journal file name is present 
-+** zMaster[0] is set to 0 and SQLITE_OK returned.
- **
--** The isHot parameter indicates that we are trying to rollback a journal
--** that might be a hot journal.  Or, it could be that the journal is 
--** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE.
--** If the journal really is hot, reset the pager cache prior rolling
--** back any content.  If the journal is merely persistent, no reset is
--** needed.
-+** If an error occurs while reading from the journal file, an SQLite
-+** error code is returned.
- */
--static int pager_playback(Pager *pPager, int isHot){
--  sqlite3_vfs *pVfs = pPager->pVfs;
--  i64 szJ;                 /* Size of the journal file in bytes */
--  u32 nRec;                /* Number of Records in the journal */
--  u32 u;                   /* Unsigned loop counter */
--  Pgno mxPg = 0;           /* Size of the original file in pages */
--  int rc;                  /* Result code of a subroutine */
--  int res = 1;             /* Value returned by sqlite3OsAccess() */
--  char *zMaster = 0;       /* Name of master journal file if any */
--  int needPagerReset;      /* True to reset page prior to first page rollback */
--  int nPlayback = 0;       /* Total number of pages restored from journal */
--
--  /* Figure out how many records are in the journal.  Abort early if
--  ** the journal is empty.
--  */
--  assert( isOpen(pPager->jfd) );
--  rc = sqlite3OsFileSize(pPager->jfd, &szJ);
--  if( rc!=SQLITE_OK ){
--    goto end_playback;
--  }
--
--  /* Read the master journal name from the journal, if it is present.
--  ** If a master journal file name is specified, but the file is not
--  ** present on disk, then the journal is not hot and does not need to be
--  ** played back.
--  **
--  ** TODO: Technically the following is an error because it assumes that
--  ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
--  ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
--  **  mxPathname is 512, which is the same as the minimum allowable value
--  ** for pageSize.
--  */
--  zMaster = pPager->pTmpSpace;
--  rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
--  if( rc==SQLITE_OK && zMaster[0] ){
--    rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
--  }
--  zMaster = 0;
--  if( rc!=SQLITE_OK || !res ){
--    goto end_playback;
--  }
--  pPager->journalOff = 0;
--  needPagerReset = isHot;
--
--  /* This loop terminates either when a readJournalHdr() or 
--  ** pager_playback_one_page() call returns SQLITE_DONE or an IO error 
--  ** occurs. 
--  */
--  while( 1 ){
--    /* Read the next journal header from the journal file.  If there are
--    ** not enough bytes left in the journal file for a complete header, or
--    ** it is corrupted, then a process must have failed while writing it.
--    ** This indicates nothing more needs to be rolled back.
--    */
--    rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg);
--    if( rc!=SQLITE_OK ){ 
--      if( rc==SQLITE_DONE ){
--        rc = SQLITE_OK;
--      }
--      goto end_playback;
--    }
--
--    /* If nRec is 0xffffffff, then this journal was created by a process
--    ** working in no-sync mode. This means that the rest of the journal
--    ** file consists of pages, there are no more journal headers. Compute
--    ** the value of nRec based on this assumption.
--    */
--    if( nRec==0xffffffff ){
--      assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
--      nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager));
--    }
--
--    /* If nRec is 0 and this rollback is of a transaction created by this
--    ** process and if this is the final header in the journal, then it means
--    ** that this part of the journal was being filled but has not yet been
--    ** synced to disk.  Compute the number of pages based on the remaining
--    ** size of the file.
--    **
--    ** The third term of the test was added to fix ticket #2565.
--    ** When rolling back a hot journal, nRec==0 always means that the next
--    ** chunk of the journal contains zero pages to be rolled back.  But
--    ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in
--    ** the journal, it means that the journal might contain additional
--    ** pages that need to be rolled back and that the number of pages 
--    ** should be computed based on the journal file size.
--    */
--    if( nRec==0 && !isHot &&
--        pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){
--      nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager));
--    }
--
--    /* If this is the first header read from the journal, truncate the
--    ** database file back to its original size.
--    */
--    if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
--      rc = pager_truncate(pPager, mxPg);
--      if( rc!=SQLITE_OK ){
--        goto end_playback;
--      }
--      pPager->dbSize = mxPg;
--    }
--
--    /* Copy original pages out of the journal and back into the 
--    ** database file and/or page cache.
--    */
--    for(u=0; u<nRec; u++){
--      if( needPagerReset ){
--        pager_reset(pPager);
--        needPagerReset = 0;
--      }
--      rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
--      if( rc==SQLITE_OK ){
--        nPlayback++;
--      }else{
--        if( rc==SQLITE_DONE ){
--          pPager->journalOff = szJ;
--          break;
--        }else if( rc==SQLITE_IOERR_SHORT_READ ){
--          /* If the journal has been truncated, simply stop reading and
--          ** processing the journal. This might happen if the journal was
--          ** not completely written and synced prior to a crash.  In that
--          ** case, the database should have never been written in the
--          ** first place so it is OK to simply abandon the rollback. */
--          rc = SQLITE_OK;
--          goto end_playback;
--        }else{
--          /* If we are unable to rollback, quit and return the error
--          ** code.  This will cause the pager to enter the error state
--          ** so that no further harm will be done.  Perhaps the next
--          ** process to come along will be able to rollback the database.
--          */
--          goto end_playback;
--        }
--      }
--    }
--  }
--  /*NOTREACHED*/
--  assert( 0 );
--
--end_playback:
--  /* Following a rollback, the database file should be back in its original
--  ** state prior to the start of the transaction, so invoke the
--  ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the
--  ** assertion that the transaction counter was modified.
--  */
--#ifdef SQLITE_DEBUG
--  if( pPager->fd->pMethods ){
--    sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0);
--  }
--#endif
--
--  /* If this playback is happening automatically as a result of an IO or 
--  ** malloc error that occurred after the change-counter was updated but 
--  ** before the transaction was committed, then the change-counter 
--  ** modification may just have been reverted. If this happens in exclusive 
--  ** mode, then subsequent transactions performed by the connection will not
--  ** update the change-counter at all. This may lead to cache inconsistency
--  ** problems for other processes at some point in the future. So, just
--  ** in case this has happened, clear the changeCountDone flag now.
--  */
--  pPager->changeCountDone = pPager->tempFile;
-+static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
-+  int rc;                    /* Return code */
-+  u32 len;                   /* Length in bytes of master journal name */
-+  i64 szJ;                   /* Total size in bytes of journal file pJrnl */
-+  u32 cksum;                 /* MJ checksum value read from journal */
-+  u32 u;                     /* Unsigned loop counter */
-+  unsigned char aMagic[8];   /* A buffer to hold the magic header */
-+  zMaster[0] = '\0';
- 
--  if( rc==SQLITE_OK ){
--    zMaster = pPager->pTmpSpace;
--    rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
--    testcase( rc!=SQLITE_OK );
--  }
--  if( rc==SQLITE_OK
--   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
-+  if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ))
-+   || szJ<16
-+   || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
-+   || len>=nMaster 
-+   || len==0 
-+   || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
-+   || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
-+   || memcmp(aMagic, aJournalMagic, 8)
-+   || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len))
-   ){
--    rc = sqlite3PagerSync(pPager, 0);
-+    return rc;
-   }
--  if( rc==SQLITE_OK ){
--    rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0);
--    testcase( rc!=SQLITE_OK );
-+
-+  /* See if the checksum matches the master journal name */
-+  for(u=0; u<len; u++){
-+    cksum -= zMaster[u];
-   }
--  if( rc==SQLITE_OK && zMaster[0] && res ){
--    /* If there was a master journal and this routine will return success,
--    ** see if it is possible to delete the master journal.
-+  if( cksum ){
-+    /* If the checksum doesn't add up, then one or more of the disk sectors
-+    ** containing the master journal filename is corrupted. This means
-+    ** definitely roll back, so just return SQLITE_OK and report a (nul)
-+    ** master-journal filename.
-     */
--    rc = pager_delmaster(pPager, zMaster);
--    testcase( rc!=SQLITE_OK );
--  }
--  if( isHot && nPlayback ){
--    sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s",
--                nPlayback, pPager->zJournal);
-+    len = 0;
-   }
--
--  /* The Pager.sectorSize variable may have been updated while rolling
--  ** back a journal created by a process with a different sector size
--  ** value. Reset it to the correct value for this process.
--  */
--  setSectorSize(pPager);
--  return rc;
-+  zMaster[len] = '\0';
-+   
-+  return SQLITE_OK;
- }
- 
--
- /*
--** Read the content for page pPg out of the database file and into 
--** pPg->pData. A shared lock or greater must be held on the database
--** file before this function is called.
-+** Return the offset of the sector boundary at or immediately 
-+** following the value in pPager->journalOff, assuming a sector 
-+** size of pPager->sectorSize bytes.
- **
--** If page 1 is read, then the value of Pager.dbFileVers[] is set to
--** the value read from the database file.
-+** i.e for a sector size of 512:
- **
--** If an IO error occurs, then the IO error is returned to the caller.
--** Otherwise, SQLITE_OK is returned.
-+**   Pager.journalOff          Return value
-+**   ---------------------------------------
-+**   0                         0
-+**   512                       512
-+**   100                       512
-+**   2000                      2048
-+** 
- */
--static int readDbPage(PgHdr *pPg, u32 iFrame){
--  Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
--  Pgno pgno = pPg->pgno;       /* Page number to read */
--  int rc = SQLITE_OK;          /* Return code */
--  int pgsz = pPager->pageSize; /* Number of bytes to read */
--
--  assert( pPager->eState>=PAGER_READER && !MEMDB );
--  assert( isOpen(pPager->fd) );
--
--#ifndef SQLITE_OMIT_WAL
--  if( iFrame ){
--    /* Try to pull the page from the write-ahead log. */
--    rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData);
--  }else
--#endif
--  {
--    i64 iOffset = (pgno-1)*(i64)pPager->pageSize;
--    rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
--    if( rc==SQLITE_IOERR_SHORT_READ ){
--      rc = SQLITE_OK;
--    }
--  }
--
--  if( pgno==1 ){
--    if( rc ){
--      /* If the read is unsuccessful, set the dbFileVers[] to something
--      ** that will never be a valid file version.  dbFileVers[] is a copy
--      ** of bytes 24..39 of the database.  Bytes 28..31 should always be
--      ** zero or the size of the database in page. Bytes 32..35 and 35..39
--      ** should be page numbers which are never 0xffffffff.  So filling
--      ** pPager->dbFileVers[] with all 0xff bytes should suffice.
--      **
--      ** For an encrypted database, the situation is more complex:  bytes
--      ** 24..39 of the database are white noise.  But the probability of
--      ** white noise equaling 16 bytes of 0xff is vanishingly small so
--      ** we should still be ok.
--      */
--      memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
--    }else{
--      u8 *dbFileVers = &((u8*)pPg->pData)[24];
--      memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
--    }
-+static i64 journalHdrOffset(Pager *pPager){
-+  i64 offset = 0;
-+  i64 c = pPager->journalOff;
-+  if( c ){
-+    offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager);
-   }
--  CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
--
--  PAGER_INCR(sqlite3_pager_readdb_count);
--  PAGER_INCR(pPager->nRead);
--  IOTRACE(("PGIN %p %d\n", pPager, pgno));
--  PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
--               PAGERID(pPager), pgno, pager_pagehash(pPg)));
--
--  return rc;
-+  assert( offset%JOURNAL_HDR_SZ(pPager)==0 );
-+  assert( offset>=c );
-+  assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
-+  return offset;
- }
- 
- /*
--** Update the value of the change-counter at offsets 24 and 92 in
--** the header and the sqlite version number at offset 96.
-+** The journal file must be open when this function is called.
- **
--** This is an unconditional update.  See also the pager_incr_changecounter()
--** routine which only updates the change-counter if the update is actually
--** needed, as determined by the pPager->changeCountDone state variable.
-+** This function is a no-op if the journal file has not been written to
-+** within the current transaction (i.e. if Pager.journalOff==0).
-+**
-+** If doTruncate is non-zero or the Pager.journalSizeLimit variable is
-+** set to 0, then truncate the journal file to zero bytes in size. Otherwise,
-+** zero the 28-byte header at the start of the journal file. In either case, 
-+** if the pager is not in no-sync mode, sync the journal file immediately 
-+** after writing or truncating it.
-+**
-+** If Pager.journalSizeLimit is set to a positive, non-zero value, and
-+** following the truncation or zeroing described above the size of the 
-+** journal file in bytes is larger than this value, then truncate the
-+** journal file to Pager.journalSizeLimit bytes. The journal file does
-+** not need to be synced following this operation.
-+**
-+** If an IO error occurs, abandon processing and return the IO error code.
-+** Otherwise, return SQLITE_OK.
- */
--static void pager_write_changecounter(PgHdr *pPg){
--  u32 change_counter;
-+static int zeroJournalHdr(Pager *pPager, int doTruncate){
-+  int rc = SQLITE_OK;                               /* Return code */
-+  assert( isOpen(pPager->jfd) );
-+  if( pPager->journalOff ){
-+    const i64 iLimit = pPager->journalSizeLimit;    /* Local cache of jsl */
- 
--  /* Increment the value just read and write it back to byte 24. */
--  change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1;
--  put32bits(((char*)pPg->pData)+24, change_counter);
-+    IOTRACE(("JZEROHDR %p\n", pPager))
-+    if( doTruncate || iLimit==0 ){
-+      rc = sqlite3OsTruncate(pPager->jfd, 0);
-+    }else{
-+      static const char zeroHdr[28] = {0};
-+      rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0);
-+    }
-+    if( rc==SQLITE_OK && !pPager->noSync ){
-+      rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags);
-+    }
- 
--  /* Also store the SQLite version number in bytes 96..99 and in
--  ** bytes 92..95 store the change counter for which the version number
--  ** is valid. */
--  put32bits(((char*)pPg->pData)+92, change_counter);
--  put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER);
-+    /* At this point the transaction is committed but the write lock 
-+    ** is still held on the file. If there is a size limit configured for 
-+    ** the persistent journal and the journal file currently consumes more
-+    ** space than that limit allows for, truncate it now. There is no need
-+    ** to sync the file following this operation.
-+    */
-+    if( rc==SQLITE_OK && iLimit>0 ){
-+      i64 sz;
-+      rc = sqlite3OsFileSize(pPager->jfd, &sz);
-+      if( rc==SQLITE_OK && sz>iLimit ){
-+        rc = sqlite3OsTruncate(pPager->jfd, iLimit);
-+      }
++static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){
++  Fts5Colset *pColset = pIter->pColset;
++  pIter->base.iRowid = pSeg->iRowid;
++
++  assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_FULL );
++  assert( pColset );
++
++  if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
++    /* All data is stored on the current page. Populate the output 
++    ** variables to point into the body of the page object. */
++    const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset];
++    if( pColset->nCol==1 ){
++      pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]);
++      pIter->base.pData = a;
++    }else{
++      int *pRc = &pIter->pIndex->rc;
++      fts5BufferZero(&pIter->poslist);
++      fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, &pIter->poslist);
++      pIter->base.pData = pIter->poslist.p;
++      pIter->base.nData = pIter->poslist.n;
 +    }
-+  }
-+  return rc;
- }
- 
--#ifndef SQLITE_OMIT_WAL
- /*
--** This function is invoked once for each page that has already been 
--** written into the log file when a WAL transaction is rolled back.
--** Parameter iPg is the page number of said page. The pCtx argument 
--** is actually a pointer to the Pager structure.
-+** The journal file must be open when this routine is called. A journal
-+** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the
-+** current location.
- **
--** If page iPg is present in the cache, and has no outstanding references,
--** it is discarded. Otherwise, if there are one or more outstanding
--** references, the page content is reloaded from the database. If the
--** attempt to reload content from the database is required and fails, 
--** return an SQLite error code. Otherwise, SQLITE_OK.
-+** The format for the journal header is as follows:
-+** - 8 bytes: Magic identifying journal format.
-+** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.
-+** - 4 bytes: Random number used for page hash.
-+** - 4 bytes: Initial database page count.
-+** - 4 bytes: Sector size used by the process that wrote this journal.
-+** - 4 bytes: Database page size.
-+** 
-+** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space.
- */
--static int pagerUndoCallback(void *pCtx, Pgno iPg){
--  int rc = SQLITE_OK;
--  Pager *pPager = (Pager *)pCtx;
--  PgHdr *pPg;
-+static int writeJournalHdr(Pager *pPager){
-+  int rc = SQLITE_OK;                 /* Return code */
-+  char *zHeader = pPager->pTmpSpace;  /* Temporary space used to build header */
-+  u32 nHeader = (u32)pPager->pageSize;/* Size of buffer pointed to by zHeader */
-+  u32 nWrite;                         /* Bytes of header sector written */
-+  int ii;                             /* Loop counter */
- 
--  assert( pagerUseWal(pPager) );
--  pPg = sqlite3PagerLookup(pPager, iPg);
--  if( pPg ){
--    if( sqlite3PcachePageRefcount(pPg)==1 ){
--      sqlite3PcacheDrop(pPg);
--    }else{
--      u32 iFrame = 0;
--      rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
--      if( rc==SQLITE_OK ){
--        rc = readDbPage(pPg, iFrame);
--      }
--      if( rc==SQLITE_OK ){
--        pPager->xReiniter(pPg);
--      }
--      sqlite3PagerUnrefNotNull(pPg);
-+  assert( isOpen(pPager->jfd) );      /* Journal file must be open. */
-+
-+  if( nHeader>JOURNAL_HDR_SZ(pPager) ){
-+    nHeader = JOURNAL_HDR_SZ(pPager);
-+  }
-+
-+  /* If there are active savepoints and any of them were created 
-+  ** since the most recent journal header was written, update the 
-+  ** PagerSavepoint.iHdrOffset fields now.
-+  */
-+  for(ii=0; ii<pPager->nSavepoint; ii++){
-+    if( pPager->aSavepoint[ii].iHdrOffset==0 ){
-+      pPager->aSavepoint[ii].iHdrOffset = pPager->journalOff;
-     }
-   }
- 
--  /* Normally, if a transaction is rolled back, any backup processes are
--  ** updated as data is copied out of the rollback journal and into the
--  ** database. This is not generally possible with a WAL database, as
--  ** rollback involves simply truncating the log file. Therefore, if one
--  ** or more frames have already been written to the log (and therefore 
--  ** also copied into the backup databases) as part of this transaction,
--  ** the backups must be restarted.
-+  pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager);
-+
-+  /* 
-+  ** Write the nRec Field - the number of page records that follow this
-+  ** journal header. Normally, zero is written to this value at this time.
-+  ** After the records are added to the journal (and the journal synced, 
-+  ** if in full-sync mode), the zero is overwritten with the true number
-+  ** of records (see syncJournal()).
-+  **
-+  ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When
-+  ** reading the journal this value tells SQLite to assume that the
-+  ** rest of the journal file contains valid page records. This assumption
-+  ** is dangerous, as if a failure occurred whilst writing to the journal
-+  ** file it may contain some garbage data. There are two scenarios
-+  ** where this risk can be ignored:
-+  **
-+  **   * When the pager is in no-sync mode. Corruption can follow a
-+  **     power failure in this case anyway.
-+  **
-+  **   * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees
-+  **     that garbage data is never appended to the journal file.
-   */
--  sqlite3BackupRestart(pPager->pBackup);
-+  assert( isOpen(pPager->fd) || pPager->noSync );
-+  if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY)
-+   || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) 
-+  ){
-+    memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
-+    put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
 +  }else{
-+    memset(zHeader, 0, sizeof(aJournalMagic)+4);
++    /* The data is distributed over two or more pages. Copy it into the
++    ** Fts5Iter.poslist buffer and then set the output pointer to point
++    ** to this buffer.  */
++    fts5BufferZero(&pIter->poslist);
++    fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
++    pIter->base.pData = pIter->poslist.p;
++    pIter->base.nData = pIter->poslist.n;
 +  }
- 
--  return rc;
--}
-+  /* The random check-hash initializer */ 
-+  sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
-+  put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);
-+  /* The initial database size */
-+  put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize);
-+  /* The assumed sector size for this process */
-+  put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
- 
--/*
--** This function is called to rollback a transaction on a WAL database.
--*/
--static int pagerRollbackWal(Pager *pPager){
--  int rc;                         /* Return Code */
--  PgHdr *pList;                   /* List of dirty pages to revert */
-+  /* The page size */
-+  put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize);
- 
--  /* For all pages in the cache that are currently dirty or have already
--  ** been written (but not committed) to the log file, do one of the 
--  ** following:
--  **
--  **   + Discard the cached page (if refcount==0), or
--  **   + Reload page content from the database (if refcount>0).
-+  /* Initializing the tail of the buffer is not necessary.  Everything
-+  ** works find if the following memset() is omitted.  But initializing
-+  ** the memory prevents valgrind from complaining, so we are willing to
-+  ** take the performance hit.
-   */
--  pPager->dbSize = pPager->dbOrigSize;
--  rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager);
--  pList = sqlite3PcacheDirtyList(pPager->pPCache);
--  while( pList && rc==SQLITE_OK ){
--    PgHdr *pNext = pList->pDirty;
--    rc = pagerUndoCallback((void *)pPager, pList->pgno);
--    pList = pNext;
-+  memset(&zHeader[sizeof(aJournalMagic)+20], 0,
-+         nHeader-(sizeof(aJournalMagic)+20));
-+
-+  /* In theory, it is only necessary to write the 28 bytes that the 
-+  ** journal header consumes to the journal file here. Then increment the 
-+  ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next 
-+  ** record is written to the following sector (leaving a gap in the file
-+  ** that will be implicitly filled in by the OS).
-+  **
-+  ** However it has been discovered that on some systems this pattern can 
-+  ** be significantly slower than contiguously writing data to the file,
-+  ** even if that means explicitly writing data to the block of 
-+  ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what
-+  ** is done. 
-+  **
-+  ** The loop is required here in case the sector-size is larger than the 
-+  ** database page size. Since the zHeader buffer is only Pager.pageSize
-+  ** bytes in size, more than one call to sqlite3OsWrite() may be required
-+  ** to populate the entire journal header sector.
-+  */ 
-+  for(nWrite=0; rc==SQLITE_OK&&nWrite<JOURNAL_HDR_SZ(pPager); nWrite+=nHeader){
-+    IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, nHeader))
-+    rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff);
-+    assert( pPager->journalHdr <= pPager->journalOff );
-+    pPager->journalOff += nHeader;
-   }
- 
-   return rc;
- }
- 
- /*
--** This function is a wrapper around sqlite3WalFrames(). As well as logging
--** the contents of the list of pages headed by pList (connected by pDirty),
--** this function notifies any active backup processes that the pages have
--** changed. 
-+** The journal file must be open when this is called. A journal header file
-+** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal
-+** file. The current location in the journal file is given by
-+** pPager->journalOff. See comments above function writeJournalHdr() for
-+** a description of the journal header format.
- **
--** The list of pages passed into this routine is always sorted by page number.
--** Hence, if page 1 appears anywhere on the list, it will be the first page.
--*/ 
--static int pagerWalFrames(
--  Pager *pPager,                  /* Pager object */
--  PgHdr *pList,                   /* List of frames to log */
--  Pgno nTruncate,                 /* Database size after this commit */
--  int isCommit                    /* True if this is a commit */
-+** If the header is read successfully, *pNRec is set to the number of
-+** page records following this header and *pDbSize is set to the size of the
-+** database before the transaction began, in pages. Also, pPager->cksumInit
-+** is set to the value read from the journal header. SQLITE_OK is returned
-+** in this case.
-+**
-+** If the journal header file appears to be corrupted, SQLITE_DONE is
-+** returned and *pNRec and *PDbSize are undefined.  If JOURNAL_HDR_SZ bytes
-+** cannot be read from the journal file an error code is returned.
-+*/
-+static int readJournalHdr(
-+  Pager *pPager,               /* Pager object */
-+  int isHot,
-+  i64 journalSize,             /* Size of the open journal file in bytes */
-+  u32 *pNRec,                  /* OUT: Value read from the nRec field */
-+  u32 *pDbSize                 /* OUT: Value of original database size field */
- ){
--  int rc;                         /* Return code */
--  int nList;                      /* Number of pages in pList */
--  PgHdr *p;                       /* For looping over pages */
-+  int rc;                      /* Return code */
-+  unsigned char aMagic[8];     /* A buffer to hold the magic header */
-+  i64 iHdrOff;                 /* Offset of journal header being read */
- 
--  assert( pPager->pWal );
--  assert( pList );
--#ifdef SQLITE_DEBUG
--  /* Verify that the page list is in accending order */
--  for(p=pList; p && p->pDirty; p=p->pDirty){
--    assert( p->pgno < p->pDirty->pgno );
--  }
--#endif
-+  assert( isOpen(pPager->jfd) );      /* Journal file must be open. */
- 
--  assert( pList->pDirty==0 || isCommit );
--  if( isCommit ){
--    /* If a WAL transaction is being committed, there is no point in writing
--    ** any pages with page numbers greater than nTruncate into the WAL file.
--    ** They will never be read by any client. So remove them from the pDirty
--    ** list here. */
--    PgHdr **ppNext = &pList;
--    nList = 0;
--    for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
--      if( p->pgno<=nTruncate ){
--        ppNext = &p->pDirty;
--        nList++;
--      }
--    }
--    assert( pList );
--  }else{
--    nList = 1;
-+  /* Advance Pager.journalOff to the start of the next sector. If the
-+  ** journal file is too small for there to be a header stored at this
-+  ** point, return SQLITE_DONE.
-+  */
-+  pPager->journalOff = journalHdrOffset(pPager);
-+  if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
-+    return SQLITE_DONE;
-   }
--  pPager->aStat[PAGER_STAT_WRITE] += nList;
-+  iHdrOff = pPager->journalOff;
- 
--  if( pList->pgno==1 ) pager_write_changecounter(pList);
--  rc = sqlite3WalFrames(pPager->pWal, 
--      pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags
--  );
--  if( rc==SQLITE_OK && pPager->pBackup ){
--    for(p=pList; p; p=p->pDirty){
--      sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
-+  /* Read in the first 8 bytes of the journal header. If they do not match
-+  ** the  magic string found at the start of each journal header, return
-+  ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise,
-+  ** proceed.
-+  */
-+  if( isHot || iHdrOff!=pPager->journalHdr ){
-+    rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff);
-+    if( rc ){
-+      return rc;
++}
++
++static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){
++  if( *pRc==SQLITE_OK ){
++    Fts5Config *pConfig = pIter->pIndex->pConfig;
++    if( pConfig->eDetail==FTS5_DETAIL_NONE ){
++      pIter->xSetOutputs = fts5IterSetOutputs_None;
 +    }
-+    if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
-+      return SQLITE_DONE;
-     }
-   }
- 
--#ifdef SQLITE_CHECK_PAGES
--  pList = sqlite3PcacheDirtyList(pPager->pPCache);
--  for(p=pList; p; p=p->pDirty){
--    pager_set_pagehash(p);
-+  /* Read the first three 32-bit fields of the journal header: The nRec
-+  ** field, the checksum-initializer and the database size at the start
-+  ** of the transaction. Return an error code if anything goes wrong.
-+  */
-+  if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+8, pNRec))
-+   || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+12, &pPager->cksumInit))
-+   || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+16, pDbSize))
-+  ){
-+    return rc;
-   }
--#endif
- 
--  return rc;
--}
-+  if( pPager->journalOff==0 ){
-+    u32 iPageSize;               /* Page-size field of journal header */
-+    u32 iSectorSize;             /* Sector-size field of journal header */
- 
--/*
--** Begin a read transaction on the WAL.
--**
--** This routine used to be called "pagerOpenSnapshot()" because it essentially
--** makes a snapshot of the database at the current point in time and preserves
--** that snapshot for use by the reader in spite of concurrently changes by
--** other writers or checkpointers.
--*/
--static int pagerBeginReadTransaction(Pager *pPager){
--  int rc;                         /* Return code */
--  int changed = 0;                /* True if cache must be reset */
-+    /* Read the page-size and sector-size journal header fields. */
-+    if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize))
-+     || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize))
-+    ){
-+      return rc;
++
++    else if( pIter->pColset==0 ){
++      pIter->xSetOutputs = fts5IterSetOutputs_Nocolset;
 +    }
- 
--  assert( pagerUseWal(pPager) );
--  assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
-+    /* Versions of SQLite prior to 3.5.8 set the page-size field of the
-+    ** journal header to zero. In this case, assume that the Pager.pageSize
-+    ** variable is already set to the correct page size.
-+    */
-+    if( iPageSize==0 ){
-+      iPageSize = pPager->pageSize;
++
++    else if( pIter->pColset->nCol==0 ){
++      pIter->xSetOutputs = fts5IterSetOutputs_ZeroColset;
 +    }
- 
--  /* sqlite3WalEndReadTransaction() was not called for the previous
--  ** transaction in locking_mode=EXCLUSIVE.  So call it now.  If we
--  ** are in locking_mode=NORMAL and EndRead() was previously called,
--  ** the duplicate call is harmless.
--  */
--  sqlite3WalEndReadTransaction(pPager->pWal);
-+    /* Check that the values read from the page-size and sector-size fields
-+    ** are within range. To be 'in range', both values need to be a power
-+    ** of two greater than or equal to 512 or 32, and not greater than their 
-+    ** respective compile time maximum limits.
-+    */
-+    if( iPageSize<512                  || iSectorSize<32
-+     || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE
-+     || ((iPageSize-1)&iPageSize)!=0   || ((iSectorSize-1)&iSectorSize)!=0 
-+    ){
-+      /* If the either the page-size or sector-size in the journal-header is 
-+      ** invalid, then the process that wrote the journal-header must have 
-+      ** crashed before the header was synced. In this case stop reading 
-+      ** the journal file here.
-+      */
-+      return SQLITE_DONE;
++
++    else if( pConfig->eDetail==FTS5_DETAIL_FULL ){
++      pIter->xSetOutputs = fts5IterSetOutputs_Full;
 +    }
- 
--  rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
--  if( rc!=SQLITE_OK || changed ){
--    pager_reset(pPager);
--    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
-+    /* Update the page-size to match the value read from the journal. 
-+    ** Use a testcase() macro to make sure that malloc failure within 
-+    ** PagerSetPagesize() is tested.
-+    */
-+    rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1);
-+    testcase( rc!=SQLITE_OK );
-+
-+    /* Update the assumed sector-size to match the value used by 
-+    ** the process that created this journal. If this journal was
-+    ** created by a process other than this one, then this routine
-+    ** is being called from within pager_playback(). The local value
-+    ** of Pager.sectorSize is restored at the end of that routine.
-+    */
-+    pPager->sectorSize = iSectorSize;
-   }
- 
-+  pPager->journalOff += JOURNAL_HDR_SZ(pPager);
-   return rc;
- }
--#endif
 +
- 
- /*
--** This function is called as part of the transition from PAGER_OPEN
--** to PAGER_READER state to determine the size of the database file
--** in pages (assuming the page size currently stored in Pager.pageSize).
-+** Write the supplied master journal name into the journal file for pager
-+** pPager at the current location. The master journal name must be the last
-+** thing written to a journal file. If the pager is in full-sync mode, the
-+** journal file descriptor is advanced to the next sector boundary before
-+** anything is written. The format is:
- **
--** If no error occurs, SQLITE_OK is returned and the size of the database
--** in pages is stored in *pnPage. Otherwise, an error code (perhaps
--** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified.
-+**   + 4 bytes: PAGER_MJ_PGNO.
-+**   + N bytes: Master journal filename in utf-8.
-+**   + 4 bytes: N (length of master journal name in bytes, no nul-terminator).
-+**   + 4 bytes: Master journal name checksum.
-+**   + 8 bytes: aJournalMagic[].
-+**
-+** The master journal page checksum is the sum of the bytes in the master
-+** journal name, where each byte is interpreted as a signed 8-bit integer.
-+**
-+** If zMaster is a NULL pointer (occurs for a single database transaction), 
-+** this call is a no-op.
- */
--static int pagerPagecount(Pager *pPager, Pgno *pnPage){
--  Pgno nPage;                     /* Value to return via *pnPage */
-+static int writeMasterJournal(Pager *pPager, const char *zMaster){
-+  int rc;                          /* Return code */
-+  int nMaster;                     /* Length of string zMaster */
-+  i64 iHdrOff;                     /* Offset of header in journal file */
-+  i64 jrnlSize;                    /* Size of journal file on disk */
-+  u32 cksum = 0;                   /* Checksum of string zMaster */
- 
--  /* Query the WAL sub-system for the database size. The WalDbsize()
--  ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or
--  ** if the database size is not available. The database size is not
--  ** available from the WAL sub-system if the log file is empty or
--  ** contains no valid committed transactions.
--  */
--  assert( pPager->eState==PAGER_OPEN );
--  assert( pPager->eLock>=SHARED_LOCK );
--  nPage = sqlite3WalDbsize(pPager->pWal);
-+  assert( pPager->setMaster==0 );
-+  assert( !pagerUseWal(pPager) );
- 
--  /* If the database size was not available from the WAL sub-system,
--  ** determine it based on the size of the database file. If the size
--  ** of the database file is not an integer multiple of the page-size,
--  ** round down to the nearest page. Except, any file larger than 0
--  ** bytes in size is considered to contain at least one page.
-+  if( !zMaster 
-+   || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
-+   || !isOpen(pPager->jfd)
-+  ){
-+    return SQLITE_OK;
++    else{
++      assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS );
++      if( pConfig->nCol<=100 ){
++        pIter->xSetOutputs = fts5IterSetOutputs_Col100;
++        sqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol);
++      }else{
++        pIter->xSetOutputs = fts5IterSetOutputs_Col;
++      }
++    }
 +  }
-+  pPager->setMaster = 1;
-+  assert( pPager->journalHdr <= pPager->journalOff );
++}
 +
-+  /* Calculate the length in bytes and the checksum of zMaster */
-+  for(nMaster=0; zMaster[nMaster]; nMaster++){
-+    cksum += zMaster[nMaster];
++
++/*
++** Allocate a new Fts5Iter object.
++**
++** The new object will be used to iterate through data in structure pStruct.
++** If iLevel is -ve, then all data in all segments is merged. Or, if iLevel
++** is zero or greater, data from the first nSegment segments on level iLevel
++** is merged.
++**
++** The iterator initially points to the first term/rowid entry in the 
++** iterated data.
++*/
++static void fts5MultiIterNew(
++  Fts5Index *p,                   /* FTS5 backend to iterate within */
++  Fts5Structure *pStruct,         /* Structure of specific index */
++  int flags,                      /* FTS5INDEX_QUERY_XXX flags */
++  Fts5Colset *pColset,            /* Colset to filter on (or NULL) */
++  const u8 *pTerm, int nTerm,     /* Term to seek to (or NULL/0) */
++  int iLevel,                     /* Level to iterate (-1 for all) */
++  int nSegment,                   /* Number of segments to merge (iLevel>=0) */
++  Fts5Iter **ppOut                /* New object */
++){
++  int nSeg = 0;                   /* Number of segment-iters in use */
++  int iIter = 0;                  /* */
++  int iSeg;                       /* Used to iterate through segments */
++  Fts5StructureLevel *pLvl;
++  Fts5Iter *pNew;
++
++  assert( (pTerm==0 && nTerm==0) || iLevel<0 );
++
++  /* Allocate space for the new multi-seg-iterator. */
++  if( p->rc==SQLITE_OK ){
++    if( iLevel<0 ){
++      assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
++      nSeg = pStruct->nSegment;
++      nSeg += (p->pHash ? 1 : 0);
++    }else{
++      nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment);
++    }
++  }
++  *ppOut = pNew = fts5MultiIterAlloc(p, nSeg);
++  if( pNew==0 ) return;
++  pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC));
++  pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY));
++  pNew->pStruct = pStruct;
++  pNew->pColset = pColset;
++  fts5StructureRef(pStruct);
++  if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){
++    fts5IterSetOutputCb(&p->rc, pNew);
 +  }
 +
-+  /* If in full-sync mode, advance to the next disk sector before writing
-+  ** the master journal name. This is in case the previous page written to
-+  ** the journal has already been synced.
-   */
--  if( nPage==0 ){
--    i64 n = 0;                    /* Size of db file in bytes */
--    assert( isOpen(pPager->fd) || pPager->tempFile );
--    if( isOpen(pPager->fd) ){
--      int rc = sqlite3OsFileSize(pPager->fd, &n);
--      if( rc!=SQLITE_OK ){
--        return rc;
--      }
--    }
--    nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize);
-+  if( pPager->fullSync ){
-+    pPager->journalOff = journalHdrOffset(pPager);
-   }
-+  iHdrOff = pPager->journalOff;
- 
--  /* If the current number of pages in the file is greater than the
--  ** configured maximum pager number, increase the allowed limit so
--  ** that the file can be read.
-+  /* Write the master journal data to the end of the journal file. If
-+  ** an error occurs, return the error code to the caller.
-   */
--  if( nPage>pPager->mxPgno ){
--    pPager->mxPgno = (Pgno)nPage;
-+  if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
-+   || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4)))
-+   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster)))
-+   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum)))
-+   || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8)))
-+  ){
-+    return rc;
-   }
-+  pPager->journalOff += (nMaster+20);
- 
--  *pnPage = nPage;
--  return SQLITE_OK;
-+  /* If the pager is in peristent-journal mode, then the physical 
-+  ** journal-file may extend past the end of the master-journal name
-+  ** and 8 bytes of magic data just written to the file. This is 
-+  ** dangerous because the code to rollback a hot-journal file
-+  ** will not be able to find the master-journal name to determine 
-+  ** whether or not the journal is hot. 
-+  **
-+  ** Easiest thing to do in this scenario is to truncate the journal 
-+  ** file to the required size.
-+  */ 
-+  if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize))
-+   && jrnlSize>pPager->journalOff
-+  ){
-+    rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff);
++  /* Initialize each of the component segment iterators. */
++  if( p->rc==SQLITE_OK ){
++    if( iLevel<0 ){
++      Fts5StructureLevel *pEnd = &pStruct->aLevel[pStruct->nLevel];
++      if( p->pHash ){
++        /* Add a segment iterator for the current contents of the hash table. */
++        Fts5SegIter *pIter = &pNew->aSeg[iIter++];
++        fts5SegIterHashInit(p, pTerm, nTerm, flags, pIter);
++      }
++      for(pLvl=&pStruct->aLevel[0]; pLvl<pEnd; pLvl++){
++        for(iSeg=pLvl->nSeg-1; iSeg>=0; iSeg--){
++          Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
++          Fts5SegIter *pIter = &pNew->aSeg[iIter++];
++          if( pTerm==0 ){
++            fts5SegIterInit(p, pSeg, pIter);
++          }else{
++            fts5SegIterSeekInit(p, pTerm, nTerm, flags, pSeg, pIter);
++          }
++        }
++      }
++    }else{
++      pLvl = &pStruct->aLevel[iLevel];
++      for(iSeg=nSeg-1; iSeg>=0; iSeg--){
++        fts5SegIterInit(p, &pLvl->aSeg[iSeg], &pNew->aSeg[iIter++]);
++      }
++    }
++    assert( iIter==nSeg );
++  }
++
++  /* If the above was successful, each component iterators now points 
++  ** to the first entry in its segment. In this case initialize the 
++  ** aFirst[] array. Or, if an error has occurred, free the iterator
++  ** object and set the output variable to NULL.  */
++  if( p->rc==SQLITE_OK ){
++    for(iIter=pNew->nSeg-1; iIter>0; iIter--){
++      int iEq;
++      if( (iEq = fts5MultiIterDoCompare(pNew, iIter)) ){
++        Fts5SegIter *pSeg = &pNew->aSeg[iEq];
++        if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0);
++        fts5MultiIterAdvanced(p, pNew, iEq, iIter);
++      }
++    }
++    fts5MultiIterSetEof(pNew);
++    fts5AssertMultiIterSetup(p, pNew);
++
++    if( pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){
++      fts5MultiIterNext(p, pNew, 0, 0);
++    }else if( pNew->base.bEof==0 ){
++      Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst];
++      pNew->xSetOutputs(pNew, pSeg);
++    }
++
++  }else{
++    fts5MultiIterFree(pNew);
++    *ppOut = 0;
 +  }
-+  return rc;
- }
- 
--#ifndef SQLITE_OMIT_WAL
- /*
--** Check if the *-wal file that corresponds to the database opened by pPager
--** exists if the database is not empy, or verify that the *-wal file does
--** not exist (by deleting it) if the database file is empty.
--**
--** If the database is not empty and the *-wal file exists, open the pager
--** in WAL mode.  If the database is empty or if no *-wal file exists and
--** if no error occurs, make sure Pager.journalMode is not set to
--** PAGER_JOURNALMODE_WAL.
--**
--** Return SQLITE_OK or an error code.
--**
--** The caller must hold a SHARED lock on the database file to call this
--** function. Because an EXCLUSIVE lock on the db file is required to delete 
--** a WAL on a none-empty database, this ensures there is no race condition 
--** between the xAccess() below and an xDelete() being executed by some 
--** other connection.
-+** Discard the entire contents of the in-memory page-cache.
- */
--static int pagerOpenWalIfPresent(Pager *pPager){
--  int rc = SQLITE_OK;
--  assert( pPager->eState==PAGER_OPEN );
--  assert( pPager->eLock>=SHARED_LOCK );
-+static void pager_reset(Pager *pPager){
-+  pPager->iDataVersion++;
-+  sqlite3BackupRestart(pPager->pBackup);
-+  sqlite3PcacheClear(pPager->pPCache);
 +}
- 
--  if( !pPager->tempFile ){
--    int isWal;                    /* True if WAL file exists */
--    Pgno nPage;                   /* Size of the database file */
++
 +/*
-+** Return the pPager->iDataVersion value
++** Create an Fts5Iter that iterates through the doclist provided
++** as the second argument.
 +*/
-+SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){
-+  assert( pPager->eState>PAGER_OPEN );
-+  return pPager->iDataVersion;
++static void fts5MultiIterNew2(
++  Fts5Index *p,                   /* FTS5 backend to iterate within */
++  Fts5Data *pData,                /* Doclist to iterate through */
++  int bDesc,                      /* True for descending rowid order */
++  Fts5Iter **ppOut                /* New object */
++){
++  Fts5Iter *pNew;
++  pNew = fts5MultiIterAlloc(p, 2);
++  if( pNew ){
++    Fts5SegIter *pIter = &pNew->aSeg[1];
++
++    pIter->flags = FTS5_SEGITER_ONETERM;
++    if( pData->szLeaf>0 ){
++      pIter->pLeaf = pData;
++      pIter->iLeafOffset = fts5GetVarint(pData->p, (u64*)&pIter->iRowid);
++      pIter->iEndofDoclist = pData->nn;
++      pNew->aFirst[1].iFirst = 1;
++      if( bDesc ){
++        pNew->bRev = 1;
++        pIter->flags |= FTS5_SEGITER_REVERSE;
++        fts5SegIterReverseInitPage(p, pIter);
++      }else{
++        fts5SegIterLoadNPos(p, pIter);
++      }
++      pData = 0;
++    }else{
++      pNew->base.bEof = 1;
++    }
++    fts5SegIterSetNext(p, pIter);
++
++    *ppOut = pNew;
++  }
++
++  fts5DataRelease(pData);
 +}
 +
 +/*
-+** Free all structures in the Pager.aSavepoint[] array and set both
-+** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
-+** if it is open and the pager is not in exclusive mode.
++** Return true if the iterator is at EOF or if an error has occurred. 
++** False otherwise.
 +*/
-+static void releaseAllSavepoints(Pager *pPager){
-+  int ii;               /* Iterator for looping through Pager.aSavepoint */
-+  for(ii=0; ii<pPager->nSavepoint; ii++){
-+    sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
-+  }
-+  if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){
-+    sqlite3OsClose(pPager->sjfd);
-+  }
-+  sqlite3_free(pPager->aSavepoint);
-+  pPager->aSavepoint = 0;
-+  pPager->nSavepoint = 0;
-+  pPager->nSubRec = 0;
++static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){
++  assert( p->rc 
++      || (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->base.bEof 
++  );
++  return (p->rc || pIter->base.bEof);
 +}
 +
 +/*
-+** Set the bit number pgno in the PagerSavepoint.pInSavepoint 
-+** bitvecs of all open savepoints. Return SQLITE_OK if successful
-+** or SQLITE_NOMEM if a malloc failure occurs.
++** Return the rowid of the entry that the iterator currently points
++** to. If the iterator points to EOF when this function is called the
++** results are undefined.
 +*/
-+static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){
-+  int ii;                   /* Loop counter */
-+  int rc = SQLITE_OK;       /* Result code */
- 
--    rc = pagerPagecount(pPager, &nPage);
--    if( rc ) return rc;
--    if( nPage==0 ){
--      rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
--      if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
--      isWal = 0;
--    }else{
--      rc = sqlite3OsAccess(
--          pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
--      );
--    }
--    if( rc==SQLITE_OK ){
--      if( isWal ){
--        testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
--        rc = sqlite3PagerOpenWal(pPager, 0);
--      }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
--        pPager->journalMode = PAGER_JOURNALMODE_DELETE;
--      }
-+  for(ii=0; ii<pPager->nSavepoint; ii++){
-+    PagerSavepoint *p = &pPager->aSavepoint[ii];
-+    if( pgno<=p->nOrig ){
-+      rc |= sqlite3BitvecSet(p->pInSavepoint, pgno);
-+      testcase( rc==SQLITE_NOMEM );
-+      assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
-     }
-   }
-   return rc;
- }
--#endif
- 
- /*
--** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback
--** the entire master journal file. The case pSavepoint==NULL occurs when 
--** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction 
--** savepoint.
--**
--** When pSavepoint is not NULL (meaning a non-transaction savepoint is 
--** being rolled back), then the rollback consists of up to three stages,
--** performed in the order specified:
--**
--**   * Pages are played back from the main journal starting at byte
--**     offset PagerSavepoint.iOffset and continuing to 
--**     PagerSavepoint.iHdrOffset, or to the end of the main journal
--**     file if PagerSavepoint.iHdrOffset is zero.
--**
--**   * If PagerSavepoint.iHdrOffset is not zero, then pages are played
--**     back starting from the journal header immediately following 
--**     PagerSavepoint.iHdrOffset to the end of the main journal file.
--**
--**   * Pages are then played back from the sub-journal file, starting
--**     with the PagerSavepoint.iSubRec and continuing to the end of
--**     the journal file.
--**
--** Throughout the rollback process, each time a page is rolled back, the
--** corresponding bit is set in a bitvec structure (variable pDone in the
--** implementation below). This is used to ensure that a page is only
--** rolled back the first time it is encountered in either journal.
-+** This function is a no-op if the pager is in exclusive mode and not
-+** in the ERROR state. Otherwise, it switches the pager to PAGER_OPEN
-+** state.
- **
--** If pSavepoint is NULL, then pages are only played back from the main
--** journal file. There is no need for a bitvec in this case.
-+** If the pager is not in exclusive-access mode, the database file is
-+** completely unlocked. If the file is unlocked and the file-system does
-+** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is
-+** closed (if it is open).
- **
--** In either case, before playback commences the Pager.dbSize variable
--** is reset to the value that it held at the start of the savepoint 
--** (or transaction). No page with a page-number greater than this value
--** is played back. If one is encountered it is simply skipped.
-+** If the pager is in ERROR state when this function is called, the 
-+** contents of the pager cache are discarded before switching back to 
-+** the OPEN state. Regardless of whether the pager is in exclusive-mode
-+** or not, any journal file left in the file-system will be treated
-+** as a hot-journal and rolled back the next time a read-transaction
-+** is opened (by this or by any other connection).
- */
--static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
--  i64 szJ;                 /* Effective size of the main journal */
--  i64 iHdrOff;             /* End of first segment of main-journal records */
--  int rc = SQLITE_OK;      /* Return code */
--  Bitvec *pDone = 0;       /* Bitvec to ensure pages played back only once */
--
--  assert( pPager->eState!=PAGER_ERROR );
--  assert( pPager->eState>=PAGER_WRITER_LOCKED );
--
--  /* Allocate a bitvec to use to store the set of pages rolled back */
--  if( pSavepoint ){
--    pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
--    if( !pDone ){
--      return SQLITE_NOMEM;
--    }
--  }
--
--  /* Set the database size back to the value it was before the savepoint 
--  ** being reverted was opened.
--  */
--  pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize;
--  pPager->changeCountDone = pPager->tempFile;
--
--  if( !pSavepoint && pagerUseWal(pPager) ){
--    return pagerRollbackWal(pPager);
--  }
-+static void pager_unlock(Pager *pPager){
- 
--  /* Use pPager->journalOff as the effective size of the main rollback
--  ** journal.  The actual file might be larger than this in
--  ** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST.  But anything
--  ** past pPager->journalOff is off-limits to us.
--  */
--  szJ = pPager->journalOff;
--  assert( pagerUseWal(pPager)==0 || szJ==0 );
-+  assert( pPager->eState==PAGER_READER 
-+       || pPager->eState==PAGER_OPEN 
-+       || pPager->eState==PAGER_ERROR 
-+  );
- 
--  /* Begin by rolling back records from the main journal starting at
--  ** PagerSavepoint.iOffset and continuing to the next journal header.
--  ** There might be records in the main journal that have a page number
--  ** greater than the current database size (pPager->dbSize) but those
--  ** will be skipped automatically.  Pages are added to pDone as they
--  ** are played back.
--  */
--  if( pSavepoint && !pagerUseWal(pPager) ){
--    iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ;
--    pPager->journalOff = pSavepoint->iOffset;
--    while( rc==SQLITE_OK && pPager->journalOff<iHdrOff ){
--      rc = pager_playback_one_page(pPager, &pPager->journalOff, pDone, 1, 1);
--    }
--    assert( rc!=SQLITE_DONE );
--  }else{
--    pPager->journalOff = 0;
--  }
-+  sqlite3BitvecDestroy(pPager->pInJournal);
-+  pPager->pInJournal = 0;
-+  releaseAllSavepoints(pPager);
- 
--  /* Continue rolling back records out of the main journal starting at
--  ** the first journal header seen and continuing until the effective end
--  ** of the main journal file.  Continue to skip out-of-range pages and
--  ** continue adding pages rolled back to pDone.
--  */
--  while( rc==SQLITE_OK && pPager->journalOff<szJ ){
--    u32 ii;            /* Loop counter */
--    u32 nJRec = 0;     /* Number of Journal Records */
--    u32 dummy;
--    rc = readJournalHdr(pPager, 0, szJ, &nJRec, &dummy);
--    assert( rc!=SQLITE_DONE );
-+  if( pagerUseWal(pPager) ){
-+    assert( !isOpen(pPager->jfd) );
-+    sqlite3WalEndReadTransaction(pPager->pWal);
-+    pPager->eState = PAGER_OPEN;
-+  }else if( !pPager->exclusiveMode ){
-+    int rc;                       /* Error code returned by pagerUnlockDb() */
-+    int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0;
- 
--    /*
--    ** The "pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff"
--    ** test is related to ticket #2565.  See the discussion in the
--    ** pager_playback() function for additional information.
-+    /* If the operating system support deletion of open files, then
-+    ** close the journal file when dropping the database lock.  Otherwise
-+    ** another connection with journal_mode=delete might delete the file
-+    ** out from under us.
-     */
--    if( nJRec==0 
--     && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff
-+    assert( (PAGER_JOURNALMODE_MEMORY   & 5)!=1 );
-+    assert( (PAGER_JOURNALMODE_OFF      & 5)!=1 );
-+    assert( (PAGER_JOURNALMODE_WAL      & 5)!=1 );
-+    assert( (PAGER_JOURNALMODE_DELETE   & 5)!=1 );
-+    assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
-+    assert( (PAGER_JOURNALMODE_PERSIST  & 5)==1 );
-+    if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN)
-+     || 1!=(pPager->journalMode & 5)
-     ){
--      nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager));
--    }
--    for(ii=0; rc==SQLITE_OK && ii<nJRec && pPager->journalOff<szJ; ii++){
--      rc = pager_playback_one_page(pPager, &pPager->journalOff, pDone, 1, 1);
-+      sqlite3OsClose(pPager->jfd);
-     }
--    assert( rc!=SQLITE_DONE );
--  }
--  assert( rc!=SQLITE_OK || pPager->journalOff>=szJ );
--
--  /* Finally,  rollback pages from the sub-journal.  Page that were
--  ** previously rolled back out of the main journal (and are hence in pDone)
--  ** will be skipped.  Out-of-range pages are also skipped.
--  */
--  if( pSavepoint ){
--    u32 ii;            /* Loop counter */
--    i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize);
- 
--    if( pagerUseWal(pPager) ){
--      rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData);
--    }
--    for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && ii<pPager->nSubRec; ii++){
--      assert( offset==(i64)ii*(4+pPager->pageSize) );
--      rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1);
-+    /* If the pager is in the ERROR state and the call to unlock the database
-+    ** file fails, set the current lock to UNKNOWN_LOCK. See the comment
-+    ** above the #define for UNKNOWN_LOCK for an explanation of why this
-+    ** is necessary.
-+    */
-+    rc = pagerUnlockDb(pPager, NO_LOCK);
-+    if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){
-+      pPager->eLock = UNKNOWN_LOCK;
-     }
--    assert( rc!=SQLITE_DONE );
--  }
- 
--  sqlite3BitvecDestroy(pDone);
--  if( rc==SQLITE_OK ){
--    pPager->journalOff = szJ;
-+    /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here
-+    ** without clearing the error code. This is intentional - the error
-+    ** code is cleared and the cache reset in the block below.
-+    */
-+    assert( pPager->errCode || pPager->eState!=PAGER_ERROR );
-+    pPager->changeCountDone = 0;
-+    pPager->eState = PAGER_OPEN;
-   }
- 
--  return rc;
--}
-+  /* If Pager.errCode is set, the contents of the pager cache cannot be
-+  ** trusted. Now that there are no outstanding references to the pager,
-+  ** it can safely move back to PAGER_OPEN state. This happens in both
-+  ** normal and exclusive-locking mode.
-+  */
-+  if( pPager->errCode ){
-+    assert( !MEMDB );
-+    pager_reset(pPager);
-+    pPager->changeCountDone = pPager->tempFile;
-+    pPager->eState = PAGER_OPEN;
-+    pPager->errCode = SQLITE_OK;
-+    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
++static i64 fts5MultiIterRowid(Fts5Iter *pIter){
++  assert( pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf );
++  return pIter->aSeg[ pIter->aFirst[1].iFirst ].iRowid;
++}
++
++/*
++** Move the iterator to the next entry at or following iMatch.
++*/
++static void fts5MultiIterNextFrom(
++  Fts5Index *p, 
++  Fts5Iter *pIter, 
++  i64 iMatch
++){
++  while( 1 ){
++    i64 iRowid;
++    fts5MultiIterNext(p, pIter, 1, iMatch);
++    if( fts5MultiIterEof(p, pIter) ) break;
++    iRowid = fts5MultiIterRowid(pIter);
++    if( pIter->bRev==0 && iRowid>=iMatch ) break;
++    if( pIter->bRev!=0 && iRowid<=iMatch ) break;
 +  }
- 
--/*
--** Change the maximum number of in-memory pages that are allowed.
--*/
--SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
--  sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
-+  pPager->journalOff = 0;
-+  pPager->journalHdr = 0;
-+  pPager->setMaster = 0;
- }
- 
- /*
--** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap.
-+** This function is called whenever an IOERR or FULL error that requires
-+** the pager to transition into the ERROR state may ahve occurred.
-+** The first argument is a pointer to the pager structure, the second 
-+** the error-code about to be returned by a pager API function. The 
-+** value returned is a copy of the second argument to this function. 
-+**
-+** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the
-+** IOERR sub-codes, the pager enters the ERROR state and the error code
-+** is stored in Pager.errCode. While the pager remains in the ERROR state,
-+** all major API calls on the Pager will immediately return Pager.errCode.
-+**
-+** The ERROR state indicates that the contents of the pager-cache 
-+** cannot be trusted. This state can be cleared by completely discarding 
-+** the contents of the pager-cache. If a transaction was active when
-+** the persistent error occurred, then the rollback journal may need
-+** to be replayed to restore the contents of the database file (as if
-+** it were a hot-journal).
- */
--static void pagerFixMaplimit(Pager *pPager){
--#if SQLITE_MAX_MMAP_SIZE>0
--  sqlite3_file *fd = pPager->fd;
--  if( isOpen(fd) && fd->pMethods->iVersion>=3 ){
--    sqlite3_int64 sz;
--    sz = pPager->szMmap;
--    pPager->bUseFetch = (sz>0);
--    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
-+static int pager_error(Pager *pPager, int rc){
-+  int rc2 = rc & 0xff;
-+  assert( rc==SQLITE_OK || !MEMDB );
-+  assert(
-+       pPager->errCode==SQLITE_FULL ||
-+       pPager->errCode==SQLITE_OK ||
-+       (pPager->errCode & 0xff)==SQLITE_IOERR
-+  );
-+  if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
-+    pPager->errCode = rc;
-+    pPager->eState = PAGER_ERROR;
-   }
--#endif
--}
--
--/*
--** Change the maximum size of any memory mapping made of the database file.
--*/
--SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 szMmap){
--  pPager->szMmap = szMmap;
--  pagerFixMaplimit(pPager);
-+  return rc;
- }
- 
--/*
--** Free as much memory as possible from the pager.
--*/
--SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
--  sqlite3PcacheShrink(pPager->pPCache);
--}
-+static int pager_truncate(Pager *pPager, Pgno nPage);
- 
- /*
--** Adjust settings of the pager to those specified in the pgFlags parameter.
-+** This routine ends a transaction. A transaction is usually ended by 
-+** either a COMMIT or a ROLLBACK operation. This routine may be called 
-+** after rollback of a hot-journal, or if an error occurs while opening
-+** the journal file or writing the very first journal-header of a
-+** database transaction.
-+** 
-+** This routine is never called in PAGER_ERROR state. If it is called
-+** in PAGER_NONE or PAGER_SHARED state and the lock held is less
-+** exclusive than a RESERVED lock, it is a no-op.
- **
--** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness
--** of the database to damage due to OS crashes or power failures by
--** changing the number of syncs()s when writing the journals.
--** There are three levels:
-+** Otherwise, any active savepoints are released.
- **
--**    OFF       sqlite3OsSync() is never called.  This is the default
--**              for temporary and transient files.
-+** If the journal file is open, then it is "finalized". Once a journal 
-+** file has been finalized it is not possible to use it to roll back a 
-+** transaction. Nor will it be considered to be a hot-journal by this
-+** or any other database connection. Exactly how a journal is finalized
-+** depends on whether or not the pager is running in exclusive mode and
-+** the current journal-mode (Pager.journalMode value), as follows:
- **
--**    NORMAL    The journal is synced once before writes begin on the
--**              database.  This is normally adequate protection, but
--**              it is theoretically possible, though very unlikely,
--**              that an inopertune power failure could leave the journal
--**              in a state which would cause damage to the database
--**              when it is rolled back.
-+**   journalMode==MEMORY
-+**     Journal file descriptor is simply closed. This destroys an 
-+**     in-memory journal.
- **
--**    FULL      The journal is synced twice before writes begin on the
--**              database (with some additional information - the nRec field
--**              of the journal header - being written in between the two
--**              syncs).  If we assume that writing a
--**              single disk sector is atomic, then this mode provides
--**              assurance that the journal will not be corrupted to the
--**              point of causing damage to the database during rollback.
-+**   journalMode==TRUNCATE
-+**     Journal file is truncated to zero bytes in size.
- **
--** The above is for a rollback-journal mode.  For WAL mode, OFF continues
--** to mean that no syncs ever occur.  NORMAL means that the WAL is synced
--** prior to the start of checkpoint and that the database file is synced
--** at the conclusion of the checkpoint if the entire content of the WAL
--** was written back into the database.  But no sync operations occur for
--** an ordinary commit in NORMAL mode with WAL.  FULL means that the WAL
--** file is synced following each commit operation, in addition to the
--** syncs associated with NORMAL.
-+**   journalMode==PERSIST
-+**     The first 28 bytes of the journal file are zeroed. This invalidates
-+**     the first journal header in the file, and hence the entire journal
-+**     file. An invalid journal file cannot be rolled back.
- **
--** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL.  The
--** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync
--** using fcntl(F_FULLFSYNC).  SQLITE_SYNC_NORMAL means to do an
--** ordinary fsync() call.  There is no difference between SQLITE_SYNC_FULL
--** and SQLITE_SYNC_NORMAL on platforms other than MacOSX.  But the
--** synchronous=FULL versus synchronous=NORMAL setting determines when
--** the xSync primitive is called and is relevant to all platforms.
-+**   journalMode==DELETE
-+**     The journal file is closed and deleted using sqlite3OsDelete().
- **
--** Numeric values associated with these states are OFF==1, NORMAL=2,
--** and FULL=3.
-+**     If the pager is running in exclusive mode, this method of finalizing
-+**     the journal file is never used. Instead, if the journalMode is
-+**     DELETE and the pager is in exclusive mode, the method described under
-+**     journalMode==PERSIST is used instead.
-+**
-+** After the journal is finalized, the pager moves to PAGER_READER state.
-+** If running in non-exclusive rollback mode, the lock on the file is 
-+** downgraded to a SHARED_LOCK.
-+**
-+** SQLITE_OK is returned if no error occurs. If an error occurs during
-+** any of the IO operations to finalize the journal file or unlock the
-+** database then the IO error code is returned to the user. If the 
-+** operation to finalize the journal file fails, then the code still
-+** tries to unlock the database file if not in exclusive mode. If the
-+** unlock operation fails as well, then the first error code related
-+** to the first error encountered (the journal finalization one) is
-+** returned.
- */
--#ifndef SQLITE_OMIT_PAGER_PRAGMAS
--SQLITE_PRIVATE void sqlite3PagerSetFlags(
--  Pager *pPager,        /* The pager to set safety level for */
--  unsigned pgFlags      /* Various flags */
--){
--  unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
--  assert( level>=1 && level<=3 );
--  pPager->noSync =  (level==1 || pPager->tempFile) ?1:0;
--  pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
--  if( pPager->noSync ){
--    pPager->syncFlags = 0;
--    pPager->ckptSyncFlags = 0;
--  }else if( pgFlags & PAGER_FULLFSYNC ){
--    pPager->syncFlags = SQLITE_SYNC_FULL;
--    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
--  }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){
--    pPager->syncFlags = SQLITE_SYNC_NORMAL;
--    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
--  }else{
--    pPager->syncFlags = SQLITE_SYNC_NORMAL;
--    pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
-+static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
-+  int rc = SQLITE_OK;      /* Error code from journal finalization operation */
-+  int rc2 = SQLITE_OK;     /* Error code from db file unlock operation */
-+
-+  /* Do nothing if the pager does not have an open write transaction
-+  ** or at least a RESERVED lock. This function may be called when there
-+  ** is no write-transaction active but a RESERVED or greater lock is
-+  ** held under two circumstances:
-+  **
-+  **   1. After a successful hot-journal rollback, it is called with
-+  **      eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK.
-+  **
-+  **   2. If a connection with locking_mode=exclusive holding an EXCLUSIVE 
-+  **      lock switches back to locking_mode=normal and then executes a
-+  **      read-transaction, this function is called with eState==PAGER_READER 
-+  **      and eLock==EXCLUSIVE_LOCK when the read-transaction is closed.
-+  */
-+  assert( assert_pager_state(pPager) );
-+  assert( pPager->eState!=PAGER_ERROR );
-+  if( pPager->eState<PAGER_WRITER_LOCKED && pPager->eLock<RESERVED_LOCK ){
-+    return SQLITE_OK;
-   }
--  pPager->walSyncFlags = pPager->syncFlags;
--  if( pPager->fullSync ){
--    pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
-+
-+  releaseAllSavepoints(pPager);
-+  assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
-+  if( isOpen(pPager->jfd) ){
-+    assert( !pagerUseWal(pPager) );
-+
-+    /* Finalize the journal file. */
-+    if( sqlite3IsMemJournal(pPager->jfd) ){
-+      assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
-+      sqlite3OsClose(pPager->jfd);
-+    }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
-+      if( pPager->journalOff==0 ){
-+        rc = SQLITE_OK;
-+      }else{
-+        rc = sqlite3OsTruncate(pPager->jfd, 0);
-+        if( rc==SQLITE_OK && pPager->fullSync ){
-+          /* Make sure the new file size is written into the inode right away.
-+          ** Otherwise the journal might resurrect following a power loss and
-+          ** cause the last transaction to roll back.  See
-+          ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
-+          */
-+          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
++}
++
++/*
++** Return a pointer to a buffer containing the term associated with the 
++** entry that the iterator currently points to.
++*/
++static const u8 *fts5MultiIterTerm(Fts5Iter *pIter, int *pn){
++  Fts5SegIter *p = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
++  *pn = p->term.n;
++  return p->term.p;
++}
++
++/*
++** Allocate a new segment-id for the structure pStruct. The new segment
++** id must be between 1 and 65335 inclusive, and must not be used by 
++** any currently existing segment. If a free segment id cannot be found,
++** SQLITE_FULL is returned.
++**
++** If an error has already occurred, this function is a no-op. 0 is 
++** returned in this case.
++*/
++static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
++  int iSegid = 0;
++
++  if( p->rc==SQLITE_OK ){
++    if( pStruct->nSegment>=FTS5_MAX_SEGMENT ){
++      p->rc = SQLITE_FULL;
++    }else{
++      /* FTS5_MAX_SEGMENT is currently defined as 2000. So the following
++      ** array is 63 elements, or 252 bytes, in size.  */
++      u32 aUsed[(FTS5_MAX_SEGMENT+31) / 32];
++      int iLvl, iSeg;
++      int i;
++      u32 mask;
++      memset(aUsed, 0, sizeof(aUsed));
++      for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
++        for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
++          int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid;
++          if( iId<=FTS5_MAX_SEGMENT ){
++            aUsed[(iId-1) / 32] |= 1 << ((iId-1) % 32);
++          }
 +        }
 +      }
-+      pPager->journalOff = 0;
-+    }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
-+      || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
-+    ){
-+      rc = zeroJournalHdr(pPager, hasMaster);
-+      pPager->journalOff = 0;
-+    }else{
-+      /* This branch may be executed with Pager.journalMode==MEMORY if
-+      ** a hot-journal was just rolled back. In this case the journal
-+      ** file should be closed and deleted. If this connection writes to
-+      ** the database file, it will do so using an in-memory journal. 
-+      */
-+      int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
-+      assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE 
-+           || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
-+           || pPager->journalMode==PAGER_JOURNALMODE_WAL 
-+      );
-+      sqlite3OsClose(pPager->jfd);
-+      if( bDelete ){
-+        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
++
++      for(i=0; aUsed[i]==0xFFFFFFFF; i++);
++      mask = aUsed[i];
++      for(iSegid=0; mask & (1 << iSegid); iSegid++);
++      iSegid += 1 + i*32;
++
++#ifdef SQLITE_DEBUG
++      for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
++        for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
++          assert( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
++        }
 +      }
-+    }
-   }
--  if( pgFlags & PAGER_CACHESPILL ){
--    pPager->doNotSpill &= ~SPILLFLAG_OFF;
--  }else{
--    pPager->doNotSpill |= SPILLFLAG_OFF;
++      assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );
 +
-+#ifdef SQLITE_CHECK_PAGES
-+  sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
-+  if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
-+    PgHdr *p = sqlite3PagerLookup(pPager, 1);
-+    if( p ){
-+      p->pageHash = 0;
-+      sqlite3PagerUnrefNotNull(p);
++      {
++        sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p);
++        if( p->rc==SQLITE_OK ){
++          u8 aBlob[2] = {0xff, 0xff};
++          sqlite3_bind_int(pIdxSelect, 1, iSegid);
++          sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
++          assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
++          p->rc = sqlite3_reset(pIdxSelect);
++        }
++      }
++#endif
 +    }
 +  }
-+#endif
 +
-+  sqlite3BitvecDestroy(pPager->pInJournal);
-+  pPager->pInJournal = 0;
-+  pPager->nRec = 0;
-+  sqlite3PcacheCleanAll(pPager->pPCache);
-+  sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
++  return iSegid;
++}
 +
-+  if( pagerUseWal(pPager) ){
-+    /* Drop the WAL write-lock, if any. Also, if the connection was in 
-+    ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE 
-+    ** lock held on the database file.
-+    */
-+    rc2 = sqlite3WalEndWriteTransaction(pPager->pWal);
-+    assert( rc2==SQLITE_OK );
-+  }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){
-+    /* This branch is taken when committing a transaction in rollback-journal
-+    ** mode if the database file on disk is larger than the database image.
-+    ** At this point the journal has been finalized and the transaction 
-+    ** successfully committed, but the EXCLUSIVE lock is still held on the
-+    ** file. So it is safe to truncate the database file to its minimum
-+    ** required size.  */
-+    assert( pPager->eLock==EXCLUSIVE_LOCK );
-+    rc = pager_truncate(pPager, pPager->dbSize);
-+  }
-+
-+  if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){
-+    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0);
-+    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
-   }
-+
-+  if( !pPager->exclusiveMode 
-+   && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
-+  ){
-+    rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
-+    pPager->changeCountDone = 0;
++/*
++** Discard all data currently cached in the hash-tables.
++*/
++static void fts5IndexDiscardData(Fts5Index *p){
++  assert( p->pHash || p->nPendingData==0 );
++  if( p->pHash ){
++    sqlite3Fts5HashClear(p->pHash);
++    p->nPendingData = 0;
 +  }
-+  pPager->eState = PAGER_READER;
-+  pPager->setMaster = 0;
++}
 +
-+  return (rc==SQLITE_OK?rc2:rc);
- }
--#endif
- 
- /*
--** The following global variable is incremented whenever the library
--** attempts to open a temporary file.  This information is used for
--** testing and analysis only.  
-+** Execute a rollback if a transaction is active and unlock the 
-+** database file. 
-+**
-+** If the pager has already entered the ERROR state, do not attempt 
-+** the rollback at this time. Instead, pager_unlock() is called. The
-+** call to pager_unlock() will discard all in-memory pages, unlock
-+** the database file and move the pager back to OPEN state. If this 
-+** means that there is a hot-journal left in the file-system, the next 
-+** connection to obtain a shared lock on the pager (which may be this one) 
-+** will roll it back.
++/*
++** Return the size of the prefix, in bytes, that buffer 
++** (pNew/<length-unknown>) shares with buffer (pOld/nOld).
 +**
-+** If the pager has not already entered the ERROR state, but an IO or
-+** malloc error occurs during a rollback, then this will itself cause 
-+** the pager to enter the ERROR state. Which will be cleared by the
-+** call to pager_unlock(), as described above.
- */
--#ifdef SQLITE_TEST
--SQLITE_API int sqlite3_opentemp_count = 0;
--#endif
-+static void pagerUnlockAndRollback(Pager *pPager){
-+  if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){
-+    assert( assert_pager_state(pPager) );
-+    if( pPager->eState>=PAGER_WRITER_LOCKED ){
-+      sqlite3BeginBenignMalloc();
-+      sqlite3PagerRollback(pPager);
-+      sqlite3EndBenignMalloc();
-+    }else if( !pPager->exclusiveMode ){
-+      assert( pPager->eState==PAGER_READER );
-+      pager_end_transaction(pPager, 0, 0);
-+    }
-+  }
-+  pager_unlock(pPager);
-+}
- 
- /*
--** Open a temporary file.
-+** Parameter aData must point to a buffer of pPager->pageSize bytes
-+** of data. Compute and return a checksum based ont the contents of the 
-+** page of data and the current value of pPager->cksumInit.
- **
--** Write the file descriptor into *pFile. Return SQLITE_OK on success 
--** or some other error code if we fail. The OS will automatically 
--** delete the temporary file when it is closed.
-+** This is not a real checksum. It is really just the sum of the 
-+** random initial value (pPager->cksumInit) and every 200th byte
-+** of the page data, starting with byte offset (pPager->pageSize%200).
-+** Each byte is interpreted as an 8-bit unsigned integer.
- **
--** The flags passed to the VFS layer xOpen() call are those specified
--** by parameter vfsFlags ORed with the following:
-+** Changing the formula used to compute this checksum results in an
-+** incompatible journal file format.
- **
--**     SQLITE_OPEN_READWRITE
--**     SQLITE_OPEN_CREATE
--**     SQLITE_OPEN_EXCLUSIVE
--**     SQLITE_OPEN_DELETEONCLOSE
-+** If journal corruption occurs due to a power failure, the most likely 
-+** scenario is that one end or the other of the record will be changed. 
-+** It is much less likely that the two ends of the journal record will be
-+** correct and the middle be corrupt.  Thus, this "checksum" scheme,
-+** though fast and simple, catches the mostly likely kind of corruption.
- */
--static int pagerOpentemp(
--  Pager *pPager,        /* The pager object */
--  sqlite3_file *pFile,  /* Write the file descriptor here */
--  int vfsFlags          /* Flags passed through to the VFS */
--){
--  int rc;               /* Return code */
--
--#ifdef SQLITE_TEST
--  sqlite3_opentemp_count++;  /* Used for testing and analysis only */
--#endif
-+static u32 pager_cksum(Pager *pPager, const u8 *aData){
-+  u32 cksum = pPager->cksumInit;         /* Checksum value to return */
-+  int i = pPager->pageSize-200;          /* Loop counter */
-+  while( i>0 ){
-+    cksum += aData[i];
-+    i -= 200;
++** Buffer (pNew/<length-unknown>) is guaranteed to be greater 
++** than buffer (pOld/nOld).
++*/
++static int fts5PrefixCompress(int nOld, const u8 *pOld, const u8 *pNew){
++  int i;
++  for(i=0; i<nOld; i++){
++    if( pOld[i]!=pNew[i] ) break;
 +  }
-+  return cksum;
++  return i;
 +}
- 
--  vfsFlags |=  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
--            SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
--  rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0);
--  assert( rc!=SQLITE_OK || isOpen(pFile) );
--  return rc;
++
++static void fts5WriteDlidxClear(
++  Fts5Index *p, 
++  Fts5SegWriter *pWriter,
++  int bFlush                      /* If true, write dlidx to disk */
++){
++  int i;
++  assert( bFlush==0 || (pWriter->nDlidx>0 && pWriter->aDlidx[0].buf.n>0) );
++  for(i=0; i<pWriter->nDlidx; i++){
++    Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[i];
++    if( pDlidx->buf.n==0 ) break;
++    if( bFlush ){
++      assert( pDlidx->pgno!=0 );
++      fts5DataWrite(p, 
++          FTS5_DLIDX_ROWID(pWriter->iSegid, i, pDlidx->pgno),
++          pDlidx->buf.p, pDlidx->buf.n
++      );
++    }
++    sqlite3Fts5BufferZero(&pDlidx->buf);
++    pDlidx->bPrevValid = 0;
++  }
++}
++
 +/*
-+** Report the current page size and number of reserved bytes back
-+** to the codec.
++** Grow the pWriter->aDlidx[] array to at least nLvl elements in size.
++** Any new array elements are zeroed before returning.
 +*/
-+#ifdef SQLITE_HAS_CODEC
-+static void pagerReportSize(Pager *pPager){
-+  if( pPager->xCodecSizeChng ){
-+    pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
-+                           (int)pPager->nReserve);
++static int fts5WriteDlidxGrow(
++  Fts5Index *p,
++  Fts5SegWriter *pWriter,
++  int nLvl
++){
++  if( p->rc==SQLITE_OK && nLvl>=pWriter->nDlidx ){
++    Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc(
++        pWriter->aDlidx, sizeof(Fts5DlidxWriter) * nLvl
++    );
++    if( aDlidx==0 ){
++      p->rc = SQLITE_NOMEM;
++    }else{
++      int nByte = sizeof(Fts5DlidxWriter) * (nLvl - pWriter->nDlidx);
++      memset(&aDlidx[pWriter->nDlidx], 0, nByte);
++      pWriter->aDlidx = aDlidx;
++      pWriter->nDlidx = nLvl;
++    }
 +  }
- }
-+#else
-+# define pagerReportSize(X)     /* No-op if we do not support a codec */
-+#endif
- 
- /*
--** Set the busy handler function.
-+** Read a single page from either the journal file (if isMainJrnl==1) or
-+** from the sub-journal (if isMainJrnl==0) and playback that page.
-+** The page begins at offset *pOffset into the file. The *pOffset
-+** value is increased to the start of the next page in the journal.
- **
--** The pager invokes the busy-handler if sqlite3OsLock() returns 
--** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock,
--** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE 
--** lock. It does *not* invoke the busy handler when upgrading from
--** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE
--** (which occurs during hot-journal rollback). Summary:
-+** The main rollback journal uses checksums - the statement journal does 
-+** not.
- **
--**   Transition                        | Invokes xBusyHandler
--**   --------------------------------------------------------
--**   NO_LOCK       -> SHARED_LOCK      | Yes
--**   SHARED_LOCK   -> RESERVED_LOCK    | No
--**   SHARED_LOCK   -> EXCLUSIVE_LOCK   | No
--**   RESERVED_LOCK -> EXCLUSIVE_LOCK   | Yes
-+** If the page number of the page record read from the (sub-)journal file
-+** is greater than the current value of Pager.dbSize, then playback is
-+** skipped and SQLITE_OK is returned.
- **
--** If the busy-handler callback returns non-zero, the lock is 
--** retried. If it returns zero, then the SQLITE_BUSY error is
--** returned to the caller of the pager API function.
-+** If pDone is not NULL, then it is a record of pages that have already
-+** been played back.  If the page at *pOffset has already been played back
-+** (if the corresponding pDone bit is set) then skip the playback.
-+** Make sure the pDone bit corresponding to the *pOffset page is set
-+** prior to returning.
-+**
-+** If the page record is successfully read from the (sub-)journal file
-+** and played back, then SQLITE_OK is returned. If an IO error occurs
-+** while reading the record from the (sub-)journal file or while writing
-+** to the database file, then the IO error code is returned. If data
-+** is successfully read from the (sub-)journal file but appears to be
-+** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
-+** two circumstances:
-+** 
-+**   * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or
-+**   * If the record is being rolled back from the main journal file
-+**     and the checksum field does not match the record content.
-+**
-+** Neither of these two scenarios are possible during a savepoint rollback.
-+**
-+** If this is a savepoint rollback, then memory may have to be dynamically
-+** allocated by this function. If this is the case and an allocation fails,
-+** SQLITE_NOMEM is returned.
- */
--SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(
--  Pager *pPager,                       /* Pager object */
--  int (*xBusyHandler)(void *),         /* Pointer to busy-handler function */
--  void *pBusyHandlerArg                /* Argument to pass to xBusyHandler */
-+static int pager_playback_one_page(
-+  Pager *pPager,                /* The pager being played back */
-+  i64 *pOffset,                 /* Offset of record to playback */
-+  Bitvec *pDone,                /* Bitvec of pages already played back */
-+  int isMainJrnl,               /* 1 -> main journal. 0 -> sub-journal. */
-+  int isSavepnt                 /* True for a savepoint rollback */
- ){
--  pPager->xBusyHandler = xBusyHandler;
--  pPager->pBusyHandlerArg = pBusyHandlerArg;
-+  int rc;
-+  PgHdr *pPg;                   /* An existing page in the cache */
-+  Pgno pgno;                    /* The page number of a page in journal */
-+  u32 cksum;                    /* Checksum used for sanity checking */
-+  char *aData;                  /* Temporary storage for the page */
-+  sqlite3_file *jfd;            /* The file descriptor for the journal file */
-+  int isSynced;                 /* True if journal page is synced */
- 
--  if( isOpen(pPager->fd) ){
--    void **ap = (void **)&pPager->xBusyHandler;
--    assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
--    assert( ap[1]==pBusyHandlerArg );
--    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
-+  assert( (isMainJrnl&~1)==0 );      /* isMainJrnl is 0 or 1 */
-+  assert( (isSavepnt&~1)==0 );       /* isSavepnt is 0 or 1 */
-+  assert( isMainJrnl || pDone );     /* pDone always used on sub-journals */
-+  assert( isSavepnt || pDone==0 );   /* pDone never used on non-savepoint */
-+
-+  aData = pPager->pTmpSpace;
-+  assert( aData );         /* Temp storage must have already been allocated */
-+  assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) );
-+
-+  /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction 
-+  ** or savepoint rollback done at the request of the caller) or this is
-+  ** a hot-journal rollback. If it is a hot-journal rollback, the pager
-+  ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback
-+  ** only reads from the main journal, not the sub-journal.
-+  */
-+  assert( pPager->eState>=PAGER_WRITER_CACHEMOD
-+       || (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK)
-+  );
-+  assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl );
++  return p->rc;
++}
 +
-+  /* Read the page number and page data from the journal or sub-journal
-+  ** file. Return an error code to the caller if an IO error occurs.
-+  */
-+  jfd = isMainJrnl ? pPager->jfd : pPager->sjfd;
-+  rc = read32bits(jfd, *pOffset, &pgno);
-+  if( rc!=SQLITE_OK ) return rc;
-+  rc = sqlite3OsRead(jfd, (u8*)aData, pPager->pageSize, (*pOffset)+4);
-+  if( rc!=SQLITE_OK ) return rc;
-+  *pOffset += pPager->pageSize + 4 + isMainJrnl*4;
++/*
++** If the current doclist-index accumulating in pWriter->aDlidx[] is large
++** enough, flush it to disk and return 1. Otherwise discard it and return
++** zero.
++*/
++static int fts5WriteFlushDlidx(Fts5Index *p, Fts5SegWriter *pWriter){
++  int bFlag = 0;
 +
-+  /* Sanity checking on the page.  This is more important that I originally
-+  ** thought.  If a power failure occurs while the journal is being written,
-+  ** it could cause invalid data to be written into the journal.  We need to
-+  ** detect this invalid data (with high probability) and ignore it.
-+  */
-+  if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
-+    assert( !isSavepnt );
-+    return SQLITE_DONE;
-+  }
-+  if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
-+    return SQLITE_OK;
-+  }
-+  if( isMainJrnl ){
-+    rc = read32bits(jfd, (*pOffset)-4, &cksum);
-+    if( rc ) return rc;
-+    if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){
-+      return SQLITE_DONE;
-+    }
++  /* If there were FTS5_MIN_DLIDX_SIZE or more empty leaf pages written
++  ** to the database, also write the doclist-index to disk.  */
++  if( pWriter->aDlidx[0].buf.n>0 && pWriter->nEmpty>=FTS5_MIN_DLIDX_SIZE ){
++    bFlag = 1;
 +  }
++  fts5WriteDlidxClear(p, pWriter, bFlag);
++  pWriter->nEmpty = 0;
++  return bFlag;
++}
 +
-+  /* If this page has already been played by before during the current
-+  ** rollback, then don't bother to play it back again.
-+  */
-+  if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
-+    return rc;
++/*
++** This function is called whenever processing of the doclist for the 
++** last term on leaf page (pWriter->iBtPage) is completed. 
++**
++** The doclist-index for that term is currently stored in-memory within the
++** Fts5SegWriter.aDlidx[] array. If it is large enough, this function
++** writes it out to disk. Or, if it is too small to bother with, discards
++** it.
++**
++** Fts5SegWriter.btterm currently contains the first term on page iBtPage.
++*/
++static void fts5WriteFlushBtree(Fts5Index *p, Fts5SegWriter *pWriter){
++  int bFlag;
++
++  assert( pWriter->iBtPage || pWriter->nEmpty==0 );
++  if( pWriter->iBtPage==0 ) return;
++  bFlag = fts5WriteFlushDlidx(p, pWriter);
++
++  if( p->rc==SQLITE_OK ){
++    const char *z = (pWriter->btterm.n>0?(const char*)pWriter->btterm.p:"");
++    /* The following was already done in fts5WriteInit(): */
++    /* sqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid); */
++    sqlite3_bind_blob(p->pIdxWriter, 2, z, pWriter->btterm.n, SQLITE_STATIC);
++    sqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1));
++    sqlite3_step(p->pIdxWriter);
++    p->rc = sqlite3_reset(p->pIdxWriter);
 +  }
++  pWriter->iBtPage = 0;
++}
 +
-+  /* When playing back page 1, restore the nReserve setting
-+  */
-+  if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){
-+    pPager->nReserve = ((u8*)aData)[20];
-+    pagerReportSize(pPager);
-+  }
++/*
++** This is called once for each leaf page except the first that contains
++** at least one term. Argument (nTerm/pTerm) is the split-key - a term that
++** is larger than all terms written to earlier leaves, and equal to or
++** smaller than the first term on the new leaf.
++**
++** If an error occurs, an error code is left in Fts5Index.rc. If an error
++** has already occurred when this function is called, it is a no-op.
++*/
++static void fts5WriteBtreeTerm(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5SegWriter *pWriter,         /* Writer object */
++  int nTerm, const u8 *pTerm      /* First term on new page */
++){
++  fts5WriteFlushBtree(p, pWriter);
++  fts5BufferSet(&p->rc, &pWriter->btterm, nTerm, pTerm);
++  pWriter->iBtPage = pWriter->writer.pgno;
++}
 +
-+  /* If the pager is in CACHEMOD state, then there must be a copy of this
-+  ** page in the pager cache. In this case just update the pager cache,
-+  ** not the database file. The page is left marked dirty in this case.
-+  **
-+  ** An exception to the above rule: If the database is in no-sync mode
-+  ** and a page is moved during an incremental vacuum then the page may
-+  ** not be in the pager cache. Later: if a malloc() or IO error occurs
-+  ** during a Movepage() call, then the page may not be in the cache
-+  ** either. So the condition described in the above paragraph is not
-+  ** assert()able.
-+  **
-+  ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the
-+  ** pager cache if it exists and the main file. The page is then marked 
-+  ** not dirty. Since this code is only executed in PAGER_OPEN state for
-+  ** a hot-journal rollback, it is guaranteed that the page-cache is empty
-+  ** if the pager is in OPEN state.
-+  **
-+  ** Ticket #1171:  The statement journal might contain page content that is
-+  ** different from the page content at the start of the transaction.
-+  ** This occurs when a page is changed prior to the start of a statement
-+  ** then changed again within the statement.  When rolling back such a
-+  ** statement we must not write to the original database unless we know
-+  ** for certain that original page contents are synced into the main rollback
-+  ** journal.  Otherwise, a power loss might leave modified data in the
-+  ** database file without an entry in the rollback journal that can
-+  ** restore the database to its original form.  Two conditions must be
-+  ** met before writing to the database files. (1) the database must be
-+  ** locked.  (2) we know that the original page content is fully synced
-+  ** in the main journal either because the page is not in cache or else
-+  ** the page is marked as needSync==0.
-+  **
-+  ** 2008-04-14:  When attempting to vacuum a corrupt database file, it
-+  ** is possible to fail a statement on a database that does not yet exist.
-+  ** Do not attempt to write if database file has never been opened.
-+  */
-+  if( pagerUseWal(pPager) ){
-+    pPg = 0;
-+  }else{
-+    pPg = sqlite3PagerLookup(pPager, pgno);
-+  }
-+  assert( pPg || !MEMDB );
-+  assert( pPager->eState!=PAGER_OPEN || pPg==0 );
-+  PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
-+           PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData),
-+           (isMainJrnl?"main-journal":"sub-journal")
-+  ));
-+  if( isMainJrnl ){
-+    isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr);
-+  }else{
-+    isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC));
++/*
++** This function is called when flushing a leaf page that contains no
++** terms at all to disk.
++*/
++static void fts5WriteBtreeNoTerm(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5SegWriter *pWriter          /* Writer object */
++){
++  /* If there were no rowids on the leaf page either and the doclist-index
++  ** has already been started, append an 0x00 byte to it.  */
++  if( pWriter->bFirstRowidInPage && pWriter->aDlidx[0].buf.n>0 ){
++    Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[0];
++    assert( pDlidx->bPrevValid );
++    sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, 0);
 +  }
-+  if( isOpen(pPager->fd)
-+   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
-+   && isSynced
-+  ){
-+    i64 ofst = (pgno-1)*(i64)pPager->pageSize;
-+    testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
-+    assert( !pagerUseWal(pPager) );
-+    rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
-+    if( pgno>pPager->dbFileSize ){
-+      pPager->dbFileSize = pgno;
-+    }
-+    if( pPager->pBackup ){
-+      CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM);
-+      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
-+      CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData);
-+    }
-+  }else if( !isMainJrnl && pPg==0 ){
-+    /* If this is a rollback of a savepoint and data was not written to
-+    ** the database and the page is not in-memory, there is a potential
-+    ** problem. When the page is next fetched by the b-tree layer, it 
-+    ** will be read from the database file, which may or may not be 
-+    ** current. 
-+    **
-+    ** There are a couple of different ways this can happen. All are quite
-+    ** obscure. When running in synchronous mode, this can only happen 
-+    ** if the page is on the free-list at the start of the transaction, then
-+    ** populated, then moved using sqlite3PagerMovepage().
-+    **
-+    ** The solution is to add an in-memory page to the cache containing
-+    ** the data just read from the sub-journal. Mark the page as dirty 
-+    ** and if the pager requires a journal-sync, then mark the page as 
-+    ** requiring a journal-sync before it is written.
-+    */
-+    assert( isSavepnt );
-+    assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
-+    pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
-+    rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
-+    assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
-+    pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
-+    if( rc!=SQLITE_OK ) return rc;
-+    pPg->flags &= ~PGHDR_NEED_READ;
-+    sqlite3PcacheMakeDirty(pPg);
-+  }
-+  if( pPg ){
-+    /* No page should ever be explicitly rolled back that is in use, except
-+    ** for page 1 which is held in use in order to keep the lock on the
-+    ** database active. However such a page may be rolled back as a result
-+    ** of an internal error resulting in an automatic call to
-+    ** sqlite3PagerRollback().
-+    */
-+    void *pData;
-+    pData = pPg->pData;
-+    memcpy(pData, (u8*)aData, pPager->pageSize);
-+    pPager->xReiniter(pPg);
-+    if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){
-+      /* If the contents of this page were just restored from the main 
-+      ** journal file, then its content must be as they were when the 
-+      ** transaction was first opened. In this case we can mark the page
-+      ** as clean, since there will be no need to write it out to the
-+      ** database.
-+      **
-+      ** There is one exception to this rule. If the page is being rolled
-+      ** back as part of a savepoint (or statement) rollback from an 
-+      ** unsynced portion of the main journal file, then it is not safe
-+      ** to mark the page as clean. This is because marking the page as
-+      ** clean will clear the PGHDR_NEED_SYNC flag. Since the page is
-+      ** already in the journal file (recorded in Pager.pInJournal) and
-+      ** the PGHDR_NEED_SYNC flag is cleared, if the page is written to
-+      ** again within this transaction, it will be marked as dirty but
-+      ** the PGHDR_NEED_SYNC flag will not be set. It could then potentially
-+      ** be written out into the database file before its journal file
-+      ** segment is synced. If a crash occurs during or following this,
-+      ** database corruption may ensue.
-+      */
-+      assert( !pagerUseWal(pPager) );
-+      sqlite3PcacheMakeClean(pPg);
++
++  /* Increment the "number of sequential leaves without a term" counter. */
++  pWriter->nEmpty++;
++}
++
++static i64 fts5DlidxExtractFirstRowid(Fts5Buffer *pBuf){
++  i64 iRowid;
++  int iOff;
++
++  iOff = 1 + fts5GetVarint(&pBuf->p[1], (u64*)&iRowid);
++  fts5GetVarint(&pBuf->p[iOff], (u64*)&iRowid);
++  return iRowid;
++}
++
++/*
++** Rowid iRowid has just been appended to the current leaf page. It is the
++** first on the page. This function appends an appropriate entry to the current
++** doclist-index.
++*/
++static void fts5WriteDlidxAppend(
++  Fts5Index *p, 
++  Fts5SegWriter *pWriter, 
++  i64 iRowid
++){
++  int i;
++  int bDone = 0;
++
++  for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
++    i64 iVal;
++    Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[i];
++
++    if( pDlidx->buf.n>=p->pConfig->pgsz ){
++      /* The current doclist-index page is full. Write it to disk and push
++      ** a copy of iRowid (which will become the first rowid on the next
++      ** doclist-index leaf page) up into the next level of the b-tree 
++      ** hierarchy. If the node being flushed is currently the root node,
++      ** also push its first rowid upwards. */
++      pDlidx->buf.p[0] = 0x01;    /* Not the root node */
++      fts5DataWrite(p, 
++          FTS5_DLIDX_ROWID(pWriter->iSegid, i, pDlidx->pgno),
++          pDlidx->buf.p, pDlidx->buf.n
++      );
++      fts5WriteDlidxGrow(p, pWriter, i+2);
++      pDlidx = &pWriter->aDlidx[i];
++      if( p->rc==SQLITE_OK && pDlidx[1].buf.n==0 ){
++        i64 iFirst = fts5DlidxExtractFirstRowid(&pDlidx->buf);
++
++        /* This was the root node. Push its first rowid up to the new root. */
++        pDlidx[1].pgno = pDlidx->pgno;
++        sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, 0);
++        sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, pDlidx->pgno);
++        sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, iFirst);
++        pDlidx[1].bPrevValid = 1;
++        pDlidx[1].iPrev = iFirst;
++      }
++
++      sqlite3Fts5BufferZero(&pDlidx->buf);
++      pDlidx->bPrevValid = 0;
++      pDlidx->pgno++;
++    }else{
++      bDone = 1;
 +    }
-+    pager_set_pagehash(pPg);
 +
-+    /* If this was page 1, then restore the value of Pager.dbFileVers.
-+    ** Do this before any decoding. */
-+    if( pgno==1 ){
-+      memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
++    if( pDlidx->bPrevValid ){
++      iVal = iRowid - pDlidx->iPrev;
++    }else{
++      i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno);
++      assert( pDlidx->buf.n==0 );
++      sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, !bDone);
++      sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iPgno);
++      iVal = iRowid;
 +    }
 +
-+    /* Decode the page just read from disk */
-+    CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
-+    sqlite3PcacheRelease(pPg);
-   }
-+  return rc;
- }
- 
- /*
--** Change the page size used by the Pager object. The new page size 
--** is passed in *pPageSize.
-+** Parameter zMaster is the name of a master journal file. A single journal
-+** file that referred to the master journal file has just been rolled back.
-+** This routine checks if it is possible to delete the master journal file,
-+** and does so if it is.
- **
--** If the pager is in the error state when this function is called, it
--** is a no-op. The value returned is the error state error code (i.e. 
--** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL).
-+** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not 
-+** available for use within this function.
- **
--** Otherwise, if all of the following are true:
-+** When a master journal file is created, it is populated with the names 
-+** of all of its child journals, one after another, formatted as utf-8 
-+** encoded text. The end of each child journal file is marked with a 
-+** nul-terminator byte (0x00). i.e. the entire contents of a master journal
-+** file for a transaction involving two databases might be:
- **
--**   * the new page size (value of *pPageSize) is valid (a power 
--**     of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and
-+**   "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00"
- **
--**   * there are no outstanding page references, and
-+** A master journal file may only be deleted once all of its child 
-+** journals have been rolled back.
- **
--**   * the database is either not an in-memory database or it is
--**     an in-memory database that currently consists of zero pages.
-+** This function reads the contents of the master-journal file into 
-+** memory and loops through each of the child journal names. For
-+** each child journal, it checks if:
- **
--** then the pager object page size is set to *pPageSize.
-+**   * if the child journal exists, and if so
-+**   * if the child journal contains a reference to master journal 
-+**     file zMaster
- **
--** If the page size is changed, then this function uses sqlite3PagerMalloc() 
--** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt 
--** fails, SQLITE_NOMEM is returned and the page size remains unchanged. 
--** In all other cases, SQLITE_OK is returned.
-+** If a child journal can be found that matches both of the criteria
-+** above, this function returns without doing anything. Otherwise, if
-+** no such child journal can be found, file zMaster is deleted from
-+** the file-system using sqlite3OsDelete().
- **
--** If the page size is not changed, either because one of the enumerated
--** conditions above is not true, the pager was in error state when this
--** function was called, or because the memory allocation attempt failed, 
--** then *pPageSize is set to the old, retained page size before returning.
-+** If an IO error within this function, an error code is returned. This
-+** function allocates memory by calling sqlite3Malloc(). If an allocation
-+** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors 
-+** occur, SQLITE_OK is returned.
-+**
-+** TODO: This function allocates a single block of memory to load
-+** the entire contents of the master journal file. This could be
-+** a couple of kilobytes or so - potentially larger than the page 
-+** size.
- */
--SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
--  int rc = SQLITE_OK;
-+static int pager_delmaster(Pager *pPager, const char *zMaster){
-+  sqlite3_vfs *pVfs = pPager->pVfs;
-+  int rc;                   /* Return code */
-+  sqlite3_file *pMaster;    /* Malloc'd master-journal file descriptor */
-+  sqlite3_file *pJournal;   /* Malloc'd child-journal file descriptor */
-+  char *zMasterJournal = 0; /* Contents of master journal file */
-+  i64 nMasterJournal;       /* Size of master journal file */
-+  char *zJournal;           /* Pointer to one journal within MJ file */
-+  char *zMasterPtr;         /* Space to hold MJ filename from a journal file */
-+  int nMasterPtr;           /* Amount of space allocated to zMasterPtr[] */
- 
--  /* It is not possible to do a full assert_pager_state() here, as this
--  ** function may be called from within PagerOpen(), before the state
--  ** of the Pager object is internally consistent.
--  **
--  ** At one point this function returned an error if the pager was in 
--  ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that
--  ** there is at least one outstanding page reference, this function
--  ** is a no-op for that case anyhow.
-+  /* Allocate space for both the pJournal and pMaster file descriptors.
-+  ** If successful, open the master journal file for reading.
-   */
-+  pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
-+  pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
-+  if( !pMaster ){
-+    rc = SQLITE_NOMEM;
-+  }else{
-+    const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
-+    rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
-+  }
-+  if( rc!=SQLITE_OK ) goto delmaster_out;
- 
--  u32 pageSize = *pPageSize;
--  assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
--  if( (pPager->memDb==0 || pPager->dbSize==0)
--   && sqlite3PcacheRefCount(pPager->pPCache)==0 
--   && pageSize && pageSize!=(u32)pPager->pageSize 
--  ){
--    char *pNew = NULL;             /* New temp space */
--    i64 nByte = 0;
-+  /* Load the entire master journal file into space obtained from
-+  ** sqlite3_malloc() and pointed to by zMasterJournal.   Also obtain
-+  ** sufficient space (in zMasterPtr) to hold the names of master
-+  ** journal files extracted from regular rollback-journals.
-+  */
-+  rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
-+  if( rc!=SQLITE_OK ) goto delmaster_out;
-+  nMasterPtr = pVfs->mxPathname+1;
-+  zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
-+  if( !zMasterJournal ){
-+    rc = SQLITE_NOMEM;
-+    goto delmaster_out;
++    sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iVal);
++    pDlidx->bPrevValid = 1;
++    pDlidx->iPrev = iRowid;
 +  }
-+  zMasterPtr = &zMasterJournal[nMasterJournal+1];
-+  rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
-+  if( rc!=SQLITE_OK ) goto delmaster_out;
-+  zMasterJournal[nMasterJournal] = 0;
- 
--    if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){
--      rc = sqlite3OsFileSize(pPager->fd, &nByte);
--    }
--    if( rc==SQLITE_OK ){
--      pNew = (char *)sqlite3PageMalloc(pageSize);
--      if( !pNew ) rc = SQLITE_NOMEM;
-+  zJournal = zMasterJournal;
-+  while( (zJournal-zMasterJournal)<nMasterJournal ){
-+    int exists;
-+    rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists);
-+    if( rc!=SQLITE_OK ){
-+      goto delmaster_out;
-     }
-+    if( exists ){
-+      /* One of the journals pointed to by the master journal exists.
-+      ** Open it and check if it points at the master journal. If
-+      ** so, return without deleting the master journal file.
-+      */
-+      int c;
-+      int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
-+      rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
-+      if( rc!=SQLITE_OK ){
-+        goto delmaster_out;
-+      }
++}
 +
-+      rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
-+      sqlite3OsClose(pJournal);
-+      if( rc!=SQLITE_OK ){
-+        goto delmaster_out;
-+      }
- 
--    if( rc==SQLITE_OK ){
--      pager_reset(pPager);
--      rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
--    }
--    if( rc==SQLITE_OK ){
--      sqlite3PageFree(pPager->pTmpSpace);
--      pPager->pTmpSpace = pNew;
--      pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
--      pPager->pageSize = pageSize;
--    }else{
--      sqlite3PageFree(pNew);
-+      c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0;
-+      if( c ){
-+        /* We have a match. Do not delete the master journal file. */
-+        goto delmaster_out;
-+      }
-     }
-+    zJournal += (sqlite3Strlen30(zJournal)+1);
-   }
-+ 
-+  sqlite3OsClose(pMaster);
-+  rc = sqlite3OsDelete(pVfs, zMaster, 0);
- 
--  *pPageSize = pPager->pageSize;
--  if( rc==SQLITE_OK ){
--    if( nReserve<0 ) nReserve = pPager->nReserve;
--    assert( nReserve>=0 && nReserve<1000 );
--    pPager->nReserve = (i16)nReserve;
--    pagerReportSize(pPager);
--    pagerFixMaplimit(pPager);
-+delmaster_out:
-+  sqlite3_free(zMasterJournal);
-+  if( pMaster ){
-+    sqlite3OsClose(pMaster);
-+    assert( !isOpen(pJournal) );
-+    sqlite3_free(pMaster);
-   }
-   return rc;
- }
- 
--/*
--** Return a pointer to the "temporary page" buffer held internally
--** by the pager.  This is a buffer that is big enough to hold the
--** entire content of a database page.  This buffer is used internally
--** during rollback and will be overwritten whenever a rollback
--** occurs.  But other modules are free to use it too, as long as
--** no rollbacks are happening.
--*/
--SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager *pPager){
--  return pPager->pTmpSpace;
--}
--
--/*
--** Attempt to set the maximum database page count if mxPage is positive. 
--** Make no changes if mxPage is zero or negative.  And never reduce the
--** maximum page count below the current size of the database.
--**
--** Regardless of mxPage, return the current maximum page count.
--*/
--SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
--  if( mxPage>0 ){
--    pPager->mxPgno = mxPage;
--  }
--  assert( pPager->eState!=PAGER_OPEN );      /* Called only by OP_MaxPgcnt */
--  assert( pPager->mxPgno>=pPager->dbSize );  /* OP_MaxPgcnt enforces this */
--  return pPager->mxPgno;
--}
- 
- /*
--** The following set of routines are used to disable the simulated
--** I/O error mechanism.  These routines are used to avoid simulated
--** errors in places where we do not care about errors.
-+** This function is used to change the actual size of the database 
-+** file in the file-system. This only happens when committing a transaction,
-+** or rolling back a transaction (including rolling back a hot-journal).
- **
--** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops
--** and generate no code.
--*/
--#ifdef SQLITE_TEST
--SQLITE_API extern int sqlite3_io_error_pending;
--SQLITE_API extern int sqlite3_io_error_hit;
--static int saved_cnt;
--void disable_simulated_io_errors(void){
--  saved_cnt = sqlite3_io_error_pending;
--  sqlite3_io_error_pending = -1;
--}
--void enable_simulated_io_errors(void){
--  sqlite3_io_error_pending = saved_cnt;
--}
--#else
--# define disable_simulated_io_errors()
--# define enable_simulated_io_errors()
--#endif
--
--/*
--** Read the first N bytes from the beginning of the file into memory
--** that pDest points to. 
-+** If the main database file is not open, or the pager is not in either
-+** DBMOD or OPEN state, this function is a no-op. Otherwise, the size 
-+** of the file is changed to nPage pages (nPage*pPager->pageSize bytes). 
-+** If the file on disk is currently larger than nPage pages, then use the VFS
-+** xTruncate() method to truncate it.
- **
--** If the pager was opened on a transient file (zFilename==""), or
--** opened on a file less than N bytes in size, the output buffer is
--** zeroed and SQLITE_OK returned. The rationale for this is that this 
--** function is used to read database headers, and a new transient or
--** zero sized database has a header than consists entirely of zeroes.
-+** Or, it might be the case that the file on disk is smaller than 
-+** nPage pages. Some operating system implementations can get confused if 
-+** you try to truncate a file to some size that is larger than it 
-+** currently is, so detect this case and write a single zero byte to 
-+** the end of the new file instead.
- **
--** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered,
--** the error code is returned to the caller and the contents of the
--** output buffer undefined.
-+** If successful, return SQLITE_OK. If an IO error occurs while modifying
-+** the database file, return the error code to the caller.
- */
--SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
-+static int pager_truncate(Pager *pPager, Pgno nPage){
-   int rc = SQLITE_OK;
--  memset(pDest, 0, N);
--  assert( isOpen(pPager->fd) || pPager->tempFile );
--
--  /* This routine is only called by btree immediately after creating
--  ** the Pager object.  There has not been an opportunity to transition
--  ** to WAL mode yet.
--  */
--  assert( !pagerUseWal(pPager) );
--
--  if( isOpen(pPager->fd) ){
--    IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
--    rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
--    if( rc==SQLITE_IOERR_SHORT_READ ){
--      rc = SQLITE_OK;
-+  assert( pPager->eState!=PAGER_ERROR );
-+  assert( pPager->eState!=PAGER_READER );
-+  
-+  if( isOpen(pPager->fd) 
-+   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) 
-+  ){
-+    i64 currentSize, newSize;
-+    int szPage = pPager->pageSize;
-+    assert( pPager->eLock==EXCLUSIVE_LOCK );
-+    /* TODO: Is it safe to use Pager.dbFileSize here? */
-+    rc = sqlite3OsFileSize(pPager->fd, &currentSize);
-+    newSize = szPage*(i64)nPage;
-+    if( rc==SQLITE_OK && currentSize!=newSize ){
-+      if( currentSize>newSize ){
-+        rc = sqlite3OsTruncate(pPager->fd, newSize);
-+      }else if( (currentSize+szPage)<=newSize ){
-+        char *pTmp = pPager->pTmpSpace;
-+        memset(pTmp, 0, szPage);
-+        testcase( (newSize-szPage) == currentSize );
-+        testcase( (newSize-szPage) >  currentSize );
-+        rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage);
-+      }
-+      if( rc==SQLITE_OK ){
-+        pPager->dbFileSize = nPage;
-+      }
-     }
-   }
-   return rc;
- }
- 
- /*
--** This function may only be called when a read-transaction is open on
--** the pager. It returns the total number of pages in the database.
--**
--** However, if the file is between 1 and <page-size> bytes in size, then 
--** this is considered a 1 page file.
-+** Return a sanitized version of the sector-size of OS file pFile. The
-+** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE.
- */
--SQLITE_PRIVATE void sqlite3PagerPagecount(Pager *pPager, int *pnPage){
--  assert( pPager->eState>=PAGER_READER );
--  assert( pPager->eState!=PAGER_WRITER_FINISHED );
--  *pnPage = (int)pPager->dbSize;
-+SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){
-+  int iRet = sqlite3OsSectorSize(pFile);
-+  if( iRet<32 ){
-+    iRet = 512;
-+  }else if( iRet>MAX_SECTOR_SIZE ){
-+    assert( MAX_SECTOR_SIZE>=512 );
-+    iRet = MAX_SECTOR_SIZE;
-+  }
-+  return iRet;
- }
- 
--
- /*
--** Try to obtain a lock of type locktype on the database file. If
--** a similar or greater lock is already held, this function is a no-op
--** (returning SQLITE_OK immediately).
-+** Set the value of the Pager.sectorSize variable for the given
-+** pager based on the value returned by the xSectorSize method
-+** of the open database file. The sector size will be used 
-+** to determine the size and alignment of journal header and 
-+** master journal pointers within created journal files.
- **
--** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke 
--** the busy callback if the lock is currently not available. Repeat 
--** until the busy callback returns false or until the attempt to 
--** obtain the lock succeeds.
-+** For temporary files the effective sector size is always 512 bytes.
- **
--** Return SQLITE_OK on success and an error code if we cannot obtain
--** the lock. If the lock is obtained successfully, set the Pager.state 
--** variable to locktype before returning.
-+** Otherwise, for non-temporary files, the effective sector size is
-+** the value returned by the xSectorSize() method rounded up to 32 if
-+** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it
-+** is greater than MAX_SECTOR_SIZE.
-+**
-+** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set
-+** the effective sector size to its minimum value (512).  The purpose of
-+** pPager->sectorSize is to define the "blast radius" of bytes that
-+** might change if a crash occurs while writing to a single byte in
-+** that range.  But with POWERSAFE_OVERWRITE, the blast radius is zero
-+** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector
-+** size.  For backwards compatibility of the rollback journal file format,
-+** we cannot reduce the effective sector size below 512.
- */
--static int pager_wait_on_lock(Pager *pPager, int locktype){
--  int rc;                              /* Return code */
--
--  /* Check that this is either a no-op (because the requested lock is 
--  ** already held), or one of the transitions that the busy-handler
--  ** may be invoked during, according to the comment above
--  ** sqlite3PagerSetBusyhandler().
--  */
--  assert( (pPager->eLock>=locktype)
--       || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK)
--       || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK)
--  );
-+static void setSectorSize(Pager *pPager){
-+  assert( isOpen(pPager->fd) || pPager->tempFile );
- 
--  do {
--    rc = pagerLockDb(pPager, locktype);
--  }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) );
--  return rc;
-+  if( pPager->tempFile
-+   || (sqlite3OsDeviceCharacteristics(pPager->fd) & 
-+              SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0
-+  ){
-+    /* Sector size doesn't matter for temporary files. Also, the file
-+    ** may not have been opened yet, in which case the OsSectorSize()
-+    ** call will segfault. */
-+    pPager->sectorSize = 512;
-+  }else{
-+    pPager->sectorSize = sqlite3SectorSize(pPager->fd);
-+  }
- }
- 
- /*
--** Function assertTruncateConstraint(pPager) checks that one of the 
--** following is true for all dirty pages currently in the page-cache:
-+** Playback the journal and thus restore the database file to
-+** the state it was in before we started making changes.  
- **
--**   a) The page number is less than or equal to the size of the 
--**      current database image, in pages, OR
-+** The journal file format is as follows: 
- **
--**   b) if the page content were written at this time, it would not
--**      be necessary to write the current content out to the sub-journal
--**      (as determined by function subjRequiresPage()).
-+**  (1)  8 byte prefix.  A copy of aJournalMagic[].
-+**  (2)  4 byte big-endian integer which is the number of valid page records
-+**       in the journal.  If this value is 0xffffffff, then compute the
-+**       number of page records from the journal size.
-+**  (3)  4 byte big-endian integer which is the initial value for the 
-+**       sanity checksum.
-+**  (4)  4 byte integer which is the number of pages to truncate the
-+**       database to during a rollback.
-+**  (5)  4 byte big-endian integer which is the sector size.  The header
-+**       is this many bytes in size.
-+**  (6)  4 byte big-endian integer which is the page size.
-+**  (7)  zero padding out to the next sector size.
-+**  (8)  Zero or more pages instances, each as follows:
-+**        +  4 byte page number.
-+**        +  pPager->pageSize bytes of data.
-+**        +  4 byte checksum
- **
--** If the condition asserted by this function were not true, and the
--** dirty page were to be discarded from the cache via the pagerStress()
--** routine, pagerStress() would not write the current page content to
--** the database file. If a savepoint transaction were rolled back after
--** this happened, the correct behavior would be to restore the current
--** content of the page. However, since this content is not present in either
--** the database file or the portion of the rollback journal and 
--** sub-journal rolled back the content could not be restored and the
--** database image would become corrupt. It is therefore fortunate that 
--** this circumstance cannot arise.
--*/
--#if defined(SQLITE_DEBUG)
--static void assertTruncateConstraintCb(PgHdr *pPg){
--  assert( pPg->flags&PGHDR_DIRTY );
--  assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize );
--}
--static void assertTruncateConstraint(Pager *pPager){
--  sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb);
--}
--#else
--# define assertTruncateConstraint(pPager)
--#endif
--
--/*
--** Truncate the in-memory database file image to nPage pages. This 
--** function does not actually modify the database file on disk. It 
--** just sets the internal state of the pager object so that the 
--** truncation will be done when the current transaction is committed.
-+** When we speak of the journal header, we mean the first 7 items above.
-+** Each entry in the journal is an instance of the 8th item.
- **
--** This function is only called right before committing a transaction.
--** Once this function has been called, the transaction must either be
--** rolled back or committed. It is not safe to call this function and
--** then continue writing to the database.
--*/
--SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
--  assert( pPager->dbSize>=nPage );
--  assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
--  pPager->dbSize = nPage;
--
--  /* At one point the code here called assertTruncateConstraint() to
--  ** ensure that all pages being truncated away by this operation are,
--  ** if one or more savepoints are open, present in the savepoint 
--  ** journal so that they can be restored if the savepoint is rolled
--  ** back. This is no longer necessary as this function is now only
--  ** called right before committing a transaction. So although the 
--  ** Pager object may still have open savepoints (Pager.nSavepoint!=0), 
--  ** they cannot be rolled back. So the assertTruncateConstraint() call
--  ** is no longer correct. */
--}
--
--
--/*
--** This function is called before attempting a hot-journal rollback. It
--** syncs the journal file to disk, then sets pPager->journalHdr to the
--** size of the journal file so that the pager_playback() routine knows
--** that the entire journal file has been synced.
-+** Call the value from the second bullet "nRec".  nRec is the number of
-+** valid page entries in the journal.  In most cases, you can compute the
-+** value of nRec from the size of the journal file.  But if a power
-+** failure occurred while the journal was being written, it could be the
-+** case that the size of the journal file had already been increased but
-+** the extra entries had not yet made it safely to disk.  In such a case,
-+** the value of nRec computed from the file size would be too large.  For
-+** that reason, we always use the nRec value in the header.
- **
--** Syncing a hot-journal to disk before attempting to roll it back ensures 
--** that if a power-failure occurs during the rollback, the process that
--** attempts rollback following system recovery sees the same journal
--** content as this process.
-+** If the nRec value is 0xffffffff it means that nRec should be computed
-+** from the file size.  This value is used when the user selects the
-+** no-sync option for the journal.  A power failure could lead to corruption
-+** in this case.  But for things like temporary table (which will be
-+** deleted when the power is restored) we don't care.  
- **
--** If everything goes as planned, SQLITE_OK is returned. Otherwise, 
--** an SQLite error code.
-+** If the file opened as the journal file is not a well-formed
-+** journal file then all pages up to the first corrupted page are rolled
-+** back (or no pages if the journal header is corrupted). The journal file
-+** is then deleted and SQLITE_OK returned, just as if no corruption had
-+** been encountered.
-+**
-+** If an I/O or malloc() error occurs, the journal-file is not deleted
-+** and an error code is returned.
-+**
-+** The isHot parameter indicates that we are trying to rollback a journal
-+** that might be a hot journal.  Or, it could be that the journal is 
-+** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE.
-+** If the journal really is hot, reset the pager cache prior rolling
-+** back any content.  If the journal is merely persistent, no reset is
-+** needed.
- */
--static int pagerSyncHotJournal(Pager *pPager){
--  int rc = SQLITE_OK;
--  if( !pPager->noSync ){
--    rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL);
-+static int pager_playback(Pager *pPager, int isHot){
-+  sqlite3_vfs *pVfs = pPager->pVfs;
-+  i64 szJ;                 /* Size of the journal file in bytes */
-+  u32 nRec;                /* Number of Records in the journal */
-+  u32 u;                   /* Unsigned loop counter */
-+  Pgno mxPg = 0;           /* Size of the original file in pages */
-+  int rc;                  /* Result code of a subroutine */
-+  int res = 1;             /* Value returned by sqlite3OsAccess() */
-+  char *zMaster = 0;       /* Name of master journal file if any */
-+  int needPagerReset;      /* True to reset page prior to first page rollback */
-+  int nPlayback = 0;       /* Total number of pages restored from journal */
-+
-+  /* Figure out how many records are in the journal.  Abort early if
-+  ** the journal is empty.
-+  */
-+  assert( isOpen(pPager->jfd) );
-+  rc = sqlite3OsFileSize(pPager->jfd, &szJ);
-+  if( rc!=SQLITE_OK ){
-+    goto end_playback;
-   }
--  if( rc==SQLITE_OK ){
--    rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr);
++static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){
++  static const u8 zero[] = { 0x00, 0x00, 0x00, 0x00 };
++  Fts5PageWriter *pPage = &pWriter->writer;
++  i64 iRowid;
 +
-+  /* Read the master journal name from the journal, if it is present.
-+  ** If a master journal file name is specified, but the file is not
-+  ** present on disk, then the journal is not hot and does not need to be
-+  ** played back.
-+  **
-+  ** TODO: Technically the following is an error because it assumes that
-+  ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
-+  ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
-+  **  mxPathname is 512, which is the same as the minimum allowable value
-+  ** for pageSize.
-+  */
-+  zMaster = pPager->pTmpSpace;
-+  rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
-+  if( rc==SQLITE_OK && zMaster[0] ){
-+    rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
-   }
--  return rc;
--}
-+  zMaster = 0;
-+  if( rc!=SQLITE_OK || !res ){
-+    goto end_playback;
++  assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) );
++
++  /* Set the szLeaf header field. */
++  assert( 0==fts5GetU16(&pPage->buf.p[2]) );
++  fts5PutU16(&pPage->buf.p[2], (u16)pPage->buf.n);
++
++  if( pWriter->bFirstTermInPage ){
++    /* No term was written to this page. */
++    assert( pPage->pgidx.n==0 );
++    fts5WriteBtreeNoTerm(p, pWriter);
++  }else{
++    /* Append the pgidx to the page buffer. Set the szLeaf header field. */
++    fts5BufferAppendBlob(&p->rc, &pPage->buf, pPage->pgidx.n, pPage->pgidx.p);
 +  }
-+  pPager->journalOff = 0;
-+  needPagerReset = isHot;
- 
--/*
--** Obtain a reference to a memory mapped page object for page number pgno. 
--** The new object will use the pointer pData, obtained from xFetch().
--** If successful, set *ppPage to point to the new page reference
--** and return SQLITE_OK. Otherwise, return an SQLite error code and set
--** *ppPage to zero.
--**
--** Page references obtained by calling this function should be released
--** by calling pagerReleaseMapPage().
--*/
--static int pagerAcquireMapPage(
--  Pager *pPager,                  /* Pager object */
--  Pgno pgno,                      /* Page number */
--  void *pData,                    /* xFetch()'d data for this page */
--  PgHdr **ppPage                  /* OUT: Acquired page object */
--){
--  PgHdr *p;                       /* Memory mapped page to return */
--  
--  if( pPager->pMmapFreelist ){
--    *ppPage = p = pPager->pMmapFreelist;
--    pPager->pMmapFreelist = p->pDirty;
--    p->pDirty = 0;
--    memset(p->pExtra, 0, pPager->nExtra);
--  }else{
--    *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
--    if( p==0 ){
--      sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
--      return SQLITE_NOMEM;
-+  /* This loop terminates either when a readJournalHdr() or 
-+  ** pager_playback_one_page() call returns SQLITE_DONE or an IO error 
-+  ** occurs. 
-+  */
-+  while( 1 ){
-+    /* Read the next journal header from the journal file.  If there are
-+    ** not enough bytes left in the journal file for a complete header, or
-+    ** it is corrupted, then a process must have failed while writing it.
-+    ** This indicates nothing more needs to be rolled back.
-+    */
-+    rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg);
-+    if( rc!=SQLITE_OK ){ 
-+      if( rc==SQLITE_DONE ){
-+        rc = SQLITE_OK;
++
++  /* Write the page out to disk */
++  iRowid = FTS5_SEGMENT_ROWID(pWriter->iSegid, pPage->pgno);
++  fts5DataWrite(p, iRowid, pPage->buf.p, pPage->buf.n);
++
++  /* Initialize the next page. */
++  fts5BufferZero(&pPage->buf);
++  fts5BufferZero(&pPage->pgidx);
++  fts5BufferAppendBlob(&p->rc, &pPage->buf, 4, zero);
++  pPage->iPrevPgidx = 0;
++  pPage->pgno++;
++
++  /* Increase the leaves written counter */
++  pWriter->nLeafWritten++;
++
++  /* The new leaf holds no terms or rowids */
++  pWriter->bFirstTermInPage = 1;
++  pWriter->bFirstRowidInPage = 1;
++}
++
++/*
++** Append term pTerm/nTerm to the segment being written by the writer passed
++** as the second argument.
++**
++** If an error occurs, set the Fts5Index.rc error code. If an error has 
++** already occurred, this function is a no-op.
++*/
++static void fts5WriteAppendTerm(
++  Fts5Index *p, 
++  Fts5SegWriter *pWriter,
++  int nTerm, const u8 *pTerm 
++){
++  int nPrefix;                    /* Bytes of prefix compression for term */
++  Fts5PageWriter *pPage = &pWriter->writer;
++  Fts5Buffer *pPgidx = &pWriter->writer.pgidx;
++
++  assert( p->rc==SQLITE_OK );
++  assert( pPage->buf.n>=4 );
++  assert( pPage->buf.n>4 || pWriter->bFirstTermInPage );
++
++  /* If the current leaf page is full, flush it to disk. */
++  if( (pPage->buf.n + pPgidx->n + nTerm + 2)>=p->pConfig->pgsz ){
++    if( pPage->buf.n>4 ){
++      fts5WriteFlushLeaf(p, pWriter);
++    }
++    fts5BufferGrow(&p->rc, &pPage->buf, nTerm+FTS5_DATA_PADDING);
++  }
++  
++  /* TODO1: Updating pgidx here. */
++  pPgidx->n += sqlite3Fts5PutVarint(
++      &pPgidx->p[pPgidx->n], pPage->buf.n - pPage->iPrevPgidx
++  );
++  pPage->iPrevPgidx = pPage->buf.n;
++#if 0
++  fts5PutU16(&pPgidx->p[pPgidx->n], pPage->buf.n);
++  pPgidx->n += 2;
++#endif
++
++  if( pWriter->bFirstTermInPage ){
++    nPrefix = 0;
++    if( pPage->pgno!=1 ){
++      /* This is the first term on a leaf that is not the leftmost leaf in
++      ** the segment b-tree. In this case it is necessary to add a term to
++      ** the b-tree hierarchy that is (a) larger than the largest term 
++      ** already written to the segment and (b) smaller than or equal to
++      ** this term. In other words, a prefix of (pTerm/nTerm) that is one
++      ** byte longer than the longest prefix (pTerm/nTerm) shares with the
++      ** previous term. 
++      **
++      ** Usually, the previous term is available in pPage->term. The exception
++      ** is if this is the first term written in an incremental-merge step.
++      ** In this case the previous term is not available, so just write a
++      ** copy of (pTerm/nTerm) into the parent node. This is slightly
++      ** inefficient, but still correct.  */
++      int n = nTerm;
++      if( pPage->term.n ){
++        n = 1 + fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
 +      }
-+      goto end_playback;
++      fts5WriteBtreeTerm(p, pWriter, n, pTerm);
++      pPage = &pWriter->writer;
 +    }
++  }else{
++    nPrefix = fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
++    fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix);
++  }
 +
-+    /* If nRec is 0xffffffff, then this journal was created by a process
-+    ** working in no-sync mode. This means that the rest of the journal
-+    ** file consists of pages, there are no more journal headers. Compute
-+    ** the value of nRec based on this assumption.
-+    */
-+    if( nRec==0xffffffff ){
-+      assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
-+      nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager));
++  /* Append the number of bytes of new data, then the term data itself
++  ** to the page. */
++  fts5BufferAppendVarint(&p->rc, &pPage->buf, nTerm - nPrefix);
++  fts5BufferAppendBlob(&p->rc, &pPage->buf, nTerm - nPrefix, &pTerm[nPrefix]);
++
++  /* Update the Fts5PageWriter.term field. */
++  fts5BufferSet(&p->rc, &pPage->term, nTerm, pTerm);
++  pWriter->bFirstTermInPage = 0;
++
++  pWriter->bFirstRowidInPage = 0;
++  pWriter->bFirstRowidInDoclist = 1;
++
++  assert( p->rc || (pWriter->nDlidx>0 && pWriter->aDlidx[0].buf.n==0) );
++  pWriter->aDlidx[0].pgno = pPage->pgno;
++}
++
++/*
++** Append a rowid and position-list size field to the writers output. 
++*/
++static void fts5WriteAppendRowid(
++  Fts5Index *p, 
++  Fts5SegWriter *pWriter,
++  i64 iRowid
++){
++  if( p->rc==SQLITE_OK ){
++    Fts5PageWriter *pPage = &pWriter->writer;
++
++    if( (pPage->buf.n + pPage->pgidx.n)>=p->pConfig->pgsz ){
++      fts5WriteFlushLeaf(p, pWriter);
 +    }
 +
-+    /* If nRec is 0 and this rollback is of a transaction created by this
-+    ** process and if this is the final header in the journal, then it means
-+    ** that this part of the journal was being filled but has not yet been
-+    ** synced to disk.  Compute the number of pages based on the remaining
-+    ** size of the file.
-+    **
-+    ** The third term of the test was added to fix ticket #2565.
-+    ** When rolling back a hot journal, nRec==0 always means that the next
-+    ** chunk of the journal contains zero pages to be rolled back.  But
-+    ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in
-+    ** the journal, it means that the journal might contain additional
-+    ** pages that need to be rolled back and that the number of pages 
-+    ** should be computed based on the journal file size.
-+    */
-+    if( nRec==0 && !isHot &&
-+        pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){
-+      nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager));
++    /* If this is to be the first rowid written to the page, set the 
++    ** rowid-pointer in the page-header. Also append a value to the dlidx
++    ** buffer, in case a doclist-index is required.  */
++    if( pWriter->bFirstRowidInPage ){
++      fts5PutU16(pPage->buf.p, (u16)pPage->buf.n);
++      fts5WriteDlidxAppend(p, pWriter, iRowid);
 +    }
 +
-+    /* If this is the first header read from the journal, truncate the
-+    ** database file back to its original size.
-+    */
-+    if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
-+      rc = pager_truncate(pPager, mxPg);
-+      if( rc!=SQLITE_OK ){
-+        goto end_playback;
-+      }
-+      pPager->dbSize = mxPg;
++    /* Write the rowid. */
++    if( pWriter->bFirstRowidInDoclist || pWriter->bFirstRowidInPage ){
++      fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid);
++    }else{
++      assert( p->rc || iRowid>pWriter->iPrevRowid );
++      fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid);
 +    }
++    pWriter->iPrevRowid = iRowid;
++    pWriter->bFirstRowidInDoclist = 0;
++    pWriter->bFirstRowidInPage = 0;
++  }
++}
 +
-+    /* Copy original pages out of the journal and back into the 
-+    ** database file and/or page cache.
-+    */
-+    for(u=0; u<nRec; u++){
-+      if( needPagerReset ){
-+        pager_reset(pPager);
-+        needPagerReset = 0;
-+      }
-+      rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
-+      if( rc==SQLITE_OK ){
-+        nPlayback++;
-+      }else{
-+        if( rc==SQLITE_DONE ){
-+          pPager->journalOff = szJ;
-+          break;
-+        }else if( rc==SQLITE_IOERR_SHORT_READ ){
-+          /* If the journal has been truncated, simply stop reading and
-+          ** processing the journal. This might happen if the journal was
-+          ** not completely written and synced prior to a crash.  In that
-+          ** case, the database should have never been written in the
-+          ** first place so it is OK to simply abandon the rollback. */
-+          rc = SQLITE_OK;
-+          goto end_playback;
-+        }else{
-+          /* If we are unable to rollback, quit and return the error
-+          ** code.  This will cause the pager to enter the error state
-+          ** so that no further harm will be done.  Perhaps the next
-+          ** process to come along will be able to rollback the database.
-+          */
-+          goto end_playback;
-+        }
-+      }
-     }
--    p->pExtra = (void *)&p[1];
--    p->flags = PGHDR_MMAP;
--    p->nRef = 1;
--    p->pPager = pPager;
-   }
-+  /*NOTREACHED*/
-+  assert( 0 );
- 
--  assert( p->pExtra==(void *)&p[1] );
--  assert( p->pPage==0 );
--  assert( p->flags==PGHDR_MMAP );
--  assert( p->pPager==pPager );
--  assert( p->nRef==1 );
--
--  p->pgno = pgno;
--  p->pData = pData;
--  pPager->nMmapOut++;
--
--  return SQLITE_OK;
--}
--
--/*
--** Release a reference to page pPg. pPg must have been returned by an 
--** earlier call to pagerAcquireMapPage().
--*/
--static void pagerReleaseMapPage(PgHdr *pPg){
--  Pager *pPager = pPg->pPager;
--  pPager->nMmapOut--;
--  pPg->pDirty = pPager->pMmapFreelist;
--  pPager->pMmapFreelist = pPg;
-+end_playback:
-+  /* Following a rollback, the database file should be back in its original
-+  ** state prior to the start of the transaction, so invoke the
-+  ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the
-+  ** assertion that the transaction counter was modified.
-+  */
-+#ifdef SQLITE_DEBUG
-+  if( pPager->fd->pMethods ){
-+    sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0);
++static void fts5WriteAppendPoslistData(
++  Fts5Index *p, 
++  Fts5SegWriter *pWriter, 
++  const u8 *aData, 
++  int nData
++){
++  Fts5PageWriter *pPage = &pWriter->writer;
++  const u8 *a = aData;
++  int n = nData;
++  
++  assert( p->pConfig->pgsz>0 );
++  while( p->rc==SQLITE_OK 
++     && (pPage->buf.n + pPage->pgidx.n + n)>=p->pConfig->pgsz 
++  ){
++    int nReq = p->pConfig->pgsz - pPage->buf.n - pPage->pgidx.n;
++    int nCopy = 0;
++    while( nCopy<nReq ){
++      i64 dummy;
++      nCopy += fts5GetVarint(&a[nCopy], (u64*)&dummy);
++    }
++    fts5BufferAppendBlob(&p->rc, &pPage->buf, nCopy, a);
++    a += nCopy;
++    n -= nCopy;
++    fts5WriteFlushLeaf(p, pWriter);
 +  }
-+#endif
- 
--  assert( pPager->fd->pMethods->iVersion>=3 );
--  sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData);
--}
-+  /* If this playback is happening automatically as a result of an IO or 
-+  ** malloc error that occurred after the change-counter was updated but 
-+  ** before the transaction was committed, then the change-counter 
-+  ** modification may just have been reverted. If this happens in exclusive 
-+  ** mode, then subsequent transactions performed by the connection will not
-+  ** update the change-counter at all. This may lead to cache inconsistency
-+  ** problems for other processes at some point in the future. So, just
-+  ** in case this has happened, clear the changeCountDone flag now.
-+  */
-+  pPager->changeCountDone = pPager->tempFile;
- 
--/*
--** Free all PgHdr objects stored in the Pager.pMmapFreelist list.
--*/
--static void pagerFreeMapHdrs(Pager *pPager){
--  PgHdr *p;
--  PgHdr *pNext;
--  for(p=pPager->pMmapFreelist; p; p=pNext){
--    pNext = p->pDirty;
--    sqlite3_free(p);
-+  if( rc==SQLITE_OK ){
-+    zMaster = pPager->pTmpSpace;
-+    rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
-+    testcase( rc!=SQLITE_OK );
++  if( n>0 ){
++    fts5BufferAppendBlob(&p->rc, &pPage->buf, n, a);
 +  }
-+  if( rc==SQLITE_OK
-+   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
-+  ){
-+    rc = sqlite3PagerSync(pPager, 0);
++}
++
++/*
++** Flush any data cached by the writer object to the database. Free any
++** allocations associated with the writer.
++*/
++static void fts5WriteFinish(
++  Fts5Index *p, 
++  Fts5SegWriter *pWriter,         /* Writer object */
++  int *pnLeaf                     /* OUT: Number of leaf pages in b-tree */
++){
++  int i;
++  Fts5PageWriter *pLeaf = &pWriter->writer;
++  if( p->rc==SQLITE_OK ){
++    assert( pLeaf->pgno>=1 );
++    if( pLeaf->buf.n>4 ){
++      fts5WriteFlushLeaf(p, pWriter);
++    }
++    *pnLeaf = pLeaf->pgno-1;
++    if( pLeaf->pgno>1 ){
++      fts5WriteFlushBtree(p, pWriter);
++    }
 +  }
-+  if( rc==SQLITE_OK ){
-+    rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0);
-+    testcase( rc!=SQLITE_OK );
++  fts5BufferFree(&pLeaf->term);
++  fts5BufferFree(&pLeaf->buf);
++  fts5BufferFree(&pLeaf->pgidx);
++  fts5BufferFree(&pWriter->btterm);
++
++  for(i=0; i<pWriter->nDlidx; i++){
++    sqlite3Fts5BufferFree(&pWriter->aDlidx[i].buf);
 +  }
-+  if( rc==SQLITE_OK && zMaster[0] && res ){
-+    /* If there was a master journal and this routine will return success,
-+    ** see if it is possible to delete the master journal.
-+    */
-+    rc = pager_delmaster(pPager, zMaster);
-+    testcase( rc!=SQLITE_OK );
++  sqlite3_free(pWriter->aDlidx);
++}
++
++static void fts5WriteInit(
++  Fts5Index *p, 
++  Fts5SegWriter *pWriter, 
++  int iSegid
++){
++  const int nBuffer = p->pConfig->pgsz + FTS5_DATA_PADDING;
++
++  memset(pWriter, 0, sizeof(Fts5SegWriter));
++  pWriter->iSegid = iSegid;
++
++  fts5WriteDlidxGrow(p, pWriter, 1);
++  pWriter->writer.pgno = 1;
++  pWriter->bFirstTermInPage = 1;
++  pWriter->iBtPage = 1;
++
++  assert( pWriter->writer.buf.n==0 );
++  assert( pWriter->writer.pgidx.n==0 );
++
++  /* Grow the two buffers to pgsz + padding bytes in size. */
++  sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.pgidx, nBuffer);
++  sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.buf, nBuffer);
++
++  if( p->pIdxWriter==0 ){
++    Fts5Config *pConfig = p->pConfig;
++    fts5IndexPrepareStmt(p, &p->pIdxWriter, sqlite3_mprintf(
++          "INSERT INTO '%q'.'%q_idx'(segid,term,pgno) VALUES(?,?,?)", 
++          pConfig->zDb, pConfig->zName
++    ));
 +  }
-+  if( isHot && nPlayback ){
-+    sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s",
-+                nPlayback, pPager->zJournal);
-   }
 +
-+  /* The Pager.sectorSize variable may have been updated while rolling
-+  ** back a journal created by a process with a different sector size
-+  ** value. Reset it to the correct value for this process.
-+  */
-+  setSectorSize(pPager);
-+  return rc;
- }
- 
- 
- /*
--** Shutdown the page cache.  Free all memory and close all files.
-+** Read the content for page pPg out of the database file and into 
-+** pPg->pData. A shared lock or greater must be held on the database
-+** file before this function is called.
- **
--** If a transaction was in progress when this routine is called, that
--** transaction is rolled back.  All outstanding pages are invalidated
--** and their memory is freed.  Any attempt to use a page associated
--** with this page cache after this function returns will likely
--** result in a coredump.
-+** If page 1 is read, then the value of Pager.dbFileVers[] is set to
-+** the value read from the database file.
- **
--** This function always succeeds. If a transaction is active an attempt
--** is made to roll it back. If an error occurs during the rollback 
--** a hot journal may be left in the filesystem but no error is returned
--** to the caller.
-+** If an IO error occurs, then the IO error is returned to the caller.
-+** Otherwise, SQLITE_OK is returned.
- */
--SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
--  u8 *pTmp = (u8 *)pPager->pTmpSpace;
-+static int readDbPage(PgHdr *pPg, u32 iFrame){
-+  Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
-+  Pgno pgno = pPg->pgno;       /* Page number to read */
-+  int rc = SQLITE_OK;          /* Return code */
-+  int pgsz = pPager->pageSize; /* Number of bytes to read */
++  if( p->rc==SQLITE_OK ){
++    /* Initialize the 4-byte leaf-page header to 0x00. */
++    memset(pWriter->writer.buf.p, 0, 4);
++    pWriter->writer.buf.n = 4;
 +
-+  assert( pPager->eState>=PAGER_READER && !MEMDB );
-+  assert( isOpen(pPager->fd) );
- 
--  assert( assert_pager_state(pPager) );
--  disable_simulated_io_errors();
--  sqlite3BeginBenignMalloc();
--  pagerFreeMapHdrs(pPager);
--  /* pPager->errCode = 0; */
--  pPager->exclusiveMode = 0;
- #ifndef SQLITE_OMIT_WAL
--  sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
--  pPager->pWal = 0;
-+  if( iFrame ){
-+    /* Try to pull the page from the write-ahead log. */
-+    rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData);
-+  }else
- #endif
--  pager_reset(pPager);
--  if( MEMDB ){
--    pager_unlock(pPager);
--  }else{
--    /* If it is open, sync the journal file before calling UnlockAndRollback.
--    ** If this is not done, then an unsynced portion of the open journal 
--    ** file may be played back into the database. If a power failure occurs 
--    ** while this is happening, the database could become corrupt.
--    **
--    ** If an error occurs while trying to sync the journal, shift the pager
--    ** into the ERROR state. This causes UnlockAndRollback to unlock the
--    ** database and close the journal file without attempting to roll it
--    ** back or finalize it. The next database user will have to do hot-journal
--    ** rollback before accessing the database file.
--    */
--    if( isOpen(pPager->jfd) ){
--      pager_error(pPager, pagerSyncHotJournal(pPager));
-+  {
-+    i64 iOffset = (pgno-1)*(i64)pPager->pageSize;
-+    rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
-+    if( rc==SQLITE_IOERR_SHORT_READ ){
-+      rc = SQLITE_OK;
-     }
--    pagerUnlockAndRollback(pPager);
-   }
--  sqlite3EndBenignMalloc();
--  enable_simulated_io_errors();
--  PAGERTRACE(("CLOSE %d\n", PAGERID(pPager)));
--  IOTRACE(("CLOSE %p\n", pPager))
--  sqlite3OsClose(pPager->jfd);
--  sqlite3OsClose(pPager->fd);
--  sqlite3PageFree(pTmp);
--  sqlite3PcacheClose(pPager->pPCache);
- 
--#ifdef SQLITE_HAS_CODEC
--  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
--#endif
-+  if( pgno==1 ){
-+    if( rc ){
-+      /* If the read is unsuccessful, set the dbFileVers[] to something
-+      ** that will never be a valid file version.  dbFileVers[] is a copy
-+      ** of bytes 24..39 of the database.  Bytes 28..31 should always be
-+      ** zero or the size of the database in page. Bytes 32..35 and 35..39
-+      ** should be page numbers which are never 0xffffffff.  So filling
-+      ** pPager->dbFileVers[] with all 0xff bytes should suffice.
-+      **
-+      ** For an encrypted database, the situation is more complex:  bytes
-+      ** 24..39 of the database are white noise.  But the probability of
-+      ** white noise equaling 16 bytes of 0xff is vanishingly small so
-+      ** we should still be ok.
-+      */
-+      memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
++    /* Bind the current output segment id to the index-writer. This is an
++    ** optimization over binding the same value over and over as rows are
++    ** inserted into %_idx by the current writer.  */
++    sqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid);
++  }
++}
++
++/*
++** Iterator pIter was used to iterate through the input segments of on an
++** incremental merge operation. This function is called if the incremental
++** merge step has finished but the input has not been completely exhausted.
++*/
++static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
++  int i;
++  Fts5Buffer buf;
++  memset(&buf, 0, sizeof(Fts5Buffer));
++  for(i=0; i<pIter->nSeg; i++){
++    Fts5SegIter *pSeg = &pIter->aSeg[i];
++    if( pSeg->pSeg==0 ){
++      /* no-op */
++    }else if( pSeg->pLeaf==0 ){
++      /* All keys from this input segment have been transfered to the output.
++      ** Set both the first and last page-numbers to 0 to indicate that the
++      ** segment is now empty. */
++      pSeg->pSeg->pgnoLast = 0;
++      pSeg->pSeg->pgnoFirst = 0;
 +    }else{
-+      u8 *dbFileVers = &((u8*)pPg->pData)[24];
-+      memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
++      int iOff = pSeg->iTermLeafOffset;     /* Offset on new first leaf page */
++      i64 iLeafRowid;
++      Fts5Data *pData;
++      int iId = pSeg->pSeg->iSegid;
++      u8 aHdr[4] = {0x00, 0x00, 0x00, 0x00};
++
++      iLeafRowid = FTS5_SEGMENT_ROWID(iId, pSeg->iTermLeafPgno);
++      pData = fts5DataRead(p, iLeafRowid);
++      if( pData ){
++        fts5BufferZero(&buf);
++        fts5BufferGrow(&p->rc, &buf, pData->nn);
++        fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr);
++        fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n);
++        fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p);
++        fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff, &pData->p[iOff]);
++        if( p->rc==SQLITE_OK ){
++          /* Set the szLeaf field */
++          fts5PutU16(&buf.p[2], (u16)buf.n);
++        }
++
++        /* Set up the new page-index array */
++        fts5BufferAppendVarint(&p->rc, &buf, 4);
++        if( pSeg->iLeafPgno==pSeg->iTermLeafPgno 
++         && pSeg->iEndofDoclist<pData->szLeaf 
++        ){
++          int nDiff = pData->szLeaf - pSeg->iEndofDoclist;
++          fts5BufferAppendVarint(&p->rc, &buf, buf.n - 1 - nDiff - 4);
++          fts5BufferAppendBlob(&p->rc, &buf, 
++              pData->nn - pSeg->iPgidxOff, &pData->p[pSeg->iPgidxOff]
++          );
++        }
++
++        fts5DataRelease(pData);
++        pSeg->pSeg->pgnoFirst = pSeg->iTermLeafPgno;
++        fts5DataDelete(p, FTS5_SEGMENT_ROWID(iId, 1), iLeafRowid);
++        fts5DataWrite(p, iLeafRowid, buf.p, buf.n);
++      }
 +    }
 +  }
-+  CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
- 
--  assert( !pPager->aSavepoint && !pPager->pInJournal );
--  assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
-+  PAGER_INCR(sqlite3_pager_readdb_count);
-+  PAGER_INCR(pPager->nRead);
-+  IOTRACE(("PGIN %p %d\n", pPager, pgno));
-+  PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
-+               PAGERID(pPager), pgno, pager_pagehash(pPg)));
- 
--  sqlite3_free(pPager);
--  return SQLITE_OK;
-+  return rc;
- }
- 
--#if !defined(NDEBUG) || defined(SQLITE_TEST)
- /*
--** Return the page number for page pPg.
-+** Update the value of the change-counter at offsets 24 and 92 in
-+** the header and the sqlite version number at offset 96.
++  fts5BufferFree(&buf);
++}
++
++static void fts5MergeChunkCallback(
++  Fts5Index *p, 
++  void *pCtx, 
++  const u8 *pChunk, int nChunk
++){
++  Fts5SegWriter *pWriter = (Fts5SegWriter*)pCtx;
++  fts5WriteAppendPoslistData(p, pWriter, pChunk, nChunk);
++}
++
++/*
 +**
-+** This is an unconditional update.  See also the pager_incr_changecounter()
-+** routine which only updates the change-counter if the update is actually
-+** needed, as determined by the pPager->changeCountDone state variable.
- */
--SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){
--  return pPg->pgno;
--}
--#endif
-+static void pager_write_changecounter(PgHdr *pPg){
-+  u32 change_counter;
- 
--/*
--** Increment the reference count for page pPg.
--*/
--SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){
--  sqlite3PcacheRef(pPg);
-+  /* Increment the value just read and write it back to byte 24. */
-+  change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1;
-+  put32bits(((char*)pPg->pData)+24, change_counter);
++*/
++static void fts5IndexMergeLevel(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5Structure **ppStruct,       /* IN/OUT: Stucture of index */
++  int iLvl,                       /* Level to read input from */
++  int *pnRem                      /* Write up to this many output leaves */
++){
++  Fts5Structure *pStruct = *ppStruct;
++  Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
++  Fts5StructureLevel *pLvlOut;
++  Fts5Iter *pIter = 0;       /* Iterator to read input data */
++  int nRem = pnRem ? *pnRem : 0;  /* Output leaf pages left to write */
++  int nInput;                     /* Number of input segments */
++  Fts5SegWriter writer;           /* Writer object */
++  Fts5StructureSegment *pSeg;     /* Output segment */
++  Fts5Buffer term;
++  int bOldest;                    /* True if the output segment is the oldest */
++  int eDetail = p->pConfig->eDetail;
++  const int flags = FTS5INDEX_QUERY_NOOUTPUT;
++  int bTermWritten = 0;           /* True if current term already output */
++
++  assert( iLvl<pStruct->nLevel );
++  assert( pLvl->nMerge<=pLvl->nSeg );
++
++  memset(&writer, 0, sizeof(Fts5SegWriter));
++  memset(&term, 0, sizeof(Fts5Buffer));
++  if( pLvl->nMerge ){
++    pLvlOut = &pStruct->aLevel[iLvl+1];
++    assert( pLvlOut->nSeg>0 );
++    nInput = pLvl->nMerge;
++    pSeg = &pLvlOut->aSeg[pLvlOut->nSeg-1];
++
++    fts5WriteInit(p, &writer, pSeg->iSegid);
++    writer.writer.pgno = pSeg->pgnoLast+1;
++    writer.iBtPage = 0;
++  }else{
++    int iSegid = fts5AllocateSegid(p, pStruct);
 +
-+  /* Also store the SQLite version number in bytes 96..99 and in
-+  ** bytes 92..95 store the change counter for which the version number
-+  ** is valid. */
-+  put32bits(((char*)pPg->pData)+92, change_counter);
-+  put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER);
- }
- 
-+#ifndef SQLITE_OMIT_WAL
- /*
--** Sync the journal. In other words, make sure all the pages that have
--** been written to the journal have actually reached the surface of the
--** disk and can be restored in the event of a hot-journal rollback.
--**
--** If the Pager.noSync flag is set, then this function is a no-op.
--** Otherwise, the actions required depend on the journal-mode and the 
--** device characteristics of the file-system, as follows:
--**
--**   * If the journal file is an in-memory journal file, no action need
--**     be taken.
--**
--**   * Otherwise, if the device does not support the SAFE_APPEND property,
--**     then the nRec field of the most recently written journal header
--**     is updated to contain the number of journal records that have
--**     been written following it. If the pager is operating in full-sync
--**     mode, then the journal file is synced before this field is updated.
--**
--**   * If the device does not support the SEQUENTIAL property, then 
--**     journal file is synced.
--**
--** Or, in pseudo-code:
--**
--**   if( NOT <in-memory journal> ){
--**     if( NOT SAFE_APPEND ){
--**       if( <full-sync mode> ) xSync(<journal file>);
--**       <update nRec field>
--**     } 
--**     if( NOT SEQUENTIAL ) xSync(<journal file>);
--**   }
-+** This function is invoked once for each page that has already been 
-+** written into the log file when a WAL transaction is rolled back.
-+** Parameter iPg is the page number of said page. The pCtx argument 
-+** is actually a pointer to the Pager structure.
- **
--** If successful, this routine clears the PGHDR_NEED_SYNC flag of every 
--** page currently held in memory before returning SQLITE_OK. If an IO
--** error is encountered, then the IO error code is returned to the caller.
-+** If page iPg is present in the cache, and has no outstanding references,
-+** it is discarded. Otherwise, if there are one or more outstanding
-+** references, the page content is reloaded from the database. If the
-+** attempt to reload content from the database is required and fails, 
-+** return an SQLite error code. Otherwise, SQLITE_OK.
- */
--static int syncJournal(Pager *pPager, int newHdr){
--  int rc;                         /* Return code */
--
--  assert( pPager->eState==PAGER_WRITER_CACHEMOD
--       || pPager->eState==PAGER_WRITER_DBMOD
--  );
--  assert( assert_pager_state(pPager) );
--  assert( !pagerUseWal(pPager) );
--
--  rc = sqlite3PagerExclusiveLock(pPager);
--  if( rc!=SQLITE_OK ) return rc;
--
--  if( !pPager->noSync ){
--    assert( !pPager->tempFile );
--    if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){
--      const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
--      assert( isOpen(pPager->jfd) );
--
--      if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
--        /* This block deals with an obscure problem. If the last connection
--        ** that wrote to this database was operating in persistent-journal
--        ** mode, then the journal file may at this point actually be larger
--        ** than Pager.journalOff bytes. If the next thing in the journal
--        ** file happens to be a journal-header (written as part of the
--        ** previous connection's transaction), and a crash or power-failure 
--        ** occurs after nRec is updated but before this connection writes 
--        ** anything else to the journal file (or commits/rolls back its 
--        ** transaction), then SQLite may become confused when doing the 
--        ** hot-journal rollback following recovery. It may roll back all
--        ** of this connections data, then proceed to rolling back the old,
--        ** out-of-date data that follows it. Database corruption.
--        **
--        ** To work around this, if the journal file does appear to contain
--        ** a valid header following Pager.journalOff, then write a 0x00
--        ** byte to the start of it to prevent it from being recognized.
--        **
--        ** Variable iNextHdrOffset is set to the offset at which this
--        ** problematic header will occur, if it exists. aMagic is used 
--        ** as a temporary buffer to inspect the first couple of bytes of
--        ** the potential journal header.
--        */
--        i64 iNextHdrOffset;
--        u8 aMagic[8];
--        u8 zHeader[sizeof(aJournalMagic)+4];
--
--        memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
--        put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec);
--
--        iNextHdrOffset = journalHdrOffset(pPager);
--        rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset);
--        if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){
--          static const u8 zerobyte = 0;
--          rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset);
--        }
--        if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
--          return rc;
--        }
-+static int pagerUndoCallback(void *pCtx, Pgno iPg){
-+  int rc = SQLITE_OK;
-+  Pager *pPager = (Pager *)pCtx;
-+  PgHdr *pPg;
- 
--        /* Write the nRec value into the journal file header. If in
--        ** full-synchronous mode, sync the journal first. This ensures that
--        ** all data has really hit the disk before nRec is updated to mark
--        ** it as a candidate for rollback.
--        **
--        ** This is not required if the persistent media supports the
--        ** SAFE_APPEND property. Because in this case it is not possible 
--        ** for garbage data to be appended to the file, the nRec field
--        ** is populated with 0xFFFFFFFF when the journal header is written
--        ** and never needs to be updated.
--        */
--        if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
--          PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
--          IOTRACE(("JSYNC %p\n", pPager))
--          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
--          if( rc!=SQLITE_OK ) return rc;
--        }
--        IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr));
--        rc = sqlite3OsWrite(
--            pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr
--        );
--        if( rc!=SQLITE_OK ) return rc;
--      }
--      if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
--        PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
--        IOTRACE(("JSYNC %p\n", pPager))
--        rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| 
--          (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0)
--        );
--        if( rc!=SQLITE_OK ) return rc;
-+  assert( pagerUseWal(pPager) );
-+  pPg = sqlite3PagerLookup(pPager, iPg);
-+  if( pPg ){
-+    if( sqlite3PcachePageRefcount(pPg)==1 ){
-+      sqlite3PcacheDrop(pPg);
-+    }else{
-+      u32 iFrame = 0;
-+      rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
-+      if( rc==SQLITE_OK ){
-+        rc = readDbPage(pPg, iFrame);
-       }
--
--      pPager->journalHdr = pPager->journalOff;
--      if( newHdr && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
--        pPager->nRec = 0;
--        rc = writeJournalHdr(pPager);
--        if( rc!=SQLITE_OK ) return rc;
-+      if( rc==SQLITE_OK ){
-+        pPager->xReiniter(pPg);
-       }
--    }else{
--      pPager->journalHdr = pPager->journalOff;
-+      sqlite3PagerUnrefNotNull(pPg);
-     }
-   }
- 
--  /* Unless the pager is in noSync mode, the journal file was just 
--  ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on 
--  ** all pages.
-+  /* Normally, if a transaction is rolled back, any backup processes are
-+  ** updated as data is copied out of the rollback journal and into the
-+  ** database. This is not generally possible with a WAL database, as
-+  ** rollback involves simply truncating the log file. Therefore, if one
-+  ** or more frames have already been written to the log (and therefore 
-+  ** also copied into the backup databases) as part of this transaction,
-+  ** the backups must be restarted.
-   */
--  sqlite3PcacheClearSyncFlags(pPager->pPCache);
--  pPager->eState = PAGER_WRITER_DBMOD;
--  assert( assert_pager_state(pPager) );
--  return SQLITE_OK;
-+  sqlite3BackupRestart(pPager->pBackup);
++    /* Extend the Fts5Structure object as required to ensure the output
++    ** segment exists. */
++    if( iLvl==pStruct->nLevel-1 ){
++      fts5StructureAddLevel(&p->rc, ppStruct);
++      pStruct = *ppStruct;
++    }
++    fts5StructureExtendLevel(&p->rc, pStruct, iLvl+1, 1, 0);
++    if( p->rc ) return;
++    pLvl = &pStruct->aLevel[iLvl];
++    pLvlOut = &pStruct->aLevel[iLvl+1];
++
++    fts5WriteInit(p, &writer, iSegid);
++
++    /* Add the new segment to the output level */
++    pSeg = &pLvlOut->aSeg[pLvlOut->nSeg];
++    pLvlOut->nSeg++;
++    pSeg->pgnoFirst = 1;
++    pSeg->iSegid = iSegid;
++    pStruct->nSegment++;
++
++    /* Read input from all segments in the input level */
++    nInput = pLvl->nSeg;
++  }
++  bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2);
++
++  assert( iLvl>=0 );
++  for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, iLvl, nInput, &pIter);
++      fts5MultiIterEof(p, pIter)==0;
++      fts5MultiIterNext(p, pIter, 0, 0)
++  ){
++    Fts5SegIter *pSegIter = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
++    int nPos;                     /* position-list size field value */
++    int nTerm;
++    const u8 *pTerm;
++
++    pTerm = fts5MultiIterTerm(pIter, &nTerm);
++    if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){
++      if( pnRem && writer.nLeafWritten>nRem ){
++        break;
++      }
++      fts5BufferSet(&p->rc, &term, nTerm, pTerm);
++      bTermWritten =0;
++    }
++
++    /* Check for key annihilation. */
++    if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;
++
++    if( p->rc==SQLITE_OK && bTermWritten==0 ){
++      /* This is a new term. Append a term to the output segment. */
++      fts5WriteAppendTerm(p, &writer, nTerm, pTerm);
++      bTermWritten = 1;
++    }
++
++    /* Append the rowid to the output */
++    /* WRITEPOSLISTSIZE */
++    fts5WriteAppendRowid(p, &writer, fts5MultiIterRowid(pIter));
++
++    if( eDetail==FTS5_DETAIL_NONE ){
++      if( pSegIter->bDel ){
++        fts5BufferAppendVarint(&p->rc, &writer.writer.buf, 0);
++        if( pSegIter->nPos>0 ){
++          fts5BufferAppendVarint(&p->rc, &writer.writer.buf, 0);
++        }
++      }
++    }else{
++      /* Append the position-list data to the output */
++      nPos = pSegIter->nPos*2 + pSegIter->bDel;
++      fts5BufferAppendVarint(&p->rc, &writer.writer.buf, nPos);
++      fts5ChunkIterate(p, pSegIter, (void*)&writer, fts5MergeChunkCallback);
++    }
++  }
++
++  /* Flush the last leaf page to disk. Set the output segment b-tree height
++  ** and last leaf page number at the same time.  */
++  fts5WriteFinish(p, &writer, &pSeg->pgnoLast);
++
++  if( fts5MultiIterEof(p, pIter) ){
++    int i;
++
++    /* Remove the redundant segments from the %_data table */
++    for(i=0; i<nInput; i++){
++      fts5DataRemoveSegment(p, pLvl->aSeg[i].iSegid);
++    }
++
++    /* Remove the redundant segments from the input level */
++    if( pLvl->nSeg!=nInput ){
++      int nMove = (pLvl->nSeg - nInput) * sizeof(Fts5StructureSegment);
++      memmove(pLvl->aSeg, &pLvl->aSeg[nInput], nMove);
++    }
++    pStruct->nSegment -= nInput;
++    pLvl->nSeg -= nInput;
++    pLvl->nMerge = 0;
++    if( pSeg->pgnoLast==0 ){
++      pLvlOut->nSeg--;
++      pStruct->nSegment--;
++    }
++  }else{
++    assert( pSeg->pgnoLast>0 );
++    fts5TrimSegments(p, pIter);
++    pLvl->nMerge = nInput;
++  }
++
++  fts5MultiIterFree(pIter);
++  fts5BufferFree(&term);
++  if( pnRem ) *pnRem -= writer.nLeafWritten;
++}
++
++/*
++** Do up to nPg pages of automerge work on the index.
++**
++** Return true if any changes were actually made, or false otherwise.
++*/
++static int fts5IndexMerge(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5Structure **ppStruct,       /* IN/OUT: Current structure of index */
++  int nPg,                        /* Pages of work to do */
++  int nMin                        /* Minimum number of segments to merge */
++){
++  int nRem = nPg;
++  int bRet = 0;
++  Fts5Structure *pStruct = *ppStruct;
++  while( nRem>0 && p->rc==SQLITE_OK ){
++    int iLvl;                   /* To iterate through levels */
++    int iBestLvl = 0;           /* Level offering the most input segments */
++    int nBest = 0;              /* Number of input segments on best level */
++
++    /* Set iBestLvl to the level to read input segments from. */
++    assert( pStruct->nLevel>0 );
++    for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
++      Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
++      if( pLvl->nMerge ){
++        if( pLvl->nMerge>nBest ){
++          iBestLvl = iLvl;
++          nBest = pLvl->nMerge;
++        }
++        break;
++      }
++      if( pLvl->nSeg>nBest ){
++        nBest = pLvl->nSeg;
++        iBestLvl = iLvl;
++      }
++    }
++
++    /* If nBest is still 0, then the index must be empty. */
++#ifdef SQLITE_DEBUG
++    for(iLvl=0; nBest==0 && iLvl<pStruct->nLevel; iLvl++){
++      assert( pStruct->aLevel[iLvl].nSeg==0 );
++    }
++#endif
++
++    if( nBest<nMin && pStruct->aLevel[iBestLvl].nMerge==0 ){
++      break;
++    }
++    bRet = 1;
++    fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem);
++    if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){
++      fts5StructurePromote(p, iBestLvl+1, pStruct);
++    }
++  }
++  *ppStruct = pStruct;
++  return bRet;
++}
++
++/*
++** A total of nLeaf leaf pages of data has just been flushed to a level-0
++** segment. This function updates the write-counter accordingly and, if
++** necessary, performs incremental merge work.
++**
++** If an error occurs, set the Fts5Index.rc error code. If an error has 
++** already occurred, this function is a no-op.
++*/
++static void fts5IndexAutomerge(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5Structure **ppStruct,       /* IN/OUT: Current structure of index */
++  int nLeaf                       /* Number of output leaves just written */
++){
++  if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 ){
++    Fts5Structure *pStruct = *ppStruct;
++    u64 nWrite;                   /* Initial value of write-counter */
++    int nWork;                    /* Number of work-quanta to perform */
++    int nRem;                     /* Number of leaf pages left to write */
++
++    /* Update the write-counter. While doing so, set nWork. */
++    nWrite = pStruct->nWriteCounter;
++    nWork = (int)(((nWrite + nLeaf) / p->nWorkUnit) - (nWrite / p->nWorkUnit));
++    pStruct->nWriteCounter += nLeaf;
++    nRem = (int)(p->nWorkUnit * nWork * pStruct->nLevel);
++
++    fts5IndexMerge(p, ppStruct, nRem, p->pConfig->nAutomerge);
++  }
++}
 +
-+  return rc;
- }
- 
- /*
--** The argument is the first in a linked list of dirty pages connected
--** by the PgHdr.pDirty pointer. This function writes each one of the
--** in-memory pages in the list to the database file. The argument may
--** be NULL, representing an empty list. In this case this function is
--** a no-op.
--**
--** The pager must hold at least a RESERVED lock when this function
--** is called. Before writing anything to the database file, this lock
--** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained,
--** SQLITE_BUSY is returned and no data is written to the database file.
--** 
--** If the pager is a temp-file pager and the actual file-system file
--** is not yet open, it is created and opened before any data is 
--** written out.
--**
--** Once the lock has been upgraded and, if necessary, the file opened,
--** the pages are written out to the database file in list order. Writing
--** a page is skipped if it meets either of the following criteria:
--**
--**   * The page number is greater than Pager.dbSize, or
--**   * The PGHDR_DONT_WRITE flag is set on the page.
--**
--** If writing out a page causes the database file to grow, Pager.dbFileSize
--** is updated accordingly. If page 1 is written out, then the value cached
--** in Pager.dbFileVers[] is updated to match the new value stored in
--** the database file.
--**
--** If everything is successful, SQLITE_OK is returned. If an IO error 
--** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot
--** be obtained, SQLITE_BUSY is returned.
-+** This function is called to rollback a transaction on a WAL database.
- */
--static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
--  int rc = SQLITE_OK;                  /* Return code */
--
--  /* This function is only called for rollback pagers in WRITER_DBMOD state. */
--  assert( !pagerUseWal(pPager) );
--  assert( pPager->eState==PAGER_WRITER_DBMOD );
--  assert( pPager->eLock==EXCLUSIVE_LOCK );
--
--  /* If the file is a temp-file has not yet been opened, open it now. It
--  ** is not possible for rc to be other than SQLITE_OK if this branch
--  ** is taken, as pager_wait_on_lock() is a no-op for temp-files.
--  */
--  if( !isOpen(pPager->fd) ){
--    assert( pPager->tempFile && rc==SQLITE_OK );
--    rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
--  }
-+static int pagerRollbackWal(Pager *pPager){
-+  int rc;                         /* Return Code */
-+  PgHdr *pList;                   /* List of dirty pages to revert */
- 
--  /* Before the first write, give the VFS a hint of what the final
--  ** file size will be.
-+  /* For all pages in the cache that are currently dirty or have already
-+  ** been written (but not committed) to the log file, do one of the 
-+  ** following:
-+  **
-+  **   + Discard the cached page (if refcount==0), or
-+  **   + Reload page content from the database (if refcount>0).
-   */
--  assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
--  if( rc==SQLITE_OK 
--   && pPager->dbHintSize<pPager->dbSize
--   && (pList->pDirty || pList->pgno>pPager->dbHintSize)
--  ){
--    sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
--    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
--    pPager->dbHintSize = pPager->dbSize;
-+  pPager->dbSize = pPager->dbOrigSize;
-+  rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager);
-+  pList = sqlite3PcacheDirtyList(pPager->pPCache);
-+  while( pList && rc==SQLITE_OK ){
-+    PgHdr *pNext = pList->pDirty;
-+    rc = pagerUndoCallback((void *)pPager, pList->pgno);
-+    pList = pNext;
-   }
- 
--  while( rc==SQLITE_OK && pList ){
--    Pgno pgno = pList->pgno;
--
--    /* If there are dirty pages in the page cache with page numbers greater
--    ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to
--    ** make the file smaller (presumably by auto-vacuum code). Do not write
--    ** any such pages to the file.
--    **
--    ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag
--    ** set (set by sqlite3PagerDontWrite()).
--    */
--    if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
--      i64 offset = (pgno-1)*(i64)pPager->pageSize;   /* Offset to write */
--      char *pData;                                   /* Data to write */    
--
--      assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
--      if( pList->pgno==1 ) pager_write_changecounter(pList);
--
--      /* Encode the database */
--      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
++static void fts5IndexCrisismerge(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5Structure **ppStruct        /* IN/OUT: Current structure of index */
++){
++  const int nCrisis = p->pConfig->nCrisisMerge;
++  Fts5Structure *pStruct = *ppStruct;
++  int iLvl = 0;
++
++  assert( p->rc!=SQLITE_OK || pStruct->nLevel>0 );
++  while( p->rc==SQLITE_OK && pStruct->aLevel[iLvl].nSeg>=nCrisis ){
++    fts5IndexMergeLevel(p, &pStruct, iLvl, 0);
++    assert( p->rc!=SQLITE_OK || pStruct->nLevel>(iLvl+1) );
++    fts5StructurePromote(p, iLvl+1, pStruct);
++    iLvl++;
++  }
++  *ppStruct = pStruct;
++}
++
++static int fts5IndexReturn(Fts5Index *p){
++  int rc = p->rc;
++  p->rc = SQLITE_OK;
 +  return rc;
 +}
- 
--      /* Write out the page data. */
--      rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
++
++typedef struct Fts5FlushCtx Fts5FlushCtx;
++struct Fts5FlushCtx {
++  Fts5Index *pIdx;
++  Fts5SegWriter writer; 
++};
++
++/*
++** Buffer aBuf[] contains a list of varints, all small enough to fit
++** in a 32-bit integer. Return the size of the largest prefix of this 
++** list nMax bytes or less in size.
++*/
++static int fts5PoslistPrefix(const u8 *aBuf, int nMax){
++  int ret;
++  u32 dummy;
++  ret = fts5GetVarint32(aBuf, dummy);
++  if( ret<nMax ){
++    while( 1 ){
++      int i = fts5GetVarint32(&aBuf[ret], dummy);
++      if( (ret + i) > nMax ) break;
++      ret += i;
++    }
++  }
++  return ret;
++}
++
 +/*
-+** This function is a wrapper around sqlite3WalFrames(). As well as logging
-+** the contents of the list of pages headed by pList (connected by pDirty),
-+** this function notifies any active backup processes that the pages have
-+** changed. 
++** Flush the contents of in-memory hash table iHash to a new level-0 
++** segment on disk. Also update the corresponding structure record.
 +**
-+** The list of pages passed into this routine is always sorted by page number.
-+** Hence, if page 1 appears anywhere on the list, it will be the first page.
-+*/ 
-+static int pagerWalFrames(
-+  Pager *pPager,                  /* Pager object */
-+  PgHdr *pList,                   /* List of frames to log */
-+  Pgno nTruncate,                 /* Database size after this commit */
-+  int isCommit                    /* True if this is a commit */
++** If an error occurs, set the Fts5Index.rc error code. If an error has 
++** already occurred, this function is a no-op.
++*/
++static void fts5FlushOneHash(Fts5Index *p){
++  Fts5Hash *pHash = p->pHash;
++  Fts5Structure *pStruct;
++  int iSegid;
++  int pgnoLast = 0;                 /* Last leaf page number in segment */
++
++  /* Obtain a reference to the index structure and allocate a new segment-id
++  ** for the new level-0 segment.  */
++  pStruct = fts5StructureRead(p);
++  iSegid = fts5AllocateSegid(p, pStruct);
++  fts5StructureInvalidate(p);
++
++  if( iSegid ){
++    const int pgsz = p->pConfig->pgsz;
++    int eDetail = p->pConfig->eDetail;
++    Fts5StructureSegment *pSeg;   /* New segment within pStruct */
++    Fts5Buffer *pBuf;             /* Buffer in which to assemble leaf page */
++    Fts5Buffer *pPgidx;           /* Buffer in which to assemble pgidx */
++
++    Fts5SegWriter writer;
++    fts5WriteInit(p, &writer, iSegid);
++
++    pBuf = &writer.writer.buf;
++    pPgidx = &writer.writer.pgidx;
++
++    /* fts5WriteInit() should have initialized the buffers to (most likely)
++    ** the maximum space required. */
++    assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) );
++    assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) );
++
++    /* Begin scanning through hash table entries. This loop runs once for each
++    ** term/doclist currently stored within the hash table. */
++    if( p->rc==SQLITE_OK ){
++      p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0);
++    }
++    while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){
++      const char *zTerm;          /* Buffer containing term */
++      const u8 *pDoclist;         /* Pointer to doclist for this term */
++      int nDoclist;               /* Size of doclist in bytes */
++
++      /* Write the term for this entry to disk. */
++      sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
++      fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm);
++
++      assert( writer.bFirstRowidInPage==0 );
++      if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
++        /* The entire doclist will fit on the current leaf. */
++        fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist);
++      }else{
++        i64 iRowid = 0;
++        i64 iDelta = 0;
++        int iOff = 0;
++
++        /* The entire doclist will not fit on this leaf. The following 
++        ** loop iterates through the poslists that make up the current 
++        ** doclist.  */
++        while( p->rc==SQLITE_OK && iOff<nDoclist ){
++          iOff += fts5GetVarint(&pDoclist[iOff], (u64*)&iDelta);
++          iRowid += iDelta;
++          
++          if( writer.bFirstRowidInPage ){
++            fts5PutU16(&pBuf->p[0], (u16)pBuf->n);   /* first rowid on page */
++            pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
++            writer.bFirstRowidInPage = 0;
++            fts5WriteDlidxAppend(p, &writer, iRowid);
++          }else{
++            pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta);
++          }
++          assert( pBuf->n<=pBuf->nSpace );
++
++          if( eDetail==FTS5_DETAIL_NONE ){
++            if( iOff<nDoclist && pDoclist[iOff]==0 ){
++              pBuf->p[pBuf->n++] = 0;
++              iOff++;
++              if( iOff<nDoclist && pDoclist[iOff]==0 ){
++                pBuf->p[pBuf->n++] = 0;
++                iOff++;
++              }
++            }
++            if( (pBuf->n + pPgidx->n)>=pgsz ){
++              fts5WriteFlushLeaf(p, &writer);
++            }
++          }else{
++            int bDummy;
++            int nPos;
++            int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy);
++            nCopy += nPos;
++            if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){
++              /* The entire poslist will fit on the current leaf. So copy
++              ** it in one go. */
++              fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy);
++            }else{
++              /* The entire poslist will not fit on this leaf. So it needs
++              ** to be broken into sections. The only qualification being
++              ** that each varint must be stored contiguously.  */
++              const u8 *pPoslist = &pDoclist[iOff];
++              int iPos = 0;
++              while( p->rc==SQLITE_OK ){
++                int nSpace = pgsz - pBuf->n - pPgidx->n;
++                int n = 0;
++                if( (nCopy - iPos)<=nSpace ){
++                  n = nCopy - iPos;
++                }else{
++                  n = fts5PoslistPrefix(&pPoslist[iPos], nSpace);
++                }
++                assert( n>0 );
++                fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n);
++                iPos += n;
++                if( (pBuf->n + pPgidx->n)>=pgsz ){
++                  fts5WriteFlushLeaf(p, &writer);
++                }
++                if( iPos>=nCopy ) break;
++              }
++            }
++            iOff += nCopy;
++          }
++        }
++      }
++
++      /* TODO2: Doclist terminator written here. */
++      /* pBuf->p[pBuf->n++] = '\0'; */
++      assert( pBuf->n<=pBuf->nSpace );
++      sqlite3Fts5HashScanNext(pHash);
++    }
++    sqlite3Fts5HashClear(pHash);
++    fts5WriteFinish(p, &writer, &pgnoLast);
++
++    /* Update the Fts5Structure. It is written back to the database by the
++    ** fts5StructureRelease() call below.  */
++    if( pStruct->nLevel==0 ){
++      fts5StructureAddLevel(&p->rc, &pStruct);
++    }
++    fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0);
++    if( p->rc==SQLITE_OK ){
++      pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ];
++      pSeg->iSegid = iSegid;
++      pSeg->pgnoFirst = 1;
++      pSeg->pgnoLast = pgnoLast;
++      pStruct->nSegment++;
++    }
++    fts5StructurePromote(p, 0, pStruct);
++  }
++
++  fts5IndexAutomerge(p, &pStruct, pgnoLast);
++  fts5IndexCrisismerge(p, &pStruct);
++  fts5StructureWrite(p, pStruct);
++  fts5StructureRelease(pStruct);
++}
++
++/*
++** Flush any data stored in the in-memory hash tables to the database.
++*/
++static void fts5IndexFlush(Fts5Index *p){
++  /* Unless it is empty, flush the hash table to disk */
++  if( p->nPendingData ){
++    assert( p->pHash );
++    p->nPendingData = 0;
++    fts5FlushOneHash(p);
++  }
++}
++
++static Fts5Structure *fts5IndexOptimizeStruct(
++  Fts5Index *p, 
++  Fts5Structure *pStruct
 +){
-+  int rc;                         /* Return code */
-+  int nList;                      /* Number of pages in pList */
-+  PgHdr *p;                       /* For looping over pages */
- 
--      /* If page 1 was just written, update Pager.dbFileVers to match
--      ** the value now stored in the database file. If writing this 
--      ** page caused the database file to grow, update dbFileSize. 
--      */
--      if( pgno==1 ){
--        memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers));
--      }
--      if( pgno>pPager->dbFileSize ){
--        pPager->dbFileSize = pgno;
--      }
--      pPager->aStat[PAGER_STAT_WRITE]++;
-+  assert( pPager->pWal );
-+  assert( pList );
-+#ifdef SQLITE_DEBUG
-+  /* Verify that the page list is in accending order */
-+  for(p=pList; p && p->pDirty; p=p->pDirty){
-+    assert( p->pgno < p->pDirty->pgno );
++  Fts5Structure *pNew = 0;
++  int nByte = sizeof(Fts5Structure);
++  int nSeg = pStruct->nSegment;
++  int i;
++
++  /* Figure out if this structure requires optimization. A structure does
++  ** not require optimization if either:
++  **
++  **  + it consists of fewer than two segments, or 
++  **  + all segments are on the same level, or
++  **  + all segments except one are currently inputs to a merge operation.
++  **
++  ** In the first case, return NULL. In the second, increment the ref-count
++  ** on *pStruct and return a copy of the pointer to it.
++  */
++  if( nSeg<2 ) return 0;
++  for(i=0; i<pStruct->nLevel; i++){
++    int nThis = pStruct->aLevel[i].nSeg;
++    if( nThis==nSeg || (nThis==nSeg-1 && pStruct->aLevel[i].nMerge==nThis) ){
++      fts5StructureRef(pStruct);
++      return pStruct;
++    }
++    assert( pStruct->aLevel[i].nMerge<=nThis );
 +  }
-+#endif
- 
--      /* Update any backup objects copying the contents of this pager. */
--      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData);
-+  assert( pList->pDirty==0 || isCommit );
-+  if( isCommit ){
-+    /* If a WAL transaction is being committed, there is no point in writing
-+    ** any pages with page numbers greater than nTruncate into the WAL file.
-+    ** They will never be read by any client. So remove them from the pDirty
-+    ** list here. */
-+    PgHdr **ppNext = &pList;
-+    nList = 0;
-+    for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
-+      if( p->pgno<=nTruncate ){
-+        ppNext = &p->pDirty;
-+        nList++;
++
++  nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel);
++  pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
++
++  if( pNew ){
++    Fts5StructureLevel *pLvl;
++    nByte = nSeg * sizeof(Fts5StructureSegment);
++    pNew->nLevel = pStruct->nLevel+1;
++    pNew->nRef = 1;
++    pNew->nWriteCounter = pStruct->nWriteCounter;
++    pLvl = &pNew->aLevel[pStruct->nLevel];
++    pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte);
++    if( pLvl->aSeg ){
++      int iLvl, iSeg;
++      int iSegOut = 0;
++      /* Iterate through all segments, from oldest to newest. Add them to
++      ** the new Fts5Level object so that pLvl->aSeg[0] is the oldest
++      ** segment in the data structure.  */
++      for(iLvl=pStruct->nLevel-1; iLvl>=0; iLvl--){
++        for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
++          pLvl->aSeg[iSegOut] = pStruct->aLevel[iLvl].aSeg[iSeg];
++          iSegOut++;
++        }
 +      }
++      pNew->nSegment = pLvl->nSeg = nSeg;
++    }else{
++      sqlite3_free(pNew);
++      pNew = 0;
 +    }
-+    assert( pList );
-+  }else{
-+    nList = 1;
 +  }
-+  pPager->aStat[PAGER_STAT_WRITE] += nList;
- 
--      PAGERTRACE(("STORE %d page %d hash(%08x)\n",
--                   PAGERID(pPager), pgno, pager_pagehash(pList)));
--      IOTRACE(("PGOUT %p %d\n", pPager, pgno));
--      PAGER_INCR(sqlite3_pager_writedb_count);
--    }else{
--      PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno));
-+  if( pList->pgno==1 ) pager_write_changecounter(pList);
-+  rc = sqlite3WalFrames(pPager->pWal, 
-+      pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags
-+  );
-+  if( rc==SQLITE_OK && pPager->pBackup ){
-+    for(p=pList; p; p=p->pDirty){
-+      sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
-     }
--    pager_set_pagehash(pList);
--    pList = pList->pDirty;
-   }
- 
-+#ifdef SQLITE_CHECK_PAGES
-+  pList = sqlite3PcacheDirtyList(pPager->pPCache);
-+  for(p=pList; p; p=p->pDirty){
-+    pager_set_pagehash(p);
++
++  return pNew;
++}
++
++static int sqlite3Fts5IndexOptimize(Fts5Index *p){
++  Fts5Structure *pStruct;
++  Fts5Structure *pNew = 0;
++
++  assert( p->rc==SQLITE_OK );
++  fts5IndexFlush(p);
++  pStruct = fts5StructureRead(p);
++  fts5StructureInvalidate(p);
++
++  if( pStruct ){
++    pNew = fts5IndexOptimizeStruct(p, pStruct);
 +  }
-+#endif
++  fts5StructureRelease(pStruct);
++
++  assert( pNew==0 || pNew->nSegment>0 );
++  if( pNew ){
++    int iLvl;
++    for(iLvl=0; pNew->aLevel[iLvl].nSeg==0; iLvl++){}
++    while( p->rc==SQLITE_OK && pNew->aLevel[iLvl].nSeg>0 ){
++      int nRem = FTS5_OPT_WORK_UNIT;
++      fts5IndexMergeLevel(p, &pNew, iLvl, &nRem);
++    }
 +
-   return rc;
- }
- 
- /*
--** Ensure that the sub-journal file is open. If it is already open, this 
--** function is a no-op.
-+** Begin a read transaction on the WAL.
- **
--** SQLITE_OK is returned if everything goes according to plan. An 
--** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() 
--** fails.
-+** This routine used to be called "pagerOpenSnapshot()" because it essentially
-+** makes a snapshot of the database at the current point in time and preserves
-+** that snapshot for use by the reader in spite of concurrently changes by
-+** other writers or checkpointers.
- */
--static int openSubJournal(Pager *pPager){
--  int rc = SQLITE_OK;
--  if( !isOpen(pPager->sjfd) ){
--    if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
--      sqlite3MemJournalOpen(pPager->sjfd);
--    }else{
--      rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
--    }
-+static int pagerBeginReadTransaction(Pager *pPager){
-+  int rc;                         /* Return code */
-+  int changed = 0;                /* True if cache must be reset */
++    fts5StructureWrite(p, pNew);
++    fts5StructureRelease(pNew);
++  }
 +
-+  assert( pagerUseWal(pPager) );
-+  assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
++  return fts5IndexReturn(p); 
++}
 +
-+  /* sqlite3WalEndReadTransaction() was not called for the previous
-+  ** transaction in locking_mode=EXCLUSIVE.  So call it now.  If we
-+  ** are in locking_mode=NORMAL and EndRead() was previously called,
-+  ** the duplicate call is harmless.
-+  */
-+  sqlite3WalEndReadTransaction(pPager->pWal);
++/*
++** This is called to implement the special "VALUES('merge', $nMerge)"
++** INSERT command.
++*/
++static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
++  Fts5Structure *pStruct = fts5StructureRead(p);
++  if( pStruct ){
++    int nMin = p->pConfig->nUsermerge;
++    fts5StructureInvalidate(p);
++    if( nMerge<0 ){
++      Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct);
++      fts5StructureRelease(pStruct);
++      pStruct = pNew;
++      nMin = 2;
++      nMerge = nMerge*-1;
++    }
++    if( pStruct && pStruct->nLevel ){
++      if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
++        fts5StructureWrite(p, pStruct);
++      }
++    }
++    fts5StructureRelease(pStruct);
++  }
++  return fts5IndexReturn(p);
++}
 +
-+  rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
-+  if( rc!=SQLITE_OK || changed ){
-+    pager_reset(pPager);
-+    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
-   }
++static void fts5AppendRowid(
++  Fts5Index *p,
++  i64 iDelta,
++  Fts5Iter *pUnused,
++  Fts5Buffer *pBuf
++){
++  UNUSED_PARAM(pUnused);
++  fts5BufferAppendVarint(&p->rc, pBuf, iDelta);
++}
 +
-   return rc;
- }
++static void fts5AppendPoslist(
++  Fts5Index *p,
++  i64 iDelta,
++  Fts5Iter *pMulti,
++  Fts5Buffer *pBuf
++){
++  int nData = pMulti->base.nData;
++  assert( nData>0 );
++  if( p->rc==SQLITE_OK && 0==fts5BufferGrow(&p->rc, pBuf, nData+9+9) ){
++    fts5BufferSafeAppendVarint(pBuf, iDelta);
++    fts5BufferSafeAppendVarint(pBuf, nData*2);
++    fts5BufferSafeAppendBlob(pBuf, pMulti->base.pData, nData);
++  }
++}
++
++
++static void fts5DoclistIterNext(Fts5DoclistIter *pIter){
++  u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist;
++
++  assert( pIter->aPoslist );
++  if( p>=pIter->aEof ){
++    pIter->aPoslist = 0;
++  }else{
++    i64 iDelta;
++
++    p += fts5GetVarint(p, (u64*)&iDelta);
++    pIter->iRowid += iDelta;
++
++    /* Read position list size */
++    if( p[0] & 0x80 ){
++      int nPos;
++      pIter->nSize = fts5GetVarint32(p, nPos);
++      pIter->nPoslist = (nPos>>1);
++    }else{
++      pIter->nPoslist = ((int)(p[0])) >> 1;
++      pIter->nSize = 1;
++    }
++
++    pIter->aPoslist = p;
++  }
++}
++
++static void fts5DoclistIterInit(
++  Fts5Buffer *pBuf, 
++  Fts5DoclistIter *pIter
++){
++  memset(pIter, 0, sizeof(*pIter));
++  pIter->aPoslist = pBuf->p;
++  pIter->aEof = &pBuf->p[pBuf->n];
++  fts5DoclistIterNext(pIter);
++}
++
++#if 0
++/*
++** Append a doclist to buffer pBuf.
++**
++** This function assumes that space within the buffer has already been
++** allocated.
++*/
++static void fts5MergeAppendDocid(
++  Fts5Buffer *pBuf,               /* Buffer to write to */
++  i64 *piLastRowid,               /* IN/OUT: Previous rowid written (if any) */
++  i64 iRowid                      /* Rowid to append */
++){
++  assert( pBuf->n!=0 || (*piLastRowid)==0 );
++  fts5BufferSafeAppendVarint(pBuf, iRowid - *piLastRowid);
++  *piLastRowid = iRowid;
++}
 +#endif
- 
- /*
--** Append a record of the current state of page pPg to the sub-journal. 
--** It is the callers responsibility to use subjRequiresPage() to check 
--** that it is really required before calling this function.
--**
--** If successful, set the bit corresponding to pPg->pgno in the bitvecs
--** for all open savepoints before returning.
-+** This function is called as part of the transition from PAGER_OPEN
-+** to PAGER_READER state to determine the size of the database file
-+** in pages (assuming the page size currently stored in Pager.pageSize).
- **
--** This function returns SQLITE_OK if everything is successful, an IO
--** error code if the attempt to write to the sub-journal fails, or 
--** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint
--** bitvec.
-+** If no error occurs, SQLITE_OK is returned and the size of the database
-+** in pages is stored in *pnPage. Otherwise, an error code (perhaps
-+** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified.
- */
--static int subjournalPage(PgHdr *pPg){
--  int rc = SQLITE_OK;
--  Pager *pPager = pPg->pPager;
--  if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
-+static int pagerPagecount(Pager *pPager, Pgno *pnPage){
-+  Pgno nPage;                     /* Value to return via *pnPage */
- 
--    /* Open the sub-journal, if it has not already been opened */
--    assert( pPager->useJournal );
--    assert( isOpen(pPager->jfd) || pagerUseWal(pPager) );
--    assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 );
--    assert( pagerUseWal(pPager) 
--         || pageInJournal(pPager, pPg) 
--         || pPg->pgno>pPager->dbOrigSize 
--    );
--    rc = openSubJournal(pPager);
-+  /* Query the WAL sub-system for the database size. The WalDbsize()
-+  ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or
-+  ** if the database size is not available. The database size is not
-+  ** available from the WAL sub-system if the log file is empty or
-+  ** contains no valid committed transactions.
-+  */
-+  assert( pPager->eState==PAGER_OPEN );
-+  assert( pPager->eLock>=SHARED_LOCK );
-+  nPage = sqlite3WalDbsize(pPager->pWal);
- 
--    /* If the sub-journal was opened successfully (or was already open),
--    ** write the journal record into the file.  */
--    if( rc==SQLITE_OK ){
--      void *pData = pPg->pData;
--      i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
--      char *pData2;
--  
--      CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
--      PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
--      rc = write32bits(pPager->sjfd, offset, pPg->pgno);
--      if( rc==SQLITE_OK ){
--        rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
-+  /* If the database size was not available from the WAL sub-system,
-+  ** determine it based on the size of the database file. If the size
-+  ** of the database file is not an integer multiple of the page-size,
-+  ** round down to the nearest page. Except, any file larger than 0
-+  ** bytes in size is considered to contain at least one page.
-+  */
-+  if( nPage==0 ){
-+    i64 n = 0;                    /* Size of db file in bytes */
-+    assert( isOpen(pPager->fd) || pPager->tempFile );
-+    if( isOpen(pPager->fd) ){
-+      int rc = sqlite3OsFileSize(pPager->fd, &n);
-+      if( rc!=SQLITE_OK ){
-+        return rc;
-       }
-     }
-+    nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize);
-   }
--  if( rc==SQLITE_OK ){
--    pPager->nSubRec++;
--    assert( pPager->nSavepoint>0 );
--    rc = addToSavepointBitvecs(pPager, pPg->pgno);
 +
-+  /* If the current number of pages in the file is greater than the
-+  ** configured maximum pager number, increase the allowed limit so
-+  ** that the file can be read.
-+  */
-+  if( nPage>pPager->mxPgno ){
-+    pPager->mxPgno = (Pgno)nPage;
-   }
--  return rc;
++#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) {       \
++  assert( (pBuf)->n!=0 || (iLastRowid)==0 );                   \
++  fts5BufferSafeAppendVarint((pBuf), (iRowid) - (iLastRowid)); \
++  (iLastRowid) = (iRowid);                                     \
++}
 +
-+  *pnPage = nPage;
-+  return SQLITE_OK;
- }
- 
-+#ifndef SQLITE_OMIT_WAL
- /*
--** This function is called by the pcache layer when it has reached some
--** soft memory limit. The first argument is a pointer to a Pager object
--** (cast as a void*). The pager is always 'purgeable' (not an in-memory
--** database). The second argument is a reference to a page that is 
--** currently dirty but has no outstanding references. The page
--** is always associated with the Pager object passed as the first 
--** argument.
-+** Check if the *-wal file that corresponds to the database opened by pPager
-+** exists if the database is not empy, or verify that the *-wal file does
-+** not exist (by deleting it) if the database file is empty.
- **
--** The job of this function is to make pPg clean by writing its contents
--** out to the database file, if possible. This may involve syncing the
--** journal file. 
-+** If the database is not empty and the *-wal file exists, open the pager
-+** in WAL mode.  If the database is empty or if no *-wal file exists and
-+** if no error occurs, make sure Pager.journalMode is not set to
-+** PAGER_JOURNALMODE_WAL.
- **
--** If successful, sqlite3PcacheMakeClean() is called on the page and
--** SQLITE_OK returned. If an IO error occurs while trying to make the
--** page clean, the IO error code is returned. If the page cannot be
--** made clean for some other reason, but no error occurs, then SQLITE_OK
--** is returned by sqlite3PcacheMakeClean() is not called.
-+** Return SQLITE_OK or an error code.
-+**
-+** The caller must hold a SHARED lock on the database file to call this
-+** function. Because an EXCLUSIVE lock on the db file is required to delete 
-+** a WAL on a none-empty database, this ensures there is no race condition 
-+** between the xAccess() below and an xDelete() being executed by some 
-+** other connection.
- */
--static int pagerStress(void *p, PgHdr *pPg){
--  Pager *pPager = (Pager *)p;
-+static int pagerOpenWalIfPresent(Pager *pPager){
-   int rc = SQLITE_OK;
-+  assert( pPager->eState==PAGER_OPEN );
-+  assert( pPager->eLock>=SHARED_LOCK );
- 
--  assert( pPg->pPager==pPager );
--  assert( pPg->flags&PGHDR_DIRTY );
--
--  /* The doNotSpill NOSYNC bit is set during times when doing a sync of
--  ** journal (and adding a new header) is not allowed.  This occurs
--  ** during calls to sqlite3PagerWrite() while trying to journal multiple
--  ** pages belonging to the same sector.
--  **
--  ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling
--  ** regardless of whether or not a sync is required.  This is set during
--  ** a rollback or by user request, respectively.
--  **
--  ** Spilling is also prohibited when in an error state since that could
--  ** lead to database corruption.   In the current implementation it 
--  ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3
--  ** while in the error state, hence it is impossible for this routine to
--  ** be called in the error state.  Nevertheless, we include a NEVER()
--  ** test for the error state as a safeguard against future changes.
--  */
--  if( NEVER(pPager->errCode) ) return SQLITE_OK;
--  testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK );
--  testcase( pPager->doNotSpill & SPILLFLAG_OFF );
--  testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC );
--  if( pPager->doNotSpill
--   && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0
--      || (pPg->flags & PGHDR_NEED_SYNC)!=0)
--  ){
--    return SQLITE_OK;
--  }
-+  if( !pPager->tempFile ){
-+    int isWal;                    /* True if WAL file exists */
-+    Pgno nPage;                   /* Size of the database file */
- 
--  pPg->pDirty = 0;
--  if( pagerUseWal(pPager) ){
--    /* Write a single frame for this page to the log. */
--    if( subjRequiresPage(pPg) ){ 
--      rc = subjournalPage(pPg); 
--    }
--    if( rc==SQLITE_OK ){
--      rc = pagerWalFrames(pPager, pPg, 0, 0);
--    }
--  }else{
--  
--    /* Sync the journal file if required. */
--    if( pPg->flags&PGHDR_NEED_SYNC 
--     || pPager->eState==PAGER_WRITER_CACHEMOD
--    ){
--      rc = syncJournal(pPager, 1);
--    }
--  
--    /* If the page number of this page is larger than the current size of
--    ** the database image, it may need to be written to the sub-journal.
--    ** This is because the call to pager_write_pagelist() below will not
--    ** actually write data to the file in this case.
--    **
--    ** Consider the following sequence of events:
--    **
--    **   BEGIN;
--    **     <journal page X>
--    **     <modify page X>
--    **     SAVEPOINT sp;
--    **       <shrink database file to Y pages>
--    **       pagerStress(page X)
--    **     ROLLBACK TO sp;
--    **
--    ** If (X>Y), then when pagerStress is called page X will not be written
--    ** out to the database file, but will be dropped from the cache. Then,
--    ** following the "ROLLBACK TO sp" statement, reading page X will read
--    ** data from the database file. This will be the copy of page X as it
--    ** was when the transaction started, not as it was when "SAVEPOINT sp"
--    ** was executed.
--    **
--    ** The solution is to write the current data for page X into the 
--    ** sub-journal file now (if it is not already there), so that it will
--    ** be restored to its current value when the "ROLLBACK TO sp" is 
--    ** executed.
--    */
--    if( NEVER(
--        rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
--    ) ){
--      rc = subjournalPage(pPg);
-+    rc = pagerPagecount(pPager, &nPage);
-+    if( rc ) return rc;
-+    if( nPage==0 ){
-+      rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
-+      if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
-+      isWal = 0;
++/*
++** Swap the contents of buffer *p1 with that of *p2.
++*/
++static void fts5BufferSwap(Fts5Buffer *p1, Fts5Buffer *p2){
++  Fts5Buffer tmp = *p1;
++  *p1 = *p2;
++  *p2 = tmp;
++}
++
++static void fts5NextRowid(Fts5Buffer *pBuf, int *piOff, i64 *piRowid){
++  int i = *piOff;
++  if( i>=pBuf->n ){
++    *piOff = -1;
++  }else{
++    u64 iVal;
++    *piOff = i + sqlite3Fts5GetVarint(&pBuf->p[i], &iVal);
++    *piRowid += iVal;
++  }
++}
++
++/*
++** This is the equivalent of fts5MergePrefixLists() for detail=none mode.
++** In this case the buffers consist of a delta-encoded list of rowids only.
++*/
++static void fts5MergeRowidLists(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5Buffer *p1,                 /* First list to merge */
++  Fts5Buffer *p2                  /* Second list to merge */
++){
++  int i1 = 0;
++  int i2 = 0;
++  i64 iRowid1 = 0;
++  i64 iRowid2 = 0;
++  i64 iOut = 0;
++
++  Fts5Buffer out;
++  memset(&out, 0, sizeof(out));
++  sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n);
++  if( p->rc ) return;
++
++  fts5NextRowid(p1, &i1, &iRowid1);
++  fts5NextRowid(p2, &i2, &iRowid2);
++  while( i1>=0 || i2>=0 ){
++    if( i1>=0 && (i2<0 || iRowid1<iRowid2) ){
++      assert( iOut==0 || iRowid1>iOut );
++      fts5BufferSafeAppendVarint(&out, iRowid1 - iOut);
++      iOut = iRowid1;
++      fts5NextRowid(p1, &i1, &iRowid1);
 +    }else{
-+      rc = sqlite3OsAccess(
-+          pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
-+      );
-     }
--  
--    /* Write the contents of the page out to the database file. */
-     if( rc==SQLITE_OK ){
--      assert( (pPg->flags&PGHDR_NEED_SYNC)==0 );
--      rc = pager_write_pagelist(pPager, pPg);
-+      if( isWal ){
-+        testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
-+        rc = sqlite3PagerOpenWal(pPager, 0);
-+      }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
-+        pPager->journalMode = PAGER_JOURNALMODE_DELETE;
++      assert( iOut==0 || iRowid2>iOut );
++      fts5BufferSafeAppendVarint(&out, iRowid2 - iOut);
++      iOut = iRowid2;
++      if( i1>=0 && iRowid1==iRowid2 ){
++        fts5NextRowid(p1, &i1, &iRowid1);
++      }
++      fts5NextRowid(p2, &i2, &iRowid2);
++    }
++  }
++
++  fts5BufferSwap(&out, p1);
++  fts5BufferFree(&out);
++}
++
++/*
++** Buffers p1 and p2 contain doclists. This function merges the content
++** of the two doclists together and sets buffer p1 to the result before
++** returning.
++**
++** If an error occurs, an error code is left in p->rc. If an error has
++** already occurred, this function is a no-op.
++*/
++static void fts5MergePrefixLists(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5Buffer *p1,                 /* First list to merge */
++  Fts5Buffer *p2                  /* Second list to merge */
++){
++  if( p2->n ){
++    i64 iLastRowid = 0;
++    Fts5DoclistIter i1;
++    Fts5DoclistIter i2;
++    Fts5Buffer out = {0, 0, 0};
++    Fts5Buffer tmp = {0, 0, 0};
++
++    if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n) ) return;
++    fts5DoclistIterInit(p1, &i1);
++    fts5DoclistIterInit(p2, &i2);
++
++    while( 1 ){
++      if( i1.iRowid<i2.iRowid ){
++        /* Copy entry from i1 */
++        fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid);
++        fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize);
++        fts5DoclistIterNext(&i1);
++        if( i1.aPoslist==0 ) break;
++      }
++      else if( i2.iRowid!=i1.iRowid ){
++        /* Copy entry from i2 */
++        fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
++        fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize);
++        fts5DoclistIterNext(&i2);
++        if( i2.aPoslist==0 ) break;
++      }
++      else{
++        /* Merge the two position lists. */ 
++        i64 iPos1 = 0;
++        i64 iPos2 = 0;
++        int iOff1 = 0;
++        int iOff2 = 0;
++        u8 *a1 = &i1.aPoslist[i1.nSize];
++        u8 *a2 = &i2.aPoslist[i2.nSize];
++
++        i64 iPrev = 0;
++        Fts5PoslistWriter writer;
++        memset(&writer, 0, sizeof(writer));
++
++        fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
++        fts5BufferZero(&tmp);
++        sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist);
++        if( p->rc ) break;
++
++        sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
++        sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
++        assert( iPos1>=0 && iPos2>=0 );
++
++        if( iPos1<iPos2 ){
++          sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
++          sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
++        }else{
++          sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
++          sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
++        }
++
++        if( iPos1>=0 && iPos2>=0 ){
++          while( 1 ){
++            if( iPos1<iPos2 ){
++              if( iPos1!=iPrev ){
++                sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
++              }
++              sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
++              if( iPos1<0 ) break;
++            }else{
++              assert( iPos2!=iPrev );
++              sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
++              sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
++              if( iPos2<0 ) break;
++            }
++          }
++        }
++
++        if( iPos1>=0 ){
++          if( iPos1!=iPrev ){
++            sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
++          }
++          fts5BufferSafeAppendBlob(&tmp, &a1[iOff1], i1.nPoslist-iOff1);
++        }else{
++          assert( iPos2>=0 && iPos2!=iPrev );
++          sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
++          fts5BufferSafeAppendBlob(&tmp, &a2[iOff2], i2.nPoslist-iOff2);
++        }
++
++        /* WRITEPOSLISTSIZE */
++        fts5BufferSafeAppendVarint(&out, tmp.n * 2);
++        fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
++        fts5DoclistIterNext(&i1);
++        fts5DoclistIterNext(&i2);
++        if( i1.aPoslist==0 || i2.aPoslist==0 ) break;
 +      }
-     }
-   }
--
--  /* Mark the page as clean. */
--  if( rc==SQLITE_OK ){
--    PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
--    sqlite3PcacheMakeClean(pPg);
--  }
--
--  return pager_error(pPager, rc); 
-+  return rc;
- }
--
-+#endif
- 
- /*
--** Allocate and initialize a new Pager object and put a pointer to it
--** in *ppPager. The pager should eventually be freed by passing it
--** to sqlite3PagerClose().
-+** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback
-+** the entire master journal file. The case pSavepoint==NULL occurs when 
-+** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction 
-+** savepoint.
- **
--** The zFilename argument is the path to the database file to open.
--** If zFilename is NULL then a randomly-named temporary file is created
--** and used as the file to be cached. Temporary files are be deleted
--** automatically when they are closed. If zFilename is ":memory:" then 
--** all information is held in cache. It is never written to disk. 
--** This can be used to implement an in-memory database.
-+** When pSavepoint is not NULL (meaning a non-transaction savepoint is 
-+** being rolled back), then the rollback consists of up to three stages,
-+** performed in the order specified:
- **
--** The nExtra parameter specifies the number of bytes of space allocated
--** along with each page reference. This space is available to the user
--** via the sqlite3PagerGetExtra() API.
-+**   * Pages are played back from the main journal starting at byte
-+**     offset PagerSavepoint.iOffset and continuing to 
-+**     PagerSavepoint.iHdrOffset, or to the end of the main journal
-+**     file if PagerSavepoint.iHdrOffset is zero.
- **
--** The flags argument is used to specify properties that affect the
--** operation of the pager. It should be passed some bitwise combination
--** of the PAGER_* flags.
-+**   * If PagerSavepoint.iHdrOffset is not zero, then pages are played
-+**     back starting from the journal header immediately following 
-+**     PagerSavepoint.iHdrOffset to the end of the main journal file.
- **
--** The vfsFlags parameter is a bitmask to pass to the flags parameter
--** of the xOpen() method of the supplied VFS when opening files. 
-+**   * Pages are then played back from the sub-journal file, starting
-+**     with the PagerSavepoint.iSubRec and continuing to the end of
-+**     the journal file.
- **
--** If the pager object is allocated and the specified file opened 
--** successfully, SQLITE_OK is returned and *ppPager set to point to
--** the new pager object. If an error occurs, *ppPager is set to NULL
--** and error code returned. This function may return SQLITE_NOMEM
--** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or 
--** various SQLITE_IO_XXX errors.
-+** Throughout the rollback process, each time a page is rolled back, the
-+** corresponding bit is set in a bitvec structure (variable pDone in the
-+** implementation below). This is used to ensure that a page is only
-+** rolled back the first time it is encountered in either journal.
-+**
-+** If pSavepoint is NULL, then pages are only played back from the main
-+** journal file. There is no need for a bitvec in this case.
-+**
-+** In either case, before playback commences the Pager.dbSize variable
-+** is reset to the value that it held at the start of the savepoint 
-+** (or transaction). No page with a page-number greater than this value
-+** is played back. If one is encountered it is simply skipped.
- */
--SQLITE_PRIVATE int sqlite3PagerOpen(
--  sqlite3_vfs *pVfs,       /* The virtual file system to use */
--  Pager **ppPager,         /* OUT: Return the Pager structure here */
--  const char *zFilename,   /* Name of the database file to open */
--  int nExtra,              /* Extra bytes append to each in-memory page */
--  int flags,               /* flags controlling this file */
--  int vfsFlags,            /* flags passed through to sqlite3_vfs.xOpen() */
--  void (*xReinit)(DbPage*) /* Function to reinitialize pages */
--){
--  u8 *pPtr;
--  Pager *pPager = 0;       /* Pager object to allocate and return */
-+static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
-+  i64 szJ;                 /* Effective size of the main journal */
-+  i64 iHdrOff;             /* End of first segment of main-journal records */
-   int rc = SQLITE_OK;      /* Return code */
--  int tempFile = 0;        /* True for temp files (incl. in-memory files) */
--  int memDb = 0;           /* True if this is an in-memory file */
--  int readOnly = 0;        /* True if this is a read-only file */
--  int journalFileSize;     /* Bytes to allocate for each journal fd */
--  char *zPathname = 0;     /* Full path to database file */
--  int nPathname = 0;       /* Number of bytes in zPathname */
--  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
--  int pcacheSize = sqlite3PcacheSize();       /* Bytes to allocate for PCache */
--  u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
--  const char *zUri = 0;    /* URI args to copy */
--  int nUri = 0;            /* Number of bytes of URI args at *zUri */
--
--  /* Figure out how much space is required for each journal file-handle
--  ** (there are two of them, the main journal and the sub-journal). This
--  ** is the maximum space required for an in-memory journal file handle 
--  ** and a regular journal file-handle. Note that a "regular journal-handle"
--  ** may be a wrapper capable of caching the first portion of the journal
--  ** file in memory to implement the atomic-write optimization (see 
--  ** source file journal.c).
--  */
--  if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
--    journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
--  }else{
--    journalFileSize = ROUND8(sqlite3MemJournalSize());
--  }
--
--  /* Set the output variable to NULL in case an error occurs. */
--  *ppPager = 0;
-+  Bitvec *pDone = 0;       /* Bitvec to ensure pages played back only once */
- 
--#ifndef SQLITE_OMIT_MEMORYDB
--  if( flags & PAGER_MEMORY ){
--    memDb = 1;
--    if( zFilename && zFilename[0] ){
--      zPathname = sqlite3DbStrDup(0, zFilename);
--      if( zPathname==0  ) return SQLITE_NOMEM;
--      nPathname = sqlite3Strlen30(zPathname);
--      zFilename = 0;
--    }
--  }
--#endif
-+  assert( pPager->eState!=PAGER_ERROR );
-+  assert( pPager->eState>=PAGER_WRITER_LOCKED );
- 
--  /* Compute and store the full pathname in an allocated buffer pointed
--  ** to by zPathname, length nPathname. Or, if this is a temporary file,
--  ** leave both nPathname and zPathname set to 0.
--  */
--  if( zFilename && zFilename[0] ){
--    const char *z;
--    nPathname = pVfs->mxPathname+1;
--    zPathname = sqlite3DbMallocRaw(0, nPathname*2);
--    if( zPathname==0 ){
-+  /* Allocate a bitvec to use to store the set of pages rolled back */
-+  if( pSavepoint ){
-+    pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
-+    if( !pDone ){
-       return SQLITE_NOMEM;
-     }
--    zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
--    rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
--    nPathname = sqlite3Strlen30(zPathname);
--    z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1];
--    while( *z ){
--      z += sqlite3Strlen30(z)+1;
--      z += sqlite3Strlen30(z)+1;
--    }
--    nUri = (int)(&z[1] - zUri);
--    assert( nUri>=0 );
--    if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){
--      /* This branch is taken when the journal path required by
--      ** the database being opened will be more than pVfs->mxPathname
--      ** bytes in length. This means the database cannot be opened,
--      ** as it will not be possible to open the journal file or even
--      ** check for a hot-journal before reading.
--      */
--      rc = SQLITE_CANTOPEN_BKPT;
--    }
--    if( rc!=SQLITE_OK ){
--      sqlite3DbFree(0, zPathname);
--      return rc;
--    }
-   }
- 
--  /* Allocate memory for the Pager structure, PCache object, the
--  ** three file descriptors, the database file name and the journal 
--  ** file name. The layout in memory is as follows:
--  **
--  **     Pager object                    (sizeof(Pager) bytes)
--  **     PCache object                   (sqlite3PcacheSize() bytes)
--  **     Database file handle            (pVfs->szOsFile bytes)
--  **     Sub-journal file handle         (journalFileSize bytes)
--  **     Main journal file handle        (journalFileSize bytes)
--  **     Database file name              (nPathname+1 bytes)
--  **     Journal file name               (nPathname+8+1 bytes)
-+  /* Set the database size back to the value it was before the savepoint 
-+  ** being reverted was opened.
-   */
--  pPtr = (u8 *)sqlite3MallocZero(
--    ROUND8(sizeof(*pPager)) +      /* Pager structure */
--    ROUND8(pcacheSize) +           /* PCache object */
--    ROUND8(pVfs->szOsFile) +       /* The main db file */
--    journalFileSize * 2 +          /* The two journal files */ 
--    nPathname + 1 + nUri +         /* zFilename */
--    nPathname + 8 + 2              /* zJournal */
--#ifndef SQLITE_OMIT_WAL
--    + nPathname + 4 + 2            /* zWal */
--#endif
--  );
--  assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
--  if( !pPtr ){
--    sqlite3DbFree(0, zPathname);
--    return SQLITE_NOMEM;
--  }
--  pPager =              (Pager*)(pPtr);
--  pPager->pPCache =    (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
--  pPager->fd =   (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
--  pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
--  pPager->jfd =  (sqlite3_file*)(pPtr += journalFileSize);
--  pPager->zFilename =    (char*)(pPtr += journalFileSize);
--  assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
-+  pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize;
-+  pPager->changeCountDone = pPager->tempFile;
-+
-+  if( !pSavepoint && pagerUseWal(pPager) ){
-+    return pagerRollbackWal(pPager);
-+  }
- 
--  /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
--  if( zPathname ){
--    assert( nPathname>0 );
--    pPager->zJournal =   (char*)(pPtr += nPathname + 1 + nUri);
--    memcpy(pPager->zFilename, zPathname, nPathname);
--    if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
--    memcpy(pPager->zJournal, zPathname, nPathname);
--    memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2);
--    sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
--#ifndef SQLITE_OMIT_WAL
--    pPager->zWal = &pPager->zJournal[nPathname+8+1];
--    memcpy(pPager->zWal, zPathname, nPathname);
--    memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1);
--    sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
--#endif
--    sqlite3DbFree(0, zPathname);
-+  /* Use pPager->journalOff as the effective size of the main rollback
-+  ** journal.  The actual file might be larger than this in
-+  ** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST.  But anything
-+  ** past pPager->journalOff is off-limits to us.
-+  */
-+  szJ = pPager->journalOff;
-+  assert( pagerUseWal(pPager)==0 || szJ==0 );
-+
-+  /* Begin by rolling back records from the main journal starting at
-+  ** PagerSavepoint.iOffset and continuing to the next journal header.
-+  ** There might be records in the main journal that have a page number
-+  ** greater than the current database size (pPager->dbSize) but those
-+  ** will be skipped automatically.  Pages are added to pDone as they
-+  ** are played back.
-+  */
-+  if( pSavepoint && !pagerUseWal(pPager) ){
-+    iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ;
-+    pPager->journalOff = pSavepoint->iOffset;
-+    while( rc==SQLITE_OK && pPager->journalOff<iHdrOff ){
-+      rc = pager_playback_one_page(pPager, &pPager->journalOff, pDone, 1, 1);
 +    }
-+    assert( rc!=SQLITE_DONE );
++
++    if( i1.aPoslist ){
++      fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid);
++      fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.aEof - i1.aPoslist);
++    }
++    else if( i2.aPoslist ){
++      fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
++      fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist);
++    }
++
++    fts5BufferSet(&p->rc, p1, out.n, out.p);
++    fts5BufferFree(&tmp);
++    fts5BufferFree(&out);
++  }
++}
++
++static void fts5SetupPrefixIter(
++  Fts5Index *p,                   /* Index to read from */
++  int bDesc,                      /* True for "ORDER BY rowid DESC" */
++  const u8 *pToken,               /* Buffer containing prefix to match */
++  int nToken,                     /* Size of buffer pToken in bytes */
++  Fts5Colset *pColset,            /* Restrict matches to these columns */
++  Fts5Iter **ppIter          /* OUT: New iterator */
++){
++  Fts5Structure *pStruct;
++  Fts5Buffer *aBuf;
++  const int nBuf = 32;
++
++  void (*xMerge)(Fts5Index*, Fts5Buffer*, Fts5Buffer*);
++  void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*);
++  if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
++    xMerge = fts5MergeRowidLists;
++    xAppend = fts5AppendRowid;
 +  }else{
-+    pPager->journalOff = 0;
-   }
--  pPager->pVfs = pVfs;
--  pPager->vfsFlags = vfsFlags;
- 
--  /* Open the pager file.
-+  /* Continue rolling back records out of the main journal starting at
-+  ** the first journal header seen and continuing until the effective end
-+  ** of the main journal file.  Continue to skip out-of-range pages and
-+  ** continue adding pages rolled back to pDone.
-   */
--  if( zFilename && zFilename[0] ){
--    int fout = 0;                    /* VFS flags returned by xOpen() */
--    rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
--    assert( !memDb );
--    readOnly = (fout&SQLITE_OPEN_READONLY);
-+  while( rc==SQLITE_OK && pPager->journalOff<szJ ){
-+    u32 ii;            /* Loop counter */
-+    u32 nJRec = 0;     /* Number of Journal Records */
-+    u32 dummy;
-+    rc = readJournalHdr(pPager, 0, szJ, &nJRec, &dummy);
-+    assert( rc!=SQLITE_DONE );
- 
--    /* If the file was successfully opened for read/write access,
--    ** choose a default page size in case we have to create the
--    ** database file. The default page size is the maximum of:
--    **
--    **    + SQLITE_DEFAULT_PAGE_SIZE,
--    **    + The value returned by sqlite3OsSectorSize()
--    **    + The largest page size that can be written atomically.
-+    /*
-+    ** The "pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff"
-+    ** test is related to ticket #2565.  See the discussion in the
-+    ** pager_playback() function for additional information.
-     */
--    if( rc==SQLITE_OK ){
--      int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
--      if( !readOnly ){
--        setSectorSize(pPager);
--        assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE);
--        if( szPageDflt<pPager->sectorSize ){
--          if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
--            szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
--          }else{
--            szPageDflt = (u32)pPager->sectorSize;
--          }
--        }
--#ifdef SQLITE_ENABLE_ATOMIC_WRITE
--        {
--          int ii;
--          assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
--          assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
--          assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536);
--          for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
--            if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){
--              szPageDflt = ii;
--            }
--          }
--        }
--#endif
--      }
--      pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0);
--      if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0
--       || sqlite3_uri_boolean(zFilename, "immutable", 0) ){
--          vfsFlags |= SQLITE_OPEN_READONLY;
--          goto act_like_temp_file;
--      }
-+    if( nJRec==0 
-+     && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff
++    xMerge = fts5MergePrefixLists;
++    xAppend = fts5AppendPoslist;
++  }
++
++  aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
++  pStruct = fts5StructureRead(p);
++
++  if( aBuf && pStruct ){
++    const int flags = FTS5INDEX_QUERY_SCAN 
++                    | FTS5INDEX_QUERY_SKIPEMPTY 
++                    | FTS5INDEX_QUERY_NOOUTPUT;
++    int i;
++    i64 iLastRowid = 0;
++    Fts5Iter *p1 = 0;     /* Iterator used to gather data from index */
++    Fts5Data *pData;
++    Fts5Buffer doclist;
++    int bNewTerm = 1;
++
++    memset(&doclist, 0, sizeof(doclist));
++    fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
++    fts5IterSetOutputCb(&p->rc, p1);
++    for( /* no-op */ ;
++        fts5MultiIterEof(p, p1)==0;
++        fts5MultiIterNext2(p, p1, &bNewTerm)
 +    ){
-+      nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager));
-     }
--  }else{
--    /* If a temporary file is requested, it is not opened immediately.
--    ** In this case we accept the default page size and delay actually
--    ** opening the file until the first call to OsWrite().
--    **
--    ** This branch is also run for an in-memory database. An in-memory
--    ** database is the same as a temp-file that is never written out to
--    ** disk and uses an in-memory rollback journal.
--    **
--    ** This branch also runs for files marked as immutable.
--    */ 
--act_like_temp_file:
--    tempFile = 1;
--    pPager->eState = PAGER_READER;     /* Pretend we already have a lock */
--    pPager->eLock = EXCLUSIVE_LOCK;    /* Pretend we are in EXCLUSIVE locking mode */
--    pPager->noLock = 1;                /* Do no locking */
--    readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
-+    for(ii=0; rc==SQLITE_OK && ii<nJRec && pPager->journalOff<szJ; ii++){
-+      rc = pager_playback_one_page(pPager, &pPager->journalOff, pDone, 1, 1);
++      Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
++      int nTerm = pSeg->term.n;
++      const u8 *pTerm = pSeg->term.p;
++      p1->xSetOutputs(p1, pSeg);
++
++      assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 );
++      if( bNewTerm ){
++        if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
++      }
++
++      if( p1->base.nData==0 ) continue;
++
++      if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){
++        for(i=0; p->rc==SQLITE_OK && doclist.n; i++){
++          assert( i<nBuf );
++          if( aBuf[i].n==0 ){
++            fts5BufferSwap(&doclist, &aBuf[i]);
++            fts5BufferZero(&doclist);
++          }else{
++            xMerge(p, &doclist, &aBuf[i]);
++            fts5BufferZero(&aBuf[i]);
++          }
++        }
++        iLastRowid = 0;
++      }
++
++      xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist);
++      iLastRowid = p1->base.iRowid;
 +    }
-+    assert( rc!=SQLITE_DONE );
-   }
-+  assert( rc!=SQLITE_OK || pPager->journalOff>=szJ );
- 
--  /* The following call to PagerSetPagesize() serves to set the value of 
--  ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer.
-+  /* Finally,  rollback pages from the sub-journal.  Page that were
-+  ** previously rolled back out of the main journal (and are hence in pDone)
-+  ** will be skipped.  Out-of-range pages are also skipped.
-   */
--  if( rc==SQLITE_OK ){
--    assert( pPager->memDb==0 );
--    rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1);
--    testcase( rc!=SQLITE_OK );
-+  if( pSavepoint ){
-+    u32 ii;            /* Loop counter */
-+    i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize);
 +
-+    if( pagerUseWal(pPager) ){
-+      rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData);
++    for(i=0; i<nBuf; i++){
++      if( p->rc==SQLITE_OK ){
++        xMerge(p, &doclist, &aBuf[i]);
++      }
++      fts5BufferFree(&aBuf[i]);
 +    }
-+    for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && ii<pPager->nSubRec; ii++){
-+      assert( offset==(i64)ii*(4+pPager->pageSize) );
-+      rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1);
++    fts5MultiIterFree(p1);
++
++    pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n);
++    if( pData ){
++      pData->p = (u8*)&pData[1];
++      pData->nn = pData->szLeaf = doclist.n;
++      if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
++      fts5MultiIterNew2(p, pData, bDesc, ppIter);
 +    }
-+    assert( rc!=SQLITE_DONE );
-   }
- 
--  /* Initialize the PCache object. */
-+  sqlite3BitvecDestroy(pDone);
-   if( rc==SQLITE_OK ){
--    assert( nExtra<1000 );
--    nExtra = ROUND8(nExtra);
--    rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
--                           !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
-+    pPager->journalOff = szJ;
-   }
- 
--  /* If an error occurred above, free the  Pager structure and close the file.
--  */
--  if( rc!=SQLITE_OK ){
--    sqlite3OsClose(pPager->fd);
--    sqlite3PageFree(pPager->pTmpSpace);
--    sqlite3_free(pPager);
--    return rc;
-+  return rc;
++    fts5BufferFree(&doclist);
++  }
++
++  fts5StructureRelease(pStruct);
++  sqlite3_free(aBuf);
 +}
 +
++
 +/*
-+** Change the maximum number of in-memory pages that are allowed.
++** Indicate that all subsequent calls to sqlite3Fts5IndexWrite() pertain
++** to the document with rowid iRowid.
 +*/
-+SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
-+  sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
++static int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){
++  assert( p->rc==SQLITE_OK );
++
++  /* Allocate the hash table if it has not already been allocated */
++  if( p->pHash==0 ){
++    p->rc = sqlite3Fts5HashNew(p->pConfig, &p->pHash, &p->nPendingData);
++  }
++
++  /* Flush the hash table to disk if required */
++  if( iRowid<p->iWriteRowid 
++   || (iRowid==p->iWriteRowid && p->bDelete==0)
++   || (p->nPendingData > p->pConfig->nHashSize) 
++  ){
++    fts5IndexFlush(p);
++  }
++
++  p->iWriteRowid = iRowid;
++  p->bDelete = bDelete;
++  return fts5IndexReturn(p);
 +}
 +
 +/*
-+** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap.
++** Commit data to disk.
 +*/
-+static void pagerFixMaplimit(Pager *pPager){
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  sqlite3_file *fd = pPager->fd;
-+  if( isOpen(fd) && fd->pMethods->iVersion>=3 ){
-+    sqlite3_int64 sz;
-+    sz = pPager->szMmap;
-+    pPager->bUseFetch = (sz>0);
-+    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
-   }
-+#endif
-+}
- 
--  PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
--  IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
-+/*
-+** Change the maximum size of any memory mapping made of the database file.
-+*/
-+SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 szMmap){
-+  pPager->szMmap = szMmap;
-+  pagerFixMaplimit(pPager);
-+}
- 
--  pPager->useJournal = (u8)useJournal;
--  /* pPager->stmtOpen = 0; */
--  /* pPager->stmtInUse = 0; */
--  /* pPager->nRef = 0; */
--  /* pPager->stmtSize = 0; */
--  /* pPager->stmtJSize = 0; */
--  /* pPager->nPage = 0; */
--  pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
--  /* pPager->state = PAGER_UNLOCK; */
--  /* pPager->errMask = 0; */
--  pPager->tempFile = (u8)tempFile;
--  assert( tempFile==PAGER_LOCKINGMODE_NORMAL 
--          || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
--  assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
--  pPager->exclusiveMode = (u8)tempFile; 
--  pPager->changeCountDone = pPager->tempFile;
--  pPager->memDb = (u8)memDb;
--  pPager->readOnly = (u8)readOnly;
--  assert( useJournal || pPager->tempFile );
--  pPager->noSync = pPager->tempFile;
-+/*
-+** Free as much memory as possible from the pager.
-+*/
-+SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
-+  sqlite3PcacheShrink(pPager->pPCache);
-+}
-+
-+/*
-+** Adjust settings of the pager to those specified in the pgFlags parameter.
-+**
-+** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness
-+** of the database to damage due to OS crashes or power failures by
-+** changing the number of syncs()s when writing the journals.
-+** There are three levels:
-+**
-+**    OFF       sqlite3OsSync() is never called.  This is the default
-+**              for temporary and transient files.
-+**
-+**    NORMAL    The journal is synced once before writes begin on the
-+**              database.  This is normally adequate protection, but
-+**              it is theoretically possible, though very unlikely,
-+**              that an inopertune power failure could leave the journal
-+**              in a state which would cause damage to the database
-+**              when it is rolled back.
-+**
-+**    FULL      The journal is synced twice before writes begin on the
-+**              database (with some additional information - the nRec field
-+**              of the journal header - being written in between the two
-+**              syncs).  If we assume that writing a
-+**              single disk sector is atomic, then this mode provides
-+**              assurance that the journal will not be corrupted to the
-+**              point of causing damage to the database during rollback.
-+**
-+** The above is for a rollback-journal mode.  For WAL mode, OFF continues
-+** to mean that no syncs ever occur.  NORMAL means that the WAL is synced
-+** prior to the start of checkpoint and that the database file is synced
-+** at the conclusion of the checkpoint if the entire content of the WAL
-+** was written back into the database.  But no sync operations occur for
-+** an ordinary commit in NORMAL mode with WAL.  FULL means that the WAL
-+** file is synced following each commit operation, in addition to the
-+** syncs associated with NORMAL.
-+**
-+** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL.  The
-+** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync
-+** using fcntl(F_FULLFSYNC).  SQLITE_SYNC_NORMAL means to do an
-+** ordinary fsync() call.  There is no difference between SQLITE_SYNC_FULL
-+** and SQLITE_SYNC_NORMAL on platforms other than MacOSX.  But the
-+** synchronous=FULL versus synchronous=NORMAL setting determines when
-+** the xSync primitive is called and is relevant to all platforms.
-+**
-+** Numeric values associated with these states are OFF==1, NORMAL=2,
-+** and FULL=3.
-+*/
-+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-+SQLITE_PRIVATE void sqlite3PagerSetFlags(
-+  Pager *pPager,        /* The pager to set safety level for */
-+  unsigned pgFlags      /* Various flags */
-+){
-+  unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
-+  assert( level>=1 && level<=3 );
-+  pPager->noSync =  (level==1 || pPager->tempFile) ?1:0;
-+  pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
-   if( pPager->noSync ){
--    assert( pPager->fullSync==0 );
--    assert( pPager->syncFlags==0 );
--    assert( pPager->walSyncFlags==0 );
--    assert( pPager->ckptSyncFlags==0 );
-+    pPager->syncFlags = 0;
-+    pPager->ckptSyncFlags = 0;
-+  }else if( pgFlags & PAGER_FULLFSYNC ){
-+    pPager->syncFlags = SQLITE_SYNC_FULL;
-+    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
-+  }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){
-+    pPager->syncFlags = SQLITE_SYNC_NORMAL;
-+    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
-   }else{
--    pPager->fullSync = 1;
-     pPager->syncFlags = SQLITE_SYNC_NORMAL;
--    pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS;
-     pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
-   }
--  /* pPager->pFirst = 0; */
--  /* pPager->pFirstSynced = 0; */
--  /* pPager->pLast = 0; */
--  pPager->nExtra = (u16)nExtra;
--  pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
--  assert( isOpen(pPager->fd) || tempFile );
--  setSectorSize(pPager);
--  if( !useJournal ){
--    pPager->journalMode = PAGER_JOURNALMODE_OFF;
--  }else if( memDb ){
--    pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
-+  pPager->walSyncFlags = pPager->syncFlags;
-+  if( pPager->fullSync ){
-+    pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
-+  }
-+  if( pgFlags & PAGER_CACHESPILL ){
-+    pPager->doNotSpill &= ~SPILLFLAG_OFF;
-+  }else{
-+    pPager->doNotSpill |= SPILLFLAG_OFF;
-   }
--  /* pPager->xBusyHandler = 0; */
--  /* pPager->pBusyHandlerArg = 0; */
--  pPager->xReiniter = xReinit;
--  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
--  /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
--
--  *ppPager = pPager;
--  return SQLITE_OK;
- }
-+#endif
- 
++static int sqlite3Fts5IndexSync(Fts5Index *p){
++  assert( p->rc==SQLITE_OK );
++  fts5IndexFlush(p);
++  fts5CloseReader(p);
++  return fts5IndexReturn(p);
++}
++
 +/*
-+** The following global variable is incremented whenever the library
-+** attempts to open a temporary file.  This information is used for
-+** testing and analysis only.  
++** Discard any data stored in the in-memory hash tables. Do not write it
++** to the database. Additionally, assume that the contents of the %_data
++** table may have changed on disk. So any in-memory caches of %_data 
++** records must be invalidated.
 +*/
-+#ifdef SQLITE_TEST
-+SQLITE_API int sqlite3_opentemp_count = 0;
-+#endif
- 
--/* Verify that the database file has not be deleted or renamed out from
--** under the pager.  Return SQLITE_OK if the database is still were it ought
--** to be on disk.  Return non-zero (SQLITE_READONLY_DBMOVED or some other error
--** code from sqlite3OsAccess()) if the database has gone missing.
++static int sqlite3Fts5IndexRollback(Fts5Index *p){
++  fts5CloseReader(p);
++  fts5IndexDiscardData(p);
++  fts5StructureInvalidate(p);
++  /* assert( p->rc==SQLITE_OK ); */
++  return SQLITE_OK;
++}
++
 +/*
-+** Open a temporary file.
-+**
-+** Write the file descriptor into *pFile. Return SQLITE_OK on success 
-+** or some other error code if we fail. The OS will automatically 
-+** delete the temporary file when it is closed.
-+**
-+** The flags passed to the VFS layer xOpen() call are those specified
-+** by parameter vfsFlags ORed with the following:
-+**
-+**     SQLITE_OPEN_READWRITE
-+**     SQLITE_OPEN_CREATE
-+**     SQLITE_OPEN_EXCLUSIVE
-+**     SQLITE_OPEN_DELETEONCLOSE
- */
--static int databaseIsUnmoved(Pager *pPager){
--  int bHasMoved = 0;
--  int rc;
-+static int pagerOpentemp(
-+  Pager *pPager,        /* The pager object */
-+  sqlite3_file *pFile,  /* Write the file descriptor here */
-+  int vfsFlags          /* Flags passed through to the VFS */
-+){
-+  int rc;               /* Return code */
- 
--  if( pPager->tempFile ) return SQLITE_OK;
--  if( pPager->dbSize==0 ) return SQLITE_OK;
--  assert( pPager->zFilename && pPager->zFilename[0] );
--  rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
--  if( rc==SQLITE_NOTFOUND ){
--    /* If the HAS_MOVED file-control is unimplemented, assume that the file
--    ** has not been moved.  That is the historical behavior of SQLite: prior to
--    ** version 3.8.3, it never checked */
--    rc = SQLITE_OK;
--  }else if( rc==SQLITE_OK && bHasMoved ){
--    rc = SQLITE_READONLY_DBMOVED;
--  }
-+#ifdef SQLITE_TEST
-+  sqlite3_opentemp_count++;  /* Used for testing and analysis only */
-+#endif
++** The %_data table is completely empty when this function is called. This
++** function populates it with the initial structure objects for each index,
++** and the initial version of the "averages" record (a zero-byte blob).
++*/
++static int sqlite3Fts5IndexReinit(Fts5Index *p){
++  Fts5Structure s;
++  fts5StructureInvalidate(p);
++  memset(&s, 0, sizeof(Fts5Structure));
++  fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
++  fts5StructureWrite(p, &s);
++  return fts5IndexReturn(p);
++}
 +
-+  vfsFlags |=  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
-+            SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
-+  rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0);
-+  assert( rc!=SQLITE_OK || isOpen(pFile) );
-   return rc;
- }
- 
--
- /*
--** This function is called after transitioning from PAGER_UNLOCK to
--** PAGER_SHARED state. It tests if there is a hot journal present in
--** the file-system for the given pager. A hot journal is one that 
--** needs to be played back. According to this function, a hot-journal
--** file exists if the following criteria are met:
--**
--**   * The journal file exists in the file system, and
--**   * No process holds a RESERVED or greater lock on the database file, and
--**   * The database file itself is greater than 0 bytes in size, and
--**   * The first byte of the journal file exists and is not 0x00.
-+** Set the busy handler function.
- **
--** If the current size of the database file is 0 but a journal file
--** exists, that is probably an old journal left over from a prior
--** database with the same name. In this case the journal file is
--** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK
--** is returned.
-+** The pager invokes the busy-handler if sqlite3OsLock() returns 
-+** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock,
-+** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE 
-+** lock. It does *not* invoke the busy handler when upgrading from
-+** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE
-+** (which occurs during hot-journal rollback). Summary:
- **
--** This routine does not check if there is a master journal filename
--** at the end of the file. If there is, and that master journal file
--** does not exist, then the journal file is not really hot. In this
--** case this routine will return a false-positive. The pager_playback()
--** routine will discover that the journal file is not really hot and 
--** will not roll it back. 
-+**   Transition                        | Invokes xBusyHandler
-+**   --------------------------------------------------------
-+**   NO_LOCK       -> SHARED_LOCK      | Yes
-+**   SHARED_LOCK   -> RESERVED_LOCK    | No
-+**   SHARED_LOCK   -> EXCLUSIVE_LOCK   | No
-+**   RESERVED_LOCK -> EXCLUSIVE_LOCK   | Yes
- **
--** If a hot-journal file is found to exist, *pExists is set to 1 and 
--** SQLITE_OK returned. If no hot-journal file is present, *pExists is
--** set to 0 and SQLITE_OK returned. If an IO error occurs while trying
--** to determine whether or not a hot-journal file exists, the IO error
--** code is returned and the value of *pExists is undefined.
-+** If the busy-handler callback returns non-zero, the lock is 
-+** retried. If it returns zero, then the SQLITE_BUSY error is
-+** returned to the caller of the pager API function.
- */
--static int hasHotJournal(Pager *pPager, int *pExists){
--  sqlite3_vfs * const pVfs = pPager->pVfs;
--  int rc = SQLITE_OK;           /* Return code */
--  int exists = 1;               /* True if a journal file is present */
--  int jrnlOpen = !!isOpen(pPager->jfd);
--
--  assert( pPager->useJournal );
--  assert( isOpen(pPager->fd) );
--  assert( pPager->eState==PAGER_OPEN );
--
--  assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) &
--    SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
--  ));
--
--  *pExists = 0;
--  if( !jrnlOpen ){
--    rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
--  }
--  if( rc==SQLITE_OK && exists ){
--    int locked = 0;             /* True if some process holds a RESERVED lock */
--
--    /* Race condition here:  Another process might have been holding the
--    ** the RESERVED lock and have a journal open at the sqlite3OsAccess() 
--    ** call above, but then delete the journal and drop the lock before
--    ** we get to the following sqlite3OsCheckReservedLock() call.  If that
--    ** is the case, this routine might think there is a hot journal when
--    ** in fact there is none.  This results in a false-positive which will
--    ** be dealt with by the playback routine.  Ticket #3883.
--    */
--    rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
--    if( rc==SQLITE_OK && !locked ){
--      Pgno nPage;                 /* Number of pages in database file */
-+SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(
-+  Pager *pPager,                       /* Pager object */
-+  int (*xBusyHandler)(void *),         /* Pointer to busy-handler function */
-+  void *pBusyHandlerArg                /* Argument to pass to xBusyHandler */
++/*
++** Open a new Fts5Index handle. If the bCreate argument is true, create
++** and initialize the underlying %_data table.
++**
++** If successful, set *pp to point to the new object and return SQLITE_OK.
++** Otherwise, set *pp to NULL and return an SQLite error code.
++*/
++static int sqlite3Fts5IndexOpen(
++  Fts5Config *pConfig, 
++  int bCreate, 
++  Fts5Index **pp,
++  char **pzErr
 +){
-+  pPager->xBusyHandler = xBusyHandler;
-+  pPager->pBusyHandlerArg = pBusyHandlerArg;
- 
--      rc = pagerPagecount(pPager, &nPage);
--      if( rc==SQLITE_OK ){
--        /* If the database is zero pages in size, that means that either (1) the
--        ** journal is a remnant from a prior database with the same name where
--        ** the database file but not the journal was deleted, or (2) the initial
--        ** transaction that populates a new database is being rolled back.
--        ** In either case, the journal file can be deleted.  However, take care
--        ** not to delete the journal file if it is already open due to
--        ** journal_mode=PERSIST.
--        */
--        if( nPage==0 && !jrnlOpen ){
--          sqlite3BeginBenignMalloc();
--          if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
--            sqlite3OsDelete(pVfs, pPager->zJournal, 0);
--            if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
--          }
--          sqlite3EndBenignMalloc();
--        }else{
--          /* The journal file exists and no other connection has a reserved
--          ** or greater lock on the database file. Now check that there is
--          ** at least one non-zero bytes at the start of the journal file.
--          ** If there is, then we consider this journal to be hot. If not, 
--          ** it can be ignored.
--          */
--          if( !jrnlOpen ){
--            int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL;
--            rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f);
--          }
--          if( rc==SQLITE_OK ){
--            u8 first = 0;
--            rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0);
--            if( rc==SQLITE_IOERR_SHORT_READ ){
--              rc = SQLITE_OK;
--            }
--            if( !jrnlOpen ){
--              sqlite3OsClose(pPager->jfd);
--            }
--            *pExists = (first!=0);
--          }else if( rc==SQLITE_CANTOPEN ){
--            /* If we cannot open the rollback journal file in order to see if
--            ** it has a zero header, that might be due to an I/O error, or
--            ** it might be due to the race condition described above and in
--            ** ticket #3883.  Either way, assume that the journal is hot.
--            ** This might be a false positive.  But if it is, then the
--            ** automatic journal playback and recovery mechanism will deal
--            ** with it under an EXCLUSIVE lock where we do not need to
--            ** worry so much with race conditions.
--            */
--            *pExists = 1;
--            rc = SQLITE_OK;
--          }
--        }
--      }
--    }
-+  if( isOpen(pPager->fd) ){
-+    void **ap = (void **)&pPager->xBusyHandler;
-+    assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
-+    assert( ap[1]==pBusyHandlerArg );
-+    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
-   }
--
--  return rc;
- }
- 
- /*
--** This function is called to obtain a shared lock on the database file.
--** It is illegal to call sqlite3PagerAcquire() until after this function
--** has been successfully called. If a shared-lock is already held when
--** this function is called, it is a no-op.
-+** Change the page size used by the Pager object. The new page size 
-+** is passed in *pPageSize.
- **
--** The following operations are also performed by this function.
-+** If the pager is in the error state when this function is called, it
-+** is a no-op. The value returned is the error state error code (i.e. 
-+** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL).
- **
--**   1) If the pager is currently in PAGER_OPEN state (no lock held
--**      on the database file), then an attempt is made to obtain a
--**      SHARED lock on the database file. Immediately after obtaining
--**      the SHARED lock, the file-system is checked for a hot-journal,
--**      which is played back if present. Following any hot-journal 
--**      rollback, the contents of the cache are validated by checking
--**      the 'change-counter' field of the database file header and
--**      discarded if they are found to be invalid.
-+** Otherwise, if all of the following are true:
- **
--**   2) If the pager is running in exclusive-mode, and there are currently
--**      no outstanding references to any pages, and is in the error state,
--**      then an attempt is made to clear the error state by discarding
--**      the contents of the page cache and rolling back any open journal
--**      file.
-+**   * the new page size (value of *pPageSize) is valid (a power 
-+**     of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and
- **
--** If everything is successful, SQLITE_OK is returned. If an IO error 
--** occurs while locking the database, checking for a hot-journal file or 
--** rolling back a journal file, the IO error code is returned.
-+**   * there are no outstanding page references, and
-+**
-+**   * the database is either not an in-memory database or it is
-+**     an in-memory database that currently consists of zero pages.
-+**
-+** then the pager object page size is set to *pPageSize.
-+**
-+** If the page size is changed, then this function uses sqlite3PagerMalloc() 
-+** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt 
-+** fails, SQLITE_NOMEM is returned and the page size remains unchanged. 
-+** In all other cases, SQLITE_OK is returned.
-+**
-+** If the page size is not changed, either because one of the enumerated
-+** conditions above is not true, the pager was in error state when this
-+** function was called, or because the memory allocation attempt failed, 
-+** then *pPageSize is set to the old, retained page size before returning.
- */
--SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
--  int rc = SQLITE_OK;                /* Return code */
-+SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
 +  int rc = SQLITE_OK;
- 
--  /* This routine is only called from b-tree and only when there are no
--  ** outstanding pages. This implies that the pager state should either
--  ** be OPEN or READER. READER is only possible if the pager is or was in 
--  ** exclusive access mode.
-+  /* It is not possible to do a full assert_pager_state() here, as this
-+  ** function may be called from within PagerOpen(), before the state
-+  ** of the Pager object is internally consistent.
-+  **
-+  ** At one point this function returned an error if the pager was in 
-+  ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that
-+  ** there is at least one outstanding page reference, this function
-+  ** is a no-op for that case anyhow.
-   */
--  assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
--  assert( assert_pager_state(pPager) );
--  assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
--  if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
--
--  if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
--    int bHotJournal = 1;          /* True if there exists a hot journal-file */
- 
--    assert( !MEMDB );
-+  u32 pageSize = *pPageSize;
-+  assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
-+  if( (pPager->memDb==0 || pPager->dbSize==0)
-+   && sqlite3PcacheRefCount(pPager->pPCache)==0 
-+   && pageSize && pageSize!=(u32)pPager->pageSize 
-+  ){
-+    char *pNew = NULL;             /* New temp space */
-+    i64 nByte = 0;
- 
--    rc = pager_wait_on_lock(pPager, SHARED_LOCK);
--    if( rc!=SQLITE_OK ){
--      assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK );
--      goto failed;
-+    if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){
-+      rc = sqlite3OsFileSize(pPager->fd, &nByte);
++  Fts5Index *p;                   /* New object */
++
++  *pp = p = (Fts5Index*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Index));
++  if( rc==SQLITE_OK ){
++    p->pConfig = pConfig;
++    p->nWorkUnit = FTS5_WORK_UNIT;
++    p->zDataTbl = sqlite3Fts5Mprintf(&rc, "%s_data", pConfig->zName);
++    if( p->zDataTbl && bCreate ){
++      rc = sqlite3Fts5CreateTable(
++          pConfig, "data", "id INTEGER PRIMARY KEY, block BLOB", 0, pzErr
++      );
++      if( rc==SQLITE_OK ){
++        rc = sqlite3Fts5CreateTable(pConfig, "idx", 
++            "segid, term, pgno, PRIMARY KEY(segid, term)", 
++            1, pzErr
++        );
++      }
++      if( rc==SQLITE_OK ){
++        rc = sqlite3Fts5IndexReinit(p);
++      }
 +    }
-+    if( rc==SQLITE_OK ){
-+      pNew = (char *)sqlite3PageMalloc(pageSize);
-+      if( !pNew ) rc = SQLITE_NOMEM;
-     }
- 
--    /* If a journal file exists, and there is no RESERVED lock on the
--    ** database file, then it either needs to be played back or deleted.
--    */
--    if( pPager->eLock<=SHARED_LOCK ){
--      rc = hasHotJournal(pPager, &bHotJournal);
-+    if( rc==SQLITE_OK ){
-+      pager_reset(pPager);
-+      rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
-     }
--    if( rc!=SQLITE_OK ){
--      goto failed;
-+    if( rc==SQLITE_OK ){
-+      sqlite3PageFree(pPager->pTmpSpace);
-+      pPager->pTmpSpace = pNew;
-+      pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
-+      pPager->pageSize = pageSize;
-+    }else{
-+      sqlite3PageFree(pNew);
-     }
--    if( bHotJournal ){
--      if( pPager->readOnly ){
--        rc = SQLITE_READONLY_ROLLBACK;
--        goto failed;
--      }
 +  }
- 
--      /* Get an EXCLUSIVE lock on the database file. At this point it is
--      ** important that a RESERVED lock is not obtained on the way to the
--      ** EXCLUSIVE lock. If it were, another process might open the
--      ** database file, detect the RESERVED lock, and conclude that the
--      ** database is safe to read while this process is still rolling the 
--      ** hot-journal back.
--      ** 
--      ** Because the intermediate RESERVED lock is not requested, any
--      ** other process attempting to access the database file will get to 
--      ** this point in the code and fail to obtain its own EXCLUSIVE lock 
--      ** on the database file.
--      **
--      ** Unless the pager is in locking_mode=exclusive mode, the lock is
--      ** downgraded to SHARED_LOCK before this function returns.
--      */
--      rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
--      if( rc!=SQLITE_OK ){
--        goto failed;
--      }
-- 
--      /* If it is not already open and the file exists on disk, open the 
--      ** journal for read/write access. Write access is required because 
--      ** in exclusive-access mode the file descriptor will be kept open 
--      ** and possibly used for a transaction later on. Also, write-access 
--      ** is usually required to finalize the journal in journal_mode=persist 
--      ** mode (and also for journal_mode=truncate on some systems).
--      **
--      ** If the journal does not exist, it usually means that some 
--      ** other connection managed to get in and roll it back before 
--      ** this connection obtained the exclusive lock above. Or, it 
--      ** may mean that the pager was in the error-state when this
--      ** function was called and the journal file does not exist.
--      */
--      if( !isOpen(pPager->jfd) ){
--        sqlite3_vfs * const pVfs = pPager->pVfs;
--        int bExists;              /* True if journal file exists */
--        rc = sqlite3OsAccess(
--            pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists);
--        if( rc==SQLITE_OK && bExists ){
--          int fout = 0;
--          int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
--          assert( !pPager->tempFile );
--          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
--          assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
--          if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
--            rc = SQLITE_CANTOPEN_BKPT;
--            sqlite3OsClose(pPager->jfd);
--          }
--        }
--      }
-- 
--      /* Playback and delete the journal.  Drop the database write
--      ** lock and reacquire the read lock. Purge the cache before
--      ** playing back the hot-journal so that we don't end up with
--      ** an inconsistent cache.  Sync the hot journal before playing
--      ** it back since the process that crashed and left the hot journal
--      ** probably did not sync it and we are required to always sync
--      ** the journal before playing it back.
--      */
--      if( isOpen(pPager->jfd) ){
--        assert( rc==SQLITE_OK );
--        rc = pagerSyncHotJournal(pPager);
--        if( rc==SQLITE_OK ){
--          rc = pager_playback(pPager, 1);
--          pPager->eState = PAGER_OPEN;
--        }
--      }else if( !pPager->exclusiveMode ){
--        pagerUnlockDb(pPager, SHARED_LOCK);
--      }
-+  *pPageSize = pPager->pageSize;
-+  if( rc==SQLITE_OK ){
-+    if( nReserve<0 ) nReserve = pPager->nReserve;
-+    assert( nReserve>=0 && nReserve<1000 );
-+    pPager->nReserve = (i16)nReserve;
-+    pagerReportSize(pPager);
-+    pagerFixMaplimit(pPager);
++
++  assert( rc!=SQLITE_OK || p->rc==SQLITE_OK );
++  if( rc ){
++    sqlite3Fts5IndexClose(p);
++    *pp = 0;
 +  }
 +  return rc;
 +}
- 
--      if( rc!=SQLITE_OK ){
--        /* This branch is taken if an error occurs while trying to open
--        ** or roll back a hot-journal while holding an EXCLUSIVE lock. The
--        ** pager_unlock() routine will be called before returning to unlock
--        ** the file. If the unlock attempt fails, then Pager.eLock must be
--        ** set to UNKNOWN_LOCK (see the comment above the #define for 
--        ** UNKNOWN_LOCK above for an explanation). 
--        **
--        ** In order to get pager_unlock() to do this, set Pager.eState to
--        ** PAGER_ERROR now. This is not actually counted as a transition
--        ** to ERROR state in the state diagram at the top of this file,
--        ** since we know that the same call to pager_unlock() will very
--        ** shortly transition the pager object to the OPEN state. Calling
--        ** assert_pager_state() would fail now, as it should not be possible
--        ** to be in ERROR state when there are zero outstanding page 
--        ** references.
--        */
--        pager_error(pPager, rc);
--        goto failed;
--      }
++
 +/*
-+** Return a pointer to the "temporary page" buffer held internally
-+** by the pager.  This is a buffer that is big enough to hold the
-+** entire content of a database page.  This buffer is used internally
-+** during rollback and will be overwritten whenever a rollback
-+** occurs.  But other modules are free to use it too, as long as
-+** no rollbacks are happening.
++** Close a handle opened by an earlier call to sqlite3Fts5IndexOpen().
 +*/
-+SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager *pPager){
-+  return pPager->pTmpSpace;
++static int sqlite3Fts5IndexClose(Fts5Index *p){
++  int rc = SQLITE_OK;
++  if( p ){
++    assert( p->pReader==0 );
++    fts5StructureInvalidate(p);
++    sqlite3_finalize(p->pWriter);
++    sqlite3_finalize(p->pDeleter);
++    sqlite3_finalize(p->pIdxWriter);
++    sqlite3_finalize(p->pIdxDeleter);
++    sqlite3_finalize(p->pIdxSelect);
++    sqlite3_finalize(p->pDataVersion);
++    sqlite3Fts5HashFree(p->pHash);
++    sqlite3_free(p->zDataTbl);
++    sqlite3_free(p);
++  }
++  return rc;
 +}
- 
--      assert( pPager->eState==PAGER_OPEN );
--      assert( (pPager->eLock==SHARED_LOCK)
--           || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
--      );
++
 +/*
-+** Attempt to set the maximum database page count if mxPage is positive. 
-+** Make no changes if mxPage is zero or negative.  And never reduce the
-+** maximum page count below the current size of the database.
-+**
-+** Regardless of mxPage, return the current maximum page count.
++** Argument p points to a buffer containing utf-8 text that is n bytes in 
++** size. Return the number of bytes in the nChar character prefix of the
++** buffer, or 0 if there are less than nChar characters in total.
 +*/
-+SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
-+  if( mxPage>0 ){
-+    pPager->mxPgno = mxPage;
++static int sqlite3Fts5IndexCharlenToBytelen(
++  const char *p, 
++  int nByte, 
++  int nChar
++){
++  int n = 0;
++  int i;
++  for(i=0; i<nChar; i++){
++    if( n>=nByte ) return 0;      /* Input contains fewer than nChar chars */
++    if( (unsigned char)p[n++]>=0xc0 ){
++      while( (p[n] & 0xc0)==0x80 ) n++;
++    }
 +  }
-+  assert( pPager->eState!=PAGER_OPEN );      /* Called only by OP_MaxPgcnt */
-+  assert( pPager->mxPgno>=pPager->dbSize );  /* OP_MaxPgcnt enforces this */
-+  return pPager->mxPgno;
++  return n;
 +}
 +
 +/*
-+** The following set of routines are used to disable the simulated
-+** I/O error mechanism.  These routines are used to avoid simulated
-+** errors in places where we do not care about errors.
-+**
-+** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops
-+** and generate no code.
++** pIn is a UTF-8 encoded string, nIn bytes in size. Return the number of
++** unicode characters in the string.
 +*/
-+#ifdef SQLITE_TEST
-+SQLITE_API extern int sqlite3_io_error_pending;
-+SQLITE_API extern int sqlite3_io_error_hit;
-+static int saved_cnt;
-+void disable_simulated_io_errors(void){
-+  saved_cnt = sqlite3_io_error_pending;
-+  sqlite3_io_error_pending = -1;
-+}
-+void enable_simulated_io_errors(void){
-+  sqlite3_io_error_pending = saved_cnt;
++static int fts5IndexCharlen(const char *pIn, int nIn){
++  int nChar = 0;            
++  int i = 0;
++  while( i<nIn ){
++    if( (unsigned char)pIn[i++]>=0xc0 ){
++      while( i<nIn && (pIn[i] & 0xc0)==0x80 ) i++;
++    }
++    nChar++;
++  }
++  return nChar;
 +}
-+#else
-+# define disable_simulated_io_errors()
-+# define enable_simulated_io_errors()
-+#endif
 +
 +/*
-+** Read the first N bytes from the beginning of the file into memory
-+** that pDest points to. 
++** Insert or remove data to or from the index. Each time a document is 
++** added to or removed from the index, this function is called one or more
++** times.
 +**
-+** If the pager was opened on a transient file (zFilename==""), or
-+** opened on a file less than N bytes in size, the output buffer is
-+** zeroed and SQLITE_OK returned. The rationale for this is that this 
-+** function is used to read database headers, and a new transient or
-+** zero sized database has a header than consists entirely of zeroes.
-+**
-+** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered,
-+** the error code is returned to the caller and the contents of the
-+** output buffer undefined.
++** For an insert, it must be called once for each token in the new document.
++** If the operation is a delete, it must be called (at least) once for each
++** unique token in the document with an iCol value less than zero. The iPos
++** argument is ignored for a delete.
 +*/
-+SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
-+  int rc = SQLITE_OK;
-+  memset(pDest, 0, N);
-+  assert( isOpen(pPager->fd) || pPager->tempFile );
++static int sqlite3Fts5IndexWrite(
++  Fts5Index *p,                   /* Index to write to */
++  int iCol,                       /* Column token appears in (-ve -> delete) */
++  int iPos,                       /* Position of token within column */
++  const char *pToken, int nToken  /* Token to add or remove to or from index */
++){
++  int i;                          /* Used to iterate through indexes */
++  int rc = SQLITE_OK;             /* Return code */
++  Fts5Config *pConfig = p->pConfig;
 +
-+  /* This routine is only called by btree immediately after creating
-+  ** the Pager object.  There has not been an opportunity to transition
-+  ** to WAL mode yet.
-+  */
-+  assert( !pagerUseWal(pPager) );
++  assert( p->rc==SQLITE_OK );
++  assert( (iCol<0)==p->bDelete );
 +
-+  if( isOpen(pPager->fd) ){
-+    IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
-+    rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
-+    if( rc==SQLITE_IOERR_SHORT_READ ){
-+      rc = SQLITE_OK;
-     }
++  /* Add the entry to the main terms index. */
++  rc = sqlite3Fts5HashWrite(
++      p->pHash, p->iWriteRowid, iCol, iPos, FTS5_MAIN_PREFIX, pToken, nToken
++  );
++
++  for(i=0; i<pConfig->nPrefix && rc==SQLITE_OK; i++){
++    const int nChar = pConfig->aPrefix[i];
++    int nByte = sqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar);
++    if( nByte ){
++      rc = sqlite3Fts5HashWrite(p->pHash, 
++          p->iWriteRowid, iCol, iPos, (char)(FTS5_MAIN_PREFIX+i+1), pToken,
++          nByte
++      );
++    }
 +  }
++
 +  return rc;
 +}
- 
--    if( !pPager->tempFile && pPager->hasBeenUsed ){
--      /* The shared-lock has just been acquired then check to
--      ** see if the database has been modified.  If the database has changed,
--      ** flush the cache.  The pPager->hasBeenUsed flag prevents this from
--      ** occurring on the very first access to a file, in order to save a
--      ** single unnecessary sqlite3OsRead() call at the start-up.
--      **
--      ** Database changes is detected by looking at 15 bytes beginning
--      ** at offset 24 into the file.  The first 4 of these 16 bytes are
--      ** a 32-bit counter that is incremented with each change.  The
--      ** other bytes change randomly with each file change when
--      ** a codec is in use.
--      ** 
--      ** There is a vanishingly small chance that a change will not be 
--      ** detected.  The chance of an undetected change is so small that
--      ** it can be neglected.
--      */
--      Pgno nPage = 0;
--      char dbFileVers[sizeof(pPager->dbFileVers)];
++
 +/*
-+** This function may only be called when a read-transaction is open on
-+** the pager. It returns the total number of pages in the database.
-+**
-+** However, if the file is between 1 and <page-size> bytes in size, then 
-+** this is considered a 1 page file.
++** Open a new iterator to iterate though all rowid that match the 
++** specified token or token prefix.
 +*/
-+SQLITE_PRIVATE void sqlite3PagerPagecount(Pager *pPager, int *pnPage){
-+  assert( pPager->eState>=PAGER_READER );
-+  assert( pPager->eState!=PAGER_WRITER_FINISHED );
-+  *pnPage = (int)pPager->dbSize;
++static int sqlite3Fts5IndexQuery(
++  Fts5Index *p,                   /* FTS index to query */
++  const char *pToken, int nToken, /* Token (or prefix) to query for */
++  int flags,                      /* Mask of FTS5INDEX_QUERY_X flags */
++  Fts5Colset *pColset,            /* Match these columns only */
++  Fts5IndexIter **ppIter          /* OUT: New iterator object */
++){
++  Fts5Config *pConfig = p->pConfig;
++  Fts5Iter *pRet = 0;
++  Fts5Buffer buf = {0, 0, 0};
++
++  /* If the QUERY_SCAN flag is set, all other flags must be clear. */
++  assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
++
++  if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
++    int iIdx = 0;                 /* Index to search */
++    if( nToken ) memcpy(&buf.p[1], pToken, nToken);
++
++    /* Figure out which index to search and set iIdx accordingly. If this
++    ** is a prefix query for which there is no prefix index, set iIdx to
++    ** greater than pConfig->nPrefix to indicate that the query will be
++    ** satisfied by scanning multiple terms in the main index.
++    **
++    ** If the QUERY_TEST_NOIDX flag was specified, then this must be a
++    ** prefix-query. Instead of using a prefix-index (if one exists), 
++    ** evaluate the prefix query using the main FTS index. This is used
++    ** for internal sanity checking by the integrity-check in debug 
++    ** mode only.  */
++#ifdef SQLITE_DEBUG
++    if( pConfig->bPrefixIndex==0 || (flags & FTS5INDEX_QUERY_TEST_NOIDX) ){
++      assert( flags & FTS5INDEX_QUERY_PREFIX );
++      iIdx = 1+pConfig->nPrefix;
++    }else
++#endif
++    if( flags & FTS5INDEX_QUERY_PREFIX ){
++      int nChar = fts5IndexCharlen(pToken, nToken);
++      for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){
++        if( pConfig->aPrefix[iIdx-1]==nChar ) break;
++      }
++    }
++
++    if( iIdx<=pConfig->nPrefix ){
++      /* Straight index lookup */
++      Fts5Structure *pStruct = fts5StructureRead(p);
++      buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
++      if( pStruct ){
++        fts5MultiIterNew(p, pStruct, flags | FTS5INDEX_QUERY_SKIPEMPTY, 
++            pColset, buf.p, nToken+1, -1, 0, &pRet
++        );
++        fts5StructureRelease(pStruct);
++      }
++    }else{
++      /* Scan multiple terms in the main index */
++      int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
++      buf.p[0] = FTS5_MAIN_PREFIX;
++      fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet);
++      assert( p->rc!=SQLITE_OK || pRet->pColset==0 );
++      fts5IterSetOutputCb(&p->rc, pRet);
++      if( p->rc==SQLITE_OK ){
++        Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
++        if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
++      }
++    }
++
++    if( p->rc ){
++      sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
++      pRet = 0;
++      fts5CloseReader(p);
++    }
++
++    *ppIter = &pRet->base;
++    sqlite3Fts5BufferFree(&buf);
++  }
++  return fts5IndexReturn(p);
 +}
- 
--      rc = pagerPagecount(pPager, &nPage);
--      if( rc ) goto failed;
- 
--      if( nPage>0 ){
--        IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
--        rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
--        if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
--          goto failed;
--        }
--      }else{
--        memset(dbFileVers, 0, sizeof(dbFileVers));
--      }
++
 +/*
-+** Try to obtain a lock of type locktype on the database file. If
-+** a similar or greater lock is already held, this function is a no-op
-+** (returning SQLITE_OK immediately).
-+**
-+** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke 
-+** the busy callback if the lock is currently not available. Repeat 
-+** until the busy callback returns false or until the attempt to 
-+** obtain the lock succeeds.
-+**
-+** Return SQLITE_OK on success and an error code if we cannot obtain
-+** the lock. If the lock is obtained successfully, set the Pager.state 
-+** variable to locktype before returning.
++** Return true if the iterator passed as the only argument is at EOF.
 +*/
-+static int pager_wait_on_lock(Pager *pPager, int locktype){
-+  int rc;                              /* Return code */
- 
--      if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
--        pager_reset(pPager);
-+  /* Check that this is either a no-op (because the requested lock is 
-+  ** already held), or one of the transitions that the busy-handler
-+  ** may be invoked during, according to the comment above
-+  ** sqlite3PagerSetBusyhandler().
-+  */
-+  assert( (pPager->eLock>=locktype)
-+       || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK)
-+       || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK)
-+  );
- 
--        /* Unmap the database file. It is possible that external processes
--        ** may have truncated the database file and then extended it back
--        ** to its original size while this process was not holding a lock.
--        ** In this case there may exist a Pager.pMap mapping that appears
--        ** to be the right size but is not actually valid. Avoid this
--        ** possibility by unmapping the db here. */
--        if( USEFETCH(pPager) ){
--          sqlite3OsUnfetch(pPager->fd, 0, 0);
--        }
--      }
--    }
-+  do {
-+    rc = pagerLockDb(pPager, locktype);
-+  }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) );
-+  return rc;
-+}
- 
--    /* If there is a WAL file in the file-system, open this database in WAL
--    ** mode. Otherwise, the following function call is a no-op.
--    */
--    rc = pagerOpenWalIfPresent(pPager);
--#ifndef SQLITE_OMIT_WAL
--    assert( pPager->pWal==0 || rc==SQLITE_OK );
 +/*
-+** Function assertTruncateConstraint(pPager) checks that one of the 
-+** following is true for all dirty pages currently in the page-cache:
-+**
-+**   a) The page number is less than or equal to the size of the 
-+**      current database image, in pages, OR
-+**
-+**   b) if the page content were written at this time, it would not
-+**      be necessary to write the current content out to the sub-journal
-+**      (as determined by function subjRequiresPage()).
-+**
-+** If the condition asserted by this function were not true, and the
-+** dirty page were to be discarded from the cache via the pagerStress()
-+** routine, pagerStress() would not write the current page content to
-+** the database file. If a savepoint transaction were rolled back after
-+** this happened, the correct behavior would be to restore the current
-+** content of the page. However, since this content is not present in either
-+** the database file or the portion of the rollback journal and 
-+** sub-journal rolled back the content could not be restored and the
-+** database image would become corrupt. It is therefore fortunate that 
-+** this circumstance cannot arise.
++** Move to the next matching rowid. 
 +*/
-+#if defined(SQLITE_DEBUG)
-+static void assertTruncateConstraintCb(PgHdr *pPg){
-+  assert( pPg->flags&PGHDR_DIRTY );
-+  assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize );
++static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
++  Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
++  assert( pIter->pIndex->rc==SQLITE_OK );
++  fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
++  return fts5IndexReturn(pIter->pIndex);
 +}
-+static void assertTruncateConstraint(Pager *pPager){
-+  sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb);
-+}
-+#else
-+# define assertTruncateConstraint(pPager)
- #endif
 +
 +/*
-+** Truncate the in-memory database file image to nPage pages. This 
-+** function does not actually modify the database file on disk. It 
-+** just sets the internal state of the pager object so that the 
-+** truncation will be done when the current transaction is committed.
-+**
-+** This function is only called right before committing a transaction.
-+** Once this function has been called, the transaction must either be
-+** rolled back or committed. It is not safe to call this function and
-+** then continue writing to the database.
++** Move to the next matching term/rowid. Used by the fts5vocab module.
 +*/
-+SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
-+  assert( pPager->dbSize>=nPage );
-+  assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
-+  pPager->dbSize = nPage;
++static int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){
++  Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
++  Fts5Index *p = pIter->pIndex;
++
++  assert( pIter->pIndex->rc==SQLITE_OK );
++
++  fts5MultiIterNext(p, pIter, 0, 0);
++  if( p->rc==SQLITE_OK ){
++    Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
++    if( pSeg->pLeaf && pSeg->term.p[0]!=FTS5_MAIN_PREFIX ){
++      fts5DataRelease(pSeg->pLeaf);
++      pSeg->pLeaf = 0;
++      pIter->base.bEof = 1;
++    }
++  }
++
++  return fts5IndexReturn(pIter->pIndex);
++}
 +
-+  /* At one point the code here called assertTruncateConstraint() to
-+  ** ensure that all pages being truncated away by this operation are,
-+  ** if one or more savepoints are open, present in the savepoint 
-+  ** journal so that they can be restored if the savepoint is rolled
-+  ** back. This is no longer necessary as this function is now only
-+  ** called right before committing a transaction. So although the 
-+  ** Pager object may still have open savepoints (Pager.nSavepoint!=0), 
-+  ** they cannot be rolled back. So the assertTruncateConstraint() call
-+  ** is no longer correct. */
++/*
++** Move to the next matching rowid that occurs at or after iMatch. The
++** definition of "at or after" depends on whether this iterator iterates
++** in ascending or descending rowid order.
++*/
++static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){
++  Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
++  fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
++  return fts5IndexReturn(pIter->pIndex);
 +}
 +
++/*
++** Return the current term.
++*/
++static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){
++  int n;
++  const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
++  *pn = n-1;
++  return &z[1];
++}
 +
 +/*
-+** This function is called before attempting a hot-journal rollback. It
-+** syncs the journal file to disk, then sets pPager->journalHdr to the
-+** size of the journal file so that the pager_playback() routine knows
-+** that the entire journal file has been synced.
-+**
-+** Syncing a hot-journal to disk before attempting to roll it back ensures 
-+** that if a power-failure occurs during the rollback, the process that
-+** attempts rollback following system recovery sees the same journal
-+** content as this process.
-+**
-+** If everything goes as planned, SQLITE_OK is returned. Otherwise, 
-+** an SQLite error code.
++** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
 +*/
-+static int pagerSyncHotJournal(Pager *pPager){
-+  int rc = SQLITE_OK;
-+  if( !pPager->noSync ){
-+    rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL);
-+  }
-+  if( rc==SQLITE_OK ){
-+    rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr);
++static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
++  if( pIndexIter ){
++    Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
++    Fts5Index *pIndex = pIter->pIndex;
++    fts5MultiIterFree(pIter);
++    fts5CloseReader(pIndex);
 +  }
-+  return rc;
 +}
 +
 +/*
-+** Obtain a reference to a memory mapped page object for page number pgno. 
-+** The new object will use the pointer pData, obtained from xFetch().
-+** If successful, set *ppPage to point to the new page reference
-+** and return SQLITE_OK. Otherwise, return an SQLite error code and set
-+** *ppPage to zero.
++** Read and decode the "averages" record from the database. 
 +**
-+** Page references obtained by calling this function should be released
-+** by calling pagerReleaseMapPage().
++** Parameter anSize must point to an array of size nCol, where nCol is
++** the number of user defined columns in the FTS table.
 +*/
-+static int pagerAcquireMapPage(
-+  Pager *pPager,                  /* Pager object */
-+  Pgno pgno,                      /* Page number */
-+  void *pData,                    /* xFetch()'d data for this page */
-+  PgHdr **ppPage                  /* OUT: Acquired page object */
-+){
-+  PgHdr *p;                       /* Memory mapped page to return */
-+  
-+  if( pPager->pMmapFreelist ){
-+    *ppPage = p = pPager->pMmapFreelist;
-+    pPager->pMmapFreelist = p->pDirty;
-+    p->pDirty = 0;
-+    memset(p->pExtra, 0, pPager->nExtra);
-+  }else{
-+    *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
-+    if( p==0 ){
-+      sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
-+      return SQLITE_NOMEM;
++static int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize){
++  int nCol = p->pConfig->nCol;
++  Fts5Data *pData;
++
++  *pnRow = 0;
++  memset(anSize, 0, sizeof(i64) * nCol);
++  pData = fts5DataRead(p, FTS5_AVERAGES_ROWID);
++  if( p->rc==SQLITE_OK && pData->nn ){
++    int i = 0;
++    int iCol;
++    i += fts5GetVarint(&pData->p[i], (u64*)pnRow);
++    for(iCol=0; i<pData->nn && iCol<nCol; iCol++){
++      i += fts5GetVarint(&pData->p[i], (u64*)&anSize[iCol]);
 +    }
-+    p->pExtra = (void *)&p[1];
-+    p->flags = PGHDR_MMAP;
-+    p->nRef = 1;
-+    p->pPager = pPager;
-   }
- 
--  if( pagerUseWal(pPager) ){
--    assert( rc==SQLITE_OK );
--    rc = pagerBeginReadTransaction(pPager);
--  }
-+  assert( p->pExtra==(void *)&p[1] );
-+  assert( p->pPage==0 );
-+  assert( p->flags==PGHDR_MMAP );
-+  assert( p->pPager==pPager );
-+  assert( p->nRef==1 );
- 
--  if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
--    rc = pagerPagecount(pPager, &pPager->dbSize);
--  }
-+  p->pgno = pgno;
-+  p->pData = pData;
-+  pPager->nMmapOut++;
- 
-- failed:
--  if( rc!=SQLITE_OK ){
--    assert( !MEMDB );
--    pager_unlock(pPager);
--    assert( pPager->eState==PAGER_OPEN );
--  }else{
--    pPager->eState = PAGER_READER;
--  }
--  return rc;
-+  return SQLITE_OK;
- }
- 
- /*
--** If the reference count has reached zero, rollback any active
--** transaction and unlock the pager.
--**
--** Except, in locking_mode=EXCLUSIVE when there is nothing to in
--** the rollback journal, the unlock is not performed and there is
--** nothing to rollback, so this routine is a no-op.
--*/ 
--static void pagerUnlockIfUnused(Pager *pPager){
--  if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
--    pagerUnlockAndRollback(pPager);
-+** Release a reference to page pPg. pPg must have been returned by an 
-+** earlier call to pagerAcquireMapPage().
-+*/
-+static void pagerReleaseMapPage(PgHdr *pPg){
-+  Pager *pPager = pPg->pPager;
-+  pPager->nMmapOut--;
-+  pPg->pDirty = pPager->pMmapFreelist;
-+  pPager->pMmapFreelist = pPg;
++  }
 +
-+  assert( pPager->fd->pMethods->iVersion>=3 );
-+  sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData);
++  fts5DataRelease(pData);
++  return fts5IndexReturn(p);
 +}
 +
 +/*
-+** Free all PgHdr objects stored in the Pager.pMmapFreelist list.
++** Replace the current "averages" record with the contents of the buffer 
++** supplied as the second argument.
 +*/
-+static void pagerFreeMapHdrs(Pager *pPager){
-+  PgHdr *p;
-+  PgHdr *pNext;
-+  for(p=pPager->pMmapFreelist; p; p=pNext){
-+    pNext = p->pDirty;
-+    sqlite3_free(p);
-   }
- }
- 
++static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8 *pData, int nData){
++  assert( p->rc==SQLITE_OK );
++  fts5DataWrite(p, FTS5_AVERAGES_ROWID, pData, nData);
++  return fts5IndexReturn(p);
++}
 +
- /*
--** Acquire a reference to page number pgno in pager pPager (a page
--** reference has type DbPage*). If the requested reference is 
--** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
--**
--** If the requested page is already in the cache, it is returned. 
--** Otherwise, a new page object is allocated and populated with data
--** read from the database file. In some cases, the pcache module may
--** choose not to allocate a new page object and may reuse an existing
--** object with no outstanding references.
--**
--** The extra data appended to a page is always initialized to zeros the 
--** first time a page is loaded into memory. If the page requested is 
--** already in the cache when this function is called, then the extra
--** data is left as it was when the page object was last used.
--**
--** If the database image is smaller than the requested page or if a 
--** non-zero value is passed as the noContent parameter and the 
--** requested page is not already stored in the cache, then no 
--** actual disk read occurs. In this case the memory image of the 
--** page is initialized to all zeros. 
--**
--** If noContent is true, it means that we do not care about the contents
--** of the page. This occurs in two scenarios:
--**
--**   a) When reading a free-list leaf page from the database, and
--**
--**   b) When a savepoint is being rolled back and we need to load
--**      a new page into the cache to be filled with the data read
--**      from the savepoint journal.
--**
--** If noContent is true, then the data returned is zeroed instead of
--** being read from the database. Additionally, the bits corresponding
--** to pgno in Pager.pInJournal (bitvec of pages already written to the
--** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
--** savepoints are set. This means if the page is made writable at any
--** point in the future, using a call to sqlite3PagerWrite(), its contents
--** will not be journaled. This saves IO.
-+** Shutdown the page cache.  Free all memory and close all files.
- **
--** The acquisition might fail for several reasons.  In all cases,
--** an appropriate error code is returned and *ppPage is set to NULL.
-+** If a transaction was in progress when this routine is called, that
-+** transaction is rolled back.  All outstanding pages are invalidated
-+** and their memory is freed.  Any attempt to use a page associated
-+** with this page cache after this function returns will likely
-+** result in a coredump.
- **
--** See also sqlite3PagerLookup().  Both this routine and Lookup() attempt
--** to find a page in the in-memory cache first.  If the page is not already
--** in memory, this routine goes to disk to read it in whereas Lookup()
--** just returns 0.  This routine acquires a read-lock the first time it
--** has to go to disk, and could also playback an old journal if necessary.
--** Since Lookup() never goes to disk, it never has to deal with locks
--** or journal files.
-+** This function always succeeds. If a transaction is active an attempt
-+** is made to roll it back. If an error occurs during the rollback 
-+** a hot journal may be left in the filesystem but no error is returned
-+** to the caller.
- */
--SQLITE_PRIVATE int sqlite3PagerAcquire(
--  Pager *pPager,      /* The pager open on the database file */
--  Pgno pgno,          /* Page number to fetch */
--  DbPage **ppPage,    /* Write a pointer to the page here */
--  int flags           /* PAGER_GET_XXX flags */
--){
--  int rc = SQLITE_OK;
--  PgHdr *pPg = 0;
--  u32 iFrame = 0;                 /* Frame to read from WAL file */
--  const int noContent = (flags & PAGER_GET_NOCONTENT);
--
--  /* It is acceptable to use a read-only (mmap) page for any page except
--  ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
--  ** flag was specified by the caller. And so long as the db is not a 
--  ** temporary or in-memory database.  */
--  const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
--   && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
--#ifdef SQLITE_HAS_CODEC
--   && pPager->xCodec==0
--#endif
--  );
-+SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
-+  u8 *pTmp = (u8 *)pPager->pTmpSpace;
- 
--  assert( pPager->eState>=PAGER_READER );
-   assert( assert_pager_state(pPager) );
--  assert( noContent==0 || bMmapOk==0 );
--
--  if( pgno==0 ){
--    return SQLITE_CORRUPT_BKPT;
--  }
--  pPager->hasBeenUsed = 1;
--
--  /* If the pager is in the error state, return an error immediately. 
--  ** Otherwise, request the page from the PCache layer. */
--  if( pPager->errCode!=SQLITE_OK ){
--    rc = pPager->errCode;
-+  disable_simulated_io_errors();
-+  sqlite3BeginBenignMalloc();
-+  pagerFreeMapHdrs(pPager);
-+  /* pPager->errCode = 0; */
-+  pPager->exclusiveMode = 0;
-+#ifndef SQLITE_OMIT_WAL
-+  sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
-+  pPager->pWal = 0;
-+#endif
-+  pager_reset(pPager);
-+  if( MEMDB ){
-+    pager_unlock(pPager);
-   }else{
--    if( bMmapOk && pagerUseWal(pPager) ){
--      rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
--      if( rc!=SQLITE_OK ) goto pager_acquire_err;
--    }
--
--    if( bMmapOk && iFrame==0 ){
--      void *pData = 0;
--
--      rc = sqlite3OsFetch(pPager->fd, 
--          (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
--      );
--
--      if( rc==SQLITE_OK && pData ){
--        if( pPager->eState>PAGER_READER ){
--          pPg = sqlite3PagerLookup(pPager, pgno);
--        }
--        if( pPg==0 ){
--          rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
--        }else{
--          sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
--        }
--        if( pPg ){
--          assert( rc==SQLITE_OK );
--          *ppPage = pPg;
--          return SQLITE_OK;
--        }
--      }
--      if( rc!=SQLITE_OK ){
--        goto pager_acquire_err;
--      }
--    }
--
--    {
--      sqlite3_pcache_page *pBase;
--      pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
--      if( pBase==0 ){
--        rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
--        if( rc!=SQLITE_OK ) goto pager_acquire_err;
--      }
--      pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
--      if( pPg==0 ) rc = SQLITE_NOMEM;
-+    /* If it is open, sync the journal file before calling UnlockAndRollback.
-+    ** If this is not done, then an unsynced portion of the open journal 
-+    ** file may be played back into the database. If a power failure occurs 
-+    ** while this is happening, the database could become corrupt.
++/*
++** Return the total number of blocks this module has read from the %_data
++** table since it was created.
++*/
++static int sqlite3Fts5IndexReads(Fts5Index *p){
++  return p->nRead;
++}
++
++/*
++** Set the 32-bit cookie value stored at the start of all structure 
++** records to the value passed as the second argument.
++**
++** Return SQLITE_OK if successful, or an SQLite error code if an error
++** occurs.
++*/
++static int sqlite3Fts5IndexSetCookie(Fts5Index *p, int iNew){
++  int rc;                              /* Return code */
++  Fts5Config *pConfig = p->pConfig;    /* Configuration object */
++  u8 aCookie[4];                       /* Binary representation of iNew */
++  sqlite3_blob *pBlob = 0;
++
++  assert( p->rc==SQLITE_OK );
++  sqlite3Fts5Put32(aCookie, iNew);
++
++  rc = sqlite3_blob_open(pConfig->db, pConfig->zDb, p->zDataTbl, 
++      "block", FTS5_STRUCTURE_ROWID, 1, &pBlob
++  );
++  if( rc==SQLITE_OK ){
++    sqlite3_blob_write(pBlob, aCookie, 4, 0);
++    rc = sqlite3_blob_close(pBlob);
++  }
++
++  return rc;
++}
++
++static int sqlite3Fts5IndexLoadConfig(Fts5Index *p){
++  Fts5Structure *pStruct;
++  pStruct = fts5StructureRead(p);
++  fts5StructureRelease(pStruct);
++  return fts5IndexReturn(p);
++}
++
++
++/*************************************************************************
++**************************************************************************
++** Below this point is the implementation of the integrity-check 
++** functionality.
++*/
++
++/*
++** Return a simple checksum value based on the arguments.
++*/
++static u64 sqlite3Fts5IndexEntryCksum(
++  i64 iRowid, 
++  int iCol, 
++  int iPos, 
++  int iIdx,
++  const char *pTerm,
++  int nTerm
++){
++  int i;
++  u64 ret = iRowid;
++  ret += (ret<<3) + iCol;
++  ret += (ret<<3) + iPos;
++  if( iIdx>=0 ) ret += (ret<<3) + (FTS5_MAIN_PREFIX + iIdx);
++  for(i=0; i<nTerm; i++) ret += (ret<<3) + pTerm[i];
++  return ret;
++}
++
++#ifdef SQLITE_DEBUG
++/*
++** This function is purely an internal test. It does not contribute to 
++** FTS functionality, or even the integrity-check, in any way.
++**
++** Instead, it tests that the same set of pgno/rowid combinations are 
++** visited regardless of whether the doclist-index identified by parameters
++** iSegid/iLeaf is iterated in forwards or reverse order.
++*/
++static void fts5TestDlidxReverse(
++  Fts5Index *p, 
++  int iSegid,                     /* Segment id to load from */
++  int iLeaf                       /* Load doclist-index for this leaf */
++){
++  Fts5DlidxIter *pDlidx = 0;
++  u64 cksum1 = 13;
++  u64 cksum2 = 13;
++
++  for(pDlidx=fts5DlidxIterInit(p, 0, iSegid, iLeaf);
++      fts5DlidxIterEof(p, pDlidx)==0;
++      fts5DlidxIterNext(p, pDlidx)
++  ){
++    i64 iRowid = fts5DlidxIterRowid(pDlidx);
++    int pgno = fts5DlidxIterPgno(pDlidx);
++    assert( pgno>iLeaf );
++    cksum1 += iRowid + ((i64)pgno<<32);
++  }
++  fts5DlidxIterFree(pDlidx);
++  pDlidx = 0;
++
++  for(pDlidx=fts5DlidxIterInit(p, 1, iSegid, iLeaf);
++      fts5DlidxIterEof(p, pDlidx)==0;
++      fts5DlidxIterPrev(p, pDlidx)
++  ){
++    i64 iRowid = fts5DlidxIterRowid(pDlidx);
++    int pgno = fts5DlidxIterPgno(pDlidx);
++    assert( fts5DlidxIterPgno(pDlidx)>iLeaf );
++    cksum2 += iRowid + ((i64)pgno<<32);
++  }
++  fts5DlidxIterFree(pDlidx);
++  pDlidx = 0;
++
++  if( p->rc==SQLITE_OK && cksum1!=cksum2 ) p->rc = FTS5_CORRUPT;
++}
++
++static int fts5QueryCksum(
++  Fts5Index *p,                   /* Fts5 index object */
++  int iIdx,
++  const char *z,                  /* Index key to query for */
++  int n,                          /* Size of index key in bytes */
++  int flags,                      /* Flags for Fts5IndexQuery */
++  u64 *pCksum                     /* IN/OUT: Checksum value */
++){
++  int eDetail = p->pConfig->eDetail;
++  u64 cksum = *pCksum;
++  Fts5IndexIter *pIter = 0;
++  int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter);
++
++  while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){
++    i64 rowid = pIter->iRowid;
++
++    if( eDetail==FTS5_DETAIL_NONE ){
++      cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n);
++    }else{
++      Fts5PoslistReader sReader;
++      for(sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &sReader);
++          sReader.bEof==0;
++          sqlite3Fts5PoslistReaderNext(&sReader)
++      ){
++        int iCol = FTS5_POS2COLUMN(sReader.iPos);
++        int iOff = FTS5_POS2OFFSET(sReader.iPos);
++        cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
++      }
++    }
++    if( rc==SQLITE_OK ){
++      rc = sqlite3Fts5IterNext(pIter);
++    }
++  }
++  sqlite3Fts5IterClose(pIter);
++
++  *pCksum = cksum;
++  return rc;
++}
++
++
++/*
++** This function is also purely an internal test. It does not contribute to 
++** FTS functionality, or even the integrity-check, in any way.
++*/
++static void fts5TestTerm(
++  Fts5Index *p, 
++  Fts5Buffer *pPrev,              /* Previous term */
++  const char *z, int n,           /* Possibly new term to test */
++  u64 expected,
++  u64 *pCksum
++){
++  int rc = p->rc;
++  if( pPrev->n==0 ){
++    fts5BufferSet(&rc, pPrev, n, (const u8*)z);
++  }else
++  if( rc==SQLITE_OK && (pPrev->n!=n || memcmp(pPrev->p, z, n)) ){
++    u64 cksum3 = *pCksum;
++    const char *zTerm = (const char*)&pPrev->p[1];  /* term sans prefix-byte */
++    int nTerm = pPrev->n-1;            /* Size of zTerm in bytes */
++    int iIdx = (pPrev->p[0] - FTS5_MAIN_PREFIX);
++    int flags = (iIdx==0 ? 0 : FTS5INDEX_QUERY_PREFIX);
++    u64 ck1 = 0;
++    u64 ck2 = 0;
++
++    /* Check that the results returned for ASC and DESC queries are
++    ** the same. If not, call this corruption.  */
++    rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, flags, &ck1);
++    if( rc==SQLITE_OK ){
++      int f = flags|FTS5INDEX_QUERY_DESC;
++      rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
++    }
++    if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
++
++    /* If this is a prefix query, check that the results returned if the
++    ** the index is disabled are the same. In both ASC and DESC order. 
 +    **
-+    ** If an error occurs while trying to sync the journal, shift the pager
-+    ** into the ERROR state. This causes UnlockAndRollback to unlock the
-+    ** database and close the journal file without attempting to roll it
-+    ** back or finalize it. The next database user will have to do hot-journal
-+    ** rollback before accessing the database file.
-+    */
-+    if( isOpen(pPager->jfd) ){
-+      pager_error(pPager, pagerSyncHotJournal(pPager));
-     }
-+    pagerUnlockAndRollback(pPager);
-   }
-+  sqlite3EndBenignMalloc();
-+  enable_simulated_io_errors();
-+  PAGERTRACE(("CLOSE %d\n", PAGERID(pPager)));
-+  IOTRACE(("CLOSE %p\n", pPager))
-+  sqlite3OsClose(pPager->jfd);
-+  sqlite3OsClose(pPager->fd);
-+  sqlite3PageFree(pTmp);
-+  sqlite3PcacheClose(pPager->pPCache);
- 
--  if( rc!=SQLITE_OK ){
--    /* Either the call to sqlite3PcacheFetch() returned an error or the
--    ** pager was already in the error-state when this function was called.
--    ** Set pPg to 0 and jump to the exception handler.  */
--    pPg = 0;
--    goto pager_acquire_err;
--  }
--  assert( (*ppPage)->pgno==pgno );
--  assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 );
--
--  if( (*ppPage)->pPager && !noContent ){
--    /* In this case the pcache already contains an initialized copy of
--    ** the page. Return without further ado.  */
--    assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
--    pPager->aStat[PAGER_STAT_HIT]++;
--    return SQLITE_OK;
--
--  }else{
--    /* The pager cache has created a new page. Its content needs to 
--    ** be initialized.  */
--
--    pPg = *ppPage;
--    pPg->pPager = pPager;
--
--    /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
--    ** number greater than this, or the unused locking-page, is requested. */
--    if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
--      rc = SQLITE_CORRUPT_BKPT;
--      goto pager_acquire_err;
--    }
-+#ifdef SQLITE_HAS_CODEC
-+  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
-+#endif
- 
--    if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){
--      if( pgno>pPager->mxPgno ){
--        rc = SQLITE_FULL;
--        goto pager_acquire_err;
--      }
--      if( noContent ){
--        /* Failure to set the bits in the InJournal bit-vectors is benign.
--        ** It merely means that we might do some extra work to journal a 
--        ** page that does not need to be journaled.  Nevertheless, be sure 
--        ** to test the case where a malloc error occurs while trying to set 
--        ** a bit in a bit vector.
--        */
--        sqlite3BeginBenignMalloc();
--        if( pgno<=pPager->dbOrigSize ){
--          TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno);
--          testcase( rc==SQLITE_NOMEM );
--        }
--        TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno);
--        testcase( rc==SQLITE_NOMEM );
--        sqlite3EndBenignMalloc();
--      }
--      memset(pPg->pData, 0, pPager->pageSize);
--      IOTRACE(("ZERO %p %d\n", pPager, pgno));
--    }else{
--      if( pagerUseWal(pPager) && bMmapOk==0 ){
--        rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
--        if( rc!=SQLITE_OK ) goto pager_acquire_err;
--      }
--      assert( pPg->pPager==pPager );
--      pPager->aStat[PAGER_STAT_MISS]++;
--      rc = readDbPage(pPg, iFrame);
--      if( rc!=SQLITE_OK ){
--        goto pager_acquire_err;
--      }
--    }
--    pager_set_pagehash(pPg);
--  }
-+  assert( !pPager->aSavepoint && !pPager->pInJournal );
-+  assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
- 
-+  sqlite3_free(pPager);
-   return SQLITE_OK;
--
--pager_acquire_err:
--  assert( rc!=SQLITE_OK );
--  if( pPg ){
--    sqlite3PcacheDrop(pPg);
--  }
--  pagerUnlockIfUnused(pPager);
--
--  *ppPage = 0;
--  return rc;
- }
- 
-+#if !defined(NDEBUG) || defined(SQLITE_TEST)
- /*
--** Acquire a page if it is already in the in-memory cache.  Do
--** not read the page from disk.  Return a pointer to the page,
--** or 0 if the page is not in cache. 
--**
--** See also sqlite3PagerGet().  The difference between this routine
--** and sqlite3PagerGet() is that _get() will go to the disk and read
--** in the page if the page is not already in cache.  This routine
--** returns NULL if the page is not in cache or if a disk I/O error 
--** has ever happened.
-+** Return the page number for page pPg.
- */
--SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
--  sqlite3_pcache_page *pPage;
--  assert( pPager!=0 );
--  assert( pgno!=0 );
--  assert( pPager->pPCache!=0 );
--  pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
--  assert( pPage==0 || pPager->hasBeenUsed );
--  return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
-+SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){
-+  return pPg->pgno;
- }
++    ** This check may only be performed if the hash table is empty. This
++    ** is because the hash table only supports a single scan query at
++    ** a time, and the multi-iter loop from which this function is called
++    ** is already performing such a scan. */
++    if( p->nPendingData==0 ){
++      if( iIdx>0 && rc==SQLITE_OK ){
++        int f = flags|FTS5INDEX_QUERY_TEST_NOIDX;
++        ck2 = 0;
++        rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
++        if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
++      }
++      if( iIdx>0 && rc==SQLITE_OK ){
++        int f = flags|FTS5INDEX_QUERY_TEST_NOIDX|FTS5INDEX_QUERY_DESC;
++        ck2 = 0;
++        rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
++        if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
++      }
++    }
++
++    cksum3 ^= ck1;
++    fts5BufferSet(&rc, pPrev, n, (const u8*)z);
++
++    if( rc==SQLITE_OK && cksum3!=expected ){
++      rc = FTS5_CORRUPT;
++    }
++    *pCksum = cksum3;
++  }
++  p->rc = rc;
++}
++ 
++#else
++# define fts5TestDlidxReverse(x,y,z)
++# define fts5TestTerm(u,v,w,x,y,z)
 +#endif
- 
- /*
--** Release a page reference.
--**
--** If the number of references to the page drop to zero, then the
--** page is added to the LRU list.  When all references to all pages
--** are released, a rollback occurs and the lock on the database is
--** removed.
-+** Increment the reference count for page pPg.
- */
--SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){
--  Pager *pPager;
--  assert( pPg!=0 );
--  pPager = pPg->pPager;
--  if( pPg->flags & PGHDR_MMAP ){
--    pagerReleaseMapPage(pPg);
--  }else{
--    sqlite3PcacheRelease(pPg);
--  }
--  pagerUnlockIfUnused(pPager);
--}
--SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
--  if( pPg ) sqlite3PagerUnrefNotNull(pPg);
-+SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){
-+  sqlite3PcacheRef(pPg);
- }
- 
- /*
--** This function is called at the start of every write transaction.
--** There must already be a RESERVED or EXCLUSIVE lock on the database 
--** file when this routine is called.
-+** Sync the journal. In other words, make sure all the pages that have
-+** been written to the journal have actually reached the surface of the
-+** disk and can be restored in the event of a hot-journal rollback.
- **
--** Open the journal file for pager pPager and write a journal header
--** to the start of it. If there are active savepoints, open the sub-journal
--** as well. This function is only used when the journal file is being 
--** opened to write a rollback log for a transaction. It is not used 
--** when opening a hot journal file to roll it back.
-+** If the Pager.noSync flag is set, then this function is a no-op.
-+** Otherwise, the actions required depend on the journal-mode and the 
-+** device characteristics of the file-system, as follows:
- **
--** If the journal file is already open (as it may be in exclusive mode),
--** then this function just writes a journal header to the start of the
--** already open file. 
-+**   * If the journal file is an in-memory journal file, no action need
-+**     be taken.
- **
--** Whether or not the journal file is opened by this function, the
--** Pager.pInJournal bitvec structure is allocated.
-+**   * Otherwise, if the device does not support the SAFE_APPEND property,
-+**     then the nRec field of the most recently written journal header
-+**     is updated to contain the number of journal records that have
-+**     been written following it. If the pager is operating in full-sync
-+**     mode, then the journal file is synced before this field is updated.
- **
--** Return SQLITE_OK if everything is successful. Otherwise, return 
--** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or 
--** an IO error code if opening or writing the journal file fails.
-+**   * If the device does not support the SEQUENTIAL property, then 
-+**     journal file is synced.
-+**
-+** Or, in pseudo-code:
-+**
-+**   if( NOT <in-memory journal> ){
-+**     if( NOT SAFE_APPEND ){
-+**       if( <full-sync mode> ) xSync(<journal file>);
-+**       <update nRec field>
-+**     } 
-+**     if( NOT SEQUENTIAL ) xSync(<journal file>);
-+**   }
++
++/*
++** Check that:
 +**
-+** If successful, this routine clears the PGHDR_NEED_SYNC flag of every 
-+** page currently held in memory before returning SQLITE_OK. If an IO
-+** error is encountered, then the IO error code is returned to the caller.
- */
--static int pager_open_journal(Pager *pPager){
--  int rc = SQLITE_OK;                        /* Return code */
--  sqlite3_vfs * const pVfs = pPager->pVfs;   /* Local cache of vfs pointer */
-+static int syncJournal(Pager *pPager, int newHdr){
-+  int rc;                         /* Return code */
- 
--  assert( pPager->eState==PAGER_WRITER_LOCKED );
-+  assert( pPager->eState==PAGER_WRITER_CACHEMOD
-+       || pPager->eState==PAGER_WRITER_DBMOD
-+  );
-   assert( assert_pager_state(pPager) );
--  assert( pPager->pInJournal==0 );
--  
--  /* If already in the error state, this function is a no-op.  But on
--  ** the other hand, this routine is never called if we are already in
--  ** an error state. */
--  if( NEVER(pPager->errCode) ) return pPager->errCode;
-+  assert( !pagerUseWal(pPager) );
- 
--  if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
--    pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
--    if( pPager->pInJournal==0 ){
--      return SQLITE_NOMEM;
--    }
--  
--    /* Open the journal file if it is not already open. */
--    if( !isOpen(pPager->jfd) ){
--      if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
--        sqlite3MemJournalOpen(pPager->jfd);
--      }else{
--        const int flags =                   /* VFS flags to open journal file */
--          SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
--          (pPager->tempFile ? 
--            (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
--            (SQLITE_OPEN_MAIN_JOURNAL)
--          );
-+  rc = sqlite3PagerExclusiveLock(pPager);
-+  if( rc!=SQLITE_OK ) return rc;
- 
--        /* Verify that the database still has the same name as it did when
--        ** it was originally opened. */
--        rc = databaseIsUnmoved(pPager);
--        if( rc==SQLITE_OK ){
--#ifdef SQLITE_ENABLE_ATOMIC_WRITE
--          rc = sqlite3JournalOpen(
--              pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
--          );
--#else
--          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
--#endif
-+  if( !pPager->noSync ){
-+    assert( !pPager->tempFile );
-+    if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){
-+      const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
-+      assert( isOpen(pPager->jfd) );
-+
-+      if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
-+        /* This block deals with an obscure problem. If the last connection
-+        ** that wrote to this database was operating in persistent-journal
-+        ** mode, then the journal file may at this point actually be larger
-+        ** than Pager.journalOff bytes. If the next thing in the journal
-+        ** file happens to be a journal-header (written as part of the
-+        ** previous connection's transaction), and a crash or power-failure 
-+        ** occurs after nRec is updated but before this connection writes 
-+        ** anything else to the journal file (or commits/rolls back its 
-+        ** transaction), then SQLite may become confused when doing the 
-+        ** hot-journal rollback following recovery. It may roll back all
-+        ** of this connections data, then proceed to rolling back the old,
-+        ** out-of-date data that follows it. Database corruption.
-+        **
-+        ** To work around this, if the journal file does appear to contain
-+        ** a valid header following Pager.journalOff, then write a 0x00
-+        ** byte to the start of it to prevent it from being recognized.
-+        **
-+        ** Variable iNextHdrOffset is set to the offset at which this
-+        ** problematic header will occur, if it exists. aMagic is used 
-+        ** as a temporary buffer to inspect the first couple of bytes of
-+        ** the potential journal header.
-+        */
-+        i64 iNextHdrOffset;
-+        u8 aMagic[8];
-+        u8 zHeader[sizeof(aJournalMagic)+4];
++**   1) All leaves of pSeg between iFirst and iLast (inclusive) exist and
++**      contain zero terms.
++**   2) All leaves of pSeg between iNoRowid and iLast (inclusive) exist and
++**      contain zero rowids.
++*/
++static void fts5IndexIntegrityCheckEmpty(
++  Fts5Index *p,
++  Fts5StructureSegment *pSeg,     /* Segment to check internal consistency */
++  int iFirst,
++  int iNoRowid,
++  int iLast
++){
++  int i;
 +
-+        memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
-+        put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec);
++  /* Now check that the iter.nEmpty leaves following the current leaf
++  ** (a) exist and (b) contain no terms. */
++  for(i=iFirst; p->rc==SQLITE_OK && i<=iLast; i++){
++    Fts5Data *pLeaf = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
++    if( pLeaf ){
++      if( !fts5LeafIsTermless(pLeaf) ) p->rc = FTS5_CORRUPT;
++      if( i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf) ) p->rc = FTS5_CORRUPT;
++    }
++    fts5DataRelease(pLeaf);
++  }
++}
 +
-+        iNextHdrOffset = journalHdrOffset(pPager);
-+        rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset);
-+        if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){
-+          static const u8 zerobyte = 0;
-+          rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset);
-+        }
-+        if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
-+          return rc;
-+        }
++static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
++  int iTermOff = 0;
++  int ii;
++
++  Fts5Buffer buf1 = {0,0,0};
++  Fts5Buffer buf2 = {0,0,0};
++
++  ii = pLeaf->szLeaf;
++  while( ii<pLeaf->nn && p->rc==SQLITE_OK ){
++    int res;
++    int iOff;
++    int nIncr;
++
++    ii += fts5GetVarint32(&pLeaf->p[ii], nIncr);
++    iTermOff += nIncr;
++    iOff = iTermOff;
++
++    if( iOff>=pLeaf->szLeaf ){
++      p->rc = FTS5_CORRUPT;
++    }else if( iTermOff==nIncr ){
++      int nByte;
++      iOff += fts5GetVarint32(&pLeaf->p[iOff], nByte);
++      if( (iOff+nByte)>pLeaf->szLeaf ){
++        p->rc = FTS5_CORRUPT;
++      }else{
++        fts5BufferSet(&p->rc, &buf1, nByte, &pLeaf->p[iOff]);
++      }
++    }else{
++      int nKeep, nByte;
++      iOff += fts5GetVarint32(&pLeaf->p[iOff], nKeep);
++      iOff += fts5GetVarint32(&pLeaf->p[iOff], nByte);
++      if( nKeep>buf1.n || (iOff+nByte)>pLeaf->szLeaf ){
++        p->rc = FTS5_CORRUPT;
++      }else{
++        buf1.n = nKeep;
++        fts5BufferAppendBlob(&p->rc, &buf1, nByte, &pLeaf->p[iOff]);
++      }
 +
-+        /* Write the nRec value into the journal file header. If in
-+        ** full-synchronous mode, sync the journal first. This ensures that
-+        ** all data has really hit the disk before nRec is updated to mark
-+        ** it as a candidate for rollback.
-+        **
-+        ** This is not required if the persistent media supports the
-+        ** SAFE_APPEND property. Because in this case it is not possible 
-+        ** for garbage data to be appended to the file, the nRec field
-+        ** is populated with 0xFFFFFFFF when the journal header is written
-+        ** and never needs to be updated.
-+        */
-+        if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
-+          PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
-+          IOTRACE(("JSYNC %p\n", pPager))
-+          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
-+          if( rc!=SQLITE_OK ) return rc;
-         }
-+        IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr));
-+        rc = sqlite3OsWrite(
-+            pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr
-+        );
-+        if( rc!=SQLITE_OK ) return rc;
++      if( p->rc==SQLITE_OK ){
++        res = fts5BufferCompare(&buf1, &buf2);
++        if( res<=0 ) p->rc = FTS5_CORRUPT;
 +      }
-+      if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
-+        PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
-+        IOTRACE(("JSYNC %p\n", pPager))
-+        rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| 
-+          (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0)
-+        );
-+        if( rc!=SQLITE_OK ) return rc;
-       }
--      assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
--    }
--  
--  
--    /* Write the first journal header to the journal file and open 
--    ** the sub-journal if necessary.
--    */
--    if( rc==SQLITE_OK ){
--      /* TODO: Check if all of these are really required. */
--      pPager->nRec = 0;
--      pPager->journalOff = 0;
--      pPager->setMaster = 0;
--      pPager->journalHdr = 0;
--      rc = writeJournalHdr(pPager);
--    }
--  }
- 
--  if( rc!=SQLITE_OK ){
--    sqlite3BitvecDestroy(pPager->pInJournal);
--    pPager->pInJournal = 0;
--  }else{
--    assert( pPager->eState==PAGER_WRITER_LOCKED );
--    pPager->eState = PAGER_WRITER_CACHEMOD;
-+      pPager->journalHdr = pPager->journalOff;
-+      if( newHdr && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
-+        pPager->nRec = 0;
-+        rc = writeJournalHdr(pPager);
-+        if( rc!=SQLITE_OK ) return rc;
++    }
++    fts5BufferSet(&p->rc, &buf2, buf1.n, buf1.p);
++  }
++
++  fts5BufferFree(&buf1);
++  fts5BufferFree(&buf2);
++}
++
++static void fts5IndexIntegrityCheckSegment(
++  Fts5Index *p,                   /* FTS5 backend object */
++  Fts5StructureSegment *pSeg      /* Segment to check internal consistency */
++){
++  Fts5Config *pConfig = p->pConfig;
++  sqlite3_stmt *pStmt = 0;
++  int rc2;
++  int iIdxPrevLeaf = pSeg->pgnoFirst-1;
++  int iDlidxPrevLeaf = pSeg->pgnoLast;
++
++  if( pSeg->pgnoFirst==0 ) return;
++
++  fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf(
++      "SELECT segid, term, (pgno>>1), (pgno&1) FROM %Q.'%q_idx' WHERE segid=%d",
++      pConfig->zDb, pConfig->zName, pSeg->iSegid
++  ));
++
++  /* Iterate through the b-tree hierarchy.  */
++  while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
++    i64 iRow;                     /* Rowid for this leaf */
++    Fts5Data *pLeaf;              /* Data for this leaf */
++
++    int nIdxTerm = sqlite3_column_bytes(pStmt, 1);
++    const char *zIdxTerm = (const char*)sqlite3_column_text(pStmt, 1);
++    int iIdxLeaf = sqlite3_column_int(pStmt, 2);
++    int bIdxDlidx = sqlite3_column_int(pStmt, 3);
++
++    /* If the leaf in question has already been trimmed from the segment, 
++    ** ignore this b-tree entry. Otherwise, load it into memory. */
++    if( iIdxLeaf<pSeg->pgnoFirst ) continue;
++    iRow = FTS5_SEGMENT_ROWID(pSeg->iSegid, iIdxLeaf);
++    pLeaf = fts5LeafRead(p, iRow);
++    if( pLeaf==0 ) break;
++
++    /* Check that the leaf contains at least one term, and that it is equal
++    ** to or larger than the split-key in zIdxTerm.  Also check that if there
++    ** is also a rowid pointer within the leaf page header, it points to a
++    ** location before the term.  */
++    if( pLeaf->nn<=pLeaf->szLeaf ){
++      p->rc = FTS5_CORRUPT;
++    }else{
++      int iOff;                   /* Offset of first term on leaf */
++      int iRowidOff;              /* Offset of first rowid on leaf */
++      int nTerm;                  /* Size of term on leaf in bytes */
++      int res;                    /* Comparison of term and split-key */
++
++      iOff = fts5LeafFirstTermOff(pLeaf);
++      iRowidOff = fts5LeafFirstRowidOff(pLeaf);
++      if( iRowidOff>=iOff ){
++        p->rc = FTS5_CORRUPT;
++      }else{
++        iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
++        res = memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
++        if( res==0 ) res = nTerm - nIdxTerm;
++        if( res<0 ) p->rc = FTS5_CORRUPT;
++      }
++
++      fts5IntegrityCheckPgidx(p, pLeaf);
++    }
++    fts5DataRelease(pLeaf);
++    if( p->rc ) break;
++
++    /* Now check that the iter.nEmpty leaves following the current leaf
++    ** (a) exist and (b) contain no terms. */
++    fts5IndexIntegrityCheckEmpty(
++        p, pSeg, iIdxPrevLeaf+1, iDlidxPrevLeaf+1, iIdxLeaf-1
++    );
++    if( p->rc ) break;
++
++    /* If there is a doclist-index, check that it looks right. */
++    if( bIdxDlidx ){
++      Fts5DlidxIter *pDlidx = 0;  /* For iterating through doclist index */
++      int iPrevLeaf = iIdxLeaf;
++      int iSegid = pSeg->iSegid;
++      int iPg = 0;
++      i64 iKey;
++
++      for(pDlidx=fts5DlidxIterInit(p, 0, iSegid, iIdxLeaf);
++          fts5DlidxIterEof(p, pDlidx)==0;
++          fts5DlidxIterNext(p, pDlidx)
++      ){
++
++        /* Check any rowid-less pages that occur before the current leaf. */
++        for(iPg=iPrevLeaf+1; iPg<fts5DlidxIterPgno(pDlidx); iPg++){
++          iKey = FTS5_SEGMENT_ROWID(iSegid, iPg);
++          pLeaf = fts5DataRead(p, iKey);
++          if( pLeaf ){
++            if( fts5LeafFirstRowidOff(pLeaf)!=0 ) p->rc = FTS5_CORRUPT;
++            fts5DataRelease(pLeaf);
++          }
++        }
++        iPrevLeaf = fts5DlidxIterPgno(pDlidx);
++
++        /* Check that the leaf page indicated by the iterator really does
++        ** contain the rowid suggested by the same. */
++        iKey = FTS5_SEGMENT_ROWID(iSegid, iPrevLeaf);
++        pLeaf = fts5DataRead(p, iKey);
++        if( pLeaf ){
++          i64 iRowid;
++          int iRowidOff = fts5LeafFirstRowidOff(pLeaf);
++          ASSERT_SZLEAF_OK(pLeaf);
++          if( iRowidOff>=pLeaf->szLeaf ){
++            p->rc = FTS5_CORRUPT;
++          }else{
++            fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid);
++            if( iRowid!=fts5DlidxIterRowid(pDlidx) ) p->rc = FTS5_CORRUPT;
++          }
++          fts5DataRelease(pLeaf);
++        }
 +      }
++
++      iDlidxPrevLeaf = iPg;
++      fts5DlidxIterFree(pDlidx);
++      fts5TestDlidxReverse(p, iSegid, iIdxLeaf);
 +    }else{
-+      pPager->journalHdr = pPager->journalOff;
++      iDlidxPrevLeaf = pSeg->pgnoLast;
++      /* TODO: Check there is no doclist index */
 +    }
-   }
- 
--  return rc;
-+  /* Unless the pager is in noSync mode, the journal file was just 
-+  ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on 
-+  ** all pages.
-+  */
-+  sqlite3PcacheClearSyncFlags(pPager->pPCache);
-+  pPager->eState = PAGER_WRITER_DBMOD;
-+  assert( assert_pager_state(pPager) );
-+  return SQLITE_OK;
- }
- 
- /*
--** Begin a write-transaction on the specified pager object. If a 
--** write-transaction has already been opened, this function is a no-op.
-+** The argument is the first in a linked list of dirty pages connected
-+** by the PgHdr.pDirty pointer. This function writes each one of the
-+** in-memory pages in the list to the database file. The argument may
-+** be NULL, representing an empty list. In this case this function is
-+** a no-op.
- **
--** If the exFlag argument is false, then acquire at least a RESERVED
--** lock on the database file. If exFlag is true, then acquire at least
--** an EXCLUSIVE lock. If such a lock is already held, no locking 
--** functions need be called.
-+** The pager must hold at least a RESERVED lock when this function
-+** is called. Before writing anything to the database file, this lock
-+** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained,
-+** SQLITE_BUSY is returned and no data is written to the database file.
-+** 
-+** If the pager is a temp-file pager and the actual file-system file
-+** is not yet open, it is created and opened before any data is 
-+** written out.
- **
--** If the subjInMemory argument is non-zero, then any sub-journal opened
--** within this transaction will be opened as an in-memory file. This
--** has no effect if the sub-journal is already opened (as it may be when
--** running in exclusive mode) or if the transaction does not require a
--** sub-journal. If the subjInMemory argument is zero, then any required
--** sub-journal is implemented in-memory if pPager is an in-memory database, 
--** or using a temporary file otherwise.
-+** Once the lock has been upgraded and, if necessary, the file opened,
-+** the pages are written out to the database file in list order. Writing
-+** a page is skipped if it meets either of the following criteria:
-+**
-+**   * The page number is greater than Pager.dbSize, or
-+**   * The PGHDR_DONT_WRITE flag is set on the page.
-+**
-+** If writing out a page causes the database file to grow, Pager.dbFileSize
-+** is updated accordingly. If page 1 is written out, then the value cached
-+** in Pager.dbFileVers[] is updated to match the new value stored in
-+** the database file.
-+**
-+** If everything is successful, SQLITE_OK is returned. If an IO error 
-+** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot
-+** be obtained, SQLITE_BUSY is returned.
- */
--SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
--  int rc = SQLITE_OK;
-+static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
-+  int rc = SQLITE_OK;                  /* Return code */
- 
--  if( pPager->errCode ) return pPager->errCode;
--  assert( pPager->eState>=PAGER_READER && pPager->eState<PAGER_ERROR );
--  pPager->subjInMemory = (u8)subjInMemory;
-+  /* This function is only called for rollback pagers in WRITER_DBMOD state. */
-+  assert( !pagerUseWal(pPager) );
-+  assert( pPager->eState==PAGER_WRITER_DBMOD );
-+  assert( pPager->eLock==EXCLUSIVE_LOCK );
- 
--  if( ALWAYS(pPager->eState==PAGER_READER) ){
--    assert( pPager->pInJournal==0 );
-+  /* If the file is a temp-file has not yet been opened, open it now. It
-+  ** is not possible for rc to be other than SQLITE_OK if this branch
-+  ** is taken, as pager_wait_on_lock() is a no-op for temp-files.
-+  */
-+  if( !isOpen(pPager->fd) ){
-+    assert( pPager->tempFile && rc==SQLITE_OK );
-+    rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
++
++    iIdxPrevLeaf = iIdxLeaf;
 +  }
- 
--    if( pagerUseWal(pPager) ){
--      /* If the pager is configured to use locking_mode=exclusive, and an
--      ** exclusive lock on the database is not already held, obtain it now.
--      */
--      if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){
--        rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
--        if( rc!=SQLITE_OK ){
--          return rc;
--        }
--        sqlite3WalExclusiveMode(pPager->pWal, 1);
--      }
-+  /* Before the first write, give the VFS a hint of what the final
-+  ** file size will be.
++
++  rc2 = sqlite3_finalize(pStmt);
++  if( p->rc==SQLITE_OK ) p->rc = rc2;
++
++  /* Page iter.iLeaf must now be the rightmost leaf-page in the segment */
++#if 0
++  if( p->rc==SQLITE_OK && iter.iLeaf!=pSeg->pgnoLast ){
++    p->rc = FTS5_CORRUPT;
++  }
++#endif
++}
++
++
++/*
++** Run internal checks to ensure that the FTS index (a) is internally 
++** consistent and (b) contains entries for which the XOR of the checksums
++** as calculated by sqlite3Fts5IndexEntryCksum() is cksum.
++**
++** Return SQLITE_CORRUPT if any of the internal checks fail, or if the
++** checksum does not match. Return SQLITE_OK if all checks pass without
++** error, or some other SQLite error code if another error (e.g. OOM)
++** occurs.
++*/
++static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
++  int eDetail = p->pConfig->eDetail;
++  u64 cksum2 = 0;                 /* Checksum based on contents of indexes */
++  Fts5Buffer poslist = {0,0,0};   /* Buffer used to hold a poslist */
++  Fts5Iter *pIter;                /* Used to iterate through entire index */
++  Fts5Structure *pStruct;         /* Index structure */
++
++#ifdef SQLITE_DEBUG
++  /* Used by extra internal tests only run if NDEBUG is not defined */
++  u64 cksum3 = 0;                 /* Checksum based on contents of indexes */
++  Fts5Buffer term = {0,0,0};      /* Buffer used to hold most recent term */
++#endif
++  const int flags = FTS5INDEX_QUERY_NOOUTPUT;
++  
++  /* Load the FTS index structure */
++  pStruct = fts5StructureRead(p);
++
++  /* Check that the internal nodes of each segment match the leaves */
++  if( pStruct ){
++    int iLvl, iSeg;
++    for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
++      for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
++        Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
++        fts5IndexIntegrityCheckSegment(p, pSeg);
++      }
++    }
++  }
++
++  /* The cksum argument passed to this function is a checksum calculated
++  ** based on all expected entries in the FTS index (including prefix index
++  ** entries). This block checks that a checksum calculated based on the
++  ** actual contents of FTS index is identical.
++  **
++  ** Two versions of the same checksum are calculated. The first (stack
++  ** variable cksum2) based on entries extracted from the full-text index
++  ** while doing a linear scan of each individual index in turn. 
++  **
++  ** As each term visited by the linear scans, a separate query for the
++  ** same term is performed. cksum3 is calculated based on the entries
++  ** extracted by these queries.
 +  */
-+  assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
-+  if( rc==SQLITE_OK 
-+   && pPager->dbHintSize<pPager->dbSize
-+   && (pList->pDirty || pList->pgno>pPager->dbHintSize)
++  for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, -1, 0, &pIter);
++      fts5MultiIterEof(p, pIter)==0;
++      fts5MultiIterNext(p, pIter, 0, 0)
 +  ){
-+    sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
-+    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
-+    pPager->dbHintSize = pPager->dbSize;
++    int n;                      /* Size of term in bytes */
++    i64 iPos = 0;               /* Position read from poslist */
++    int iOff = 0;               /* Offset within poslist */
++    i64 iRowid = fts5MultiIterRowid(pIter);
++    char *z = (char*)fts5MultiIterTerm(pIter, &n);
++
++    /* If this is a new term, query for it. Update cksum3 with the results. */
++    fts5TestTerm(p, &term, z, n, cksum2, &cksum3);
++
++    if( eDetail==FTS5_DETAIL_NONE ){
++      if( 0==fts5MultiIterIsEmpty(p, pIter) ){
++        cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, 0, 0, -1, z, n);
++      }
++    }else{
++      poslist.n = 0;
++      fts5SegiterPoslist(p, &pIter->aSeg[pIter->aFirst[1].iFirst], 0, &poslist);
++      while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){
++        int iCol = FTS5_POS2COLUMN(iPos);
++        int iTokOff = FTS5_POS2OFFSET(iPos);
++        cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n);
++      }
++    }
 +  }
- 
--      /* Grab the write lock on the log file. If successful, upgrade to
--      ** PAGER_RESERVED state. Otherwise, return an error code to the caller.
--      ** The busy-handler is not invoked if another connection already
--      ** holds the write-lock. If possible, the upper layer will call it.
--      */
--      rc = sqlite3WalBeginWriteTransaction(pPager->pWal);
--    }else{
--      /* Obtain a RESERVED lock on the database file. If the exFlag parameter
--      ** is true, then immediately upgrade this to an EXCLUSIVE lock. The
--      ** busy-handler callback can be used when upgrading to the EXCLUSIVE
--      ** lock, but not when obtaining the RESERVED lock.
-+  while( rc==SQLITE_OK && pList ){
-+    Pgno pgno = pList->pgno;
-+
-+    /* If there are dirty pages in the page cache with page numbers greater
-+    ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to
-+    ** make the file smaller (presumably by auto-vacuum code). Do not write
-+    ** any such pages to the file.
-+    **
-+    ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag
-+    ** set (set by sqlite3PagerDontWrite()).
-+    */
-+    if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
-+      i64 offset = (pgno-1)*(i64)pPager->pageSize;   /* Offset to write */
-+      char *pData;                                   /* Data to write */    
++  fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);
 +
-+      assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
-+      if( pList->pgno==1 ) pager_write_changecounter(pList);
++  fts5MultiIterFree(pIter);
++  if( p->rc==SQLITE_OK && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
 +
-+      /* Encode the database */
-+      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
++  fts5StructureRelease(pStruct);
++#ifdef SQLITE_DEBUG
++  fts5BufferFree(&term);
++#endif
++  fts5BufferFree(&poslist);
++  return fts5IndexReturn(p);
++}
 +
-+      /* Write out the page data. */
-+      rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
++/*************************************************************************
++**************************************************************************
++** Below this point is the implementation of the fts5_decode() scalar
++** function only.
++*/
 +
-+      /* If page 1 was just written, update Pager.dbFileVers to match
-+      ** the value now stored in the database file. If writing this 
-+      ** page caused the database file to grow, update dbFileSize. 
-       */
--      rc = pagerLockDb(pPager, RESERVED_LOCK);
--      if( rc==SQLITE_OK && exFlag ){
--        rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
-+      if( pgno==1 ){
-+        memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers));
-       }
--    }
-+      if( pgno>pPager->dbFileSize ){
-+        pPager->dbFileSize = pgno;
-+      }
-+      pPager->aStat[PAGER_STAT_WRITE]++;
- 
--    if( rc==SQLITE_OK ){
--      /* Change to WRITER_LOCKED state.
--      **
--      ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD
--      ** when it has an open transaction, but never to DBMOD or FINISHED.
--      ** This is because in those states the code to roll back savepoint 
--      ** transactions may copy data from the sub-journal into the database 
--      ** file as well as into the page cache. Which would be incorrect in 
--      ** WAL mode.
--      */
--      pPager->eState = PAGER_WRITER_LOCKED;
--      pPager->dbHintSize = pPager->dbSize;
--      pPager->dbFileSize = pPager->dbSize;
--      pPager->dbOrigSize = pPager->dbSize;
--      pPager->journalOff = 0;
--    }
-+      /* Update any backup objects copying the contents of this pager. */
-+      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData);
- 
--    assert( rc==SQLITE_OK || pPager->eState==PAGER_READER );
--    assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED );
--    assert( assert_pager_state(pPager) );
-+      PAGERTRACE(("STORE %d page %d hash(%08x)\n",
-+                   PAGERID(pPager), pgno, pager_pagehash(pList)));
-+      IOTRACE(("PGOUT %p %d\n", pPager, pgno));
-+      PAGER_INCR(sqlite3_pager_writedb_count);
++/*
++** Decode a segment-data rowid from the %_data table. This function is
++** the opposite of macro FTS5_SEGMENT_ROWID().
++*/
++static void fts5DecodeRowid(
++  i64 iRowid,                     /* Rowid from %_data table */
++  int *piSegid,                   /* OUT: Segment id */
++  int *pbDlidx,                   /* OUT: Dlidx flag */
++  int *piHeight,                  /* OUT: Height */
++  int *piPgno                     /* OUT: Page number */
++){
++  *piPgno = (int)(iRowid & (((i64)1 << FTS5_DATA_PAGE_B) - 1));
++  iRowid >>= FTS5_DATA_PAGE_B;
++
++  *piHeight = (int)(iRowid & (((i64)1 << FTS5_DATA_HEIGHT_B) - 1));
++  iRowid >>= FTS5_DATA_HEIGHT_B;
++
++  *pbDlidx = (int)(iRowid & 0x0001);
++  iRowid >>= FTS5_DATA_DLI_B;
++
++  *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1));
++}
++
++static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){
++  int iSegid, iHeight, iPgno, bDlidx;       /* Rowid compenents */
++  fts5DecodeRowid(iKey, &iSegid, &bDlidx, &iHeight, &iPgno);
++
++  if( iSegid==0 ){
++    if( iKey==FTS5_AVERAGES_ROWID ){
++      sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} ");
 +    }else{
-+      PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno));
++      sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{structure}");
 +    }
-+    pager_set_pagehash(pList);
-+    pList = pList->pDirty;
-   }
- 
--  PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager)));
-   return rc;
- }
- 
- /*
--** Mark a single data page as writeable. The page is written into the 
--** main journal or sub-journal as required. If the page is written into
--** one of the journals, the corresponding bit is set in the 
--** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs
--** of any open savepoints as appropriate.
-+** Ensure that the sub-journal file is open. If it is already open, this 
-+** function is a no-op.
++  }
++  else{
++    sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%ssegid=%d h=%d pgno=%d}",
++        bDlidx ? "dlidx " : "", iSegid, iHeight, iPgno
++    );
++  }
++}
++
++static void fts5DebugStructure(
++  int *pRc,                       /* IN/OUT: error code */
++  Fts5Buffer *pBuf,
++  Fts5Structure *p
++){
++  int iLvl, iSeg;                 /* Iterate through levels, segments */
++
++  for(iLvl=0; iLvl<p->nLevel; iLvl++){
++    Fts5StructureLevel *pLvl = &p->aLevel[iLvl];
++    sqlite3Fts5BufferAppendPrintf(pRc, pBuf, 
++        " {lvl=%d nMerge=%d nSeg=%d", iLvl, pLvl->nMerge, pLvl->nSeg
++    );
++    for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
++      Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
++      sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d}", 
++          pSeg->iSegid, pSeg->pgnoFirst, pSeg->pgnoLast
++      );
++    }
++    sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}");
++  }
++}
++
++/*
++** This is part of the fts5_decode() debugging aid.
 +**
-+** SQLITE_OK is returned if everything goes according to plan. An 
-+** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() 
-+** fails.
- */
--static int pager_write(PgHdr *pPg){
--  Pager *pPager = pPg->pPager;
-+static int openSubJournal(Pager *pPager){
-   int rc = SQLITE_OK;
--  int inJournal;
--
--  /* This routine is not called unless a write-transaction has already 
--  ** been started. The journal file may or may not be open at this point.
--  ** It is never called in the ERROR state.
--  */
--  assert( pPager->eState==PAGER_WRITER_LOCKED
--       || pPager->eState==PAGER_WRITER_CACHEMOD
--       || pPager->eState==PAGER_WRITER_DBMOD
--  );
--  assert( assert_pager_state(pPager) );
--  assert( pPager->errCode==0 );
--  assert( pPager->readOnly==0 );
--
--  CHECK_PAGE(pPg);
--
--  /* The journal file needs to be opened. Higher level routines have already
--  ** obtained the necessary locks to begin the write-transaction, but the
--  ** rollback journal might not yet be open. Open it now if this is the case.
--  **
--  ** This is done before calling sqlite3PcacheMakeDirty() on the page. 
--  ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then
--  ** an error might occur and the pager would end up in WRITER_LOCKED state
--  ** with pages marked as dirty in the cache.
--  */
--  if( pPager->eState==PAGER_WRITER_LOCKED ){
--    rc = pager_open_journal(pPager);
--    if( rc!=SQLITE_OK ) return rc;
-+  if( !isOpen(pPager->sjfd) ){
-+    if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
-+      sqlite3MemJournalOpen(pPager->sjfd);
-+    }else{
-+      rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
++** Arguments pBlob/nBlob contain a serialized Fts5Structure object. This
++** function appends a human-readable representation of the same object
++** to the buffer passed as the second argument. 
++*/
++static void fts5DecodeStructure(
++  int *pRc,                       /* IN/OUT: error code */
++  Fts5Buffer *pBuf,
++  const u8 *pBlob, int nBlob
++){
++  int rc;                         /* Return code */
++  Fts5Structure *p = 0;           /* Decoded structure object */
++
++  rc = fts5StructureDecode(pBlob, nBlob, 0, &p);
++  if( rc!=SQLITE_OK ){
++    *pRc = rc;
++    return;
++  }
++
++  fts5DebugStructure(pRc, pBuf, p);
++  fts5StructureRelease(p);
++}
++
++/*
++** This is part of the fts5_decode() debugging aid.
++**
++** Arguments pBlob/nBlob contain an "averages" record. This function 
++** appends a human-readable representation of record to the buffer passed 
++** as the second argument. 
++*/
++static void fts5DecodeAverages(
++  int *pRc,                       /* IN/OUT: error code */
++  Fts5Buffer *pBuf,
++  const u8 *pBlob, int nBlob
++){
++  int i = 0;
++  const char *zSpace = "";
++
++  while( i<nBlob ){
++    u64 iVal;
++    i += sqlite3Fts5GetVarint(&pBlob[i], &iVal);
++    sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "%s%d", zSpace, (int)iVal);
++    zSpace = " ";
++  }
++}
++
++/*
++** Buffer (a/n) is assumed to contain a list of serialized varints. Read
++** each varint and append its string representation to buffer pBuf. Return
++** after either the input buffer is exhausted or a 0 value is read.
++**
++** The return value is the number of bytes read from the input buffer.
++*/
++static int fts5DecodePoslist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){
++  int iOff = 0;
++  while( iOff<n ){
++    int iVal;
++    iOff += fts5GetVarint32(&a[iOff], iVal);
++    sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %d", iVal);
++  }
++  return iOff;
++}
++
++/*
++** The start of buffer (a/n) contains the start of a doclist. The doclist
++** may or may not finish within the buffer. This function appends a text
++** representation of the part of the doclist that is present to buffer
++** pBuf. 
++**
++** The return value is the number of bytes read from the input buffer.
++*/
++static int fts5DecodeDoclist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){
++  i64 iDocid = 0;
++  int iOff = 0;
++
++  if( n>0 ){
++    iOff = sqlite3Fts5GetVarint(a, (u64*)&iDocid);
++    sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " id=%lld", iDocid);
++  }
++  while( iOff<n ){
++    int nPos;
++    int bDel;
++    iOff += fts5GetPoslistSize(&a[iOff], &nPos, &bDel);
++    sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " nPos=%d%s", nPos, bDel?"*":"");
++    iOff += fts5DecodePoslist(pRc, pBuf, &a[iOff], MIN(n-iOff, nPos));
++    if( iOff<n ){
++      i64 iDelta;
++      iOff += sqlite3Fts5GetVarint(&a[iOff], (u64*)&iDelta);
++      iDocid += iDelta;
++      sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " id=%lld", iDocid);
 +    }
-   }
--  assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
--  assert( assert_pager_state(pPager) );
--
--  /* Mark the page as dirty.  If the page has already been written
--  ** to the journal then we can return right away.
--  */
--  sqlite3PcacheMakeDirty(pPg);
--  inJournal = pageInJournal(pPager, pPg);
--  if( inJournal && (pPager->nSavepoint==0 || !subjRequiresPage(pPg)) ){
--    assert( !pagerUseWal(pPager) );
--  }else{
--  
--    /* The transaction journal now exists and we have a RESERVED or an
--    ** EXCLUSIVE lock on the main database file.  Write the current page to
--    ** the transaction journal if it is not there already.
--    */
--    if( !inJournal && !pagerUseWal(pPager) ){
--      assert( pagerUseWal(pPager)==0 );
--      if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){
--        u32 cksum;
--        char *pData2;
--        i64 iOff = pPager->journalOff;
--
--        /* We should never write to the journal file the page that
--        ** contains the database locks.  The following assert verifies
--        ** that we do not. */
--        assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
--
--        assert( pPager->journalHdr<=pPager->journalOff );
--        CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
--        cksum = pager_cksum(pPager, (u8*)pData2);
--
--        /* Even if an IO or diskfull error occurs while journalling the
--        ** page in the block above, set the need-sync flag for the page.
--        ** Otherwise, when the transaction is rolled back, the logic in
--        ** playback_one_page() will think that the page needs to be restored
--        ** in the database file. And if an IO error occurs while doing so,
--        ** then corruption may follow.
--        */
--        pPg->flags |= PGHDR_NEED_SYNC;
-+  return rc;
++  }
++
++  return iOff;
 +}
- 
--        rc = write32bits(pPager->jfd, iOff, pPg->pgno);
--        if( rc!=SQLITE_OK ) return rc;
--        rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4);
--        if( rc!=SQLITE_OK ) return rc;
--        rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum);
--        if( rc!=SQLITE_OK ) return rc;
++
 +/*
-+** Append a record of the current state of page pPg to the sub-journal. 
-+** It is the callers responsibility to use subjRequiresPage() to check 
-+** that it is really required before calling this function.
++** This function is part of the fts5_decode() debugging function. It is 
++** only ever used with detail=none tables.
 +**
-+** If successful, set the bit corresponding to pPg->pgno in the bitvecs
-+** for all open savepoints before returning.
++** Buffer (pData/nData) contains a doclist in the format used by detail=none
++** tables. This function appends a human-readable version of that list to
++** buffer pBuf.
 +**
-+** This function returns SQLITE_OK if everything is successful, an IO
-+** error code if the attempt to write to the sub-journal fails, or 
-+** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint
-+** bitvec.
++** If *pRc is other than SQLITE_OK when this function is called, it is a
++** no-op. If an OOM or other error occurs within this function, *pRc is
++** set to an SQLite error code before returning. The final state of buffer
++** pBuf is undefined in this case.
 +*/
-+static int subjournalPage(PgHdr *pPg){
-+  int rc = SQLITE_OK;
-+  Pager *pPager = pPg->pPager;
-+  if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
- 
--        IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, 
--                 pPager->journalOff, pPager->pageSize));
--        PAGER_INCR(sqlite3_pager_writej_count);
--        PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n",
--             PAGERID(pPager), pPg->pgno, 
--             ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg)));
-+    /* Open the sub-journal, if it has not already been opened */
-+    assert( pPager->useJournal );
-+    assert( isOpen(pPager->jfd) || pagerUseWal(pPager) );
-+    assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 );
-+    assert( pagerUseWal(pPager) 
-+         || pageInJournal(pPager, pPg) 
-+         || pPg->pgno>pPager->dbOrigSize 
-+    );
-+    rc = openSubJournal(pPager);
- 
--        pPager->journalOff += 8 + pPager->pageSize;
--        pPager->nRec++;
--        assert( pPager->pInJournal!=0 );
--        rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
--        testcase( rc==SQLITE_NOMEM );
--        assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
--        rc |= addToSavepointBitvecs(pPager, pPg->pgno);
--        if( rc!=SQLITE_OK ){
--          assert( rc==SQLITE_NOMEM );
--          return rc;
--        }
--      }else{
--        if( pPager->eState!=PAGER_WRITER_DBMOD ){
--          pPg->flags |= PGHDR_NEED_SYNC;
--        }
--        PAGERTRACE(("APPEND %d page %d needSync=%d\n",
--                PAGERID(pPager), pPg->pgno,
--               ((pPg->flags&PGHDR_NEED_SYNC)?1:0)));
--      }
--    }
-+    /* If the sub-journal was opened successfully (or was already open),
-+    ** write the journal record into the file.  */
-+    if( rc==SQLITE_OK ){
-+      void *pData = pPg->pData;
-+      i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
-+      char *pData2;
-   
--    /* If the statement journal is open and the page is not in it,
--    ** then write the current page to the statement journal.  Note that
--    ** the statement journal format differs from the standard journal format
--    ** in that it omits the checksums and the header.
--    */
--    if( pPager->nSavepoint>0 && subjRequiresPage(pPg) ){
--      rc = subjournalPage(pPg);
-+      CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
-+      PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
-+      rc = write32bits(pPager->sjfd, offset, pPg->pgno);
-+      if( rc==SQLITE_OK ){
-+        rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
++static void fts5DecodeRowidList(
++  int *pRc,                       /* IN/OUT: Error code */
++  Fts5Buffer *pBuf,               /* Buffer to append text to */
++  const u8 *pData, int nData      /* Data to decode list-of-rowids from */
++){
++  int i = 0;
++  i64 iRowid = 0;
++
++  while( i<nData ){
++    const char *zApp = "";
++    u64 iVal;
++    i += sqlite3Fts5GetVarint(&pData[i], &iVal);
++    iRowid += iVal;
++
++    if( i<nData && pData[i]==0x00 ){
++      i++;
++      if( i<nData && pData[i]==0x00 ){
++        i++;
++        zApp = "+";
++      }else{
++        zApp = "*";
 +      }
-     }
-   }
--
--  /* Update the database size and return.
--  */
--  if( pPager->dbSize<pPg->pgno ){
--    pPager->dbSize = pPg->pgno;
-+  if( rc==SQLITE_OK ){
-+    pPager->nSubRec++;
-+    assert( pPager->nSavepoint>0 );
-+    rc = addToSavepointBitvecs(pPager, pPg->pgno);
-   }
-   return rc;
- }
- 
- /*
--** This is a variant of sqlite3PagerWrite() that runs when the sector size
--** is larger than the page size.  SQLite makes the (reasonable) assumption that
--** all bytes of a sector are written together by hardware.  Hence, all bytes of
--** a sector need to be journalled in case of a power loss in the middle of
--** a write.
-+** This function is called by the pcache layer when it has reached some
-+** soft memory limit. The first argument is a pointer to a Pager object
-+** (cast as a void*). The pager is always 'purgeable' (not an in-memory
-+** database). The second argument is a reference to a page that is 
-+** currently dirty but has no outstanding references. The page
-+** is always associated with the Pager object passed as the first 
-+** argument.
- **
--** Usually, the sector size is less than or equal to the page size, in which
--** case pages can be individually written.  This routine only runs in the exceptional
--** case where the page size is smaller than the sector size.
-+** The job of this function is to make pPg clean by writing its contents
-+** out to the database file, if possible. This may involve syncing the
-+** journal file. 
-+**
-+** If successful, sqlite3PcacheMakeClean() is called on the page and
-+** SQLITE_OK returned. If an IO error occurs while trying to make the
-+** page clean, the IO error code is returned. If the page cannot be
-+** made clean for some other reason, but no error occurs, then SQLITE_OK
-+** is returned by sqlite3PcacheMakeClean() is not called.
- */
--static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){
--  int rc = SQLITE_OK;            /* Return code */
--  Pgno nPageCount;               /* Total number of pages in database file */
--  Pgno pg1;                      /* First page of the sector pPg is located on. */
--  int nPage = 0;                 /* Number of pages starting at pg1 to journal */
--  int ii;                        /* Loop counter */
--  int needSync = 0;              /* True if any page has PGHDR_NEED_SYNC */
--  Pager *pPager = pPg->pPager;   /* The pager that owns pPg */
--  Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
-+static int pagerStress(void *p, PgHdr *pPg){
-+  Pager *pPager = (Pager *)p;
-+  int rc = SQLITE_OK;
- 
--  /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
--  ** a journal header to be written between the pages journaled by
--  ** this function.
--  */
--  assert( !MEMDB );
--  assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 );
--  pPager->doNotSpill |= SPILLFLAG_NOSYNC;
-+  assert( pPg->pPager==pPager );
-+  assert( pPg->flags&PGHDR_DIRTY );
- 
--  /* This trick assumes that both the page-size and sector-size are
--  ** an integer power of 2. It sets variable pg1 to the identifier
--  ** of the first page of the sector pPg is located on.
-+  /* The doNotSpill NOSYNC bit is set during times when doing a sync of
-+  ** journal (and adding a new header) is not allowed.  This occurs
-+  ** during calls to sqlite3PagerWrite() while trying to journal multiple
-+  ** pages belonging to the same sector.
-+  **
-+  ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling
-+  ** regardless of whether or not a sync is required.  This is set during
-+  ** a rollback or by user request, respectively.
-+  **
-+  ** Spilling is also prohibited when in an error state since that could
-+  ** lead to database corruption.   In the current implementation it 
-+  ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3
-+  ** while in the error state, hence it is impossible for this routine to
-+  ** be called in the error state.  Nevertheless, we include a NEVER()
-+  ** test for the error state as a safeguard against future changes.
-   */
--  pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
--
--  nPageCount = pPager->dbSize;
--  if( pPg->pgno>nPageCount ){
--    nPage = (pPg->pgno - pg1)+1;
--  }else if( (pg1+nPagePerSector-1)>nPageCount ){
--    nPage = nPageCount+1-pg1;
--  }else{
--    nPage = nPagePerSector;
-+  if( NEVER(pPager->errCode) ) return SQLITE_OK;
-+  testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK );
-+  testcase( pPager->doNotSpill & SPILLFLAG_OFF );
-+  testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC );
-+  if( pPager->doNotSpill
-+   && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0
-+      || (pPg->flags & PGHDR_NEED_SYNC)!=0)
-+  ){
-+    return SQLITE_OK;
-   }
--  assert(nPage>0);
--  assert(pg1<=pPg->pgno);
--  assert((pg1+nPage)>pPg->pgno);
- 
--  for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
--    Pgno pg = pg1+ii;
--    PgHdr *pPage;
--    if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
--      if( pg!=PAGER_MJ_PGNO(pPager) ){
--        rc = sqlite3PagerGet(pPager, pg, &pPage);
--        if( rc==SQLITE_OK ){
--          rc = pager_write(pPage);
--          if( pPage->flags&PGHDR_NEED_SYNC ){
--            needSync = 1;
--          }
--          sqlite3PagerUnrefNotNull(pPage);
--        }
--      }
--    }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){
--      if( pPage->flags&PGHDR_NEED_SYNC ){
--        needSync = 1;
--      }
--      sqlite3PagerUnrefNotNull(pPage);
-+  pPg->pDirty = 0;
-+  if( pagerUseWal(pPager) ){
-+    /* Write a single frame for this page to the log. */
-+    if( subjRequiresPage(pPg) ){ 
-+      rc = subjournalPage(pPg); 
 +    }
-+    if( rc==SQLITE_OK ){
-+      rc = pagerWalFrames(pPager, pPg, 0, 0);
++
++    sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp);
++  }
++}
++
++/*
++** The implementation of user-defined scalar function fts5_decode().
++*/
++static void fts5DecodeFunction(
++  sqlite3_context *pCtx,          /* Function call context */
++  int nArg,                       /* Number of args (always 2) */
++  sqlite3_value **apVal           /* Function arguments */
++){
++  i64 iRowid;                     /* Rowid for record being decoded */
++  int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */
++  const u8 *aBlob; int n;         /* Record to decode */
++  u8 *a = 0;
++  Fts5Buffer s;                   /* Build up text to return here */
++  int rc = SQLITE_OK;             /* Return code */
++  int nSpace = 0;
++  int eDetailNone = (sqlite3_user_data(pCtx)!=0);
++
++  assert( nArg==2 );
++  UNUSED_PARAM(nArg);
++  memset(&s, 0, sizeof(Fts5Buffer));
++  iRowid = sqlite3_value_int64(apVal[0]);
++
++  /* Make a copy of the second argument (a blob) in aBlob[]. The aBlob[]
++  ** copy is followed by FTS5_DATA_ZERO_PADDING 0x00 bytes, which prevents
++  ** buffer overreads even if the record is corrupt.  */
++  n = sqlite3_value_bytes(apVal[1]);
++  aBlob = sqlite3_value_blob(apVal[1]);
++  nSpace = n + FTS5_DATA_ZERO_PADDING;
++  a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
++  if( a==0 ) goto decode_out;
++  memcpy(a, aBlob, n);
++
++
++  fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno);
++
++  fts5DebugRowid(&rc, &s, iRowid);
++  if( bDlidx ){
++    Fts5Data dlidx;
++    Fts5DlidxLvl lvl;
++
++    dlidx.p = a;
++    dlidx.nn = n;
++
++    memset(&lvl, 0, sizeof(Fts5DlidxLvl));
++    lvl.pData = &dlidx;
++    lvl.iLeafPgno = iPgno;
++
++    for(fts5DlidxLvlNext(&lvl); lvl.bEof==0; fts5DlidxLvlNext(&lvl)){
++      sqlite3Fts5BufferAppendPrintf(&rc, &s, 
++          " %d(%lld)", lvl.iLeafPgno, lvl.iRowid
++      );
++    }
++  }else if( iSegid==0 ){
++    if( iRowid==FTS5_AVERAGES_ROWID ){
++      fts5DecodeAverages(&rc, &s, a, n);
++    }else{
++      fts5DecodeStructure(&rc, &s, a, n);
++    }
++  }else if( eDetailNone ){
++    Fts5Buffer term;              /* Current term read from page */
++    int szLeaf;
++    int iPgidxOff = szLeaf = fts5GetU16(&a[2]);
++    int iTermOff;
++    int nKeep = 0;
++    int iOff;
++
++    memset(&term, 0, sizeof(Fts5Buffer));
++
++    /* Decode any entries that occur before the first term. */
++    if( szLeaf<n ){
++      iPgidxOff += fts5GetVarint32(&a[iPgidxOff], iTermOff);
++    }else{
++      iTermOff = szLeaf;
++    }
++    fts5DecodeRowidList(&rc, &s, &a[4], iTermOff-4);
++
++    iOff = iTermOff;
++    while( iOff<szLeaf ){
++      int nAppend;
++
++      /* Read the term data for the next term*/
++      iOff += fts5GetVarint32(&a[iOff], nAppend);
++      term.n = nKeep;
++      fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]);
++      sqlite3Fts5BufferAppendPrintf(
++          &rc, &s, " term=%.*s", term.n, (const char*)term.p
++      );
++      iOff += nAppend;
++
++      /* Figure out where the doclist for this term ends */
++      if( iPgidxOff<n ){
++        int nIncr;
++        iPgidxOff += fts5GetVarint32(&a[iPgidxOff], nIncr);
++        iTermOff += nIncr;
++      }else{
++        iTermOff = szLeaf;
++      }
++
++      fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff);
++      iOff = iTermOff;
++      if( iOff<szLeaf ){
++        iOff += fts5GetVarint32(&a[iOff], nKeep);
++      }
 +    }
++
++    fts5BufferFree(&term);
 +  }else{
-+  
-+    /* Sync the journal file if required. */
-+    if( pPg->flags&PGHDR_NEED_SYNC 
-+     || pPager->eState==PAGER_WRITER_CACHEMOD
-+    ){
-+      rc = syncJournal(pPager, 1);
++    Fts5Buffer term;              /* Current term read from page */
++    int szLeaf;                   /* Offset of pgidx in a[] */
++    int iPgidxOff;
++    int iPgidxPrev = 0;           /* Previous value read from pgidx */
++    int iTermOff = 0;
++    int iRowidOff = 0;
++    int iOff;
++    int nDoclist;
++
++    memset(&term, 0, sizeof(Fts5Buffer));
++
++    if( n<4 ){
++      sqlite3Fts5BufferSet(&rc, &s, 7, (const u8*)"corrupt");
++      goto decode_out;
++    }else{
++      iRowidOff = fts5GetU16(&a[0]);
++      iPgidxOff = szLeaf = fts5GetU16(&a[2]);
++      if( iPgidxOff<n ){
++        fts5GetVarint32(&a[iPgidxOff], iTermOff);
++      }
 +    }
-+  
-+    /* If the page number of this page is larger than the current size of
-+    ** the database image, it may need to be written to the sub-journal.
-+    ** This is because the call to pager_write_pagelist() below will not
-+    ** actually write data to the file in this case.
-+    **
-+    ** Consider the following sequence of events:
-+    **
-+    **   BEGIN;
-+    **     <journal page X>
-+    **     <modify page X>
-+    **     SAVEPOINT sp;
-+    **       <shrink database file to Y pages>
-+    **       pagerStress(page X)
-+    **     ROLLBACK TO sp;
-+    **
-+    ** If (X>Y), then when pagerStress is called page X will not be written
-+    ** out to the database file, but will be dropped from the cache. Then,
-+    ** following the "ROLLBACK TO sp" statement, reading page X will read
-+    ** data from the database file. This will be the copy of page X as it
-+    ** was when the transaction started, not as it was when "SAVEPOINT sp"
-+    ** was executed.
-+    **
-+    ** The solution is to write the current data for page X into the 
-+    ** sub-journal file now (if it is not already there), so that it will
-+    ** be restored to its current value when the "ROLLBACK TO sp" is 
-+    ** executed.
-+    */
-+    if( NEVER(
-+        rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
-+    ) ){
-+      rc = subjournalPage(pPg);
++
++    /* Decode the position list tail at the start of the page */
++    if( iRowidOff!=0 ){
++      iOff = iRowidOff;
++    }else if( iTermOff!=0 ){
++      iOff = iTermOff;
++    }else{
++      iOff = szLeaf;
++    }
++    fts5DecodePoslist(&rc, &s, &a[4], iOff-4);
++
++    /* Decode any more doclist data that appears on the page before the
++    ** first term. */
++    nDoclist = (iTermOff ? iTermOff : szLeaf) - iOff;
++    fts5DecodeDoclist(&rc, &s, &a[iOff], nDoclist);
++
++    while( iPgidxOff<n ){
++      int bFirst = (iPgidxOff==szLeaf);     /* True for first term on page */
++      int nByte;                            /* Bytes of data */
++      int iEnd;
++      
++      iPgidxOff += fts5GetVarint32(&a[iPgidxOff], nByte);
++      iPgidxPrev += nByte;
++      iOff = iPgidxPrev;
++
++      if( iPgidxOff<n ){
++        fts5GetVarint32(&a[iPgidxOff], nByte);
++        iEnd = iPgidxPrev + nByte;
++      }else{
++        iEnd = szLeaf;
++      }
++
++      if( bFirst==0 ){
++        iOff += fts5GetVarint32(&a[iOff], nByte);
++        term.n = nByte;
++      }
++      iOff += fts5GetVarint32(&a[iOff], nByte);
++      fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]);
++      iOff += nByte;
++
++      sqlite3Fts5BufferAppendPrintf(
++          &rc, &s, " term=%.*s", term.n, (const char*)term.p
++      );
++      iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff);
 +    }
++
++    fts5BufferFree(&term);
++  }
 +  
-+    /* Write the contents of the page out to the database file. */
-+    if( rc==SQLITE_OK ){
-+      assert( (pPg->flags&PGHDR_NEED_SYNC)==0 );
-+      rc = pager_write_pagelist(pPager, pPg);
-     }
-   }
- 
--  /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages 
--  ** starting at pg1, then it needs to be set for all of them. Because
--  ** writing to any of these nPage pages may damage the others, the
--  ** journal file must contain sync()ed copies of all of them
--  ** before any of them can be written out to the database file.
--  */
--  if( rc==SQLITE_OK && needSync ){
--    assert( !MEMDB );
--    for(ii=0; ii<nPage; ii++){
--      PgHdr *pPage = sqlite3PagerLookup(pPager, pg1+ii);
--      if( pPage ){
--        pPage->flags |= PGHDR_NEED_SYNC;
--        sqlite3PagerUnrefNotNull(pPage);
--      }
--    }
-+  /* Mark the page as clean. */
++ decode_out:
++  sqlite3_free(a);
 +  if( rc==SQLITE_OK ){
-+    PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
-+    sqlite3PcacheMakeClean(pPg);
-   }
- 
--  assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
--  pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
--  return rc;
-+  return pager_error(pPager, rc); 
- }
- 
-+
- /*
--** Mark a data page as writeable. This routine must be called before 
--** making changes to a page. The caller must check the return value 
--** of this function and be careful not to change any page data unless 
--** this routine returns SQLITE_OK.
-+** Allocate and initialize a new Pager object and put a pointer to it
-+** in *ppPager. The pager should eventually be freed by passing it
-+** to sqlite3PagerClose().
- **
--** The difference between this function and pager_write() is that this
--** function also deals with the special case where 2 or more pages
--** fit on a single disk sector. In this case all co-resident pages
--** must have been written to the journal file before returning.
-+** The zFilename argument is the path to the database file to open.
-+** If zFilename is NULL then a randomly-named temporary file is created
-+** and used as the file to be cached. Temporary files are be deleted
-+** automatically when they are closed. If zFilename is ":memory:" then 
-+** all information is held in cache. It is never written to disk. 
-+** This can be used to implement an in-memory database.
- **
--** If an error occurs, SQLITE_NOMEM or an IO error code is returned
--** as appropriate. Otherwise, SQLITE_OK.
-+** The nExtra parameter specifies the number of bytes of space allocated
-+** along with each page reference. This space is available to the user
-+** via the sqlite3PagerGetExtra() API.
-+**
-+** The flags argument is used to specify properties that affect the
-+** operation of the pager. It should be passed some bitwise combination
-+** of the PAGER_* flags.
-+**
-+** The vfsFlags parameter is a bitmask to pass to the flags parameter
-+** of the xOpen() method of the supplied VFS when opening files. 
-+**
-+** If the pager object is allocated and the specified file opened 
-+** successfully, SQLITE_OK is returned and *ppPager set to point to
-+** the new pager object. If an error occurs, *ppPager is set to NULL
-+** and error code returned. This function may return SQLITE_NOMEM
-+** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or 
-+** various SQLITE_IO_XXX errors.
- */
--SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){
--  assert( (pPg->flags & PGHDR_MMAP)==0 );
--  assert( pPg->pPager->eState>=PAGER_WRITER_LOCKED );
--  assert( pPg->pPager->eState!=PAGER_ERROR );
--  assert( assert_pager_state(pPg->pPager) );
--  if( pPg->pPager->sectorSize > (u32)pPg->pPager->pageSize ){
--    return pagerWriteLargeSector(pPg);
-+SQLITE_PRIVATE int sqlite3PagerOpen(
-+  sqlite3_vfs *pVfs,       /* The virtual file system to use */
-+  Pager **ppPager,         /* OUT: Return the Pager structure here */
-+  const char *zFilename,   /* Name of the database file to open */
-+  int nExtra,              /* Extra bytes append to each in-memory page */
-+  int flags,               /* flags controlling this file */
-+  int vfsFlags,            /* flags passed through to sqlite3_vfs.xOpen() */
-+  void (*xReinit)(DbPage*) /* Function to reinitialize pages */
++    sqlite3_result_text(pCtx, (const char*)s.p, s.n, SQLITE_TRANSIENT);
++  }else{
++    sqlite3_result_error_code(pCtx, rc);
++  }
++  fts5BufferFree(&s);
++}
++
++/*
++** The implementation of user-defined scalar function fts5_rowid().
++*/
++static void fts5RowidFunction(
++  sqlite3_context *pCtx,          /* Function call context */
++  int nArg,                       /* Number of args (always 2) */
++  sqlite3_value **apVal           /* Function arguments */
 +){
-+  u8 *pPtr;
-+  Pager *pPager = 0;       /* Pager object to allocate and return */
-+  int rc = SQLITE_OK;      /* Return code */
-+  int tempFile = 0;        /* True for temp files (incl. in-memory files) */
-+  int memDb = 0;           /* True if this is an in-memory file */
-+  int readOnly = 0;        /* True if this is a read-only file */
-+  int journalFileSize;     /* Bytes to allocate for each journal fd */
-+  char *zPathname = 0;     /* Full path to database file */
-+  int nPathname = 0;       /* Number of bytes in zPathname */
-+  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
-+  int pcacheSize = sqlite3PcacheSize();       /* Bytes to allocate for PCache */
-+  u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
-+  const char *zUri = 0;    /* URI args to copy */
-+  int nUri = 0;            /* Number of bytes of URI args at *zUri */
-+
-+  /* Figure out how much space is required for each journal file-handle
-+  ** (there are two of them, the main journal and the sub-journal). This
-+  ** is the maximum space required for an in-memory journal file handle 
-+  ** and a regular journal file-handle. Note that a "regular journal-handle"
-+  ** may be a wrapper capable of caching the first portion of the journal
-+  ** file in memory to implement the atomic-write optimization (see 
-+  ** source file journal.c).
-+  */
-+  if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
-+    journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
-   }else{
--    return pager_write(pPg);
-+    journalFileSize = ROUND8(sqlite3MemJournalSize());
-   }
--}
- 
--/*
--** Return TRUE if the page given in the argument was previously passed
--** to sqlite3PagerWrite().  In other words, return TRUE if it is ok
--** to change the content of the page.
--*/
--#ifndef NDEBUG
--SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){
--  return pPg->flags&PGHDR_DIRTY;
--}
--#endif
-+  /* Set the output variable to NULL in case an error occurs. */
-+  *ppPager = 0;
- 
--/*
--** A call to this routine tells the pager that it is not necessary to
--** write the information on page pPg back to the disk, even though
--** that page might be marked as dirty.  This happens, for example, when
--** the page has been added as a leaf of the freelist and so its
--** content no longer matters.
--**
--** The overlying software layer calls this routine when all of the data
--** on the given page is unused. The pager marks the page as clean so
--** that it does not get written to disk.
--**
--** Tests show that this optimization can quadruple the speed of large 
--** DELETE operations.
--*/
--SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
--  Pager *pPager = pPg->pPager;
--  if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
--    PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
--    IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
--    pPg->flags |= PGHDR_DONT_WRITE;
--    pager_set_pagehash(pPg);
-+#ifndef SQLITE_OMIT_MEMORYDB
-+  if( flags & PAGER_MEMORY ){
-+    memDb = 1;
-+    if( zFilename && zFilename[0] ){
-+      zPathname = sqlite3DbStrDup(0, zFilename);
-+      if( zPathname==0  ) return SQLITE_NOMEM;
-+      nPathname = sqlite3Strlen30(zPathname);
-+      zFilename = 0;
-+    }
-   }
--}
--
--/*
--** This routine is called to increment the value of the database file 
--** change-counter, stored as a 4-byte big-endian integer starting at 
--** byte offset 24 of the pager file.  The secondary change counter at
--** 92 is also updated, as is the SQLite version number at offset 96.
--**
--** But this only happens if the pPager->changeCountDone flag is false.
--** To avoid excess churning of page 1, the update only happens once.
--** See also the pager_write_changecounter() routine that does an 
--** unconditional update of the change counters.
--**
--** If the isDirectMode flag is zero, then this is done by calling 
--** sqlite3PagerWrite() on page 1, then modifying the contents of the
--** page data. In this case the file will be updated when the current
--** transaction is committed.
--**
--** The isDirectMode flag may only be non-zero if the library was compiled
--** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case,
--** if isDirect is non-zero, then the database file is updated directly
--** by writing an updated version of page 1 using a call to the 
--** sqlite3OsWrite() function.
--*/
--static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
--  int rc = SQLITE_OK;
-+#endif
- 
--  assert( pPager->eState==PAGER_WRITER_CACHEMOD
--       || pPager->eState==PAGER_WRITER_DBMOD
--  );
--  assert( assert_pager_state(pPager) );
-+  /* Compute and store the full pathname in an allocated buffer pointed
-+  ** to by zPathname, length nPathname. Or, if this is a temporary file,
-+  ** leave both nPathname and zPathname set to 0.
-+  */
-+  if( zFilename && zFilename[0] ){
-+    const char *z;
-+    nPathname = pVfs->mxPathname+1;
-+    zPathname = sqlite3DbMallocRaw(0, nPathname*2);
-+    if( zPathname==0 ){
-+      return SQLITE_NOMEM;
-+    }
-+    zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
-+    rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
-+    nPathname = sqlite3Strlen30(zPathname);
-+    z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1];
-+    while( *z ){
-+      z += sqlite3Strlen30(z)+1;
-+      z += sqlite3Strlen30(z)+1;
-+    }
-+    nUri = (int)(&z[1] - zUri);
-+    assert( nUri>=0 );
-+    if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){
-+      /* This branch is taken when the journal path required by
-+      ** the database being opened will be more than pVfs->mxPathname
-+      ** bytes in length. This means the database cannot be opened,
-+      ** as it will not be possible to open the journal file or even
-+      ** check for a hot-journal before reading.
-+      */
-+      rc = SQLITE_CANTOPEN_BKPT;
-+    }
-+    if( rc!=SQLITE_OK ){
-+      sqlite3DbFree(0, zPathname);
-+      return rc;
++  const char *zArg;
++  if( nArg==0 ){
++    sqlite3_result_error(pCtx, "should be: fts5_rowid(subject, ....)", -1);
++  }else{
++    zArg = (const char*)sqlite3_value_text(apVal[0]);
++    if( 0==sqlite3_stricmp(zArg, "segment") ){
++      i64 iRowid;
++      int segid, pgno;
++      if( nArg!=3 ){
++        sqlite3_result_error(pCtx, 
++            "should be: fts5_rowid('segment', segid, pgno))", -1
++        );
++      }else{
++        segid = sqlite3_value_int(apVal[1]);
++        pgno = sqlite3_value_int(apVal[2]);
++        iRowid = FTS5_SEGMENT_ROWID(segid, pgno);
++        sqlite3_result_int64(pCtx, iRowid);
++      }
++    }else{
++      sqlite3_result_error(pCtx, 
++        "first arg to fts5_rowid() must be 'segment'" , -1
++      );
 +    }
 +  }
- 
--  /* Declare and initialize constant integer 'isDirect'. If the
--  ** atomic-write optimization is enabled in this build, then isDirect
--  ** is initialized to the value passed as the isDirectMode parameter
--  ** to this function. Otherwise, it is always set to zero.
-+  /* Allocate memory for the Pager structure, PCache object, the
-+  ** three file descriptors, the database file name and the journal 
-+  ** file name. The layout in memory is as follows:
-   **
--  ** The idea is that if the atomic-write optimization is not
--  ** enabled at compile time, the compiler can omit the tests of
--  ** 'isDirect' below, as well as the block enclosed in the
--  ** "if( isDirect )" condition.
-+  **     Pager object                    (sizeof(Pager) bytes)
-+  **     PCache object                   (sqlite3PcacheSize() bytes)
-+  **     Database file handle            (pVfs->szOsFile bytes)
-+  **     Sub-journal file handle         (journalFileSize bytes)
-+  **     Main journal file handle        (journalFileSize bytes)
-+  **     Database file name              (nPathname+1 bytes)
-+  **     Journal file name               (nPathname+8+1 bytes)
-   */
--#ifndef SQLITE_ENABLE_ATOMIC_WRITE
--# define DIRECT_MODE 0
--  assert( isDirectMode==0 );
--  UNUSED_PARAMETER(isDirectMode);
--#else
--# define DIRECT_MODE isDirectMode
-+  pPtr = (u8 *)sqlite3MallocZero(
-+    ROUND8(sizeof(*pPager)) +      /* Pager structure */
-+    ROUND8(pcacheSize) +           /* PCache object */
-+    ROUND8(pVfs->szOsFile) +       /* The main db file */
-+    journalFileSize * 2 +          /* The two journal files */ 
-+    nPathname + 1 + nUri +         /* zFilename */
-+    nPathname + 8 + 2              /* zJournal */
-+#ifndef SQLITE_OMIT_WAL
-+    + nPathname + 4 + 2            /* zWal */
- #endif
++}
++
++/*
++** This is called as part of registering the FTS5 module with database
++** connection db. It registers several user-defined scalar functions useful
++** with FTS5.
++**
++** If successful, SQLITE_OK is returned. If an error occurs, some other
++** SQLite error code is returned instead.
++*/
++static int sqlite3Fts5IndexInit(sqlite3 *db){
++  int rc = sqlite3_create_function(
++      db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0
 +  );
-+  assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
-+  if( !pPtr ){
-+    sqlite3DbFree(0, zPathname);
-+    return SQLITE_NOMEM;
-+  }
-+  pPager =              (Pager*)(pPtr);
-+  pPager->pPCache =    (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
-+  pPager->fd =   (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
-+  pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
-+  pPager->jfd =  (sqlite3_file*)(pPtr += journalFileSize);
-+  pPager->zFilename =    (char*)(pPtr += journalFileSize);
-+  assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
- 
--  if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){
--    PgHdr *pPgHdr;                /* Reference to page 1 */
--
--    assert( !pPager->tempFile && isOpen(pPager->fd) );
-+  /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
-+  if( zPathname ){
-+    assert( nPathname>0 );
-+    pPager->zJournal =   (char*)(pPtr += nPathname + 1 + nUri);
-+    memcpy(pPager->zFilename, zPathname, nPathname);
-+    if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
-+    memcpy(pPager->zJournal, zPathname, nPathname);
-+    memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2);
-+    sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
-+#ifndef SQLITE_OMIT_WAL
-+    pPager->zWal = &pPager->zJournal[nPathname+8+1];
-+    memcpy(pPager->zWal, zPathname, nPathname);
-+    memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1);
-+    sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
-+#endif
-+    sqlite3DbFree(0, zPathname);
-+  }
-+  pPager->pVfs = pVfs;
-+  pPager->vfsFlags = vfsFlags;
- 
--    /* Open page 1 of the file for writing. */
--    rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
--    assert( pPgHdr==0 || rc==SQLITE_OK );
-+  /* Open the pager file.
-+  */
-+  if( zFilename && zFilename[0] ){
-+    int fout = 0;                    /* VFS flags returned by xOpen() */
-+    rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
-+    assert( !memDb );
-+    readOnly = (fout&SQLITE_OPEN_READONLY);
- 
--    /* If page one was fetched successfully, and this function is not
--    ** operating in direct-mode, make page 1 writable.  When not in 
--    ** direct mode, page 1 is always held in cache and hence the PagerGet()
--    ** above is always successful - hence the ALWAYS on rc==SQLITE_OK.
-+    /* If the file was successfully opened for read/write access,
-+    ** choose a default page size in case we have to create the
-+    ** database file. The default page size is the maximum of:
-+    **
-+    **    + SQLITE_DEFAULT_PAGE_SIZE,
-+    **    + The value returned by sqlite3OsSectorSize()
-+    **    + The largest page size that can be written atomically.
-     */
--    if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){
--      rc = sqlite3PagerWrite(pPgHdr);
--    }
--
-     if( rc==SQLITE_OK ){
--      /* Actually do the update of the change counter */
--      pager_write_changecounter(pPgHdr);
--
--      /* If running in direct mode, write the contents of page 1 to the file. */
--      if( DIRECT_MODE ){
--        const void *zBuf;
--        assert( pPager->dbFileSize>0 );
--        CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf);
--        if( rc==SQLITE_OK ){
--          rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
--          pPager->aStat[PAGER_STAT_WRITE]++;
-+      int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
-+      if( !readOnly ){
-+        setSectorSize(pPager);
-+        assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE);
-+        if( szPageDflt<pPager->sectorSize ){
-+          if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
-+            szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
-+          }else{
-+            szPageDflt = (u32)pPager->sectorSize;
-+          }
-         }
--        if( rc==SQLITE_OK ){
--          /* Update the pager's copy of the change-counter. Otherwise, the
--          ** next time a read transaction is opened the cache will be
--          ** flushed (as the change-counter values will not match).  */
--          const void *pCopy = (const void *)&((const char *)zBuf)[24];
--          memcpy(&pPager->dbFileVers, pCopy, sizeof(pPager->dbFileVers));
--          pPager->changeCountDone = 1;
-+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-+        {
-+          int ii;
-+          assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
-+          assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
-+          assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536);
-+          for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
-+            if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){
-+              szPageDflt = ii;
-+            }
-+          }
-         }
--      }else{
--        pPager->changeCountDone = 1;
-+#endif
-+      }
-+      pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0);
-+      if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0
-+       || sqlite3_uri_boolean(zFilename, "immutable", 0) ){
-+          vfsFlags |= SQLITE_OPEN_READONLY;
-+          goto act_like_temp_file;
-       }
-     }
-+  }else{
-+    /* If a temporary file is requested, it is not opened immediately.
-+    ** In this case we accept the default page size and delay actually
-+    ** opening the file until the first call to OsWrite().
-+    **
-+    ** This branch is also run for an in-memory database. An in-memory
-+    ** database is the same as a temp-file that is never written out to
-+    ** disk and uses an in-memory rollback journal.
-+    **
-+    ** This branch also runs for files marked as immutable.
-+    */ 
-+act_like_temp_file:
-+    tempFile = 1;
-+    pPager->eState = PAGER_READER;     /* Pretend we already have a lock */
-+    pPager->eLock = EXCLUSIVE_LOCK;    /* Pretend we are in EXCLUSIVE locking mode */
-+    pPager->noLock = 1;                /* Do no locking */
-+    readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
-+  }
- 
--    /* Release the page reference. */
--    sqlite3PagerUnref(pPgHdr);
-+  /* The following call to PagerSetPagesize() serves to set the value of 
-+  ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer.
-+  */
++
 +  if( rc==SQLITE_OK ){
-+    assert( pPager->memDb==0 );
-+    rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1);
-+    testcase( rc!=SQLITE_OK );
-   }
--  return rc;
++    rc = sqlite3_create_function(
++        db, "fts5_decode_none", 2, 
++        SQLITE_UTF8, (void*)db, fts5DecodeFunction, 0, 0
++    );
++  }
 +
-+  /* Initialize the PCache object. */
 +  if( rc==SQLITE_OK ){
-+    assert( nExtra<1000 );
-+    nExtra = ROUND8(nExtra);
-+    rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
-+                           !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
++    rc = sqlite3_create_function(
++        db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0
++    );
 +  }
++  return rc;
++}
 +
-+  /* If an error occurred above, free the  Pager structure and close the file.
-+  */
-+  if( rc!=SQLITE_OK ){
-+    sqlite3OsClose(pPager->fd);
-+    sqlite3PageFree(pPager->pTmpSpace);
-+    sqlite3_free(pPager);
-+    return rc;
++
++static int sqlite3Fts5IndexReset(Fts5Index *p){
++  assert( p->pStruct==0 || p->iStructVersion!=0 );
++  if( fts5IndexDataVersion(p)!=p->iStructVersion ){
++    fts5StructureInvalidate(p);
 +  }
++  return fts5IndexReturn(p);
++}
 +
-+  PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
-+  IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
-+
-+  pPager->useJournal = (u8)useJournal;
-+  /* pPager->stmtOpen = 0; */
-+  /* pPager->stmtInUse = 0; */
-+  /* pPager->nRef = 0; */
-+  /* pPager->stmtSize = 0; */
-+  /* pPager->stmtJSize = 0; */
-+  /* pPager->nPage = 0; */
-+  pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
-+  /* pPager->state = PAGER_UNLOCK; */
-+  /* pPager->errMask = 0; */
-+  pPager->tempFile = (u8)tempFile;
-+  assert( tempFile==PAGER_LOCKINGMODE_NORMAL 
-+          || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
-+  assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
-+  pPager->exclusiveMode = (u8)tempFile; 
-+  pPager->changeCountDone = pPager->tempFile;
-+  pPager->memDb = (u8)memDb;
-+  pPager->readOnly = (u8)readOnly;
-+  assert( useJournal || pPager->tempFile );
-+  pPager->noSync = pPager->tempFile;
-+  if( pPager->noSync ){
-+    assert( pPager->fullSync==0 );
-+    assert( pPager->syncFlags==0 );
-+    assert( pPager->walSyncFlags==0 );
-+    assert( pPager->ckptSyncFlags==0 );
-+  }else{
-+    pPager->fullSync = 1;
-+    pPager->syncFlags = SQLITE_SYNC_NORMAL;
-+    pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS;
-+    pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
-+  }
-+  /* pPager->pFirst = 0; */
-+  /* pPager->pFirstSynced = 0; */
-+  /* pPager->pLast = 0; */
-+  pPager->nExtra = (u16)nExtra;
-+  pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
-+  assert( isOpen(pPager->fd) || tempFile );
-+  setSectorSize(pPager);
-+  if( !useJournal ){
-+    pPager->journalMode = PAGER_JOURNALMODE_OFF;
-+  }else if( memDb ){
-+    pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
-+  }
-+  /* pPager->xBusyHandler = 0; */
-+  /* pPager->pBusyHandlerArg = 0; */
-+  pPager->xReiniter = xReinit;
-+  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
-+  /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
-+
-+  *ppPager = pPager;
-+  return SQLITE_OK;
- }
- 
--/*
--** Sync the database file to disk. This is a no-op for in-memory databases
--** or pages with the Pager.noSync flag set.
--**
--** If successful, or if called on a pager for which it is a no-op, this
--** function returns SQLITE_OK. Otherwise, an IO error code is returned.
++/*
++** 2014 Jun 09
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This is an SQLite module implementing full-text search.
++*/
 +
-+/* Verify that the database file has not be deleted or renamed out from
-+** under the pager.  Return SQLITE_OK if the database is still were it ought
-+** to be on disk.  Return non-zero (SQLITE_READONLY_DBMOVED or some other error
-+** code from sqlite3OsAccess()) if the database has gone missing.
- */
--SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster){
--  int rc = SQLITE_OK;
-+static int databaseIsUnmoved(Pager *pPager){
-+  int bHasMoved = 0;
-+  int rc;
- 
--  if( isOpen(pPager->fd) ){
--    void *pArg = (void*)zMaster;
--    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg);
--    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
--  }
--  if( rc==SQLITE_OK && !pPager->noSync ){
--    assert( !MEMDB );
--    rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
-+  if( pPager->tempFile ) return SQLITE_OK;
-+  if( pPager->dbSize==0 ) return SQLITE_OK;
-+  assert( pPager->zFilename && pPager->zFilename[0] );
-+  rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
-+  if( rc==SQLITE_NOTFOUND ){
-+    /* If the HAS_MOVED file-control is unimplemented, assume that the file
-+    ** has not been moved.  That is the historical behavior of SQLite: prior to
-+    ** version 3.8.3, it never checked */
-+    rc = SQLITE_OK;
-+  }else if( rc==SQLITE_OK && bHasMoved ){
-+    rc = SQLITE_READONLY_DBMOVED;
-   }
-   return rc;
- }
- 
 +
- /*
--** This function may only be called while a write-transaction is active in
--** rollback. If the connection is in WAL mode, this call is a no-op. 
--** Otherwise, if the connection does not already have an EXCLUSIVE lock on 
--** the database file, an attempt is made to obtain one.
-+** This function is called after transitioning from PAGER_UNLOCK to
-+** PAGER_SHARED state. It tests if there is a hot journal present in
-+** the file-system for the given pager. A hot journal is one that 
-+** needs to be played back. According to this function, a hot-journal
-+** file exists if the following criteria are met:
- **
--** If the EXCLUSIVE lock is already held or the attempt to obtain it is
--** successful, or the connection is in WAL mode, SQLITE_OK is returned.
--** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is 
--** returned.
-+**   * The journal file exists in the file system, and
-+**   * No process holds a RESERVED or greater lock on the database file, and
-+**   * The database file itself is greater than 0 bytes in size, and
-+**   * The first byte of the journal file exists and is not 0x00.
-+**
-+** If the current size of the database file is 0 but a journal file
-+** exists, that is probably an old journal left over from a prior
-+** database with the same name. In this case the journal file is
-+** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK
-+** is returned.
-+**
-+** This routine does not check if there is a master journal filename
-+** at the end of the file. If there is, and that master journal file
-+** does not exist, then the journal file is not really hot. In this
-+** case this routine will return a false-positive. The pager_playback()
-+** routine will discover that the journal file is not really hot and 
-+** will not roll it back. 
-+**
-+** If a hot-journal file is found to exist, *pExists is set to 1 and 
-+** SQLITE_OK returned. If no hot-journal file is present, *pExists is
-+** set to 0 and SQLITE_OK returned. If an IO error occurs while trying
-+** to determine whether or not a hot-journal file exists, the IO error
-+** code is returned and the value of *pExists is undefined.
- */
--SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){
--  int rc = SQLITE_OK;
--  assert( pPager->eState==PAGER_WRITER_CACHEMOD 
--       || pPager->eState==PAGER_WRITER_DBMOD 
--       || pPager->eState==PAGER_WRITER_LOCKED 
--  );
--  assert( assert_pager_state(pPager) );
--  if( 0==pagerUseWal(pPager) ){
--    rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
-+static int hasHotJournal(Pager *pPager, int *pExists){
-+  sqlite3_vfs * const pVfs = pPager->pVfs;
-+  int rc = SQLITE_OK;           /* Return code */
-+  int exists = 1;               /* True if a journal file is present */
-+  int jrnlOpen = !!isOpen(pPager->jfd);
++/* #include "fts5Int.h" */
++
++/*
++** This variable is set to false when running tests for which the on disk
++** structures should not be corrupt. Otherwise, true. If it is false, extra
++** assert() conditions in the fts5 code are activated - conditions that are
++** only true if it is guaranteed that the fts5 database is not corrupt.
++*/
++SQLITE_API int sqlite3_fts5_may_be_corrupt = 1;
++
++
++typedef struct Fts5Auxdata Fts5Auxdata;
++typedef struct Fts5Auxiliary Fts5Auxiliary;
++typedef struct Fts5Cursor Fts5Cursor;
++typedef struct Fts5Sorter Fts5Sorter;
++typedef struct Fts5Table Fts5Table;
++typedef struct Fts5TokenizerModule Fts5TokenizerModule;
++
++/*
++** NOTES ON TRANSACTIONS: 
++**
++** SQLite invokes the following virtual table methods as transactions are 
++** opened and closed by the user:
++**
++**     xBegin():    Start of a new transaction.
++**     xSync():     Initial part of two-phase commit.
++**     xCommit():   Final part of two-phase commit.
++**     xRollback(): Rollback the transaction.
++**
++** Anything that is required as part of a commit that may fail is performed
++** in the xSync() callback. Current versions of SQLite ignore any errors 
++** returned by xCommit().
++**
++** And as sub-transactions are opened/closed:
++**
++**     xSavepoint(int S):  Open savepoint S.
++**     xRelease(int S):    Commit and close savepoint S.
++**     xRollbackTo(int S): Rollback to start of savepoint S.
++**
++** During a write-transaction the fts5_index.c module may cache some data 
++** in-memory. It is flushed to disk whenever xSync(), xRelease() or
++** xSavepoint() is called. And discarded whenever xRollback() or xRollbackTo() 
++** is called.
++**
++** Additionally, if SQLITE_DEBUG is defined, an instance of the following
++** structure is used to record the current transaction state. This information
++** is not required, but it is used in the assert() statements executed by
++** function fts5CheckTransactionState() (see below).
++*/
++struct Fts5TransactionState {
++  int eState;                     /* 0==closed, 1==open, 2==synced */
++  int iSavepoint;                 /* Number of open savepoints (0 -> none) */
++};
++
++/*
++** A single object of this type is allocated when the FTS5 module is 
++** registered with a database handle. It is used to store pointers to
++** all registered FTS5 extensions - tokenizers and auxiliary functions.
++*/
++struct Fts5Global {
++  fts5_api api;                   /* User visible part of object (see fts5.h) */
++  sqlite3 *db;                    /* Associated database connection */ 
++  i64 iNextId;                    /* Used to allocate unique cursor ids */
++  Fts5Auxiliary *pAux;            /* First in list of all aux. functions */
++  Fts5TokenizerModule *pTok;      /* First in list of all tokenizer modules */
++  Fts5TokenizerModule *pDfltTok;  /* Default tokenizer module */
++  Fts5Cursor *pCsr;               /* First in list of all open cursors */
++};
++
++/*
++** Each auxiliary function registered with the FTS5 module is represented
++** by an object of the following type. All such objects are stored as part
++** of the Fts5Global.pAux list.
++*/
++struct Fts5Auxiliary {
++  Fts5Global *pGlobal;            /* Global context for this function */
++  char *zFunc;                    /* Function name (nul-terminated) */
++  void *pUserData;                /* User-data pointer */
++  fts5_extension_function xFunc;  /* Callback function */
++  void (*xDestroy)(void*);        /* Destructor function */
++  Fts5Auxiliary *pNext;           /* Next registered auxiliary function */
++};
++
++/*
++** Each tokenizer module registered with the FTS5 module is represented
++** by an object of the following type. All such objects are stored as part
++** of the Fts5Global.pTok list.
++*/
++struct Fts5TokenizerModule {
++  char *zName;                    /* Name of tokenizer */
++  void *pUserData;                /* User pointer passed to xCreate() */
++  fts5_tokenizer x;               /* Tokenizer functions */
++  void (*xDestroy)(void*);        /* Destructor function */
++  Fts5TokenizerModule *pNext;     /* Next registered tokenizer module */
++};
++
++/*
++** Virtual-table object.
++*/
++struct Fts5Table {
++  sqlite3_vtab base;              /* Base class used by SQLite core */
++  Fts5Config *pConfig;            /* Virtual table configuration */
++  Fts5Index *pIndex;              /* Full-text index */
++  Fts5Storage *pStorage;          /* Document store */
++  Fts5Global *pGlobal;            /* Global (connection wide) data */
++  Fts5Cursor *pSortCsr;           /* Sort data from this cursor */
++#ifdef SQLITE_DEBUG
++  struct Fts5TransactionState ts;
++#endif
++};
++
++struct Fts5MatchPhrase {
++  Fts5Buffer *pPoslist;           /* Pointer to current poslist */
++  int nTerm;                      /* Size of phrase in terms */
++};
++
++/*
++** pStmt:
++**   SELECT rowid, <fts> FROM <fts> ORDER BY +rank;
++**
++** aIdx[]:
++**   There is one entry in the aIdx[] array for each phrase in the query,
++**   the value of which is the offset within aPoslist[] following the last 
++**   byte of the position list for the corresponding phrase.
++*/
++struct Fts5Sorter {
++  sqlite3_stmt *pStmt;
++  i64 iRowid;                     /* Current rowid */
++  const u8 *aPoslist;             /* Position lists for current row */
++  int nIdx;                       /* Number of entries in aIdx[] */
++  int aIdx[1];                    /* Offsets into aPoslist for current row */
++};
++
++
++/*
++** Virtual-table cursor object.
++**
++** iSpecial:
++**   If this is a 'special' query (refer to function fts5SpecialMatch()), 
++**   then this variable contains the result of the query. 
++**
++** iFirstRowid, iLastRowid:
++**   These variables are only used for FTS5_PLAN_MATCH cursors. Assuming the
++**   cursor iterates in ascending order of rowids, iFirstRowid is the lower
++**   limit of rowids to return, and iLastRowid the upper. In other words, the
++**   WHERE clause in the user's query might have been:
++**
++**       <tbl> MATCH <expr> AND rowid BETWEEN $iFirstRowid AND $iLastRowid
++**
++**   If the cursor iterates in descending order of rowid, iFirstRowid
++**   is the upper limit (i.e. the "first" rowid visited) and iLastRowid
++**   the lower.
++*/
++struct Fts5Cursor {
++  sqlite3_vtab_cursor base;       /* Base class used by SQLite core */
++  Fts5Cursor *pNext;              /* Next cursor in Fts5Cursor.pCsr list */
++  int *aColumnSize;               /* Values for xColumnSize() */
++  i64 iCsrId;                     /* Cursor id */
++
++  /* Zero from this point onwards on cursor reset */
++  int ePlan;                      /* FTS5_PLAN_XXX value */
++  int bDesc;                      /* True for "ORDER BY rowid DESC" queries */
++  i64 iFirstRowid;                /* Return no rowids earlier than this */
++  i64 iLastRowid;                 /* Return no rowids later than this */
++  sqlite3_stmt *pStmt;            /* Statement used to read %_content */
++  Fts5Expr *pExpr;                /* Expression for MATCH queries */
++  Fts5Sorter *pSorter;            /* Sorter for "ORDER BY rank" queries */
++  int csrflags;                   /* Mask of cursor flags (see below) */
++  i64 iSpecial;                   /* Result of special query */
++
++  /* "rank" function. Populated on demand from vtab.xColumn(). */
++  char *zRank;                    /* Custom rank function */
++  char *zRankArgs;                /* Custom rank function args */
++  Fts5Auxiliary *pRank;           /* Rank callback (or NULL) */
++  int nRankArg;                   /* Number of trailing arguments for rank() */
++  sqlite3_value **apRankArg;      /* Array of trailing arguments */
++  sqlite3_stmt *pRankArgStmt;     /* Origin of objects in apRankArg[] */
++
++  /* Auxiliary data storage */
++  Fts5Auxiliary *pAux;            /* Currently executing extension function */
++  Fts5Auxdata *pAuxdata;          /* First in linked list of saved aux-data */
++
++  /* Cache used by auxiliary functions xInst() and xInstCount() */
++  Fts5PoslistReader *aInstIter;   /* One for each phrase */
++  int nInstAlloc;                 /* Size of aInst[] array (entries / 3) */
++  int nInstCount;                 /* Number of phrase instances */
++  int *aInst;                     /* 3 integers per phrase instance */
++};
++
++/*
++** Bits that make up the "idxNum" parameter passed indirectly by 
++** xBestIndex() to xFilter().
++*/
++#define FTS5_BI_MATCH        0x0001         /* <tbl> MATCH ? */
++#define FTS5_BI_RANK         0x0002         /* rank MATCH ? */
++#define FTS5_BI_ROWID_EQ     0x0004         /* rowid == ? */
++#define FTS5_BI_ROWID_LE     0x0008         /* rowid <= ? */
++#define FTS5_BI_ROWID_GE     0x0010         /* rowid >= ? */
++
++#define FTS5_BI_ORDER_RANK   0x0020
++#define FTS5_BI_ORDER_ROWID  0x0040
++#define FTS5_BI_ORDER_DESC   0x0080
++
++/*
++** Values for Fts5Cursor.csrflags
++*/
++#define FTS5CSR_EOF               0x01
++#define FTS5CSR_REQUIRE_CONTENT   0x02
++#define FTS5CSR_REQUIRE_DOCSIZE   0x04
++#define FTS5CSR_REQUIRE_INST      0x08
++#define FTS5CSR_FREE_ZRANK        0x10
++#define FTS5CSR_REQUIRE_RESEEK    0x20
++#define FTS5CSR_REQUIRE_POSLIST   0x40
++
++#define BitFlagAllTest(x,y) (((x) & (y))==(y))
++#define BitFlagTest(x,y)    (((x) & (y))!=0)
++
++
++/*
++** Macros to Set(), Clear() and Test() cursor flags.
++*/
++#define CsrFlagSet(pCsr, flag)   ((pCsr)->csrflags |= (flag))
++#define CsrFlagClear(pCsr, flag) ((pCsr)->csrflags &= ~(flag))
++#define CsrFlagTest(pCsr, flag)  ((pCsr)->csrflags & (flag))
++
++struct Fts5Auxdata {
++  Fts5Auxiliary *pAux;            /* Extension to which this belongs */
++  void *pPtr;                     /* Pointer value */
++  void(*xDelete)(void*);          /* Destructor */
++  Fts5Auxdata *pNext;             /* Next object in linked list */
++};
++
++#ifdef SQLITE_DEBUG
++#define FTS5_BEGIN      1
++#define FTS5_SYNC       2
++#define FTS5_COMMIT     3
++#define FTS5_ROLLBACK   4
++#define FTS5_SAVEPOINT  5
++#define FTS5_RELEASE    6
++#define FTS5_ROLLBACKTO 7
++static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){
++  switch( op ){
++    case FTS5_BEGIN:
++      assert( p->ts.eState==0 );
++      p->ts.eState = 1;
++      p->ts.iSavepoint = -1;
++      break;
++
++    case FTS5_SYNC:
++      assert( p->ts.eState==1 );
++      p->ts.eState = 2;
++      break;
 +
-+  assert( pPager->useJournal );
-+  assert( isOpen(pPager->fd) );
-+  assert( pPager->eState==PAGER_OPEN );
++    case FTS5_COMMIT:
++      assert( p->ts.eState==2 );
++      p->ts.eState = 0;
++      break;
 +
-+  assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) &
-+    SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
-+  ));
++    case FTS5_ROLLBACK:
++      assert( p->ts.eState==1 || p->ts.eState==2 || p->ts.eState==0 );
++      p->ts.eState = 0;
++      break;
++
++    case FTS5_SAVEPOINT:
++      assert( p->ts.eState==1 );
++      assert( iSavepoint>=0 );
++      assert( iSavepoint>p->ts.iSavepoint );
++      p->ts.iSavepoint = iSavepoint;
++      break;
++      
++    case FTS5_RELEASE:
++      assert( p->ts.eState==1 );
++      assert( iSavepoint>=0 );
++      assert( iSavepoint<=p->ts.iSavepoint );
++      p->ts.iSavepoint = iSavepoint-1;
++      break;
 +
-+  *pExists = 0;
-+  if( !jrnlOpen ){
-+    rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
++    case FTS5_ROLLBACKTO:
++      assert( p->ts.eState==1 );
++      assert( iSavepoint>=0 );
++      assert( iSavepoint<=p->ts.iSavepoint );
++      p->ts.iSavepoint = iSavepoint;
++      break;
 +  }
-+  if( rc==SQLITE_OK && exists ){
-+    int locked = 0;             /* True if some process holds a RESERVED lock */
++}
++#else
++# define fts5CheckTransactionState(x,y,z)
++#endif
 +
-+    /* Race condition here:  Another process might have been holding the
-+    ** the RESERVED lock and have a journal open at the sqlite3OsAccess() 
-+    ** call above, but then delete the journal and drop the lock before
-+    ** we get to the following sqlite3OsCheckReservedLock() call.  If that
-+    ** is the case, this routine might think there is a hot journal when
-+    ** in fact there is none.  This results in a false-positive which will
-+    ** be dealt with by the playback routine.  Ticket #3883.
-+    */
-+    rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
-+    if( rc==SQLITE_OK && !locked ){
-+      Pgno nPage;                 /* Number of pages in database file */
++/*
++** Return true if pTab is a contentless table.
++*/
++static int fts5IsContentless(Fts5Table *pTab){
++  return pTab->pConfig->eContent==FTS5_CONTENT_NONE;
++}
 +
-+      rc = pagerPagecount(pPager, &nPage);
-+      if( rc==SQLITE_OK ){
-+        /* If the database is zero pages in size, that means that either (1) the
-+        ** journal is a remnant from a prior database with the same name where
-+        ** the database file but not the journal was deleted, or (2) the initial
-+        ** transaction that populates a new database is being rolled back.
-+        ** In either case, the journal file can be deleted.  However, take care
-+        ** not to delete the journal file if it is already open due to
-+        ** journal_mode=PERSIST.
-+        */
-+        if( nPage==0 && !jrnlOpen ){
-+          sqlite3BeginBenignMalloc();
-+          if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
-+            sqlite3OsDelete(pVfs, pPager->zJournal, 0);
-+            if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
-+          }
-+          sqlite3EndBenignMalloc();
-+        }else{
-+          /* The journal file exists and no other connection has a reserved
-+          ** or greater lock on the database file. Now check that there is
-+          ** at least one non-zero bytes at the start of the journal file.
-+          ** If there is, then we consider this journal to be hot. If not, 
-+          ** it can be ignored.
-+          */
-+          if( !jrnlOpen ){
-+            int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL;
-+            rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f);
-+          }
-+          if( rc==SQLITE_OK ){
-+            u8 first = 0;
-+            rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0);
-+            if( rc==SQLITE_IOERR_SHORT_READ ){
-+              rc = SQLITE_OK;
-+            }
-+            if( !jrnlOpen ){
-+              sqlite3OsClose(pPager->jfd);
-+            }
-+            *pExists = (first!=0);
-+          }else if( rc==SQLITE_CANTOPEN ){
-+            /* If we cannot open the rollback journal file in order to see if
-+            ** it has a zero header, that might be due to an I/O error, or
-+            ** it might be due to the race condition described above and in
-+            ** ticket #3883.  Either way, assume that the journal is hot.
-+            ** This might be a false positive.  But if it is, then the
-+            ** automatic journal playback and recovery mechanism will deal
-+            ** with it under an EXCLUSIVE lock where we do not need to
-+            ** worry so much with race conditions.
-+            */
-+            *pExists = 1;
-+            rc = SQLITE_OK;
-+          }
-+        }
-+      }
-+    }
-   }
++/*
++** Delete a virtual table handle allocated by fts5InitVtab(). 
++*/
++static void fts5FreeVtab(Fts5Table *pTab){
++  if( pTab ){
++    sqlite3Fts5IndexClose(pTab->pIndex);
++    sqlite3Fts5StorageClose(pTab->pStorage);
++    sqlite3Fts5ConfigFree(pTab->pConfig);
++    sqlite3_free(pTab);
++  }
++}
 +
-   return rc;
- }
- 
- /*
--** Sync the database file for the pager pPager. zMaster points to the name
--** of a master journal file that should be written into the individual
--** journal file. zMaster may be NULL, which is interpreted as no master
--** journal (a single database transaction).
--**
--** This routine ensures that:
-+** This function is called to obtain a shared lock on the database file.
-+** It is illegal to call sqlite3PagerAcquire() until after this function
-+** has been successfully called. If a shared-lock is already held when
-+** this function is called, it is a no-op.
- **
--**   * The database file change-counter is updated,
--**   * the journal is synced (unless the atomic-write optimization is used),
--**   * all dirty pages are written to the database file, 
--**   * the database file is truncated (if required), and
--**   * the database file synced. 
-+** The following operations are also performed by this function.
- **
--** The only thing that remains to commit the transaction is to finalize 
--** (delete, truncate or zero the first part of) the journal file (or 
--** delete the master journal file if specified).
-+**   1) If the pager is currently in PAGER_OPEN state (no lock held
-+**      on the database file), then an attempt is made to obtain a
-+**      SHARED lock on the database file. Immediately after obtaining
-+**      the SHARED lock, the file-system is checked for a hot-journal,
-+**      which is played back if present. Following any hot-journal 
-+**      rollback, the contents of the cache are validated by checking
-+**      the 'change-counter' field of the database file header and
-+**      discarded if they are found to be invalid.
- **
--** Note that if zMaster==NULL, this does not overwrite a previous value
--** passed to an sqlite3PagerCommitPhaseOne() call.
-+**   2) If the pager is running in exclusive-mode, and there are currently
-+**      no outstanding references to any pages, and is in the error state,
-+**      then an attempt is made to clear the error state by discarding
-+**      the contents of the page cache and rolling back any open journal
-+**      file.
- **
--** If the final parameter - noSync - is true, then the database file itself
--** is not synced. The caller must call sqlite3PagerSync() directly to
--** sync the database file before calling CommitPhaseTwo() to delete the
--** journal file in this case.
-+** If everything is successful, SQLITE_OK is returned. If an IO error 
-+** occurs while locking the database, checking for a hot-journal file or 
-+** rolling back a journal file, the IO error code is returned.
- */
--SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
--  Pager *pPager,                  /* Pager object */
--  const char *zMaster,            /* If not NULL, the master journal name */
--  int noSync                      /* True to omit the xSync on the db file */
--){
--  int rc = SQLITE_OK;             /* Return code */
-+SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
-+  int rc = SQLITE_OK;                /* Return code */
- 
--  assert( pPager->eState==PAGER_WRITER_LOCKED
--       || pPager->eState==PAGER_WRITER_CACHEMOD
--       || pPager->eState==PAGER_WRITER_DBMOD
--       || pPager->eState==PAGER_ERROR
--  );
-+  /* This routine is only called from b-tree and only when there are no
-+  ** outstanding pages. This implies that the pager state should either
-+  ** be OPEN or READER. READER is only possible if the pager is or was in 
-+  ** exclusive access mode.
-+  */
-+  assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
-   assert( assert_pager_state(pPager) );
-+  assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
-+  if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
- 
--  /* If a prior error occurred, report that error again. */
--  if( NEVER(pPager->errCode) ) return pPager->errCode;
-+  if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
-+    int bHotJournal = 1;          /* True if there exists a hot journal-file */
- 
--  PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
--      pPager->zFilename, zMaster, pPager->dbSize));
-+    assert( !MEMDB );
- 
--  /* If no database changes have been made, return early. */
--  if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
-+    rc = pager_wait_on_lock(pPager, SHARED_LOCK);
-+    if( rc!=SQLITE_OK ){
-+      assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK );
-+      goto failed;
-+    }
- 
--  if( MEMDB ){
--    /* If this is an in-memory db, or no pages have been written to, or this
--    ** function has already been called, it is mostly a no-op.  However, any
--    ** backup in progress needs to be restarted.
-+    /* If a journal file exists, and there is no RESERVED lock on the
-+    ** database file, then it either needs to be played back or deleted.
-     */
--    sqlite3BackupRestart(pPager->pBackup);
--  }else{
--    if( pagerUseWal(pPager) ){
--      PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
--      PgHdr *pPageOne = 0;
--      if( pList==0 ){
--        /* Must have at least one page for the WAL commit flag.
--        ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
--        rc = sqlite3PagerGet(pPager, 1, &pPageOne);
--        pList = pPageOne;
--        pList->pDirty = 0;
--      }
--      assert( rc==SQLITE_OK );
--      if( ALWAYS(pList) ){
--        rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1);
--      }
--      sqlite3PagerUnref(pPageOne);
--      if( rc==SQLITE_OK ){
--        sqlite3PcacheCleanAll(pPager->pPCache);
-+    if( pPager->eLock<=SHARED_LOCK ){
-+      rc = hasHotJournal(pPager, &bHotJournal);
-+    }
-+    if( rc!=SQLITE_OK ){
-+      goto failed;
-+    }
-+    if( bHotJournal ){
-+      if( pPager->readOnly ){
-+        rc = SQLITE_READONLY_ROLLBACK;
-+        goto failed;
-       }
--    }else{
--      /* The following block updates the change-counter. Exactly how it
--      ** does this depends on whether or not the atomic-update optimization
--      ** was enabled at compile time, and if this transaction meets the 
--      ** runtime criteria to use the operation: 
--      **
--      **    * The file-system supports the atomic-write property for
--      **      blocks of size page-size, and 
--      **    * This commit is not part of a multi-file transaction, and
--      **    * Exactly one page has been modified and store in the journal file.
-+
-+      /* Get an EXCLUSIVE lock on the database file. At this point it is
-+      ** important that a RESERVED lock is not obtained on the way to the
-+      ** EXCLUSIVE lock. If it were, another process might open the
-+      ** database file, detect the RESERVED lock, and conclude that the
-+      ** database is safe to read while this process is still rolling the 
-+      ** hot-journal back.
-+      ** 
-+      ** Because the intermediate RESERVED lock is not requested, any
-+      ** other process attempting to access the database file will get to 
-+      ** this point in the code and fail to obtain its own EXCLUSIVE lock 
-+      ** on the database file.
-       **
--      ** If the optimization was not enabled at compile time, then the
--      ** pager_incr_changecounter() function is called to update the change
--      ** counter in 'indirect-mode'. If the optimization is compiled in but
--      ** is not applicable to this transaction, call sqlite3JournalCreate()
--      ** to make sure the journal file has actually been created, then call
--      ** pager_incr_changecounter() to update the change-counter in indirect
--      ** mode. 
-+      ** Unless the pager is in locking_mode=exclusive mode, the lock is
-+      ** downgraded to SHARED_LOCK before this function returns.
-+      */
-+      rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
-+      if( rc!=SQLITE_OK ){
-+        goto failed;
-+      }
-+ 
-+      /* If it is not already open and the file exists on disk, open the 
-+      ** journal for read/write access. Write access is required because 
-+      ** in exclusive-access mode the file descriptor will be kept open 
-+      ** and possibly used for a transaction later on. Also, write-access 
-+      ** is usually required to finalize the journal in journal_mode=persist 
-+      ** mode (and also for journal_mode=truncate on some systems).
-       **
--      ** Otherwise, if the optimization is both enabled and applicable,
--      ** then call pager_incr_changecounter() to update the change-counter
--      ** in 'direct' mode. In this case the journal file will never be
--      ** created for this transaction.
-+      ** If the journal does not exist, it usually means that some 
-+      ** other connection managed to get in and roll it back before 
-+      ** this connection obtained the exclusive lock above. Or, it 
-+      ** may mean that the pager was in the error-state when this
-+      ** function was called and the journal file does not exist.
-       */
--  #ifdef SQLITE_ENABLE_ATOMIC_WRITE
--      PgHdr *pPg;
--      assert( isOpen(pPager->jfd) 
--           || pPager->journalMode==PAGER_JOURNALMODE_OFF 
--           || pPager->journalMode==PAGER_JOURNALMODE_WAL 
--      );
--      if( !zMaster && isOpen(pPager->jfd) 
--       && pPager->journalOff==jrnlBufferSize(pPager) 
--       && pPager->dbSize>=pPager->dbOrigSize
--       && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
--      ){
--        /* Update the db file change counter via the direct-write method. The 
--        ** following call will modify the in-memory representation of page 1 
--        ** to include the updated change counter and then write page 1 
--        ** directly to the database file. Because of the atomic-write 
--        ** property of the host file-system, this is safe.
--        */
--        rc = pager_incr_changecounter(pPager, 1);
--      }else{
--        rc = sqlite3JournalCreate(pPager->jfd);
--        if( rc==SQLITE_OK ){
--          rc = pager_incr_changecounter(pPager, 0);
-+      if( !isOpen(pPager->jfd) ){
-+        sqlite3_vfs * const pVfs = pPager->pVfs;
-+        int bExists;              /* True if journal file exists */
-+        rc = sqlite3OsAccess(
-+            pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists);
-+        if( rc==SQLITE_OK && bExists ){
-+          int fout = 0;
-+          int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
-+          assert( !pPager->tempFile );
-+          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
-+          assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
-+          if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
-+            rc = SQLITE_CANTOPEN_BKPT;
-+            sqlite3OsClose(pPager->jfd);
-+          }
-         }
-       }
--  #else
--      rc = pager_incr_changecounter(pPager, 0);
--  #endif
--      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
--  
--      /* Write the master journal name into the journal file. If a master 
--      ** journal file name has already been written to the journal file, 
--      ** or if zMaster is NULL (no master journal), then this call is a no-op.
--      */
--      rc = writeMasterJournal(pPager, zMaster);
--      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
--  
--      /* Sync the journal file and write all dirty pages to the database.
--      ** If the atomic-update optimization is being used, this sync will not 
--      ** create the journal file or perform any real IO.
--      **
--      ** Because the change-counter page was just modified, unless the
--      ** atomic-update optimization is used it is almost certain that the
--      ** journal requires a sync here. However, in locking_mode=exclusive
--      ** on a system under memory pressure it is just possible that this is 
--      ** not the case. In this case it is likely enough that the redundant
--      ** xSync() call will be changed to a no-op by the OS anyhow. 
-+ 
-+      /* Playback and delete the journal.  Drop the database write
-+      ** lock and reacquire the read lock. Purge the cache before
-+      ** playing back the hot-journal so that we don't end up with
-+      ** an inconsistent cache.  Sync the hot journal before playing
-+      ** it back since the process that crashed and left the hot journal
-+      ** probably did not sync it and we are required to always sync
-+      ** the journal before playing it back.
-       */
--      rc = syncJournal(pPager, 0);
--      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
--  
--      rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
--      if( rc!=SQLITE_OK ){
--        assert( rc!=SQLITE_IOERR_BLOCKED );
--        goto commit_phase_one_exit;
-+      if( isOpen(pPager->jfd) ){
-+        assert( rc==SQLITE_OK );
-+        rc = pagerSyncHotJournal(pPager);
-+        if( rc==SQLITE_OK ){
-+          rc = pager_playback(pPager, 1);
-+          pPager->eState = PAGER_OPEN;
-+        }
-+      }else if( !pPager->exclusiveMode ){
-+        pagerUnlockDb(pPager, SHARED_LOCK);
-       }
--      sqlite3PcacheCleanAll(pPager->pPCache);
- 
--      /* If the file on disk is smaller than the database image, use 
--      ** pager_truncate to grow the file here. This can happen if the database
--      ** image was extended as part of the current transaction and then the
--      ** last page in the db image moved to the free-list. In this case the
--      ** last page is never written out to disk, leaving the database file
--      ** undersized. Fix this now if it is the case.  */
--      if( pPager->dbSize>pPager->dbFileSize ){
--        Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
--        assert( pPager->eState==PAGER_WRITER_DBMOD );
--        rc = pager_truncate(pPager, nNew);
--        if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
--      }
--  
--      /* Finally, sync the database file. */
--      if( !noSync ){
--        rc = sqlite3PagerSync(pPager, zMaster);
-+      if( rc!=SQLITE_OK ){
-+        /* This branch is taken if an error occurs while trying to open
-+        ** or roll back a hot-journal while holding an EXCLUSIVE lock. The
-+        ** pager_unlock() routine will be called before returning to unlock
-+        ** the file. If the unlock attempt fails, then Pager.eLock must be
-+        ** set to UNKNOWN_LOCK (see the comment above the #define for 
-+        ** UNKNOWN_LOCK above for an explanation). 
-+        **
-+        ** In order to get pager_unlock() to do this, set Pager.eState to
-+        ** PAGER_ERROR now. This is not actually counted as a transition
-+        ** to ERROR state in the state diagram at the top of this file,
-+        ** since we know that the same call to pager_unlock() will very
-+        ** shortly transition the pager object to the OPEN state. Calling
-+        ** assert_pager_state() would fail now, as it should not be possible
-+        ** to be in ERROR state when there are zero outstanding page 
-+        ** references.
-+        */
-+        pager_error(pPager, rc);
-+        goto failed;
-       }
--      IOTRACE(("DBSYNC %p\n", pPager))
++/*
++** The xDisconnect() virtual table method.
++*/
++static int fts5DisconnectMethod(sqlite3_vtab *pVtab){
++  fts5FreeVtab((Fts5Table*)pVtab);
++  return SQLITE_OK;
++}
 +
-+      assert( pPager->eState==PAGER_OPEN );
-+      assert( (pPager->eLock==SHARED_LOCK)
-+           || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
-+      );
-     }
--  }
- 
--commit_phase_one_exit:
--  if( rc==SQLITE_OK && !pagerUseWal(pPager) ){
--    pPager->eState = PAGER_WRITER_FINISHED;
--  }
--  return rc;
--}
-+    if( !pPager->tempFile && pPager->hasBeenUsed ){
-+      /* The shared-lock has just been acquired then check to
-+      ** see if the database has been modified.  If the database has changed,
-+      ** flush the cache.  The pPager->hasBeenUsed flag prevents this from
-+      ** occurring on the very first access to a file, in order to save a
-+      ** single unnecessary sqlite3OsRead() call at the start-up.
-+      **
-+      ** Database changes is detected by looking at 15 bytes beginning
-+      ** at offset 24 into the file.  The first 4 of these 16 bytes are
-+      ** a 32-bit counter that is incremented with each change.  The
-+      ** other bytes change randomly with each file change when
-+      ** a codec is in use.
-+      ** 
-+      ** There is a vanishingly small chance that a change will not be 
-+      ** detected.  The chance of an undetected change is so small that
-+      ** it can be neglected.
-+      */
-+      Pgno nPage = 0;
-+      char dbFileVers[sizeof(pPager->dbFileVers)];
- 
-+      rc = pagerPagecount(pPager, &nPage);
-+      if( rc ) goto failed;
- 
--/*
--** When this function is called, the database file has been completely
--** updated to reflect the changes made by the current transaction and
--** synced to disk. The journal file still exists in the file-system 
--** though, and if a failure occurs at this point it will eventually
--** be used as a hot-journal and the current transaction rolled back.
--**
--** This function finalizes the journal file, either by deleting, 
--** truncating or partially zeroing it, so that it cannot be used 
--** for hot-journal rollback. Once this is done the transaction is
--** irrevocably committed.
--**
--** If an error occurs, an IO error code is returned and the pager
--** moves into the error state. Otherwise, SQLITE_OK is returned.
--*/
--SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){
--  int rc = SQLITE_OK;                  /* Return code */
-+      if( nPage>0 ){
-+        IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
-+        rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
-+        if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
-+          goto failed;
-+        }
-+      }else{
-+        memset(dbFileVers, 0, sizeof(dbFileVers));
-+      }
- 
--  /* This routine should not be called if a prior error has occurred.
--  ** But if (due to a coding error elsewhere in the system) it does get
--  ** called, just return the same error code without doing anything. */
--  if( NEVER(pPager->errCode) ) return pPager->errCode;
-+      if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
-+        pager_reset(pPager);
++/*
++** The xDestroy() virtual table method.
++*/
++static int fts5DestroyMethod(sqlite3_vtab *pVtab){
++  Fts5Table *pTab = (Fts5Table*)pVtab;
++  int rc = sqlite3Fts5DropAll(pTab->pConfig);
++  if( rc==SQLITE_OK ){
++    fts5FreeVtab((Fts5Table*)pVtab);
++  }
++  return rc;
++}
 +
-+        /* Unmap the database file. It is possible that external processes
-+        ** may have truncated the database file and then extended it back
-+        ** to its original size while this process was not holding a lock.
-+        ** In this case there may exist a Pager.pMap mapping that appears
-+        ** to be the right size but is not actually valid. Avoid this
-+        ** possibility by unmapping the db here. */
-+        if( USEFETCH(pPager) ){
-+          sqlite3OsUnfetch(pPager->fd, 0, 0);
-+        }
-+      }
-+    }
++/*
++** This function is the implementation of both the xConnect and xCreate
++** methods of the FTS3 virtual table.
++**
++** The argv[] array contains the following:
++**
++**   argv[0]   -> module name  ("fts5")
++**   argv[1]   -> database name
++**   argv[2]   -> table name
++**   argv[...] -> "column name" and other module argument fields.
++*/
++static int fts5InitVtab(
++  int bCreate,                    /* True for xCreate, false for xConnect */
++  sqlite3 *db,                    /* The SQLite database connection */
++  void *pAux,                     /* Hash table containing tokenizers */
++  int argc,                       /* Number of elements in argv array */
++  const char * const *argv,       /* xCreate/xConnect argument array */
++  sqlite3_vtab **ppVTab,          /* Write the resulting vtab structure here */
++  char **pzErr                    /* Write any error message here */
++){
++  Fts5Global *pGlobal = (Fts5Global*)pAux;
++  const char **azConfig = (const char**)argv;
++  int rc = SQLITE_OK;             /* Return code */
++  Fts5Config *pConfig = 0;        /* Results of parsing argc/argv */
++  Fts5Table *pTab = 0;            /* New virtual table object */
 +
-+    /* If there is a WAL file in the file-system, open this database in WAL
-+    ** mode. Otherwise, the following function call is a no-op.
-+    */
-+    rc = pagerOpenWalIfPresent(pPager);
-+#ifndef SQLITE_OMIT_WAL
-+    assert( pPager->pWal==0 || rc==SQLITE_OK );
-+#endif
++  /* Allocate the new vtab object and parse the configuration */
++  pTab = (Fts5Table*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Table));
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr);
++    assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 );
 +  }
- 
--  assert( pPager->eState==PAGER_WRITER_LOCKED
--       || pPager->eState==PAGER_WRITER_FINISHED
--       || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD)
--  );
--  assert( assert_pager_state(pPager) );
-+  if( pagerUseWal(pPager) ){
-+    assert( rc==SQLITE_OK );
-+    rc = pagerBeginReadTransaction(pPager);
++  if( rc==SQLITE_OK ){
++    pTab->pConfig = pConfig;
++    pTab->pGlobal = pGlobal;
 +  }
- 
--  /* An optimization. If the database was not actually modified during
--  ** this transaction, the pager is running in exclusive-mode and is
--  ** using persistent journals, then this function is a no-op.
--  **
--  ** The start of the journal file currently contains a single journal 
--  ** header with the nRec field set to 0. If such a journal is used as
--  ** a hot-journal during hot-journal rollback, 0 changes will be made
--  ** to the database file. So there is no need to zero the journal 
--  ** header. Since the pager is in exclusive mode, there is no need
--  ** to drop any locks either.
--  */
--  if( pPager->eState==PAGER_WRITER_LOCKED 
--   && pPager->exclusiveMode 
--   && pPager->journalMode==PAGER_JOURNALMODE_PERSIST
--  ){
--    assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff );
-+  if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
-+    rc = pagerPagecount(pPager, &pPager->dbSize);
++
++  /* Open the index sub-system */
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->pIndex, pzErr);
++  }
++
++  /* Open the storage sub-system */
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5StorageOpen(
++        pConfig, pTab->pIndex, bCreate, &pTab->pStorage, pzErr
++    );
++  }
++
++  /* Call sqlite3_declare_vtab() */
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5ConfigDeclareVtab(pConfig);
++  }
++
++  /* Load the initial configuration */
++  if( rc==SQLITE_OK ){
++    assert( pConfig->pzErrmsg==0 );
++    pConfig->pzErrmsg = pzErr;
++    rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
++    sqlite3Fts5IndexRollback(pTab->pIndex);
++    pConfig->pzErrmsg = 0;
 +  }
 +
-+ failed:
 +  if( rc!=SQLITE_OK ){
-+    assert( !MEMDB );
-+    pager_unlock(pPager);
-+    assert( pPager->eState==PAGER_OPEN );
-+  }else{
-     pPager->eState = PAGER_READER;
--    return SQLITE_OK;
-   }
++    fts5FreeVtab(pTab);
++    pTab = 0;
++  }else if( bCreate ){
++    fts5CheckTransactionState(pTab, FTS5_BEGIN, 0);
++  }
++  *ppVTab = (sqlite3_vtab*)pTab;
 +  return rc;
 +}
- 
--  PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
--  pPager->iDataVersion++;
--  rc = pager_end_transaction(pPager, pPager->setMaster, 1);
--  return pager_error(pPager, rc);
++
 +/*
-+** If the reference count has reached zero, rollback any active
-+** transaction and unlock the pager.
-+**
-+** Except, in locking_mode=EXCLUSIVE when there is nothing to in
-+** the rollback journal, the unlock is not performed and there is
-+** nothing to rollback, so this routine is a no-op.
-+*/ 
-+static void pagerUnlockIfUnused(Pager *pPager){
-+  if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
-+    pagerUnlockAndRollback(pPager);
-+  }
- }
- 
- /*
--** If a write transaction is open, then all changes made within the 
--** transaction are reverted and the current write-transaction is closed.
--** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR
--** state if an error occurs.
-+** Acquire a reference to page number pgno in pager pPager (a page
-+** reference has type DbPage*). If the requested reference is 
-+** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
- **
--** If the pager is already in PAGER_ERROR state when this function is called,
--** it returns Pager.errCode immediately. No work is performed in this case.
-+** If the requested page is already in the cache, it is returned. 
-+** Otherwise, a new page object is allocated and populated with data
-+** read from the database file. In some cases, the pcache module may
-+** choose not to allocate a new page object and may reuse an existing
-+** object with no outstanding references.
- **
--** Otherwise, in rollback mode, this function performs two functions:
-+** The extra data appended to a page is always initialized to zeros the 
-+** first time a page is loaded into memory. If the page requested is 
-+** already in the cache when this function is called, then the extra
-+** data is left as it was when the page object was last used.
- **
--**   1) It rolls back the journal file, restoring all database file and 
--**      in-memory cache pages to the state they were in when the transaction
--**      was opened, and
-+** If the database image is smaller than the requested page or if a 
-+** non-zero value is passed as the noContent parameter and the 
-+** requested page is not already stored in the cache, then no 
-+** actual disk read occurs. In this case the memory image of the 
-+** page is initialized to all zeros. 
- **
--**   2) It finalizes the journal file, so that it is not used for hot
--**      rollback at any point in the future.
-+** If noContent is true, it means that we do not care about the contents
-+** of the page. This occurs in two scenarios:
- **
--** Finalization of the journal file (task 2) is only performed if the 
--** rollback is successful.
-+**   a) When reading a free-list leaf page from the database, and
- **
--** In WAL mode, all cache-entries containing data modified within the
--** current transaction are either expelled from the cache or reverted to
--** their pre-transaction state by re-reading data from the database or
--** WAL files. The WAL transaction is then closed.
-+**   b) When a savepoint is being rolled back and we need to load
-+**      a new page into the cache to be filled with the data read
-+**      from the savepoint journal.
-+**
-+** If noContent is true, then the data returned is zeroed instead of
-+** being read from the database. Additionally, the bits corresponding
-+** to pgno in Pager.pInJournal (bitvec of pages already written to the
-+** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
-+** savepoints are set. This means if the page is made writable at any
-+** point in the future, using a call to sqlite3PagerWrite(), its contents
-+** will not be journaled. This saves IO.
-+**
-+** The acquisition might fail for several reasons.  In all cases,
-+** an appropriate error code is returned and *ppPage is set to NULL.
-+**
-+** See also sqlite3PagerLookup().  Both this routine and Lookup() attempt
-+** to find a page in the in-memory cache first.  If the page is not already
-+** in memory, this routine goes to disk to read it in whereas Lookup()
-+** just returns 0.  This routine acquires a read-lock the first time it
-+** has to go to disk, and could also playback an old journal if necessary.
-+** Since Lookup() never goes to disk, it never has to deal with locks
-+** or journal files.
- */
--SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
--  int rc = SQLITE_OK;                  /* Return code */
--  PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager)));
-+SQLITE_PRIVATE int sqlite3PagerAcquire(
-+  Pager *pPager,      /* The pager open on the database file */
-+  Pgno pgno,          /* Page number to fetch */
-+  DbPage **ppPage,    /* Write a pointer to the page here */
-+  int flags           /* PAGER_GET_XXX flags */
++** The xConnect() and xCreate() methods for the virtual table. All the
++** work is done in function fts5InitVtab().
++*/
++static int fts5ConnectMethod(
++  sqlite3 *db,                    /* Database connection */
++  void *pAux,                     /* Pointer to tokenizer hash table */
++  int argc,                       /* Number of elements in argv array */
++  const char * const *argv,       /* xCreate/xConnect argument array */
++  sqlite3_vtab **ppVtab,          /* OUT: New sqlite3_vtab object */
++  char **pzErr                    /* OUT: sqlite3_malloc'd error message */
 +){
-+  int rc = SQLITE_OK;
-+  PgHdr *pPg = 0;
-+  u32 iFrame = 0;                 /* Frame to read from WAL file */
-+  const int noContent = (flags & PAGER_GET_NOCONTENT);
- 
--  /* PagerRollback() is a no-op if called in READER or OPEN state. If
--  ** the pager is already in the ERROR state, the rollback is not 
--  ** attempted here. Instead, the error code is returned to the caller.
--  */
-+  /* It is acceptable to use a read-only (mmap) page for any page except
-+  ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
-+  ** flag was specified by the caller. And so long as the db is not a 
-+  ** temporary or in-memory database.  */
-+  const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
-+   && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
-+#ifdef SQLITE_HAS_CODEC
-+   && pPager->xCodec==0
++  return fts5InitVtab(0, db, pAux, argc, argv, ppVtab, pzErr);
++}
++static int fts5CreateMethod(
++  sqlite3 *db,                    /* Database connection */
++  void *pAux,                     /* Pointer to tokenizer hash table */
++  int argc,                       /* Number of elements in argv array */
++  const char * const *argv,       /* xCreate/xConnect argument array */
++  sqlite3_vtab **ppVtab,          /* OUT: New sqlite3_vtab object */
++  char **pzErr                    /* OUT: sqlite3_malloc'd error message */
++){
++  return fts5InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr);
++}
++
++/*
++** The different query plans.
++*/
++#define FTS5_PLAN_MATCH          1       /* (<tbl> MATCH ?) */
++#define FTS5_PLAN_SOURCE         2       /* A source cursor for SORTED_MATCH */
++#define FTS5_PLAN_SPECIAL        3       /* An internal query */
++#define FTS5_PLAN_SORTED_MATCH   4       /* (<tbl> MATCH ? ORDER BY rank) */
++#define FTS5_PLAN_SCAN           5       /* No usable constraint */
++#define FTS5_PLAN_ROWID          6       /* (rowid = ?) */
++
++/*
++** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
++** extension is currently being used by a version of SQLite too old to
++** support index-info flags. In that case this function is a no-op.
++*/
++static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
++#if SQLITE_VERSION_NUMBER>=3008012
++#ifndef SQLITE_CORE
++  if( sqlite3_libversion_number()>=3008012 )
 +#endif
-+  );
++  {
++    pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
++  }
++#endif
++}
 +
-+  assert( pPager->eState>=PAGER_READER );
-   assert( assert_pager_state(pPager) );
--  if( pPager->eState==PAGER_ERROR ) return pPager->errCode;
--  if( pPager->eState<=PAGER_READER ) return SQLITE_OK;
-+  assert( noContent==0 || bMmapOk==0 );
- 
--  if( pagerUseWal(pPager) ){
--    int rc2;
--    rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
--    rc2 = pager_end_transaction(pPager, pPager->setMaster, 0);
--    if( rc==SQLITE_OK ) rc = rc2;
--  }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){
--    int eState = pPager->eState;
--    rc = pager_end_transaction(pPager, 0, 0);
--    if( !MEMDB && eState>PAGER_WRITER_LOCKED ){
--      /* This can happen using journal_mode=off. Move the pager to the error 
--      ** state to indicate that the contents of the cache may not be trusted.
--      ** Any active readers will get SQLITE_ABORT.
--      */
--      pPager->errCode = SQLITE_ABORT;
--      pPager->eState = PAGER_ERROR;
--      return rc;
--    }
--  }else{
--    rc = pager_playback(pPager, 0);
-+  if( pgno==0 ){
-+    return SQLITE_CORRUPT_BKPT;
-   }
-+  pPager->hasBeenUsed = 1;
- 
--  assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK );
--  assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT
--          || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR 
--          || rc==SQLITE_CANTOPEN
--  );
-+  /* If the pager is in the error state, return an error immediately. 
-+  ** Otherwise, request the page from the PCache layer. */
-+  if( pPager->errCode!=SQLITE_OK ){
-+    rc = pPager->errCode;
-+  }else{
-+    if( bMmapOk && pagerUseWal(pPager) ){
-+      rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
-+      if( rc!=SQLITE_OK ) goto pager_acquire_err;
-+    }
- 
--  /* If an error occurs during a ROLLBACK, we can no longer trust the pager
--  ** cache. So call pager_error() on the way out to make any error persistent.
--  */
--  return pager_error(pPager, rc);
--}
-+    if( bMmapOk && iFrame==0 ){
-+      void *pData = 0;
- 
--/*
--** Return TRUE if the database file is opened read-only.  Return FALSE
--** if the database is (in theory) writable.
--*/
--SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){
--  return pPager->readOnly;
--}
-+      rc = sqlite3OsFetch(pPager->fd, 
-+          (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
-+      );
- 
--/*
--** Return the number of references to the pager.
--*/
--SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){
--  return sqlite3PcacheRefCount(pPager->pPCache);
--}
-+      if( rc==SQLITE_OK && pData ){
-+        if( pPager->eState>PAGER_READER ){
-+          pPg = sqlite3PagerLookup(pPager, pgno);
-+        }
-+        if( pPg==0 ){
-+          rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
-+        }else{
-+          sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
-+        }
-+        if( pPg ){
-+          assert( rc==SQLITE_OK );
-+          *ppPage = pPg;
-+          return SQLITE_OK;
-+        }
++/*
++** Implementation of the xBestIndex method for FTS5 tables. Within the 
++** WHERE constraint, it searches for the following:
++**
++**   1. A MATCH constraint against the special column.
++**   2. A MATCH constraint against the "rank" column.
++**   3. An == constraint against the rowid column.
++**   4. A < or <= constraint against the rowid column.
++**   5. A > or >= constraint against the rowid column.
++**
++** Within the ORDER BY, either:
++**
++**   5. ORDER BY rank [ASC|DESC]
++**   6. ORDER BY rowid [ASC|DESC]
++**
++** Costs are assigned as follows:
++**
++**  a) If an unusable MATCH operator is present in the WHERE clause, the
++**     cost is unconditionally set to 1e50 (a really big number).
++**
++**  a) If a MATCH operator is present, the cost depends on the other
++**     constraints also present. As follows:
++**
++**       * No other constraints:         cost=1000.0
++**       * One rowid range constraint:   cost=750.0
++**       * Both rowid range constraints: cost=500.0
++**       * An == rowid constraint:       cost=100.0
++**
++**  b) Otherwise, if there is no MATCH:
++**
++**       * No other constraints:         cost=1000000.0
++**       * One rowid range constraint:   cost=750000.0
++**       * Both rowid range constraints: cost=250000.0
++**       * An == rowid constraint:       cost=10.0
++**
++** Costs are not modified by the ORDER BY clause.
++*/
++static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
++  Fts5Table *pTab = (Fts5Table*)pVTab;
++  Fts5Config *pConfig = pTab->pConfig;
++  const int nCol = pConfig->nCol;
++  int idxFlags = 0;               /* Parameter passed through to xFilter() */
++  int bHasMatch;
++  int iNext;
++  int i;
++
++  struct Constraint {
++    int op;                       /* Mask against sqlite3_index_constraint.op */
++    int fts5op;                   /* FTS5 mask for idxFlags */
++    int iCol;                     /* 0==rowid, 1==tbl, 2==rank */
++    int omit;                     /* True to omit this if found */
++    int iConsIndex;               /* Index in pInfo->aConstraint[] */
++  } aConstraint[] = {
++    {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ, 
++                                    FTS5_BI_MATCH,    1, 1, -1},
++    {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ, 
++                                    FTS5_BI_RANK,     2, 1, -1},
++    {SQLITE_INDEX_CONSTRAINT_EQ,    FTS5_BI_ROWID_EQ, 0, 0, -1},
++    {SQLITE_INDEX_CONSTRAINT_LT|SQLITE_INDEX_CONSTRAINT_LE, 
++                                    FTS5_BI_ROWID_LE, 0, 0, -1},
++    {SQLITE_INDEX_CONSTRAINT_GT|SQLITE_INDEX_CONSTRAINT_GE, 
++                                    FTS5_BI_ROWID_GE, 0, 0, -1},
++  };
++
++  int aColMap[3];
++  aColMap[0] = -1;
++  aColMap[1] = nCol;
++  aColMap[2] = nCol+1;
++
++  /* Set idxFlags flags for all WHERE clause terms that will be used. */
++  for(i=0; i<pInfo->nConstraint; i++){
++    struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
++    int iCol = p->iColumn;
++
++    if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol)
++     || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol)
++    ){
++      /* A MATCH operator or equivalent */
++      if( p->usable ){
++        idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16);
++        aConstraint[0].iConsIndex = i;
++      }else{
++        /* As there exists an unusable MATCH constraint this is an 
++        ** unusable plan. Set a prohibitively high cost. */
++        pInfo->estimatedCost = 1e50;
++        return SQLITE_OK;
 +      }
-+      if( rc!=SQLITE_OK ){
-+        goto pager_acquire_err;
++    }else{
++      int j;
++      for(j=1; j<ArraySize(aConstraint); j++){
++        struct Constraint *pC = &aConstraint[j];
++        if( iCol==aColMap[pC->iCol] && p->op & pC->op && p->usable ){
++          pC->iConsIndex = i;
++          idxFlags |= pC->fts5op;
++        }
 +      }
 +    }
- 
--/*
--** Return the approximate number of bytes of memory currently
--** used by the pager and its associated cache.
--*/
--SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){
--  int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr)
--                                     + 5*sizeof(void*);
--  return perPageSize*sqlite3PcachePagecount(pPager->pPCache)
--           + sqlite3MallocSize(pPager)
--           + pPager->pageSize;
--}
-+    {
-+      sqlite3_pcache_page *pBase;
-+      pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
-+      if( pBase==0 ){
-+        rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
-+        if( rc!=SQLITE_OK ) goto pager_acquire_err;
++  }
++
++  /* Set idxFlags flags for the ORDER BY clause */
++  if( pInfo->nOrderBy==1 ){
++    int iSort = pInfo->aOrderBy[0].iColumn;
++    if( iSort==(pConfig->nCol+1) && BitFlagTest(idxFlags, FTS5_BI_MATCH) ){
++      idxFlags |= FTS5_BI_ORDER_RANK;
++    }else if( iSort==-1 ){
++      idxFlags |= FTS5_BI_ORDER_ROWID;
++    }
++    if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){
++      pInfo->orderByConsumed = 1;
++      if( pInfo->aOrderBy[0].desc ){
++        idxFlags |= FTS5_BI_ORDER_DESC;
 +      }
-+      pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
-+      if( pPg==0 ) rc = SQLITE_NOMEM;
 +    }
 +  }
- 
--/*
--** Return the number of references to the specified page.
--*/
--SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){
--  return sqlite3PcachePageRefcount(pPage);
--}
-+  if( rc!=SQLITE_OK ){
-+    /* Either the call to sqlite3PcacheFetch() returned an error or the
-+    ** pager was already in the error-state when this function was called.
-+    ** Set pPg to 0 and jump to the exception handler.  */
-+    pPg = 0;
-+    goto pager_acquire_err;
-+  }
-+  assert( (*ppPage)->pgno==pgno );
-+  assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 );
- 
--#ifdef SQLITE_TEST
--/*
--** This routine is used for testing and analysis only.
--*/
--SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){
--  static int a[11];
--  a[0] = sqlite3PcacheRefCount(pPager->pPCache);
--  a[1] = sqlite3PcachePagecount(pPager->pPCache);
--  a[2] = sqlite3PcacheGetCachesize(pPager->pPCache);
--  a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize;
--  a[4] = pPager->eState;
--  a[5] = pPager->errCode;
--  a[6] = pPager->aStat[PAGER_STAT_HIT];
--  a[7] = pPager->aStat[PAGER_STAT_MISS];
--  a[8] = 0;  /* Used to be pPager->nOvfl */
--  a[9] = pPager->nRead;
--  a[10] = pPager->aStat[PAGER_STAT_WRITE];
--  return a;
--}
--#endif
-+  if( (*ppPage)->pPager && !noContent ){
-+    /* In this case the pcache already contains an initialized copy of
-+    ** the page. Return without further ado.  */
-+    assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
-+    pPager->aStat[PAGER_STAT_HIT]++;
-+    return SQLITE_OK;
- 
--/*
--** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or
--** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the
--** current cache hit or miss count, according to the value of eStat. If the 
--** reset parameter is non-zero, the cache hit or miss count is zeroed before 
--** returning.
--*/
--SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
++
++  /* Calculate the estimated cost based on the flags set in idxFlags. */
++  bHasMatch = BitFlagTest(idxFlags, FTS5_BI_MATCH);
++  if( BitFlagTest(idxFlags, FTS5_BI_ROWID_EQ) ){
++    pInfo->estimatedCost = bHasMatch ? 100.0 : 10.0;
++    if( bHasMatch==0 ) fts5SetUniqueFlag(pInfo);
++  }else if( BitFlagAllTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
++    pInfo->estimatedCost = bHasMatch ? 500.0 : 250000.0;
++  }else if( BitFlagTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
++    pInfo->estimatedCost = bHasMatch ? 750.0 : 750000.0;
 +  }else{
-+    /* The pager cache has created a new page. Its content needs to 
-+    ** be initialized.  */
- 
--  assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
--       || eStat==SQLITE_DBSTATUS_CACHE_MISS
--       || eStat==SQLITE_DBSTATUS_CACHE_WRITE
--  );
-+    pPg = *ppPage;
-+    pPg->pPager = pPager;
- 
--  assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS );
--  assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE );
--  assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 );
-+    /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
-+    ** number greater than this, or the unused locking-page, is requested. */
-+    if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
-+      rc = SQLITE_CORRUPT_BKPT;
-+      goto pager_acquire_err;
++    pInfo->estimatedCost = bHasMatch ? 1000.0 : 1000000.0;
++  }
++
++  /* Assign argvIndex values to each constraint in use. */
++  iNext = 1;
++  for(i=0; i<ArraySize(aConstraint); i++){
++    struct Constraint *pC = &aConstraint[i];
++    if( pC->iConsIndex>=0 ){
++      pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
++      pInfo->aConstraintUsage[pC->iConsIndex].omit = (unsigned char)pC->omit;
 +    }
- 
--  *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT];
--  if( reset ){
--    pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0;
-+    if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){
-+      if( pgno>pPager->mxPgno ){
-+        rc = SQLITE_FULL;
-+        goto pager_acquire_err;
-+      }
-+      if( noContent ){
-+        /* Failure to set the bits in the InJournal bit-vectors is benign.
-+        ** It merely means that we might do some extra work to journal a 
-+        ** page that does not need to be journaled.  Nevertheless, be sure 
-+        ** to test the case where a malloc error occurs while trying to set 
-+        ** a bit in a bit vector.
-+        */
-+        sqlite3BeginBenignMalloc();
-+        if( pgno<=pPager->dbOrigSize ){
-+          TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno);
-+          testcase( rc==SQLITE_NOMEM );
-+        }
-+        TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno);
-+        testcase( rc==SQLITE_NOMEM );
-+        sqlite3EndBenignMalloc();
-+      }
-+      memset(pPg->pData, 0, pPager->pageSize);
-+      IOTRACE(("ZERO %p %d\n", pPager, pgno));
++  }
++
++  pInfo->idxNum = idxFlags;
++  return SQLITE_OK;
++}
++
++static int fts5NewTransaction(Fts5Table *pTab){
++  Fts5Cursor *pCsr;
++  for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
++    if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK;
++  }
++  return sqlite3Fts5StorageReset(pTab->pStorage);
++}
++
++/*
++** Implementation of xOpen method.
++*/
++static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
++  Fts5Table *pTab = (Fts5Table*)pVTab;
++  Fts5Config *pConfig = pTab->pConfig;
++  Fts5Cursor *pCsr = 0;           /* New cursor object */
++  int nByte;                      /* Bytes of space to allocate */
++  int rc;                         /* Return code */
++
++  rc = fts5NewTransaction(pTab);
++  if( rc==SQLITE_OK ){
++    nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int);
++    pCsr = (Fts5Cursor*)sqlite3_malloc(nByte);
++    if( pCsr ){
++      Fts5Global *pGlobal = pTab->pGlobal;
++      memset(pCsr, 0, nByte);
++      pCsr->aColumnSize = (int*)&pCsr[1];
++      pCsr->pNext = pGlobal->pCsr;
++      pGlobal->pCsr = pCsr;
++      pCsr->iCsrId = ++pGlobal->iNextId;
 +    }else{
-+      if( pagerUseWal(pPager) && bMmapOk==0 ){
-+        rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
-+        if( rc!=SQLITE_OK ) goto pager_acquire_err;
-+      }
-+      assert( pPg->pPager==pPager );
-+      pPager->aStat[PAGER_STAT_MISS]++;
-+      rc = readDbPage(pPg, iFrame);
-+      if( rc!=SQLITE_OK ){
-+        goto pager_acquire_err;
-+      }
++      rc = SQLITE_NOMEM;
 +    }
-+    pager_set_pagehash(pPg);
-   }
++  }
++  *ppCsr = (sqlite3_vtab_cursor*)pCsr;
++  return rc;
++}
++
++static int fts5StmtType(Fts5Cursor *pCsr){
++  if( pCsr->ePlan==FTS5_PLAN_SCAN ){
++    return (pCsr->bDesc) ? FTS5_STMT_SCAN_DESC : FTS5_STMT_SCAN_ASC;
++  }
++  return FTS5_STMT_LOOKUP;
++}
++
++/*
++** This function is called after the cursor passed as the only argument
++** is moved to point at a different row. It clears all cached data 
++** specific to the previous row stored by the cursor object.
++*/
++static void fts5CsrNewrow(Fts5Cursor *pCsr){
++  CsrFlagSet(pCsr, 
++      FTS5CSR_REQUIRE_CONTENT 
++    | FTS5CSR_REQUIRE_DOCSIZE 
++    | FTS5CSR_REQUIRE_INST 
++    | FTS5CSR_REQUIRE_POSLIST 
++  );
++}
++
++static void fts5FreeCursorComponents(Fts5Cursor *pCsr){
++  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
++  Fts5Auxdata *pData;
++  Fts5Auxdata *pNext;
++
++  sqlite3_free(pCsr->aInstIter);
++  sqlite3_free(pCsr->aInst);
++  if( pCsr->pStmt ){
++    int eStmt = fts5StmtType(pCsr);
++    sqlite3Fts5StorageStmtRelease(pTab->pStorage, eStmt, pCsr->pStmt);
++  }
++  if( pCsr->pSorter ){
++    Fts5Sorter *pSorter = pCsr->pSorter;
++    sqlite3_finalize(pSorter->pStmt);
++    sqlite3_free(pSorter);
++  }
++
++  if( pCsr->ePlan!=FTS5_PLAN_SOURCE ){
++    sqlite3Fts5ExprFree(pCsr->pExpr);
++  }
++
++  for(pData=pCsr->pAuxdata; pData; pData=pNext){
++    pNext = pData->pNext;
++    if( pData->xDelete ) pData->xDelete(pData->pPtr);
++    sqlite3_free(pData);
++  }
++
++  sqlite3_finalize(pCsr->pRankArgStmt);
++  sqlite3_free(pCsr->apRankArg);
++
++  if( CsrFlagTest(pCsr, FTS5CSR_FREE_ZRANK) ){
++    sqlite3_free(pCsr->zRank);
++    sqlite3_free(pCsr->zRankArgs);
++  }
++
++  memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan - (u8*)pCsr));
++}
 +
++
++/*
++** Close the cursor.  For additional information see the documentation
++** on the xClose method of the virtual table interface.
++*/
++static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){
++  if( pCursor ){
++    Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
++    Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
++    Fts5Cursor **pp;
++
++    fts5FreeCursorComponents(pCsr);
++    /* Remove the cursor from the Fts5Global.pCsr list */
++    for(pp=&pTab->pGlobal->pCsr; (*pp)!=pCsr; pp=&(*pp)->pNext);
++    *pp = pCsr->pNext;
++
++    sqlite3_free(pCsr);
++  }
 +  return SQLITE_OK;
++}
++
++static int fts5SorterNext(Fts5Cursor *pCsr){
++  Fts5Sorter *pSorter = pCsr->pSorter;
++  int rc;
++
++  rc = sqlite3_step(pSorter->pStmt);
++  if( rc==SQLITE_DONE ){
++    rc = SQLITE_OK;
++    CsrFlagSet(pCsr, FTS5CSR_EOF);
++  }else if( rc==SQLITE_ROW ){
++    const u8 *a;
++    const u8 *aBlob;
++    int nBlob;
++    int i;
++    int iOff = 0;
++    rc = SQLITE_OK;
++
++    pSorter->iRowid = sqlite3_column_int64(pSorter->pStmt, 0);
++    nBlob = sqlite3_column_bytes(pSorter->pStmt, 1);
++    aBlob = a = sqlite3_column_blob(pSorter->pStmt, 1);
++
++    /* nBlob==0 in detail=none mode. */
++    if( nBlob>0 ){
++      for(i=0; i<(pSorter->nIdx-1); i++){
++        int iVal;
++        a += fts5GetVarint32(a, iVal);
++        iOff += iVal;
++        pSorter->aIdx[i] = iOff;
++      }
++      pSorter->aIdx[i] = &aBlob[nBlob] - a;
++      pSorter->aPoslist = a;
++    }
 +
-+pager_acquire_err:
-+  assert( rc!=SQLITE_OK );
-+  if( pPg ){
-+    sqlite3PcacheDrop(pPg);
++    fts5CsrNewrow(pCsr);
 +  }
-+  pagerUnlockIfUnused(pPager);
 +
-+  *ppPage = 0;
 +  return rc;
- }
- 
- /*
--** Return true if this is an in-memory pager.
-+** Acquire a page if it is already in the in-memory cache.  Do
-+** not read the page from disk.  Return a pointer to the page,
-+** or 0 if the page is not in cache. 
++}
++
++
++/*
++** Set the FTS5CSR_REQUIRE_RESEEK flag on all FTS5_PLAN_MATCH cursors 
++** open on table pTab.
++*/
++static void fts5TripCursors(Fts5Table *pTab){
++  Fts5Cursor *pCsr;
++  for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
++    if( pCsr->ePlan==FTS5_PLAN_MATCH
++     && pCsr->base.pVtab==(sqlite3_vtab*)pTab 
++    ){
++      CsrFlagSet(pCsr, FTS5CSR_REQUIRE_RESEEK);
++    }
++  }
++}
++
++/*
++** If the REQUIRE_RESEEK flag is set on the cursor passed as the first
++** argument, close and reopen all Fts5IndexIter iterators that the cursor 
++** is using. Then attempt to move the cursor to a rowid equal to or laster
++** (in the cursors sort order - ASC or DESC) than the current rowid. 
 +**
-+** See also sqlite3PagerGet().  The difference between this routine
-+** and sqlite3PagerGet() is that _get() will go to the disk and read
-+** in the page if the page is not already in cache.  This routine
-+** returns NULL if the page is not in cache or if a disk I/O error 
-+** has ever happened.
- */
--SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
--  return MEMDB;
-+SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
-+  sqlite3_pcache_page *pPage;
-+  assert( pPager!=0 );
-+  assert( pgno!=0 );
-+  assert( pPager->pPCache!=0 );
-+  pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
-+  assert( pPage==0 || pPager->hasBeenUsed );
-+  return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
- }
- 
- /*
--** Check that there are at least nSavepoint savepoints open. If there are
--** currently less than nSavepoints open, then open one or more savepoints
--** to make up the difference. If the number of savepoints is already
--** equal to nSavepoint, then this function is a no-op.
-+** Release a page reference.
- **
--** If a memory allocation fails, SQLITE_NOMEM is returned. If an error 
--** occurs while opening the sub-journal file, then an IO error code is
--** returned. Otherwise, SQLITE_OK.
-+** If the number of references to the page drop to zero, then the
-+** page is added to the LRU list.  When all references to all pages
-+** are released, a rollback occurs and the lock on the database is
-+** removed.
- */
--SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
--  int rc = SQLITE_OK;                       /* Return code */
--  int nCurrent = pPager->nSavepoint;        /* Current number of savepoints */
--
--  assert( pPager->eState>=PAGER_WRITER_LOCKED );
--  assert( assert_pager_state(pPager) );
--
--  if( nSavepoint>nCurrent && pPager->useJournal ){
--    int ii;                                 /* Iterator variable */
--    PagerSavepoint *aNew;                   /* New Pager.aSavepoint array */
--
--    /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
--    ** if the allocation fails. Otherwise, zero the new portion in case a 
--    ** malloc failure occurs while populating it in the for(...) loop below.
--    */
--    aNew = (PagerSavepoint *)sqlite3Realloc(
--        pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
--    );
--    if( !aNew ){
--      return SQLITE_NOMEM;
--    }
--    memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
--    pPager->aSavepoint = aNew;
--
--    /* Populate the PagerSavepoint structures just allocated. */
--    for(ii=nCurrent; ii<nSavepoint; ii++){
--      aNew[ii].nOrig = pPager->dbSize;
--      if( isOpen(pPager->jfd) && pPager->journalOff>0 ){
--        aNew[ii].iOffset = pPager->journalOff;
--      }else{
--        aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager);
--      }
--      aNew[ii].iSubRec = pPager->nSubRec;
--      aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
--      if( !aNew[ii].pInSavepoint ){
--        return SQLITE_NOMEM;
--      }
--      if( pagerUseWal(pPager) ){
--        sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
--      }
--      pPager->nSavepoint = ii+1;
--    }
--    assert( pPager->nSavepoint==nSavepoint );
--    assertTruncateConstraint(pPager);
-+SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){
-+  Pager *pPager;
-+  assert( pPg!=0 );
-+  pPager = pPg->pPager;
-+  if( pPg->flags & PGHDR_MMAP ){
-+    pagerReleaseMapPage(pPg);
-+  }else{
-+    sqlite3PcacheRelease(pPg);
-   }
--
--  return rc;
-+  pagerUnlockIfUnused(pPager);
++** If the new rowid is not equal to the old, set output parameter *pbSkip
++** to 1 before returning. Otherwise, leave it unchanged.
++**
++** Return SQLITE_OK if successful or if no reseek was required, or an 
++** error code if an error occurred.
++*/
++static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
++  int rc = SQLITE_OK;
++  assert( *pbSkip==0 );
++  if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){
++    Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
++    int bDesc = pCsr->bDesc;
++    i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
++
++    rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->pIndex, iRowid, bDesc);
++    if( rc==SQLITE_OK &&  iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
++      *pbSkip = 1;
++    }
++
++    CsrFlagClear(pCsr, FTS5CSR_REQUIRE_RESEEK);
++    fts5CsrNewrow(pCsr);
++    if( sqlite3Fts5ExprEof(pCsr->pExpr) ){
++      CsrFlagSet(pCsr, FTS5CSR_EOF);
++      *pbSkip = 1;
++    }
++  }
++  return rc;
 +}
-+SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
-+  if( pPg ) sqlite3PagerUnrefNotNull(pPg);
- }
- 
- /*
--** This function is called to rollback or release (commit) a savepoint.
--** The savepoint to release or rollback need not be the most recently 
--** created savepoint.
--**
--** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE.
--** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with
--** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes
--** that have occurred since the specified savepoint was created.
-+** This function is called at the start of every write transaction.
-+** There must already be a RESERVED or EXCLUSIVE lock on the database 
-+** file when this routine is called.
- **
--** The savepoint to rollback or release is identified by parameter 
--** iSavepoint. A value of 0 means to operate on the outermost savepoint
--** (the first created). A value of (Pager.nSavepoint-1) means operate
--** on the most recently created savepoint. If iSavepoint is greater than
--** (Pager.nSavepoint-1), then this function is a no-op.
-+** Open the journal file for pager pPager and write a journal header
-+** to the start of it. If there are active savepoints, open the sub-journal
-+** as well. This function is only used when the journal file is being 
-+** opened to write a rollback log for a transaction. It is not used 
-+** when opening a hot journal file to roll it back.
- **
--** If a negative value is passed to this function, then the current
--** transaction is rolled back. This is different to calling 
--** sqlite3PagerRollback() because this function does not terminate
--** the transaction or unlock the database, it just restores the 
--** contents of the database to its original state. 
-+** If the journal file is already open (as it may be in exclusive mode),
-+** then this function just writes a journal header to the start of the
-+** already open file. 
- **
--** In any case, all savepoints with an index greater than iSavepoint 
--** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE),
--** then savepoint iSavepoint is also destroyed.
-+** Whether or not the journal file is opened by this function, the
-+** Pager.pInJournal bitvec structure is allocated.
- **
--** This function may return SQLITE_NOMEM if a memory allocation fails,
--** or an IO error code if an IO error occurs while rolling back a 
--** savepoint. If no errors occur, SQLITE_OK is returned.
--*/ 
--SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
--  int rc = pPager->errCode;       /* Return code */
--
--  assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
--  assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
-+** Return SQLITE_OK if everything is successful. Otherwise, return 
-+** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or 
-+** an IO error code if opening or writing the journal file fails.
++
++
++/*
++** Advance the cursor to the next row in the table that matches the 
++** search criteria.
++**
++** Return SQLITE_OK if nothing goes wrong.  SQLITE_OK is returned
++** even if we reach end-of-file.  The fts5EofMethod() will be called
++** subsequently to determine whether or not an EOF was hit.
 +*/
-+static int pager_open_journal(Pager *pPager){
-+  int rc = SQLITE_OK;                        /* Return code */
-+  sqlite3_vfs * const pVfs = pPager->pVfs;   /* Local cache of vfs pointer */
- 
--  if( rc==SQLITE_OK && iSavepoint<pPager->nSavepoint ){
--    int ii;            /* Iterator variable */
--    int nNew;          /* Number of remaining savepoints after this op. */
-+  assert( pPager->eState==PAGER_WRITER_LOCKED );
-+  assert( assert_pager_state(pPager) );
-+  assert( pPager->pInJournal==0 );
++static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
++  int rc;
++
++  assert( (pCsr->ePlan<3)==
++          (pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE) 
++  );
++  assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) );
++
++  if( pCsr->ePlan<3 ){
++    int bSkip = 0;
++    if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
++    rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
++    CsrFlagSet(pCsr, sqlite3Fts5ExprEof(pCsr->pExpr));
++    fts5CsrNewrow(pCsr);
++  }else{
++    switch( pCsr->ePlan ){
++      case FTS5_PLAN_SPECIAL: {
++        CsrFlagSet(pCsr, FTS5CSR_EOF);
++        rc = SQLITE_OK;
++        break;
++      }
 +  
-+  /* If already in the error state, this function is a no-op.  But on
-+  ** the other hand, this routine is never called if we are already in
-+  ** an error state. */
-+  if( NEVER(pPager->errCode) ) return pPager->errCode;
- 
--    /* Figure out how many savepoints will still be active after this
--    ** operation. Store this value in nNew. Then free resources associated 
--    ** with any savepoints that are destroyed by this operation.
--    */
--    nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1);
--    for(ii=nNew; ii<pPager->nSavepoint; ii++){
--      sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
-+  if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
-+    pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
-+    if( pPager->pInJournal==0 ){
-+      return SQLITE_NOMEM;
-     }
--    pPager->nSavepoint = nNew;
++      case FTS5_PLAN_SORTED_MATCH: {
++        rc = fts5SorterNext(pCsr);
++        break;
++      }
 +  
-+    /* Open the journal file if it is not already open. */
-+    if( !isOpen(pPager->jfd) ){
-+      if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
-+        sqlite3MemJournalOpen(pPager->jfd);
-+      }else{
-+        const int flags =                   /* VFS flags to open journal file */
-+          SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
-+          (pPager->tempFile ? 
-+            (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
-+            (SQLITE_OPEN_MAIN_JOURNAL)
-+          );
- 
--    /* If this is a release of the outermost savepoint, truncate 
--    ** the sub-journal to zero bytes in size. */
--    if( op==SAVEPOINT_RELEASE ){
--      if( nNew==0 && isOpen(pPager->sjfd) ){
--        /* Only truncate if it is an in-memory sub-journal. */
--        if( sqlite3IsMemJournal(pPager->sjfd) ){
--          rc = sqlite3OsTruncate(pPager->sjfd, 0);
--          assert( rc==SQLITE_OK );
-+        /* Verify that the database still has the same name as it did when
-+        ** it was originally opened. */
-+        rc = databaseIsUnmoved(pPager);
-+        if( rc==SQLITE_OK ){
-+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-+          rc = sqlite3JournalOpen(
-+              pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
-+          );
-+#else
-+          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
-+#endif
-         }
--        pPager->nSubRec = 0;
-       }
-+      assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
-     }
--    /* Else this is a rollback operation, playback the specified savepoint.
--    ** If this is a temp-file, it is possible that the journal file has
--    ** not yet been opened. In this case there have been no changes to
--    ** the database file, so the playback operation can be skipped.
++      default:
++        rc = sqlite3_step(pCsr->pStmt);
++        if( rc!=SQLITE_ROW ){
++          CsrFlagSet(pCsr, FTS5CSR_EOF);
++          rc = sqlite3_reset(pCsr->pStmt);
++        }else{
++          rc = SQLITE_OK;
++        }
++        break;
++    }
++  }
 +  
++  return rc;
++}
++
++
++static int fts5PrepareStatement(
++  sqlite3_stmt **ppStmt,
++  Fts5Config *pConfig, 
++  const char *zFmt,
++  ...
++){
++  sqlite3_stmt *pRet = 0;
++  int rc;
++  char *zSql;
++  va_list ap;
++
++  va_start(ap, zFmt);
++  zSql = sqlite3_vmprintf(zFmt, ap);
++  if( zSql==0 ){
++    rc = SQLITE_NOMEM; 
++  }else{
++    rc = sqlite3_prepare_v3(pConfig->db, zSql, -1, 
++                            SQLITE_PREPARE_PERSISTENT, &pRet, 0);
++    if( rc!=SQLITE_OK ){
++      *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db));
++    }
++    sqlite3_free(zSql);
++  }
++
++  va_end(ap);
++  *ppStmt = pRet;
++  return rc;
++} 
++
++static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
++  Fts5Config *pConfig = pTab->pConfig;
++  Fts5Sorter *pSorter;
++  int nPhrase;
++  int nByte;
++  int rc;
++  const char *zRank = pCsr->zRank;
++  const char *zRankArgs = pCsr->zRankArgs;
 +  
-+    /* Write the first journal header to the journal file and open 
-+    ** the sub-journal if necessary.
-     */
--    else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){
--      PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1];
--      rc = pagerPlaybackSavepoint(pPager, pSavepoint);
--      assert(rc!=SQLITE_DONE);
-+    if( rc==SQLITE_OK ){
-+      /* TODO: Check if all of these are really required. */
-+      pPager->nRec = 0;
-+      pPager->journalOff = 0;
-+      pPager->setMaster = 0;
-+      pPager->journalHdr = 0;
-+      rc = writeJournalHdr(pPager);
-     }
-   }
- 
++  nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
++  nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1);
++  pSorter = (Fts5Sorter*)sqlite3_malloc(nByte);
++  if( pSorter==0 ) return SQLITE_NOMEM;
++  memset(pSorter, 0, nByte);
++  pSorter->nIdx = nPhrase;
++
++  /* TODO: It would be better to have some system for reusing statement
++  ** handles here, rather than preparing a new one for each query. But that
++  ** is not possible as SQLite reference counts the virtual table objects.
++  ** And since the statement required here reads from this very virtual 
++  ** table, saving it creates a circular reference.
++  **
++  ** If SQLite a built-in statement cache, this wouldn't be a problem. */
++  rc = fts5PrepareStatement(&pSorter->pStmt, pConfig,
++      "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(%s%s%s) %s",
++      pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
++      (zRankArgs ? ", " : ""),
++      (zRankArgs ? zRankArgs : ""),
++      bDesc ? "DESC" : "ASC"
++  );
++
++  pCsr->pSorter = pSorter;
++  if( rc==SQLITE_OK ){
++    assert( pTab->pSortCsr==0 );
++    pTab->pSortCsr = pCsr;
++    rc = fts5SorterNext(pCsr);
++    pTab->pSortCsr = 0;
++  }
++
 +  if( rc!=SQLITE_OK ){
-+    sqlite3BitvecDestroy(pPager->pInJournal);
-+    pPager->pInJournal = 0;
-+  }else{
-+    assert( pPager->eState==PAGER_WRITER_LOCKED );
-+    pPager->eState = PAGER_WRITER_CACHEMOD;
++    sqlite3_finalize(pSorter->pStmt);
++    sqlite3_free(pSorter);
++    pCsr->pSorter = 0;
++  }
++
++  return rc;
++}
++
++static int fts5CursorFirst(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
++  int rc;
++  Fts5Expr *pExpr = pCsr->pExpr;
++  rc = sqlite3Fts5ExprFirst(pExpr, pTab->pIndex, pCsr->iFirstRowid, bDesc);
++  if( sqlite3Fts5ExprEof(pExpr) ){
++    CsrFlagSet(pCsr, FTS5CSR_EOF);
++  }
++  fts5CsrNewrow(pCsr);
++  return rc;
++}
++
++/*
++** Process a "special" query. A special query is identified as one with a
++** MATCH expression that begins with a '*' character. The remainder of
++** the text passed to the MATCH operator are used as  the special query
++** parameters.
++*/
++static int fts5SpecialMatch(
++  Fts5Table *pTab, 
++  Fts5Cursor *pCsr, 
++  const char *zQuery
++){
++  int rc = SQLITE_OK;             /* Return code */
++  const char *z = zQuery;         /* Special query text */
++  int n;                          /* Number of bytes in text at z */
++
++  while( z[0]==' ' ) z++;
++  for(n=0; z[n] && z[n]!=' '; n++);
++
++  assert( pTab->base.zErrMsg==0 );
++  pCsr->ePlan = FTS5_PLAN_SPECIAL;
++
++  if( 0==sqlite3_strnicmp("reads", z, n) ){
++    pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->pIndex);
++  }
++  else if( 0==sqlite3_strnicmp("id", z, n) ){
++    pCsr->iSpecial = pCsr->iCsrId;
++  }
++  else{
++    /* An unrecognized directive. Return an error message. */
++    pTab->base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z);
++    rc = SQLITE_ERROR;
 +  }
 +
-   return rc;
- }
- 
- /*
--** Return the full pathname of the database file.
-+** Begin a write-transaction on the specified pager object. If a 
-+** write-transaction has already been opened, this function is a no-op.
- **
--** Except, if the pager is in-memory only, then return an empty string if
--** nullIfMemDb is true.  This routine is called with nullIfMemDb==1 when
--** used to report the filename to the user, for compatibility with legacy
--** behavior.  But when the Btree needs to know the filename for matching to
--** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
--** participate in shared-cache.
-+** If the exFlag argument is false, then acquire at least a RESERVED
-+** lock on the database file. If exFlag is true, then acquire at least
-+** an EXCLUSIVE lock. If such a lock is already held, no locking 
-+** functions need be called.
-+**
-+** If the subjInMemory argument is non-zero, then any sub-journal opened
-+** within this transaction will be opened as an in-memory file. This
-+** has no effect if the sub-journal is already opened (as it may be when
-+** running in exclusive mode) or if the transaction does not require a
-+** sub-journal. If the subjInMemory argument is zero, then any required
-+** sub-journal is implemented in-memory if pPager is an in-memory database, 
-+** or using a temporary file otherwise.
- */
--SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
--  return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
--}
-+SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
++  return rc;
++}
++
++/*
++** Search for an auxiliary function named zName that can be used with table
++** pTab. If one is found, return a pointer to the corresponding Fts5Auxiliary
++** structure. Otherwise, if no such function exists, return NULL.
++*/
++static Fts5Auxiliary *fts5FindAuxiliary(Fts5Table *pTab, const char *zName){
++  Fts5Auxiliary *pAux;
++
++  for(pAux=pTab->pGlobal->pAux; pAux; pAux=pAux->pNext){
++    if( sqlite3_stricmp(zName, pAux->zFunc)==0 ) return pAux;
++  }
++
++  /* No function of the specified name was found. Return 0. */
++  return 0;
++}
++
++
++static int fts5FindRankFunction(Fts5Cursor *pCsr){
++  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
++  Fts5Config *pConfig = pTab->pConfig;
 +  int rc = SQLITE_OK;
- 
--/*
--** Return the VFS structure for the pager.
--*/
--SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
--  return pPager->pVfs;
--}
-+  if( pPager->errCode ) return pPager->errCode;
-+  assert( pPager->eState>=PAGER_READER && pPager->eState<PAGER_ERROR );
-+  pPager->subjInMemory = (u8)subjInMemory;
- 
--/*
--** Return the file handle for the database file associated
--** with the pager.  This might return NULL if the file has
--** not yet been opened.
--*/
--SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
--  return pPager->fd;
--}
-+  if( ALWAYS(pPager->eState==PAGER_READER) ){
-+    assert( pPager->pInJournal==0 );
- 
--/*
--** Return the full pathname of the journal file.
--*/
--SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
--  return pPager->zJournal;
--}
-+    if( pagerUseWal(pPager) ){
-+      /* If the pager is configured to use locking_mode=exclusive, and an
-+      ** exclusive lock on the database is not already held, obtain it now.
-+      */
-+      if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){
-+        rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
-+        if( rc!=SQLITE_OK ){
-+          return rc;
++  Fts5Auxiliary *pAux = 0;
++  const char *zRank = pCsr->zRank;
++  const char *zRankArgs = pCsr->zRankArgs;
++
++  if( zRankArgs ){
++    char *zSql = sqlite3Fts5Mprintf(&rc, "SELECT %s", zRankArgs);
++    if( zSql ){
++      sqlite3_stmt *pStmt = 0;
++      rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
++                              SQLITE_PREPARE_PERSISTENT, &pStmt, 0);
++      sqlite3_free(zSql);
++      assert( rc==SQLITE_OK || pCsr->pRankArgStmt==0 );
++      if( rc==SQLITE_OK ){
++        if( SQLITE_ROW==sqlite3_step(pStmt) ){
++          int nByte;
++          pCsr->nRankArg = sqlite3_column_count(pStmt);
++          nByte = sizeof(sqlite3_value*)*pCsr->nRankArg;
++          pCsr->apRankArg = (sqlite3_value**)sqlite3Fts5MallocZero(&rc, nByte);
++          if( rc==SQLITE_OK ){
++            int i;
++            for(i=0; i<pCsr->nRankArg; i++){
++              pCsr->apRankArg[i] = sqlite3_column_value(pStmt, i);
++            }
++          }
++          pCsr->pRankArgStmt = pStmt;
++        }else{
++          rc = sqlite3_finalize(pStmt);
++          assert( rc!=SQLITE_OK );
 +        }
-+        sqlite3WalExclusiveMode(pPager->pWal, 1);
-+      }
- 
--/*
--** Return true if fsync() calls are disabled for this pager.  Return FALSE
--** if fsync()s are executed normally.
--*/
--SQLITE_PRIVATE int sqlite3PagerNosync(Pager *pPager){
--  return pPager->noSync;
--}
-+      /* Grab the write lock on the log file. If successful, upgrade to
-+      ** PAGER_RESERVED state. Otherwise, return an error code to the caller.
-+      ** The busy-handler is not invoked if another connection already
-+      ** holds the write-lock. If possible, the upper layer will call it.
-+      */
-+      rc = sqlite3WalBeginWriteTransaction(pPager->pWal);
-+    }else{
-+      /* Obtain a RESERVED lock on the database file. If the exFlag parameter
-+      ** is true, then immediately upgrade this to an EXCLUSIVE lock. The
-+      ** busy-handler callback can be used when upgrading to the EXCLUSIVE
-+      ** lock, but not when obtaining the RESERVED lock.
-+      */
-+      rc = pagerLockDb(pPager, RESERVED_LOCK);
-+      if( rc==SQLITE_OK && exFlag ){
-+        rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
 +      }
 +    }
- 
--#ifdef SQLITE_HAS_CODEC
--/*
--** Set or retrieve the codec for this pager
--*/
--SQLITE_PRIVATE void sqlite3PagerSetCodec(
--  Pager *pPager,
--  void *(*xCodec)(void*,void*,Pgno,int),
--  void (*xCodecSizeChng)(void*,int,int),
--  void (*xCodecFree)(void*),
--  void *pCodec
--){
--  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
--  pPager->xCodec = pPager->memDb ? 0 : xCodec;
--  pPager->xCodecSizeChng = xCodecSizeChng;
--  pPager->xCodecFree = xCodecFree;
--  pPager->pCodec = pCodec;
--  pagerReportSize(pPager);
--}
--SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
--  return pPager->pCodec;
--}
-+    if( rc==SQLITE_OK ){
-+      /* Change to WRITER_LOCKED state.
-+      **
-+      ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD
-+      ** when it has an open transaction, but never to DBMOD or FINISHED.
-+      ** This is because in those states the code to roll back savepoint 
-+      ** transactions may copy data from the sub-journal into the database 
-+      ** file as well as into the page cache. Which would be incorrect in 
-+      ** WAL mode.
-+      */
-+      pPager->eState = PAGER_WRITER_LOCKED;
-+      pPager->dbHintSize = pPager->dbSize;
-+      pPager->dbFileSize = pPager->dbSize;
-+      pPager->dbOrigSize = pPager->dbSize;
-+      pPager->journalOff = 0;
++  }
++
++  if( rc==SQLITE_OK ){
++    pAux = fts5FindAuxiliary(pTab, zRank);
++    if( pAux==0 ){
++      assert( pTab->base.zErrMsg==0 );
++      pTab->base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank);
++      rc = SQLITE_ERROR;
 +    }
- 
--/*
--** This function is called by the wal module when writing page content
--** into the log file.
--**
--** This function returns a pointer to a buffer containing the encrypted
--** page content. If a malloc fails, this function may return NULL.
--*/
--SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
--  void *aData = 0;
--  CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
--  return aData;
--}
-+    assert( rc==SQLITE_OK || pPager->eState==PAGER_READER );
-+    assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED );
-+    assert( assert_pager_state(pPager) );
 +  }
- 
--/*
--** Return the current pager state
--*/
--SQLITE_PRIVATE int sqlite3PagerState(Pager *pPager){
--  return pPager->eState;
-+  PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager)));
++
++  pCsr->pRank = pAux;
 +  return rc;
- }
--#endif /* SQLITE_HAS_CODEC */
- 
--#ifndef SQLITE_OMIT_AUTOVACUUM
- /*
--** Move the page pPg to location pgno in the file.
--**
--** There must be no references to the page previously located at
--** pgno (which we call pPgOld) though that page is allowed to be
--** in cache.  If the page previously located at pgno is not already
--** in the rollback journal, it is not put there by by this routine.
--**
--** References to the page pPg remain valid. Updating any
--** meta-data associated with pPg (i.e. data stored in the nExtra bytes
--** allocated along with the page) is the responsibility of the caller.
--**
--** A transaction must be active when this routine is called. It used to be
--** required that a statement transaction was not active, but this restriction
--** has been removed (CREATE INDEX needs to move a page when a statement
--** transaction is active).
--**
--** If the fourth argument, isCommit, is non-zero, then this page is being
--** moved as part of a database reorganization just before the transaction 
--** is being committed. In this case, it is guaranteed that the database page 
--** pPg refers to will not be written to again within this transaction.
--**
--** This function may return SQLITE_NOMEM or an IO error code if an error
--** occurs. Otherwise, it returns SQLITE_OK.
-+** Mark a single data page as writeable. The page is written into the 
-+** main journal or sub-journal as required. If the page is written into
-+** one of the journals, the corresponding bit is set in the 
-+** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs
-+** of any open savepoints as appropriate.
- */
--SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
--  PgHdr *pPgOld;               /* The page being overwritten. */
--  Pgno needSyncPgno = 0;       /* Old value of pPg->pgno, if sync is required */
--  int rc;                      /* Return code */
--  Pgno origPgno;               /* The original page number */
-+static int pager_write(PgHdr *pPg){
-+  Pager *pPager = pPg->pPager;
++}
++
++
++static int fts5CursorParseRank(
++  Fts5Config *pConfig,
++  Fts5Cursor *pCsr, 
++  sqlite3_value *pRank
++){
 +  int rc = SQLITE_OK;
-+  int inJournal;
- 
--  assert( pPg->nRef>0 );
--  assert( pPager->eState==PAGER_WRITER_CACHEMOD
-+  /* This routine is not called unless a write-transaction has already 
-+  ** been started. The journal file may or may not be open at this point.
-+  ** It is never called in the ERROR state.
-+  */
-+  assert( pPager->eState==PAGER_WRITER_LOCKED
-+       || pPager->eState==PAGER_WRITER_CACHEMOD
-        || pPager->eState==PAGER_WRITER_DBMOD
-   );
-   assert( assert_pager_state(pPager) );
-+  assert( pPager->errCode==0 );
-+  assert( pPager->readOnly==0 );
- 
--  /* In order to be able to rollback, an in-memory database must journal
--  ** the page we are moving from.
--  */
--  if( MEMDB ){
--    rc = sqlite3PagerWrite(pPg);
--    if( rc ) return rc;
--  }
-+  CHECK_PAGE(pPg);
- 
--  /* If the page being moved is dirty and has not been saved by the latest
--  ** savepoint, then save the current contents of the page into the 
--  ** sub-journal now. This is required to handle the following scenario:
--  **
--  **   BEGIN;
--  **     <journal page X, then modify it in memory>
--  **     SAVEPOINT one;
--  **       <Move page X to location Y>
--  **     ROLLBACK TO one;
--  **
--  ** If page X were not written to the sub-journal here, it would not
--  ** be possible to restore its contents when the "ROLLBACK TO one"
--  ** statement were is processed.
-+  /* The journal file needs to be opened. Higher level routines have already
-+  ** obtained the necessary locks to begin the write-transaction, but the
-+  ** rollback journal might not yet be open. Open it now if this is the case.
-   **
--  ** subjournalPage() may need to allocate space to store pPg->pgno into
--  ** one or more savepoint bitvecs. This is the reason this function
--  ** may return SQLITE_NOMEM.
-+  ** This is done before calling sqlite3PcacheMakeDirty() on the page. 
-+  ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then
-+  ** an error might occur and the pager would end up in WRITER_LOCKED state
-+  ** with pages marked as dirty in the cache.
-   */
--  if( pPg->flags&PGHDR_DIRTY
--   && subjRequiresPage(pPg)
--   && SQLITE_OK!=(rc = subjournalPage(pPg))
--  ){
--    return rc;
-+  if( pPager->eState==PAGER_WRITER_LOCKED ){
-+    rc = pager_open_journal(pPager);
-+    if( rc!=SQLITE_OK ) return rc;
-   }
-+  assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
-+  assert( assert_pager_state(pPager) );
- 
--  PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", 
--      PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno));
--  IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno))
--
--  /* If the journal needs to be sync()ed before page pPg->pgno can
--  ** be written to, store pPg->pgno in local variable needSyncPgno.
--  **
--  ** If the isCommit flag is set, there is no need to remember that
--  ** the journal needs to be sync()ed before database page pPg->pgno 
--  ** can be written to. The caller has already promised not to write to it.
-+  /* Mark the page as dirty.  If the page has already been written
-+  ** to the journal then we can return right away.
-   */
--  if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
--    needSyncPgno = pPg->pgno;
--    assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
--            pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize );
--    assert( pPg->flags&PGHDR_DIRTY );
-+  sqlite3PcacheMakeDirty(pPg);
-+  inJournal = pageInJournal(pPager, pPg);
-+  if( inJournal && (pPager->nSavepoint==0 || !subjRequiresPage(pPg)) ){
-+    assert( !pagerUseWal(pPager) );
-+  }else{
-+  
-+    /* The transaction journal now exists and we have a RESERVED or an
-+    ** EXCLUSIVE lock on the main database file.  Write the current page to
-+    ** the transaction journal if it is not there already.
-+    */
-+    if( !inJournal && !pagerUseWal(pPager) ){
-+      assert( pagerUseWal(pPager)==0 );
-+      if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){
-+        u32 cksum;
-+        char *pData2;
-+        i64 iOff = pPager->journalOff;
-+
-+        /* We should never write to the journal file the page that
-+        ** contains the database locks.  The following assert verifies
-+        ** that we do not. */
-+        assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
-+
-+        assert( pPager->journalHdr<=pPager->journalOff );
-+        CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
-+        cksum = pager_cksum(pPager, (u8*)pData2);
-+
-+        /* Even if an IO or diskfull error occurs while journalling the
-+        ** page in the block above, set the need-sync flag for the page.
-+        ** Otherwise, when the transaction is rolled back, the logic in
-+        ** playback_one_page() will think that the page needs to be restored
-+        ** in the database file. And if an IO error occurs while doing so,
-+        ** then corruption may follow.
-+        */
-+        pPg->flags |= PGHDR_NEED_SYNC;
++  if( pRank ){
++    const char *z = (const char*)sqlite3_value_text(pRank);
++    char *zRank = 0;
++    char *zRankArgs = 0;
 +
-+        rc = write32bits(pPager->jfd, iOff, pPg->pgno);
-+        if( rc!=SQLITE_OK ) return rc;
-+        rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4);
-+        if( rc!=SQLITE_OK ) return rc;
-+        rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum);
-+        if( rc!=SQLITE_OK ) return rc;
-+
-+        IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, 
-+                 pPager->journalOff, pPager->pageSize));
-+        PAGER_INCR(sqlite3_pager_writej_count);
-+        PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n",
-+             PAGERID(pPager), pPg->pgno, 
-+             ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg)));
-+
-+        pPager->journalOff += 8 + pPager->pageSize;
-+        pPager->nRec++;
-+        assert( pPager->pInJournal!=0 );
-+        rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
-+        testcase( rc==SQLITE_NOMEM );
-+        assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
-+        rc |= addToSavepointBitvecs(pPager, pPg->pgno);
-+        if( rc!=SQLITE_OK ){
-+          assert( rc==SQLITE_NOMEM );
-+          return rc;
-+        }
-+      }else{
-+        if( pPager->eState!=PAGER_WRITER_DBMOD ){
-+          pPg->flags |= PGHDR_NEED_SYNC;
-+        }
-+        PAGERTRACE(("APPEND %d page %d needSync=%d\n",
-+                PAGERID(pPager), pPg->pgno,
-+               ((pPg->flags&PGHDR_NEED_SYNC)?1:0)));
-+      }
++    if( z==0 ){
++      if( sqlite3_value_type(pRank)==SQLITE_NULL ) rc = SQLITE_ERROR;
++    }else{
++      rc = sqlite3Fts5ConfigParseRank(z, &zRank, &zRankArgs);
 +    }
-+  
-+    /* If the statement journal is open and the page is not in it,
-+    ** then write the current page to the statement journal.  Note that
-+    ** the statement journal format differs from the standard journal format
-+    ** in that it omits the checksums and the header.
-+    */
-+    if( pPager->nSavepoint>0 && subjRequiresPage(pPg) ){
-+      rc = subjournalPage(pPg);
++    if( rc==SQLITE_OK ){
++      pCsr->zRank = zRank;
++      pCsr->zRankArgs = zRankArgs;
++      CsrFlagSet(pCsr, FTS5CSR_FREE_ZRANK);
++    }else if( rc==SQLITE_ERROR ){
++      pCsr->base.pVtab->zErrMsg = sqlite3_mprintf(
++          "parse error in rank function: %s", z
++      );
 +    }
-   }
- 
--  /* If the cache contains a page with page-number pgno, remove it
--  ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for 
--  ** page pgno before the 'move' operation, it needs to be retained 
--  ** for the page moved there.
-+  /* Update the database size and return.
-   */
--  pPg->flags &= ~PGHDR_NEED_SYNC;
--  pPgOld = sqlite3PagerLookup(pPager, pgno);
--  assert( !pPgOld || pPgOld->nRef==1 );
--  if( pPgOld ){
--    pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
--    if( MEMDB ){
--      /* Do not discard pages from an in-memory database since we might
--      ** need to rollback later.  Just move the page out of the way. */
--      sqlite3PcacheMove(pPgOld, pPager->dbSize+1);
--    }else{
--      sqlite3PcacheDrop(pPgOld);
--    }
-+  if( pPager->dbSize<pPg->pgno ){
-+    pPager->dbSize = pPg->pgno;
-   }
++  }else{
++    if( pConfig->zRank ){
++      pCsr->zRank = (char*)pConfig->zRank;
++      pCsr->zRankArgs = (char*)pConfig->zRankArgs;
++    }else{
++      pCsr->zRank = (char*)FTS5_DEFAULT_RANK;
++      pCsr->zRankArgs = 0;
++    }
++  }
 +  return rc;
 +}
- 
--  origPgno = pPg->pgno;
--  sqlite3PcacheMove(pPg, pgno);
--  sqlite3PcacheMakeDirty(pPg);
-+/*
-+** This is a variant of sqlite3PagerWrite() that runs when the sector size
-+** is larger than the page size.  SQLite makes the (reasonable) assumption that
-+** all bytes of a sector are written together by hardware.  Hence, all bytes of
-+** a sector need to be journalled in case of a power loss in the middle of
-+** a write.
-+**
-+** Usually, the sector size is less than or equal to the page size, in which
-+** case pages can be individually written.  This routine only runs in the exceptional
-+** case where the page size is smaller than the sector size.
-+*/
-+static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){
-+  int rc = SQLITE_OK;            /* Return code */
-+  Pgno nPageCount;               /* Total number of pages in database file */
-+  Pgno pg1;                      /* First page of the sector pPg is located on. */
-+  int nPage = 0;                 /* Number of pages starting at pg1 to journal */
-+  int ii;                        /* Loop counter */
-+  int needSync = 0;              /* True if any page has PGHDR_NEED_SYNC */
-+  Pager *pPager = pPg->pPager;   /* The pager that owns pPg */
-+  Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
- 
--  /* For an in-memory database, make sure the original page continues
--  ** to exist, in case the transaction needs to roll back.  Use pPgOld
--  ** as the original page since it has already been allocated.
-+  /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
-+  ** a journal header to be written between the pages journaled by
-+  ** this function.
-   */
--  if( MEMDB ){
--    assert( pPgOld );
--    sqlite3PcacheMove(pPgOld, origPgno);
--    sqlite3PagerUnrefNotNull(pPgOld);
-+  assert( !MEMDB );
-+  assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 );
-+  pPager->doNotSpill |= SPILLFLAG_NOSYNC;
-+
-+  /* This trick assumes that both the page-size and sector-size are
-+  ** an integer power of 2. It sets variable pg1 to the identifier
-+  ** of the first page of the sector pPg is located on.
-+  */
-+  pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
-+
-+  nPageCount = pPager->dbSize;
-+  if( pPg->pgno>nPageCount ){
-+    nPage = (pPg->pgno - pg1)+1;
-+  }else if( (pg1+nPagePerSector-1)>nPageCount ){
-+    nPage = nPageCount+1-pg1;
-+  }else{
-+    nPage = nPagePerSector;
-   }
-+  assert(nPage>0);
-+  assert(pg1<=pPg->pgno);
-+  assert((pg1+nPage)>pPg->pgno);
- 
--  if( needSyncPgno ){
--    /* If needSyncPgno is non-zero, then the journal file needs to be 
--    ** sync()ed before any data is written to database file page needSyncPgno.
--    ** Currently, no such page exists in the page-cache and the 
--    ** "is journaled" bitvec flag has been set. This needs to be remedied by
--    ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC
--    ** flag.
--    **
--    ** If the attempt to load the page into the page-cache fails, (due
--    ** to a malloc() or IO failure), clear the bit in the pInJournal[]
--    ** array. Otherwise, if the page is loaded and written again in
--    ** this transaction, it may be written to the database file before
--    ** it is synced into the journal file. This way, it may end up in
--    ** the journal file twice, but that is not a problem.
--    */
--    PgHdr *pPgHdr;
--    rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
--    if( rc!=SQLITE_OK ){
--      if( needSyncPgno<=pPager->dbOrigSize ){
--        assert( pPager->pTmpSpace!=0 );
--        sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace);
-+  for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
-+    Pgno pg = pg1+ii;
-+    PgHdr *pPage;
-+    if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
-+      if( pg!=PAGER_MJ_PGNO(pPager) ){
-+        rc = sqlite3PagerGet(pPager, pg, &pPage);
-+        if( rc==SQLITE_OK ){
-+          rc = pager_write(pPage);
-+          if( pPage->flags&PGHDR_NEED_SYNC ){
-+            needSync = 1;
-+          }
-+          sqlite3PagerUnrefNotNull(pPage);
-+        }
-       }
--      return rc;
-+    }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){
-+      if( pPage->flags&PGHDR_NEED_SYNC ){
-+        needSync = 1;
-+      }
-+      sqlite3PagerUnrefNotNull(pPage);
-     }
--    pPgHdr->flags |= PGHDR_NEED_SYNC;
--    sqlite3PcacheMakeDirty(pPgHdr);
--    sqlite3PagerUnrefNotNull(pPgHdr);
-   }
- 
--  return SQLITE_OK;
--}
--#endif
-+  /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages 
-+  ** starting at pg1, then it needs to be set for all of them. Because
-+  ** writing to any of these nPage pages may damage the others, the
-+  ** journal file must contain sync()ed copies of all of them
-+  ** before any of them can be written out to the database file.
-+  */
-+  if( rc==SQLITE_OK && needSync ){
-+    assert( !MEMDB );
-+    for(ii=0; ii<nPage; ii++){
-+      PgHdr *pPage = sqlite3PagerLookup(pPager, pg1+ii);
-+      if( pPage ){
-+        pPage->flags |= PGHDR_NEED_SYNC;
-+        sqlite3PagerUnrefNotNull(pPage);
-+      }
++
++static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){
++  if( pVal ){
++    int eType = sqlite3_value_numeric_type(pVal);
++    if( eType==SQLITE_INTEGER ){
++      return sqlite3_value_int64(pVal);
 +    }
 +  }
- 
--/*
--** The page handle passed as the first argument refers to a dirty page 
--** with a page number other than iNew. This function changes the page's 
--** page number to iNew and sets the value of the PgHdr.flags field to 
--** the value passed as the third parameter.
--*/
--SQLITE_PRIVATE void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){
--  assert( pPg->pgno!=iNew );
--  pPg->flags = flags;
--  sqlite3PcacheMove(pPg, iNew);
-+  assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
-+  pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
-+  return rc;
- }
- 
- /*
--** Return a pointer to the data for the specified page.
-+** Mark a data page as writeable. This routine must be called before 
-+** making changes to a page. The caller must check the return value 
-+** of this function and be careful not to change any page data unless 
-+** this routine returns SQLITE_OK.
-+**
-+** The difference between this function and pager_write() is that this
-+** function also deals with the special case where 2 or more pages
-+** fit on a single disk sector. In this case all co-resident pages
-+** must have been written to the journal file before returning.
++  return iDefault;
++}
++
++/*
++** This is the xFilter interface for the virtual table.  See
++** the virtual table xFilter method documentation for additional
++** information.
++** 
++** There are three possible query strategies:
 +**
-+** If an error occurs, SQLITE_NOMEM or an IO error code is returned
-+** as appropriate. Otherwise, SQLITE_OK.
- */
--SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){
--  assert( pPg->nRef>0 || pPg->pPager->memDb );
--  return pPg->pData;
-+SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){
-+  assert( (pPg->flags & PGHDR_MMAP)==0 );
-+  assert( pPg->pPager->eState>=PAGER_WRITER_LOCKED );
-+  assert( pPg->pPager->eState!=PAGER_ERROR );
-+  assert( assert_pager_state(pPg->pPager) );
-+  if( pPg->pPager->sectorSize > (u32)pPg->pPager->pageSize ){
-+    return pagerWriteLargeSector(pPg);
-+  }else{
-+    return pager_write(pPg);
++**   1. Full-text search using a MATCH operator.
++**   2. A by-rowid lookup.
++**   3. A full-table scan.
++*/
++static int fts5FilterMethod(
++  sqlite3_vtab_cursor *pCursor,   /* The cursor used for this query */
++  int idxNum,                     /* Strategy index */
++  const char *zUnused,            /* Unused */
++  int nVal,                       /* Number of elements in apVal */
++  sqlite3_value **apVal           /* Arguments for the indexing scheme */
++){
++  Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
++  Fts5Config *pConfig = pTab->pConfig;
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
++  int rc = SQLITE_OK;             /* Error code */
++  int iVal = 0;                   /* Counter for apVal[] */
++  int bDesc;                      /* True if ORDER BY [rank|rowid] DESC */
++  int bOrderByRank;               /* True if ORDER BY rank */
++  sqlite3_value *pMatch = 0;      /* <tbl> MATCH ? expression (or NULL) */
++  sqlite3_value *pRank = 0;       /* rank MATCH ? expression (or NULL) */
++  sqlite3_value *pRowidEq = 0;    /* rowid = ? expression (or NULL) */
++  sqlite3_value *pRowidLe = 0;    /* rowid <= ? expression (or NULL) */
++  sqlite3_value *pRowidGe = 0;    /* rowid >= ? expression (or NULL) */
++  int iCol;                       /* Column on LHS of MATCH operator */
++  char **pzErrmsg = pConfig->pzErrmsg;
++
++  UNUSED_PARAM(zUnused);
++  UNUSED_PARAM(nVal);
++
++  if( pCsr->ePlan ){
++    fts5FreeCursorComponents(pCsr);
++    memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
 +  }
- }
- 
- /*
--** Return a pointer to the Pager.nExtra bytes of "extra" space 
--** allocated along with the specified page.
-+** Return TRUE if the page given in the argument was previously passed
-+** to sqlite3PagerWrite().  In other words, return TRUE if it is ok
-+** to change the content of the page.
- */
--SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){
--  return pPg->pExtra;
-+#ifndef NDEBUG
-+SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){
-+  return pPg->flags&PGHDR_DIRTY;
- }
-+#endif
- 
- /*
--** Get/set the locking-mode for this pager. Parameter eMode must be one
--** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or 
--** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then
--** the locking-mode is set to the value specified.
-+** A call to this routine tells the pager that it is not necessary to
-+** write the information on page pPg back to the disk, even though
-+** that page might be marked as dirty.  This happens, for example, when
-+** the page has been added as a leaf of the freelist and so its
-+** content no longer matters.
- **
--** The returned value is either PAGER_LOCKINGMODE_NORMAL or
--** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated)
--** locking-mode.
-+** The overlying software layer calls this routine when all of the data
-+** on the given page is unused. The pager marks the page as clean so
-+** that it does not get written to disk.
-+**
-+** Tests show that this optimization can quadruple the speed of large 
-+** DELETE operations.
- */
--SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){
--  assert( eMode==PAGER_LOCKINGMODE_QUERY
--            || eMode==PAGER_LOCKINGMODE_NORMAL
--            || eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
--  assert( PAGER_LOCKINGMODE_QUERY<0 );
--  assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 );
--  assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) );
--  if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){
--    pPager->exclusiveMode = (u8)eMode;
-+SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
-+  Pager *pPager = pPg->pPager;
-+  if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
-+    PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
-+    IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
-+    pPg->flags |= PGHDR_DONT_WRITE;
-+    pager_set_pagehash(pPg);
-   }
--  return (int)pPager->exclusiveMode;
- }
- 
- /*
--** Set the journal-mode for this pager. Parameter eMode must be one of:
--**
--**    PAGER_JOURNALMODE_DELETE
--**    PAGER_JOURNALMODE_TRUNCATE
--**    PAGER_JOURNALMODE_PERSIST
--**    PAGER_JOURNALMODE_OFF
--**    PAGER_JOURNALMODE_MEMORY
--**    PAGER_JOURNALMODE_WAL
--**
--** The journalmode is set to the value specified if the change is allowed.
--** The change may be disallowed for the following reasons:
-+** This routine is called to increment the value of the database file 
-+** change-counter, stored as a 4-byte big-endian integer starting at 
-+** byte offset 24 of the pager file.  The secondary change counter at
-+** 92 is also updated, as is the SQLite version number at offset 96.
- **
--**   *  An in-memory database can only have its journal_mode set to _OFF
--**      or _MEMORY.
-+** But this only happens if the pPager->changeCountDone flag is false.
-+** To avoid excess churning of page 1, the update only happens once.
-+** See also the pager_write_changecounter() routine that does an 
-+** unconditional update of the change counters.
- **
--**   *  Temporary databases cannot have _WAL journalmode.
-+** If the isDirectMode flag is zero, then this is done by calling 
-+** sqlite3PagerWrite() on page 1, then modifying the contents of the
-+** page data. In this case the file will be updated when the current
-+** transaction is committed.
- **
--** The returned indicate the current (possibly updated) journal-mode.
-+** The isDirectMode flag may only be non-zero if the library was compiled
-+** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case,
-+** if isDirect is non-zero, then the database file is updated directly
-+** by writing an updated version of page 1 using a call to the 
-+** sqlite3OsWrite() function.
- */
--SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
--  u8 eOld = pPager->journalMode;    /* Prior journalmode */
--
--#ifdef SQLITE_DEBUG
--  /* The print_pager_state() routine is intended to be used by the debugger
--  ** only.  We invoke it once here to suppress a compiler warning. */
--  print_pager_state(pPager);
--#endif
--
-+static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
-+  int rc = SQLITE_OK;
- 
--  /* The eMode parameter is always valid */
--  assert(      eMode==PAGER_JOURNALMODE_DELETE
--            || eMode==PAGER_JOURNALMODE_TRUNCATE
--            || eMode==PAGER_JOURNALMODE_PERSIST
--            || eMode==PAGER_JOURNALMODE_OFF 
--            || eMode==PAGER_JOURNALMODE_WAL 
--            || eMode==PAGER_JOURNALMODE_MEMORY );
-+  assert( pPager->eState==PAGER_WRITER_CACHEMOD
-+       || pPager->eState==PAGER_WRITER_DBMOD
-+  );
-+  assert( assert_pager_state(pPager) );
- 
--  /* This routine is only called from the OP_JournalMode opcode, and
--  ** the logic there will never allow a temporary file to be changed
--  ** to WAL mode.
-+  /* Declare and initialize constant integer 'isDirect'. If the
-+  ** atomic-write optimization is enabled in this build, then isDirect
-+  ** is initialized to the value passed as the isDirectMode parameter
-+  ** to this function. Otherwise, it is always set to zero.
++
++  assert( pCsr->pStmt==0 );
++  assert( pCsr->pExpr==0 );
++  assert( pCsr->csrflags==0 );
++  assert( pCsr->pRank==0 );
++  assert( pCsr->zRank==0 );
++  assert( pCsr->zRankArgs==0 );
++
++  assert( pzErrmsg==0 || pzErrmsg==&pTab->base.zErrMsg );
++  pConfig->pzErrmsg = &pTab->base.zErrMsg;
++
++  /* Decode the arguments passed through to this function.
 +  **
-+  ** The idea is that if the atomic-write optimization is not
-+  ** enabled at compile time, the compiler can omit the tests of
-+  ** 'isDirect' below, as well as the block enclosed in the
-+  ** "if( isDirect )" condition.
-   */
--  assert( pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL );
-+#ifndef SQLITE_ENABLE_ATOMIC_WRITE
-+# define DIRECT_MODE 0
-+  assert( isDirectMode==0 );
-+  UNUSED_PARAMETER(isDirectMode);
-+#else
-+# define DIRECT_MODE isDirectMode
-+#endif
- 
--  /* Do allow the journalmode of an in-memory database to be set to
--  ** anything other than MEMORY or OFF
--  */
--  if( MEMDB ){
--    assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF );
--    if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){
--      eMode = eOld;
--    }
--  }
-+  if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){
-+    PgHdr *pPgHdr;                /* Reference to page 1 */
- 
--  if( eMode!=eOld ){
-+    assert( !pPager->tempFile && isOpen(pPager->fd) );
- 
--    /* Change the journal mode. */
--    assert( pPager->eState!=PAGER_ERROR );
--    pPager->journalMode = (u8)eMode;
-+    /* Open page 1 of the file for writing. */
-+    rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
-+    assert( pPgHdr==0 || rc==SQLITE_OK );
- 
--    /* When transistioning from TRUNCATE or PERSIST to any other journal
--    ** mode except WAL, unless the pager is in locking_mode=exclusive mode,
--    ** delete the journal file.
-+    /* If page one was fetched successfully, and this function is not
-+    ** operating in direct-mode, make page 1 writable.  When not in 
-+    ** direct mode, page 1 is always held in cache and hence the PagerGet()
-+    ** above is always successful - hence the ALWAYS on rc==SQLITE_OK.
-     */
--    assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
--    assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 );
--    assert( (PAGER_JOURNALMODE_DELETE & 5)==0 );
--    assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 );
--    assert( (PAGER_JOURNALMODE_OFF & 5)==0 );
--    assert( (PAGER_JOURNALMODE_WAL & 5)==5 );
-+    if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){
-+      rc = sqlite3PagerWrite(pPgHdr);
-+    }
- 
--    assert( isOpen(pPager->fd) || pPager->exclusiveMode );
--    if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){
++  ** Note: The following set of if(...) statements must be in the same
++  ** order as the corresponding entries in the struct at the top of
++  ** fts5BestIndexMethod().  */
++  if( BitFlagTest(idxNum, FTS5_BI_MATCH) ) pMatch = apVal[iVal++];
++  if( BitFlagTest(idxNum, FTS5_BI_RANK) ) pRank = apVal[iVal++];
++  if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++];
++  if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++];
++  if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++];
++  iCol = (idxNum>>16);
++  assert( iCol>=0 && iCol<=pConfig->nCol );
++  assert( iVal==nVal );
++  bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
++  pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);
++
++  /* Set the cursor upper and lower rowid limits. Only some strategies 
++  ** actually use them. This is ok, as the xBestIndex() method leaves the
++  ** sqlite3_index_constraint.omit flag clear for range constraints
++  ** on the rowid field.  */
++  if( pRowidEq ){
++    pRowidLe = pRowidGe = pRowidEq;
++  }
++  if( bDesc ){
++    pCsr->iFirstRowid = fts5GetRowidLimit(pRowidLe, LARGEST_INT64);
++    pCsr->iLastRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64);
++  }else{
++    pCsr->iLastRowid = fts5GetRowidLimit(pRowidLe, LARGEST_INT64);
++    pCsr->iFirstRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64);
++  }
++
++  if( pTab->pSortCsr ){
++    /* If pSortCsr is non-NULL, then this call is being made as part of 
++    ** processing for a "... MATCH <expr> ORDER BY rank" query (ePlan is
++    ** set to FTS5_PLAN_SORTED_MATCH). pSortCsr is the cursor that will
++    ** return results to the user for this query. The current cursor 
++    ** (pCursor) is used to execute the query issued by function 
++    ** fts5CursorFirstSorted() above.  */
++    assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 );
++    assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 );
++    assert( pCsr->iLastRowid==LARGEST_INT64 );
++    assert( pCsr->iFirstRowid==SMALLEST_INT64 );
++    pCsr->ePlan = FTS5_PLAN_SOURCE;
++    pCsr->pExpr = pTab->pSortCsr->pExpr;
++    rc = fts5CursorFirst(pTab, pCsr, bDesc);
++  }else if( pMatch ){
++    const char *zExpr = (const char*)sqlite3_value_text(apVal[0]);
++    if( zExpr==0 ) zExpr = "";
++
++    rc = fts5CursorParseRank(pConfig, pCsr, pRank);
 +    if( rc==SQLITE_OK ){
-+      /* Actually do the update of the change counter */
-+      pager_write_changecounter(pPgHdr);
- 
--      /* In this case we would like to delete the journal file. If it is
--      ** not possible, then that is not a problem. Deleting the journal file
--      ** here is an optimization only.
--      **
--      ** Before deleting the journal file, obtain a RESERVED lock on the
--      ** database file. This ensures that the journal file is not deleted
--      ** while it is in use by some other client.
--      */
--      sqlite3OsClose(pPager->jfd);
--      if( pPager->eLock>=RESERVED_LOCK ){
--        sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
--      }else{
--        int rc = SQLITE_OK;
--        int state = pPager->eState;
--        assert( state==PAGER_OPEN || state==PAGER_READER );
--        if( state==PAGER_OPEN ){
--          rc = sqlite3PagerSharedLock(pPager);
--        }
--        if( pPager->eState==PAGER_READER ){
--          assert( rc==SQLITE_OK );
--          rc = pagerLockDb(pPager, RESERVED_LOCK);
--        }
-+      /* If running in direct mode, write the contents of page 1 to the file. */
-+      if( DIRECT_MODE ){
-+        const void *zBuf;
-+        assert( pPager->dbFileSize>0 );
-+        CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf);
-         if( rc==SQLITE_OK ){
--          sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
-+          rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
-+          pPager->aStat[PAGER_STAT_WRITE]++;
-         }
--        if( rc==SQLITE_OK && state==PAGER_READER ){
--          pagerUnlockDb(pPager, SHARED_LOCK);
--        }else if( state==PAGER_OPEN ){
--          pager_unlock(pPager);
++      if( zExpr[0]=='*' ){
++        /* The user has issued a query of the form "MATCH '*...'". This
++        ** indicates that the MATCH expression is not a full text query,
++        ** but a request for an internal parameter.  */
++        rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
++      }else{
++        char **pzErr = &pTab->base.zErrMsg;
++        rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr);
 +        if( rc==SQLITE_OK ){
-+          /* Update the pager's copy of the change-counter. Otherwise, the
-+          ** next time a read transaction is opened the cache will be
-+          ** flushed (as the change-counter values will not match).  */
-+          const void *pCopy = (const void *)&((const char *)zBuf)[24];
-+          memcpy(&pPager->dbFileVers, pCopy, sizeof(pPager->dbFileVers));
-+          pPager->changeCountDone = 1;
-         }
--        assert( state==pPager->eState );
++          if( bOrderByRank ){
++            pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
++            rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
++          }else{
++            pCsr->ePlan = FTS5_PLAN_MATCH;
++            rc = fts5CursorFirst(pTab, pCsr, bDesc);
++          }
++        }
++      }
++    }
++  }else if( pConfig->zContent==0 ){
++    *pConfig->pzErrmsg = sqlite3_mprintf(
++        "%s: table does not support scanning", pConfig->zName
++    );
++    rc = SQLITE_ERROR;
++  }else{
++    /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup
++    ** by rowid (ePlan==FTS5_PLAN_ROWID).  */
++    pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN);
++    rc = sqlite3Fts5StorageStmt(
++        pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->base.zErrMsg
++    );
++    if( rc==SQLITE_OK ){
++      if( pCsr->ePlan==FTS5_PLAN_ROWID ){
++        sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
 +      }else{
-+        pPager->changeCountDone = 1;
-       }
--    }else if( eMode==PAGER_JOURNALMODE_OFF ){
--      sqlite3OsClose(pPager->jfd);
-     }
--  }
- 
--  /* Return the new journal mode */
--  return (int)pPager->journalMode;
-+    /* Release the page reference. */
-+    sqlite3PagerUnref(pPgHdr);
++        sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
++        sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid);
++      }
++      rc = fts5NextMethod(pCursor);
++    }
 +  }
++
++  pConfig->pzErrmsg = pzErrmsg;
 +  return rc;
- }
- 
- /*
--** Return the current journal mode.
-+** Sync the database file to disk. This is a no-op for in-memory databases
-+** or pages with the Pager.noSync flag set.
++}
++
++/* 
++** This is the xEof method of the virtual table. SQLite calls this 
++** routine to find out if it has reached the end of a result set.
++*/
++static int fts5EofMethod(sqlite3_vtab_cursor *pCursor){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
++  return (CsrFlagTest(pCsr, FTS5CSR_EOF) ? 1 : 0);
++}
++
++/*
++** Return the rowid that the cursor currently points to.
++*/
++static i64 fts5CursorRowid(Fts5Cursor *pCsr){
++  assert( pCsr->ePlan==FTS5_PLAN_MATCH 
++       || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH 
++       || pCsr->ePlan==FTS5_PLAN_SOURCE 
++  );
++  if( pCsr->pSorter ){
++    return pCsr->pSorter->iRowid;
++  }else{
++    return sqlite3Fts5ExprRowid(pCsr->pExpr);
++  }
++}
++
++/* 
++** This is the xRowid method. The SQLite core calls this routine to
++** retrieve the rowid for the current row of the result set. fts5
++** exposes %_content.rowid as the rowid for the virtual table. The
++** rowid should be written to *pRowid.
++*/
++static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
++  int ePlan = pCsr->ePlan;
++  
++  assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 );
++  switch( ePlan ){
++    case FTS5_PLAN_SPECIAL:
++      *pRowid = 0;
++      break;
++
++    case FTS5_PLAN_SOURCE:
++    case FTS5_PLAN_MATCH:
++    case FTS5_PLAN_SORTED_MATCH:
++      *pRowid = fts5CursorRowid(pCsr);
++      break;
++
++    default:
++      *pRowid = sqlite3_column_int64(pCsr->pStmt, 0);
++      break;
++  }
++
++  return SQLITE_OK;
++}
++
++/*
++** If the cursor requires seeking (bSeekRequired flag is set), seek it.
++** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise.
 +**
-+** If successful, or if called on a pager for which it is a no-op, this
-+** function returns SQLITE_OK. Otherwise, an IO error code is returned.
- */
--SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){
--  return (int)pPager->journalMode;
--}
-+SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster){
++** If argument bErrormsg is true and an error occurs, an error message may
++** be left in sqlite3_vtab.zErrMsg.
++*/
++static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
 +  int rc = SQLITE_OK;
- 
--/*
--** Return TRUE if the pager is in a state where it is OK to change the
--** journalmode.  Journalmode changes can only happen when the database
--** is unmodified.
--*/
--SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){
--  assert( assert_pager_state(pPager) );
--  if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0;
--  if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0;
--  return 1;
-+  if( isOpen(pPager->fd) ){
-+    void *pArg = (void*)zMaster;
-+    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg);
-+    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
++
++  /* If the cursor does not yet have a statement handle, obtain one now. */ 
++  if( pCsr->pStmt==0 ){
++    Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
++    int eStmt = fts5StmtType(pCsr);
++    rc = sqlite3Fts5StorageStmt(
++        pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->base.zErrMsg:0)
++    );
++    assert( rc!=SQLITE_OK || pTab->base.zErrMsg==0 );
++    assert( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) );
 +  }
-+  if( rc==SQLITE_OK && !pPager->noSync ){
-+    assert( !MEMDB );
-+    rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
++
++  if( rc==SQLITE_OK && CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) ){
++    assert( pCsr->pExpr );
++    sqlite3_reset(pCsr->pStmt);
++    sqlite3_bind_int64(pCsr->pStmt, 1, fts5CursorRowid(pCsr));
++    rc = sqlite3_step(pCsr->pStmt);
++    if( rc==SQLITE_ROW ){
++      rc = SQLITE_OK;
++      CsrFlagClear(pCsr, FTS5CSR_REQUIRE_CONTENT);
++    }else{
++      rc = sqlite3_reset(pCsr->pStmt);
++      if( rc==SQLITE_OK ){
++        rc = FTS5_CORRUPT;
++      }
++    }
 +  }
 +  return rc;
- }
- 
- /*
--** Get/set the size-limit used for persistent journal files.
-+** This function may only be called while a write-transaction is active in
-+** rollback. If the connection is in WAL mode, this call is a no-op. 
-+** Otherwise, if the connection does not already have an EXCLUSIVE lock on 
-+** the database file, an attempt is made to obtain one.
- **
--** Setting the size limit to -1 means no limit is enforced.
--** An attempt to set a limit smaller than -1 is a no-op.
-+** If the EXCLUSIVE lock is already held or the attempt to obtain it is
-+** successful, or the connection is in WAL mode, SQLITE_OK is returned.
-+** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is 
-+** returned.
- */
--SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
--  if( iLimit>=-1 ){
--    pPager->journalSizeLimit = iLimit;
--    sqlite3WalLimit(pPager->pWal, iLimit);
-+SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){
-+  int rc = SQLITE_OK;
-+  assert( pPager->eState==PAGER_WRITER_CACHEMOD 
-+       || pPager->eState==PAGER_WRITER_DBMOD 
-+       || pPager->eState==PAGER_WRITER_LOCKED 
-+  );
-+  assert( assert_pager_state(pPager) );
-+  if( 0==pagerUseWal(pPager) ){
-+    rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
-   }
--  return pPager->journalSizeLimit;
-+  return rc;
- }
- 
- /*
--** Return a pointer to the pPager->pBackup variable. The backup module
--** in backup.c maintains the content of this variable. This module
--** uses it opaquely as an argument to sqlite3BackupRestart() and
--** sqlite3BackupUpdate() only.
-+** Sync the database file for the pager pPager. zMaster points to the name
-+** of a master journal file that should be written into the individual
-+** journal file. zMaster may be NULL, which is interpreted as no master
-+** journal (a single database transaction).
++}
++
++static void fts5SetVtabError(Fts5Table *p, const char *zFormat, ...){
++  va_list ap;                     /* ... printf arguments */
++  va_start(ap, zFormat);
++  assert( p->base.zErrMsg==0 );
++  p->base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
++  va_end(ap);
++}
++
++/*
++** This function is called to handle an FTS INSERT command. In other words,
++** an INSERT statement of the form:
 +**
-+** This routine ensures that:
++**     INSERT INTO fts(fts) VALUES($pCmd)
++**     INSERT INTO fts(fts, rank) VALUES($pCmd, $pVal)
 +**
-+**   * The database file change-counter is updated,
-+**   * the journal is synced (unless the atomic-write optimization is used),
-+**   * all dirty pages are written to the database file, 
-+**   * the database file is truncated (if required), and
-+**   * the database file synced. 
++** Argument pVal is the value assigned to column "fts" by the INSERT 
++** statement. This function returns SQLITE_OK if successful, or an SQLite
++** error code if an error occurs.
 +**
-+** The only thing that remains to commit the transaction is to finalize 
-+** (delete, truncate or zero the first part of) the journal file (or 
-+** delete the master journal file if specified).
++** The commands implemented by this function are documented in the "Special
++** INSERT Directives" section of the documentation. It should be updated if
++** more commands are added to this function.
++*/
++static int fts5SpecialInsert(
++  Fts5Table *pTab,                /* Fts5 table object */
++  const char *zCmd,               /* Text inserted into table-name column */
++  sqlite3_value *pVal             /* Value inserted into rank column */
++){
++  Fts5Config *pConfig = pTab->pConfig;
++  int rc = SQLITE_OK;
++  int bError = 0;
++
++  if( 0==sqlite3_stricmp("delete-all", zCmd) ){
++    if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
++      fts5SetVtabError(pTab, 
++          "'delete-all' may only be used with a "
++          "contentless or external content fts5 table"
++      );
++      rc = SQLITE_ERROR;
++    }else{
++      rc = sqlite3Fts5StorageDeleteAll(pTab->pStorage);
++    }
++  }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){
++    if( pConfig->eContent==FTS5_CONTENT_NONE ){
++      fts5SetVtabError(pTab, 
++          "'rebuild' may not be used with a contentless fts5 table"
++      );
++      rc = SQLITE_ERROR;
++    }else{
++      rc = sqlite3Fts5StorageRebuild(pTab->pStorage);
++    }
++  }else if( 0==sqlite3_stricmp("optimize", zCmd) ){
++    rc = sqlite3Fts5StorageOptimize(pTab->pStorage);
++  }else if( 0==sqlite3_stricmp("merge", zCmd) ){
++    int nMerge = sqlite3_value_int(pVal);
++    rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge);
++  }else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){
++    rc = sqlite3Fts5StorageIntegrity(pTab->pStorage);
++#ifdef SQLITE_DEBUG
++  }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){
++    pConfig->bPrefixIndex = sqlite3_value_int(pVal);
++#endif
++  }else{
++    rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
++    if( rc==SQLITE_OK ){
++      rc = sqlite3Fts5ConfigSetValue(pTab->pConfig, zCmd, pVal, &bError);
++    }
++    if( rc==SQLITE_OK ){
++      if( bError ){
++        rc = SQLITE_ERROR;
++      }else{
++        rc = sqlite3Fts5StorageConfigValue(pTab->pStorage, zCmd, pVal, 0);
++      }
++    }
++  }
++  return rc;
++}
++
++static int fts5SpecialDelete(
++  Fts5Table *pTab, 
++  sqlite3_value **apVal
++){
++  int rc = SQLITE_OK;
++  int eType1 = sqlite3_value_type(apVal[1]);
++  if( eType1==SQLITE_INTEGER ){
++    sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]);
++    rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]);
++  }
++  return rc;
++}
++
++static void fts5StorageInsert(
++  int *pRc, 
++  Fts5Table *pTab, 
++  sqlite3_value **apVal, 
++  i64 *piRowid
++){
++  int rc = *pRc;
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid);
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid);
++  }
++  *pRc = rc;
++}
++
++/* 
++** This function is the implementation of the xUpdate callback used by 
++** FTS3 virtual tables. It is invoked by SQLite each time a row is to be
++** inserted, updated or deleted.
 +**
-+** Note that if zMaster==NULL, this does not overwrite a previous value
-+** passed to an sqlite3PagerCommitPhaseOne() call.
++** A delete specifies a single argument - the rowid of the row to remove.
++** 
++** Update and insert operations pass:
 +**
-+** If the final parameter - noSync - is true, then the database file itself
-+** is not synced. The caller must call sqlite3PagerSync() directly to
-+** sync the database file before calling CommitPhaseTwo() to delete the
-+** journal file in this case.
- */
--SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
--  return &pPager->pBackup;
--}
-+SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
-+  Pager *pPager,                  /* Pager object */
-+  const char *zMaster,            /* If not NULL, the master journal name */
-+  int noSync                      /* True to omit the xSync on the db file */
++**   1. The "old" rowid, or NULL.
++**   2. The "new" rowid.
++**   3. Values for each of the nCol matchable columns.
++**   4. Values for the two hidden columns (<tablename> and "rank").
++*/
++static int fts5UpdateMethod(
++  sqlite3_vtab *pVtab,            /* Virtual table handle */
++  int nArg,                       /* Size of argument array */
++  sqlite3_value **apVal,          /* Array of arguments */
++  sqlite_int64 *pRowid            /* OUT: The affected (or effected) rowid */
 +){
++  Fts5Table *pTab = (Fts5Table*)pVtab;
++  Fts5Config *pConfig = pTab->pConfig;
++  int eType0;                     /* value_type() of apVal[0] */
 +  int rc = SQLITE_OK;             /* Return code */
- 
--#ifndef SQLITE_OMIT_VACUUM
--/*
--** Unless this is an in-memory or temporary database, clear the pager cache.
--*/
--SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
--  if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager);
--}
--#endif
-+  assert( pPager->eState==PAGER_WRITER_LOCKED
-+       || pPager->eState==PAGER_WRITER_CACHEMOD
-+       || pPager->eState==PAGER_WRITER_DBMOD
-+       || pPager->eState==PAGER_ERROR
++
++  /* A transaction must be open when this is called. */
++  assert( pTab->ts.eState==1 );
++
++  assert( pVtab->zErrMsg==0 );
++  assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
++  assert( nArg==1 
++      || sqlite3_value_type(apVal[1])==SQLITE_INTEGER 
++      || sqlite3_value_type(apVal[1])==SQLITE_NULL 
 +  );
-+  assert( assert_pager_state(pPager) );
- 
--#ifndef SQLITE_OMIT_WAL
--/*
--** This function is called when the user invokes "PRAGMA wal_checkpoint",
--** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint()
--** or wal_blocking_checkpoint() API functions.
--**
--** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
--*/
--SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
--  int rc = SQLITE_OK;
--  if( pPager->pWal ){
--    rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
--        (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
--        pPager->pBusyHandlerArg,
--        pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
--        pnLog, pnCkpt
--    );
--  }
--  return rc;
--}
-+  /* If a prior error occurred, report that error again. */
-+  if( NEVER(pPager->errCode) ) return pPager->errCode;
- 
--SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
--  return sqlite3WalCallback(pPager->pWal);
--}
-+  PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
-+      pPager->zFilename, zMaster, pPager->dbSize));
- 
--/*
--** Return true if the underlying VFS for the given pager supports the
--** primitives necessary for write-ahead logging.
--*/
--SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){
--  const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
--  return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap);
--}
-+  /* If no database changes have been made, return early. */
-+  if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
- 
--/*
--** Attempt to take an exclusive lock on the database file. If a PENDING lock
--** is obtained instead, immediately release it.
--*/
--static int pagerExclusiveLock(Pager *pPager){
--  int rc;                         /* Return code */
-+  if( MEMDB ){
-+    /* If this is an in-memory db, or no pages have been written to, or this
-+    ** function has already been called, it is mostly a no-op.  However, any
-+    ** backup in progress needs to be restarted.
-+    */
-+    sqlite3BackupRestart(pPager->pBackup);
-+  }else{
-+    if( pagerUseWal(pPager) ){
-+      PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
-+      PgHdr *pPageOne = 0;
-+      if( pList==0 ){
-+        /* Must have at least one page for the WAL commit flag.
-+        ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
-+        rc = sqlite3PagerGet(pPager, 1, &pPageOne);
-+        pList = pPageOne;
-+        pList->pDirty = 0;
-+      }
-+      assert( rc==SQLITE_OK );
-+      if( ALWAYS(pList) ){
-+        rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1);
-+      }
-+      sqlite3PagerUnref(pPageOne);
-+      if( rc==SQLITE_OK ){
-+        sqlite3PcacheCleanAll(pPager->pPCache);
-+      }
++  assert( pTab->pConfig->pzErrmsg==0 );
++  pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
++
++  /* Put any active cursors into REQUIRE_SEEK state. */
++  fts5TripCursors(pTab);
++
++  eType0 = sqlite3_value_type(apVal[0]);
++  if( eType0==SQLITE_NULL 
++   && sqlite3_value_type(apVal[2+pConfig->nCol])!=SQLITE_NULL 
++  ){
++    /* A "special" INSERT op. These are handled separately. */
++    const char *z = (const char*)sqlite3_value_text(apVal[2+pConfig->nCol]);
++    if( pConfig->eContent!=FTS5_CONTENT_NORMAL 
++      && 0==sqlite3_stricmp("delete", z) 
++    ){
++      rc = fts5SpecialDelete(pTab, apVal);
 +    }else{
-+      /* The following block updates the change-counter. Exactly how it
-+      ** does this depends on whether or not the atomic-update optimization
-+      ** was enabled at compile time, and if this transaction meets the 
-+      ** runtime criteria to use the operation: 
-+      **
-+      **    * The file-system supports the atomic-write property for
-+      **      blocks of size page-size, and 
-+      **    * This commit is not part of a multi-file transaction, and
-+      **    * Exactly one page has been modified and store in the journal file.
-+      **
-+      ** If the optimization was not enabled at compile time, then the
-+      ** pager_incr_changecounter() function is called to update the change
-+      ** counter in 'indirect-mode'. If the optimization is compiled in but
-+      ** is not applicable to this transaction, call sqlite3JournalCreate()
-+      ** to make sure the journal file has actually been created, then call
-+      ** pager_incr_changecounter() to update the change-counter in indirect
-+      ** mode. 
-+      **
-+      ** Otherwise, if the optimization is both enabled and applicable,
-+      ** then call pager_incr_changecounter() to update the change-counter
-+      ** in 'direct' mode. In this case the journal file will never be
-+      ** created for this transaction.
-+      */
-+  #ifdef SQLITE_ENABLE_ATOMIC_WRITE
-+      PgHdr *pPg;
-+      assert( isOpen(pPager->jfd) 
-+           || pPager->journalMode==PAGER_JOURNALMODE_OFF 
-+           || pPager->journalMode==PAGER_JOURNALMODE_WAL 
++      rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
++    }
++  }else{
++    /* A regular INSERT, UPDATE or DELETE statement. The trick here is that
++    ** any conflict on the rowid value must be detected before any 
++    ** modifications are made to the database file. There are 4 cases:
++    **
++    **   1) DELETE
++    **   2) UPDATE (rowid not modified)
++    **   3) UPDATE (rowid modified)
++    **   4) INSERT
++    **
++    ** Cases 3 and 4 may violate the rowid constraint.
++    */
++    int eConflict = SQLITE_ABORT;
++    if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
++      eConflict = sqlite3_vtab_on_conflict(pConfig->db);
++    }
++
++    assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
++    assert( nArg!=1 || eType0==SQLITE_INTEGER );
++
++    /* Filter out attempts to run UPDATE or DELETE on contentless tables.
++    ** This is not suported.  */
++    if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){
++      pTab->base.zErrMsg = sqlite3_mprintf(
++          "cannot %s contentless fts5 table: %s", 
++          (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
 +      );
-+      if( !zMaster && isOpen(pPager->jfd) 
-+       && pPager->journalOff==jrnlBufferSize(pPager) 
-+       && pPager->dbSize>=pPager->dbOrigSize
-+       && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
++      rc = SQLITE_ERROR;
++    }
++
++    /* DELETE */
++    else if( nArg==1 ){
++      i64 iDel = sqlite3_value_int64(apVal[0]);  /* Rowid to delete */
++      rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
++    }
++
++    /* INSERT */
++    else if( eType0!=SQLITE_INTEGER ){     
++      /* If this is a REPLACE, first remove the current entry (if any) */
++      if( eConflict==SQLITE_REPLACE 
++       && sqlite3_value_type(apVal[1])==SQLITE_INTEGER 
 +      ){
-+        /* Update the db file change counter via the direct-write method. The 
-+        ** following call will modify the in-memory representation of page 1 
-+        ** to include the updated change counter and then write page 1 
-+        ** directly to the database file. Because of the atomic-write 
-+        ** property of the host file-system, this is safe.
-+        */
-+        rc = pager_incr_changecounter(pPager, 1);
-+      }else{
-+        rc = sqlite3JournalCreate(pPager->jfd);
-+        if( rc==SQLITE_OK ){
-+          rc = pager_incr_changecounter(pPager, 0);
++        i64 iNew = sqlite3_value_int64(apVal[1]);  /* Rowid to delete */
++        rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
++      }
++      fts5StorageInsert(&rc, pTab, apVal, pRowid);
++    }
++
++    /* UPDATE */
++    else{
++      i64 iOld = sqlite3_value_int64(apVal[0]);  /* Old rowid */
++      i64 iNew = sqlite3_value_int64(apVal[1]);  /* New rowid */
++      if( iOld!=iNew ){
++        if( eConflict==SQLITE_REPLACE ){
++          rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
++          if( rc==SQLITE_OK ){
++            rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
++          }
++          fts5StorageInsert(&rc, pTab, apVal, pRowid);
++        }else{
++          rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid);
++          if( rc==SQLITE_OK ){
++            rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
++          }
++          if( rc==SQLITE_OK ){
++            rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *pRowid);
++          }
 +        }
++      }else{
++        rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
++        fts5StorageInsert(&rc, pTab, apVal, pRowid);
 +      }
-+  #else
-+      rc = pager_incr_changecounter(pPager, 0);
-+  #endif
-+      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
-+  
-+      /* Write the master journal name into the journal file. If a master 
-+      ** journal file name has already been written to the journal file, 
-+      ** or if zMaster is NULL (no master journal), then this call is a no-op.
-+      */
-+      rc = writeMasterJournal(pPager, zMaster);
-+      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
-+  
-+      /* Sync the journal file and write all dirty pages to the database.
-+      ** If the atomic-update optimization is being used, this sync will not 
-+      ** create the journal file or perform any real IO.
-+      **
-+      ** Because the change-counter page was just modified, unless the
-+      ** atomic-update optimization is used it is almost certain that the
-+      ** journal requires a sync here. However, in locking_mode=exclusive
-+      ** on a system under memory pressure it is just possible that this is 
-+      ** not the case. In this case it is likely enough that the redundant
-+      ** xSync() call will be changed to a no-op by the OS anyhow. 
-+      */
-+      rc = syncJournal(pPager, 0);
-+      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
-+  
-+      rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
-+      if( rc!=SQLITE_OK ){
-+        assert( rc!=SQLITE_IOERR_BLOCKED );
-+        goto commit_phase_one_exit;
++    }
++  }
++
++  pTab->pConfig->pzErrmsg = 0;
++  return rc;
++}
++
++/*
++** Implementation of xSync() method. 
++*/
++static int fts5SyncMethod(sqlite3_vtab *pVtab){
++  int rc;
++  Fts5Table *pTab = (Fts5Table*)pVtab;
++  fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
++  pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
++  fts5TripCursors(pTab);
++  rc = sqlite3Fts5StorageSync(pTab->pStorage);
++  pTab->pConfig->pzErrmsg = 0;
++  return rc;
++}
++
++/*
++** Implementation of xBegin() method. 
++*/
++static int fts5BeginMethod(sqlite3_vtab *pVtab){
++  fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0);
++  fts5NewTransaction((Fts5Table*)pVtab);
++  return SQLITE_OK;
++}
++
++/*
++** Implementation of xCommit() method. This is a no-op. The contents of
++** the pending-terms hash-table have already been flushed into the database
++** by fts5SyncMethod().
++*/
++static int fts5CommitMethod(sqlite3_vtab *pVtab){
++  UNUSED_PARAM(pVtab);  /* Call below is a no-op for NDEBUG builds */
++  fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_COMMIT, 0);
++  return SQLITE_OK;
++}
++
++/*
++** Implementation of xRollback(). Discard the contents of the pending-terms
++** hash-table. Any changes made to the database are reverted by SQLite.
++*/
++static int fts5RollbackMethod(sqlite3_vtab *pVtab){
++  int rc;
++  Fts5Table *pTab = (Fts5Table*)pVtab;
++  fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0);
++  rc = sqlite3Fts5StorageRollback(pTab->pStorage);
++  return rc;
++}
++
++static int fts5CsrPoslist(Fts5Cursor*, int, const u8**, int*);
++
++static void *fts5ApiUserData(Fts5Context *pCtx){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  return pCsr->pAux->pUserData;
++}
++
++static int fts5ApiColumnCount(Fts5Context *pCtx){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  return ((Fts5Table*)(pCsr->base.pVtab))->pConfig->nCol;
++}
++
++static int fts5ApiColumnTotalSize(
++  Fts5Context *pCtx, 
++  int iCol, 
++  sqlite3_int64 *pnToken
++){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
++  return sqlite3Fts5StorageSize(pTab->pStorage, iCol, pnToken);
++}
++
++static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
++  return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow);
++}
++
++static int fts5ApiTokenize(
++  Fts5Context *pCtx, 
++  const char *pText, int nText, 
++  void *pUserData,
++  int (*xToken)(void*, int, const char*, int, int, int)
++){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
++  return sqlite3Fts5Tokenize(
++      pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
++  );
++}
++
++static int fts5ApiPhraseCount(Fts5Context *pCtx){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  return sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
++}
++
++static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase);
++}
++
++static int fts5ApiColumnText(
++  Fts5Context *pCtx, 
++  int iCol, 
++  const char **pz, 
++  int *pn
++){
++  int rc = SQLITE_OK;
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  if( fts5IsContentless((Fts5Table*)(pCsr->base.pVtab)) ){
++    *pz = 0;
++    *pn = 0;
++  }else{
++    rc = fts5SeekCursor(pCsr, 0);
++    if( rc==SQLITE_OK ){
++      *pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1);
++      *pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1);
++    }
++  }
++  return rc;
++}
++
++static int fts5CsrPoslist(
++  Fts5Cursor *pCsr, 
++  int iPhrase, 
++  const u8 **pa,
++  int *pn
++){
++  Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
++  int rc = SQLITE_OK;
++  int bLive = (pCsr->pSorter==0);
++
++  if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
++
++    if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
++      Fts5PoslistPopulator *aPopulator;
++      int i;
++      aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive);
++      if( aPopulator==0 ) rc = SQLITE_NOMEM;
++      for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){
++        int n; const char *z;
++        rc = fts5ApiColumnText((Fts5Context*)pCsr, i, &z, &n);
++        if( rc==SQLITE_OK ){
++          rc = sqlite3Fts5ExprPopulatePoslists(
++              pConfig, pCsr->pExpr, aPopulator, i, z, n
++          );
++        }
 +      }
-+      sqlite3PcacheCleanAll(pPager->pPCache);
- 
--  assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
--  rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
--  if( rc!=SQLITE_OK ){
--    /* If the attempt to grab the exclusive lock failed, release the 
--    ** pending lock that may have been obtained instead.  */
--    pagerUnlockDb(pPager, SHARED_LOCK);
-+      /* If the file on disk is smaller than the database image, use 
-+      ** pager_truncate to grow the file here. This can happen if the database
-+      ** image was extended as part of the current transaction and then the
-+      ** last page in the db image moved to the free-list. In this case the
-+      ** last page is never written out to disk, leaving the database file
-+      ** undersized. Fix this now if it is the case.  */
-+      if( pPager->dbSize>pPager->dbFileSize ){
-+        Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
-+        assert( pPager->eState==PAGER_WRITER_DBMOD );
-+        rc = pager_truncate(pPager, nNew);
-+        if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
++      sqlite3_free(aPopulator);
++
++      if( pCsr->pSorter ){
++        sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid);
 +      }
++    }
++    CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST);
++  }
++
++  if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){
++    Fts5Sorter *pSorter = pCsr->pSorter;
++    int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
++    *pn = pSorter->aIdx[iPhrase] - i1;
++    *pa = &pSorter->aPoslist[i1];
++  }else{
++    *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa);
++  }
++
++  return rc;
++}
++
++/*
++** Ensure that the Fts5Cursor.nInstCount and aInst[] variables are populated
++** correctly for the current view. Return SQLITE_OK if successful, or an
++** SQLite error code otherwise.
++*/
++static int fts5CacheInstArray(Fts5Cursor *pCsr){
++  int rc = SQLITE_OK;
++  Fts5PoslistReader *aIter;       /* One iterator for each phrase */
++  int nIter;                      /* Number of iterators/phrases */
 +  
-+      /* Finally, sync the database file. */
-+      if( !noSync ){
-+        rc = sqlite3PagerSync(pPager, zMaster);
++  nIter = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
++  if( pCsr->aInstIter==0 ){
++    int nByte = sizeof(Fts5PoslistReader) * nIter;
++    pCsr->aInstIter = (Fts5PoslistReader*)sqlite3Fts5MallocZero(&rc, nByte);
++  }
++  aIter = pCsr->aInstIter;
++
++  if( aIter ){
++    int nInst = 0;                /* Number instances seen so far */
++    int i;
++
++    /* Initialize all iterators */
++    for(i=0; i<nIter && rc==SQLITE_OK; i++){
++      const u8 *a;
++      int n; 
++      rc = fts5CsrPoslist(pCsr, i, &a, &n);
++      if( rc==SQLITE_OK ){
++        sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
 +      }
-+      IOTRACE(("DBSYNC %p\n", pPager))
 +    }
-   }
- 
-+commit_phase_one_exit:
-+  if( rc==SQLITE_OK && !pagerUseWal(pPager) ){
-+    pPager->eState = PAGER_WRITER_FINISHED;
++
++    if( rc==SQLITE_OK ){
++      while( 1 ){
++        int *aInst;
++        int iBest = -1;
++        for(i=0; i<nIter; i++){
++          if( (aIter[i].bEof==0) 
++              && (iBest<0 || aIter[i].iPos<aIter[iBest].iPos) 
++            ){
++            iBest = i;
++          }
++        }
++        if( iBest<0 ) break;
++
++        nInst++;
++        if( nInst>=pCsr->nInstAlloc ){
++          pCsr->nInstAlloc = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
++          aInst = (int*)sqlite3_realloc(
++              pCsr->aInst, pCsr->nInstAlloc*sizeof(int)*3
++              );
++          if( aInst ){
++            pCsr->aInst = aInst;
++          }else{
++            rc = SQLITE_NOMEM;
++            break;
++          }
++        }
++
++        aInst = &pCsr->aInst[3 * (nInst-1)];
++        aInst[0] = iBest;
++        aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
++        aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
++        sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
++      }
++    }
++
++    pCsr->nInstCount = nInst;
++    CsrFlagClear(pCsr, FTS5CSR_REQUIRE_INST);
 +  }
-   return rc;
- }
- 
++  return rc;
++}
 +
- /*
--** Call sqlite3WalOpen() to open the WAL handle. If the pager is in 
--** exclusive-locking mode when this function is called, take an EXCLUSIVE
--** lock on the database file and use heap-memory to store the wal-index
--** in. Otherwise, use the normal shared-memory.
-+** When this function is called, the database file has been completely
-+** updated to reflect the changes made by the current transaction and
-+** synced to disk. The journal file still exists in the file-system 
-+** though, and if a failure occurs at this point it will eventually
-+** be used as a hot-journal and the current transaction rolled back.
-+**
-+** This function finalizes the journal file, either by deleting, 
-+** truncating or partially zeroing it, so that it cannot be used 
-+** for hot-journal rollback. Once this is done the transaction is
-+** irrevocably committed.
-+**
-+** If an error occurs, an IO error code is returned and the pager
-+** moves into the error state. Otherwise, SQLITE_OK is returned.
- */
--static int pagerOpenWal(Pager *pPager){
--  int rc = SQLITE_OK;
-+SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){
-+  int rc = SQLITE_OK;                  /* Return code */
- 
--  assert( pPager->pWal==0 && pPager->tempFile==0 );
--  assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
-+  /* This routine should not be called if a prior error has occurred.
-+  ** But if (due to a coding error elsewhere in the system) it does get
-+  ** called, just return the same error code without doing anything. */
-+  if( NEVER(pPager->errCode) ) return pPager->errCode;
- 
--  /* If the pager is already in exclusive-mode, the WAL module will use 
--  ** heap-memory for the wal-index instead of the VFS shared-memory 
--  ** implementation. Take the exclusive lock now, before opening the WAL
--  ** file, to make sure this is safe.
--  */
--  if( pPager->exclusiveMode ){
--    rc = pagerExclusiveLock(pPager);
--  }
-+  assert( pPager->eState==PAGER_WRITER_LOCKED
-+       || pPager->eState==PAGER_WRITER_FINISHED
-+       || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD)
-+  );
-+  assert( assert_pager_state(pPager) );
- 
--  /* Open the connection to the log file. If this operation fails, 
--  ** (e.g. due to malloc() failure), return an error code.
-+  /* An optimization. If the database was not actually modified during
-+  ** this transaction, the pager is running in exclusive-mode and is
-+  ** using persistent journals, then this function is a no-op.
-+  **
-+  ** The start of the journal file currently contains a single journal 
-+  ** header with the nRec field set to 0. If such a journal is used as
-+  ** a hot-journal during hot-journal rollback, 0 changes will be made
-+  ** to the database file. So there is no need to zero the journal 
-+  ** header. Since the pager is in exclusive mode, there is no need
-+  ** to drop any locks either.
-   */
--  if( rc==SQLITE_OK ){
--    rc = sqlite3WalOpen(pPager->pVfs,
--        pPager->fd, pPager->zWal, pPager->exclusiveMode,
--        pPager->journalSizeLimit, &pPager->pWal
--    );
-+  if( pPager->eState==PAGER_WRITER_LOCKED 
-+   && pPager->exclusiveMode 
-+   && pPager->journalMode==PAGER_JOURNALMODE_PERSIST
++static int fts5ApiInstCount(Fts5Context *pCtx, int *pnInst){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  int rc = SQLITE_OK;
++  if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0 
++   || SQLITE_OK==(rc = fts5CacheInstArray(pCsr)) ){
++    *pnInst = pCsr->nInstCount;
++  }
++  return rc;
++}
++
++static int fts5ApiInst(
++  Fts5Context *pCtx, 
++  int iIdx, 
++  int *piPhrase, 
++  int *piCol, 
++  int *piOff
++){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  int rc = SQLITE_OK;
++  if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0 
++   || SQLITE_OK==(rc = fts5CacheInstArray(pCsr)) 
 +  ){
-+    assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff );
-+    pPager->eState = PAGER_READER;
-+    return SQLITE_OK;
-   }
--  pagerFixMaplimit(pPager);
- 
--  return rc;
-+  PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
-+  pPager->iDataVersion++;
-+  rc = pager_end_transaction(pPager, pPager->setMaster, 1);
-+  return pager_error(pPager, rc);
- }
- 
--
- /*
--** The caller must be holding a SHARED lock on the database file to call
--** this function.
-+** If a write transaction is open, then all changes made within the 
-+** transaction are reverted and the current write-transaction is closed.
-+** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR
-+** state if an error occurs.
- **
--** If the pager passed as the first argument is open on a real database
--** file (not a temp file or an in-memory database), and the WAL file
--** is not already open, make an attempt to open it now. If successful,
--** return SQLITE_OK. If an error occurs or the VFS used by the pager does 
--** not support the xShmXXX() methods, return an error code. *pbOpen is
--** not modified in either case.
-+** If the pager is already in PAGER_ERROR state when this function is called,
-+** it returns Pager.errCode immediately. No work is performed in this case.
- **
--** If the pager is open on a temp-file (or in-memory database), or if
--** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK
--** without doing anything.
-+** Otherwise, in rollback mode, this function performs two functions:
-+**
-+**   1) It rolls back the journal file, restoring all database file and 
-+**      in-memory cache pages to the state they were in when the transaction
-+**      was opened, and
-+**
-+**   2) It finalizes the journal file, so that it is not used for hot
-+**      rollback at any point in the future.
-+**
-+** Finalization of the journal file (task 2) is only performed if the 
-+** rollback is successful.
-+**
-+** In WAL mode, all cache-entries containing data modified within the
-+** current transaction are either expelled from the cache or reverted to
-+** their pre-transaction state by re-reading data from the database or
-+** WAL files. The WAL transaction is then closed.
- */
--SQLITE_PRIVATE int sqlite3PagerOpenWal(
--  Pager *pPager,                  /* Pager object */
--  int *pbOpen                     /* OUT: Set to true if call is a no-op */
--){
--  int rc = SQLITE_OK;             /* Return code */
-+SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
-+  int rc = SQLITE_OK;                  /* Return code */
-+  PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager)));
- 
-+  /* PagerRollback() is a no-op if called in READER or OPEN state. If
-+  ** the pager is already in the ERROR state, the rollback is not 
-+  ** attempted here. Instead, the error code is returned to the caller.
-+  */
-   assert( assert_pager_state(pPager) );
--  assert( pPager->eState==PAGER_OPEN   || pbOpen );
--  assert( pPager->eState==PAGER_READER || !pbOpen );
--  assert( pbOpen==0 || *pbOpen==0 );
--  assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) );
--
--  if( !pPager->tempFile && !pPager->pWal ){
--    if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;
--
--    /* Close any rollback journal previously open */
--    sqlite3OsClose(pPager->jfd);
-+  if( pPager->eState==PAGER_ERROR ) return pPager->errCode;
-+  if( pPager->eState<=PAGER_READER ) return SQLITE_OK;
- 
--    rc = pagerOpenWal(pPager);
--    if( rc==SQLITE_OK ){
--      pPager->journalMode = PAGER_JOURNALMODE_WAL;
--      pPager->eState = PAGER_OPEN;
-+  if( pagerUseWal(pPager) ){
-+    int rc2;
-+    rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
-+    rc2 = pager_end_transaction(pPager, pPager->setMaster, 0);
-+    if( rc==SQLITE_OK ) rc = rc2;
-+  }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){
-+    int eState = pPager->eState;
-+    rc = pager_end_transaction(pPager, 0, 0);
-+    if( !MEMDB && eState>PAGER_WRITER_LOCKED ){
-+      /* This can happen using journal_mode=off. Move the pager to the error 
-+      ** state to indicate that the contents of the cache may not be trusted.
-+      ** Any active readers will get SQLITE_ABORT.
-+      */
-+      pPager->errCode = SQLITE_ABORT;
-+      pPager->eState = PAGER_ERROR;
-+      return rc;
-     }
-   }else{
--    *pbOpen = 1;
-+    rc = pager_playback(pPager, 0);
-   }
- 
--  return rc;
-+  assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK );
-+  assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT
-+          || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR 
-+          || rc==SQLITE_CANTOPEN
-+  );
++    if( iIdx<0 || iIdx>=pCsr->nInstCount ){
++      rc = SQLITE_RANGE;
++#if 0
++    }else if( fts5IsOffsetless((Fts5Table*)pCsr->base.pVtab) ){
++      *piPhrase = pCsr->aInst[iIdx*3];
++      *piCol = pCsr->aInst[iIdx*3 + 2];
++      *piOff = -1;
++#endif
++    }else{
++      *piPhrase = pCsr->aInst[iIdx*3];
++      *piCol = pCsr->aInst[iIdx*3 + 1];
++      *piOff = pCsr->aInst[iIdx*3 + 2];
++    }
++  }
++  return rc;
++}
 +
-+  /* If an error occurs during a ROLLBACK, we can no longer trust the pager
-+  ** cache. So call pager_error() on the way out to make any error persistent.
-+  */
-+  return pager_error(pPager, rc);
- }
- 
- /*
--** This function is called to close the connection to the log file prior
--** to switching from WAL to rollback mode.
--**
--** Before closing the log file, this function attempts to take an 
--** EXCLUSIVE lock on the database file. If this cannot be obtained, an
--** error (SQLITE_BUSY) is returned and the log connection is not closed.
--** If successful, the EXCLUSIVE lock is not released before returning.
-+** Return TRUE if the database file is opened read-only.  Return FALSE
-+** if the database is (in theory) writable.
- */
--SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
--  int rc = SQLITE_OK;
-+SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){
-+  return pPager->readOnly;
++static sqlite3_int64 fts5ApiRowid(Fts5Context *pCtx){
++  return fts5CursorRowid((Fts5Cursor*)pCtx);
 +}
- 
--  assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
-+/*
-+** Return the number of references to the pager.
-+*/
-+SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){
-+  return sqlite3PcacheRefCount(pPager->pPCache);
++
++static int fts5ColumnSizeCb(
++  void *pContext,                 /* Pointer to int */
++  int tflags,
++  const char *pUnused,            /* Buffer containing token */
++  int nUnused,                    /* Size of token in bytes */
++  int iUnused1,                   /* Start offset of token */
++  int iUnused2                    /* End offset of token */
++){
++  int *pCnt = (int*)pContext;
++  UNUSED_PARAM2(pUnused, nUnused);
++  UNUSED_PARAM2(iUnused1, iUnused2);
++  if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
++    (*pCnt)++;
++  }
++  return SQLITE_OK;
 +}
- 
--  /* If the log file is not already open, but does exist in the file-system,
--  ** it may need to be checkpointed before the connection can switch to
--  ** rollback mode. Open it now so this can happen.
--  */
--  if( !pPager->pWal ){
--    int logexists = 0;
--    rc = pagerLockDb(pPager, SHARED_LOCK);
--    if( rc==SQLITE_OK ){
--      rc = sqlite3OsAccess(
--          pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists
--      );
--    }
--    if( rc==SQLITE_OK && logexists ){
--      rc = pagerOpenWal(pPager);
--    }
--  }
--    
--  /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on
--  ** the database file, the log and log-summary files will be deleted.
--  */
--  if( rc==SQLITE_OK && pPager->pWal ){
--    rc = pagerExclusiveLock(pPager);
--    if( rc==SQLITE_OK ){
--      rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
--                           pPager->pageSize, (u8*)pPager->pTmpSpace);
--      pPager->pWal = 0;
--      pagerFixMaplimit(pPager);
--    }
--  }
--  return rc;
-+/*
-+** Return the approximate number of bytes of memory currently
-+** used by the pager and its associated cache.
-+*/
-+SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){
-+  int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr)
-+                                     + 5*sizeof(void*);
-+  return perPageSize*sqlite3PcachePagecount(pPager->pPCache)
-+           + sqlite3MallocSize(pPager)
-+           + pPager->pageSize;
- }
- 
--#endif /* !SQLITE_OMIT_WAL */
++
++static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
++  Fts5Config *pConfig = pTab->pConfig;
++  int rc = SQLITE_OK;
++
++  if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_DOCSIZE) ){
++    if( pConfig->bColumnsize ){
++      i64 iRowid = fts5CursorRowid(pCsr);
++      rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize);
++    }else if( pConfig->zContent==0 ){
++      int i;
++      for(i=0; i<pConfig->nCol; i++){
++        if( pConfig->abUnindexed[i]==0 ){
++          pCsr->aColumnSize[i] = -1;
++        }
++      }
++    }else{
++      int i;
++      for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
++        if( pConfig->abUnindexed[i]==0 ){
++          const char *z; int n;
++          void *p = (void*)(&pCsr->aColumnSize[i]);
++          pCsr->aColumnSize[i] = 0;
++          rc = fts5ApiColumnText(pCtx, i, &z, &n);
++          if( rc==SQLITE_OK ){
++            rc = sqlite3Fts5Tokenize(
++                pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb
++            );
++          }
++        }
++      }
++    }
++    CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
++  }
++  if( iCol<0 ){
++    int i;
++    *pnToken = 0;
++    for(i=0; i<pConfig->nCol; i++){
++      *pnToken += pCsr->aColumnSize[i];
++    }
++  }else if( iCol<pConfig->nCol ){
++    *pnToken = pCsr->aColumnSize[iCol];
++  }else{
++    *pnToken = 0;
++    rc = SQLITE_RANGE;
++  }
++  return rc;
++}
++
 +/*
-+** Return the number of references to the specified page.
++** Implementation of the xSetAuxdata() method.
 +*/
-+SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){
-+  return sqlite3PcachePageRefcount(pPage);
++static int fts5ApiSetAuxdata(
++  Fts5Context *pCtx,              /* Fts5 context */
++  void *pPtr,                     /* Pointer to save as auxdata */
++  void(*xDelete)(void*)           /* Destructor for pPtr (or NULL) */
++){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  Fts5Auxdata *pData;
++
++  /* Search through the cursors list of Fts5Auxdata objects for one that
++  ** corresponds to the currently executing auxiliary function.  */
++  for(pData=pCsr->pAuxdata; pData; pData=pData->pNext){
++    if( pData->pAux==pCsr->pAux ) break;
++  }
++
++  if( pData ){
++    if( pData->xDelete ){
++      pData->xDelete(pData->pPtr);
++    }
++  }else{
++    int rc = SQLITE_OK;
++    pData = (Fts5Auxdata*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Auxdata));
++    if( pData==0 ){
++      if( xDelete ) xDelete(pPtr);
++      return rc;
++    }
++    pData->pAux = pCsr->pAux;
++    pData->pNext = pCsr->pAuxdata;
++    pCsr->pAuxdata = pData;
++  }
++
++  pData->xDelete = xDelete;
++  pData->pPtr = pPtr;
++  return SQLITE_OK;
 +}
- 
--#ifdef SQLITE_ENABLE_ZIPVFS
-+#ifdef SQLITE_TEST
- /*
--** A read-lock must be held on the pager when this function is called. If
--** the pager is in WAL mode and the WAL file currently contains one or more
--** frames, return the size in bytes of the page images stored within the
--** WAL frames. Otherwise, if this is not a WAL database or the WAL file
--** is empty, return 0.
-+** This routine is used for testing and analysis only.
- */
--SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
--  assert( pPager->eState>=PAGER_READER );
--  return sqlite3WalFramesize(pPager->pWal);
-+SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){
-+  static int a[11];
-+  a[0] = sqlite3PcacheRefCount(pPager->pPCache);
-+  a[1] = sqlite3PcachePagecount(pPager->pPCache);
-+  a[2] = sqlite3PcacheGetCachesize(pPager->pPCache);
-+  a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize;
-+  a[4] = pPager->eState;
-+  a[5] = pPager->errCode;
-+  a[6] = pPager->aStat[PAGER_STAT_HIT];
-+  a[7] = pPager->aStat[PAGER_STAT_MISS];
-+  a[8] = 0;  /* Used to be pPager->nOvfl */
-+  a[9] = pPager->nRead;
-+  a[10] = pPager->aStat[PAGER_STAT_WRITE];
-+  return a;
- }
- #endif
- 
--
--#endif /* SQLITE_OMIT_DISKIO */
--
--/************** End of pager.c ***********************************************/
--/************** Begin file wal.c *********************************************/
- /*
--** 2010 February 1
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
--**
--**    May you do good and not evil.
--**    May you find forgiveness for yourself and forgive others.
--**    May you share freely, never taking more than you give.
--**
--*************************************************************************
--**
--** This file contains the implementation of a write-ahead log (WAL) used in 
--** "journal_mode=WAL" mode.
--**
--** WRITE-AHEAD LOG (WAL) FILE FORMAT
--**
--** A WAL file consists of a header followed by zero or more "frames".
--** Each frame records the revised content of a single page from the
--** database file.  All changes to the database are recorded by writing
--** frames into the WAL.  Transactions commit when a frame is written that
--** contains a commit marker.  A single WAL can and usually does record 
--** multiple transactions.  Periodically, the content of the WAL is
--** transferred back into the database file in an operation called a
--** "checkpoint".
--**
--** A single WAL file can be used multiple times.  In other words, the
--** WAL can fill up with frames and then be checkpointed and then new
--** frames can overwrite the old ones.  A WAL always grows from beginning
--** toward the end.  Checksums and counters attached to each frame are
--** used to determine which frames within the WAL are valid and which
--** are leftovers from prior checkpoints.
--**
--** The WAL header is 32 bytes in size and consists of the following eight
--** big-endian 32-bit unsigned integer values:
--**
--**     0: Magic number.  0x377f0682 or 0x377f0683
--**     4: File format version.  Currently 3007000
--**     8: Database page size.  Example: 1024
--**    12: Checkpoint sequence number
--**    16: Salt-1, random integer incremented with each checkpoint
--**    20: Salt-2, a different random integer changing with each ckpt
--**    24: Checksum-1 (first part of checksum for first 24 bytes of header).
--**    28: Checksum-2 (second part of checksum for first 24 bytes of header).
--**
--** Immediately following the wal-header are zero or more frames. Each
--** frame consists of a 24-byte frame-header followed by a <page-size> bytes
--** of page data. The frame-header is six big-endian 32-bit unsigned 
--** integer values, as follows:
--**
--**     0: Page number.
--**     4: For commit records, the size of the database image in pages 
--**        after the commit. For all other records, zero.
--**     8: Salt-1 (copied from the header)
--**    12: Salt-2 (copied from the header)
--**    16: Checksum-1.
--**    20: Checksum-2.
--**
--** A frame is considered valid if and only if the following conditions are
--** true:
--**
--**    (1) The salt-1 and salt-2 values in the frame-header match
--**        salt values in the wal-header
--**
--**    (2) The checksum values in the final 8 bytes of the frame-header
--**        exactly match the checksum computed consecutively on the
--**        WAL header and the first 8 bytes and the content of all frames
--**        up to and including the current frame.
--**
--** The checksum is computed using 32-bit big-endian integers if the
--** magic number in the first 4 bytes of the WAL is 0x377f0683 and it
--** is computed using little-endian if the magic number is 0x377f0682.
--** The checksum values are always stored in the frame header in a
--** big-endian format regardless of which byte order is used to compute
--** the checksum.  The checksum is computed by interpreting the input as
--** an even number of unsigned 32-bit integers: x[0] through x[N].  The
--** algorithm used for the checksum is as follows:
--** 
--**   for i from 0 to n-1 step 2:
--**     s0 += x[i] + s1;
--**     s1 += x[i+1] + s0;
--**   endfor
--**
--** Note that s0 and s1 are both weighted checksums using fibonacci weights
--** in reverse order (the largest fibonacci weight occurs on the first element
--** of the sequence being summed.)  The s1 value spans all 32-bit 
--** terms of the sequence whereas s0 omits the final term.
--**
--** On a checkpoint, the WAL is first VFS.xSync-ed, then valid content of the
--** WAL is transferred into the database, then the database is VFS.xSync-ed.
--** The VFS.xSync operations serve as write barriers - all writes launched
--** before the xSync must complete before any write that launches after the
--** xSync begins.
--**
--** After each checkpoint, the salt-1 value is incremented and the salt-2
--** value is randomized.  This prevents old and new frames in the WAL from
--** being considered valid at the same time and being checkpointing together
--** following a crash.
--**
--** READER ALGORITHM
--**
--** To read a page from the database (call it page number P), a reader
--** first checks the WAL to see if it contains page P.  If so, then the
--** last valid instance of page P that is a followed by a commit frame
--** or is a commit frame itself becomes the value read.  If the WAL
--** contains no copies of page P that are valid and which are a commit
--** frame or are followed by a commit frame, then page P is read from
--** the database file.
--**
--** To start a read transaction, the reader records the index of the last
--** valid frame in the WAL.  The reader uses this recorded "mxFrame" value
--** for all subsequent read operations.  New transactions can be appended
--** to the WAL, but as long as the reader uses its original mxFrame value
--** and ignores the newly appended content, it will see a consistent snapshot
--** of the database from a single point in time.  This technique allows
--** multiple concurrent readers to view different versions of the database
--** content simultaneously.
--**
--** The reader algorithm in the previous paragraphs works correctly, but 
--** because frames for page P can appear anywhere within the WAL, the
--** reader has to scan the entire WAL looking for page P frames.  If the
--** WAL is large (multiple megabytes is typical) that scan can be slow,
--** and read performance suffers.  To overcome this problem, a separate
--** data structure called the wal-index is maintained to expedite the
--** search for frames of a particular page.
--** 
--** WAL-INDEX FORMAT
--**
--** Conceptually, the wal-index is shared memory, though VFS implementations
--** might choose to implement the wal-index using a mmapped file.  Because
--** the wal-index is shared memory, SQLite does not support journal_mode=WAL 
--** on a network filesystem.  All users of the database must be able to
--** share memory.
--**
--** The wal-index is transient.  After a crash, the wal-index can (and should
--** be) reconstructed from the original WAL file.  In fact, the VFS is required
--** to either truncate or zero the header of the wal-index when the last
--** connection to it closes.  Because the wal-index is transient, it can
--** use an architecture-specific format; it does not have to be cross-platform.
--** Hence, unlike the database and WAL file formats which store all values
--** as big endian, the wal-index can store multi-byte values in the native
--** byte order of the host computer.
--**
--** The purpose of the wal-index is to answer this question quickly:  Given
--** a page number P and a maximum frame index M, return the index of the 
--** last frame in the wal before frame M for page P in the WAL, or return
--** NULL if there are no frames for page P in the WAL prior to M.
--**
--** The wal-index consists of a header region, followed by an one or
--** more index blocks.  
--**
--** The wal-index header contains the total number of frames within the WAL
--** in the mxFrame field.
--**
--** Each index block except for the first contains information on 
--** HASHTABLE_NPAGE frames. The first index block contains information on
--** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and 
--** HASHTABLE_NPAGE are selected so that together the wal-index header and
--** first index block are the same size as all other index blocks in the
--** wal-index.
--**
--** Each index block contains two sections, a page-mapping that contains the
--** database page number associated with each wal frame, and a hash-table 
--** that allows readers to query an index block for a specific page number.
--** The page-mapping is an array of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE
--** for the first index block) 32-bit page numbers. The first entry in the 
--** first index-block contains the database page number corresponding to the
--** first frame in the WAL file. The first entry in the second index block
--** in the WAL file corresponds to the (HASHTABLE_NPAGE_ONE+1)th frame in
--** the log, and so on.
--**
--** The last index block in a wal-index usually contains less than the full
--** complement of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE) page-numbers,
--** depending on the contents of the WAL file. This does not change the
--** allocated size of the page-mapping array - the page-mapping array merely
--** contains unused entries.
--**
--** Even without using the hash table, the last frame for page P
--** can be found by scanning the page-mapping sections of each index block
--** starting with the last index block and moving toward the first, and
--** within each index block, starting at the end and moving toward the
--** beginning.  The first entry that equals P corresponds to the frame
--** holding the content for that page.
--**
--** The hash table consists of HASHTABLE_NSLOT 16-bit unsigned integers.
--** HASHTABLE_NSLOT = 2*HASHTABLE_NPAGE, and there is one entry in the
--** hash table for each page number in the mapping section, so the hash 
--** table is never more than half full.  The expected number of collisions 
--** prior to finding a match is 1.  Each entry of the hash table is an
--** 1-based index of an entry in the mapping section of the same
--** index block.   Let K be the 1-based index of the largest entry in
--** the mapping section.  (For index blocks other than the last, K will
--** always be exactly HASHTABLE_NPAGE (4096) and for the last index block
--** K will be (mxFrame%HASHTABLE_NPAGE).)  Unused slots of the hash table
--** contain a value of 0.
-+** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or
-+** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the
-+** current cache hit or miss count, according to the value of eStat. If the 
-+** reset parameter is non-zero, the cache hit or miss count is zeroed before 
-+** returning.
++
++static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  Fts5Auxdata *pData;
++  void *pRet = 0;
++
++  for(pData=pCsr->pAuxdata; pData; pData=pData->pNext){
++    if( pData->pAux==pCsr->pAux ) break;
++  }
++
++  if( pData ){
++    pRet = pData->pPtr;
++    if( bClear ){
++      pData->pPtr = 0;
++      pData->xDelete = 0;
++    }
++  }
++
++  return pRet;
++}
++
++static void fts5ApiPhraseNext(
++  Fts5Context *pUnused, 
++  Fts5PhraseIter *pIter, 
++  int *piCol, int *piOff
++){
++  UNUSED_PARAM(pUnused);
++  if( pIter->a>=pIter->b ){
++    *piCol = -1;
++    *piOff = -1;
++  }else{
++    int iVal;
++    pIter->a += fts5GetVarint32(pIter->a, iVal);
++    if( iVal==1 ){
++      pIter->a += fts5GetVarint32(pIter->a, iVal);
++      *piCol = iVal;
++      *piOff = 0;
++      pIter->a += fts5GetVarint32(pIter->a, iVal);
++    }
++    *piOff += (iVal-2);
++  }
++}
++
++static int fts5ApiPhraseFirst(
++  Fts5Context *pCtx, 
++  int iPhrase, 
++  Fts5PhraseIter *pIter, 
++  int *piCol, int *piOff
++){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  int n;
++  int rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
++  if( rc==SQLITE_OK ){
++    pIter->b = &pIter->a[n];
++    *piCol = 0;
++    *piOff = 0;
++    fts5ApiPhraseNext(pCtx, pIter, piCol, piOff);
++  }
++  return rc;
++}
++
++static void fts5ApiPhraseNextColumn(
++  Fts5Context *pCtx, 
++  Fts5PhraseIter *pIter, 
++  int *piCol
++){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
++
++  if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
++    if( pIter->a>=pIter->b ){
++      *piCol = -1;
++    }else{
++      int iIncr;
++      pIter->a += fts5GetVarint32(&pIter->a[0], iIncr);
++      *piCol += (iIncr-2);
++    }
++  }else{
++    while( 1 ){
++      int dummy;
++      if( pIter->a>=pIter->b ){
++        *piCol = -1;
++        return;
++      }
++      if( pIter->a[0]==0x01 ) break;
++      pIter->a += fts5GetVarint32(pIter->a, dummy);
++    }
++    pIter->a += 1 + fts5GetVarint32(&pIter->a[1], *piCol);
++  }
++}
++
++static int fts5ApiPhraseFirstColumn(
++  Fts5Context *pCtx, 
++  int iPhrase, 
++  Fts5PhraseIter *pIter, 
++  int *piCol
++){
++  int rc = SQLITE_OK;
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
++
++  if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
++    Fts5Sorter *pSorter = pCsr->pSorter;
++    int n;
++    if( pSorter ){
++      int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
++      n = pSorter->aIdx[iPhrase] - i1;
++      pIter->a = &pSorter->aPoslist[i1];
++    }else{
++      rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
++    }
++    if( rc==SQLITE_OK ){
++      pIter->b = &pIter->a[n];
++      *piCol = 0;
++      fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
++    }
++  }else{
++    int n;
++    rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
++    if( rc==SQLITE_OK ){
++      pIter->b = &pIter->a[n];
++      if( n<=0 ){
++        *piCol = -1;
++      }else if( pIter->a[0]==0x01 ){
++        pIter->a += 1 + fts5GetVarint32(&pIter->a[1], *piCol);
++      }else{
++        *piCol = 0;
++      }
++    }
++  }
++
++  return rc;
++}
++
++
++static int fts5ApiQueryPhrase(Fts5Context*, int, void*, 
++    int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
++);
++
++static const Fts5ExtensionApi sFts5Api = {
++  2,                            /* iVersion */
++  fts5ApiUserData,
++  fts5ApiColumnCount,
++  fts5ApiRowCount,
++  fts5ApiColumnTotalSize,
++  fts5ApiTokenize,
++  fts5ApiPhraseCount,
++  fts5ApiPhraseSize,
++  fts5ApiInstCount,
++  fts5ApiInst,
++  fts5ApiRowid,
++  fts5ApiColumnText,
++  fts5ApiColumnSize,
++  fts5ApiQueryPhrase,
++  fts5ApiSetAuxdata,
++  fts5ApiGetAuxdata,
++  fts5ApiPhraseFirst,
++  fts5ApiPhraseNext,
++  fts5ApiPhraseFirstColumn,
++  fts5ApiPhraseNextColumn,
++};
++
++/*
++** Implementation of API function xQueryPhrase().
 +*/
-+SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
++static int fts5ApiQueryPhrase(
++  Fts5Context *pCtx, 
++  int iPhrase, 
++  void *pUserData,
++  int(*xCallback)(const Fts5ExtensionApi*, Fts5Context*, void*)
++){
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
++  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
++  int rc;
++  Fts5Cursor *pNew = 0;
 +
-+  assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
-+       || eStat==SQLITE_DBSTATUS_CACHE_MISS
-+       || eStat==SQLITE_DBSTATUS_CACHE_WRITE
-+  );
++  rc = fts5OpenMethod(pCsr->base.pVtab, (sqlite3_vtab_cursor**)&pNew);
++  if( rc==SQLITE_OK ){
++    pNew->ePlan = FTS5_PLAN_MATCH;
++    pNew->iFirstRowid = SMALLEST_INT64;
++    pNew->iLastRowid = LARGEST_INT64;
++    pNew->base.pVtab = (sqlite3_vtab*)pTab;
++    rc = sqlite3Fts5ExprClonePhrase(pCsr->pExpr, iPhrase, &pNew->pExpr);
++  }
++
++  if( rc==SQLITE_OK ){
++    for(rc = fts5CursorFirst(pTab, pNew, 0);
++        rc==SQLITE_OK && CsrFlagTest(pNew, FTS5CSR_EOF)==0;
++        rc = fts5NextMethod((sqlite3_vtab_cursor*)pNew)
++    ){
++      rc = xCallback(&sFts5Api, (Fts5Context*)pNew, pUserData);
++      if( rc!=SQLITE_OK ){
++        if( rc==SQLITE_DONE ) rc = SQLITE_OK;
++        break;
++      }
++    }
++  }
++
++  fts5CloseMethod((sqlite3_vtab_cursor*)pNew);
++  return rc;
++}
 +
-+  assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS );
-+  assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE );
-+  assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 );
++static void fts5ApiInvoke(
++  Fts5Auxiliary *pAux,
++  Fts5Cursor *pCsr,
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  assert( pCsr->pAux==0 );
++  pCsr->pAux = pAux;
++  pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv);
++  pCsr->pAux = 0;
++}
 +
-+  *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT];
-+  if( reset ){
-+    pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0;
++static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){
++  Fts5Cursor *pCsr;
++  for(pCsr=pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
++    if( pCsr->iCsrId==iCsrId ) break;
 +  }
++  return pCsr;
 +}
 +
-+/*
-+** Return true if this is an in-memory pager.
-+*/
-+SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
-+  return MEMDB;
++static void fts5ApiCallback(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++
++  Fts5Auxiliary *pAux;
++  Fts5Cursor *pCsr;
++  i64 iCsrId;
++
++  assert( argc>=1 );
++  pAux = (Fts5Auxiliary*)sqlite3_user_data(context);
++  iCsrId = sqlite3_value_int64(argv[0]);
++
++  pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId);
++  if( pCsr==0 ){
++    char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId);
++    sqlite3_result_error(context, zErr, -1);
++    sqlite3_free(zErr);
++  }else{
++    fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]);
++  }
 +}
 +
++
 +/*
-+** Check that there are at least nSavepoint savepoints open. If there are
-+** currently less than nSavepoints open, then open one or more savepoints
-+** to make up the difference. If the number of savepoints is already
-+** equal to nSavepoint, then this function is a no-op.
- **
--** To look for page P in the hash table, first compute a hash iKey on
--** P as follows:
-+** If a memory allocation fails, SQLITE_NOMEM is returned. If an error 
-+** occurs while opening the sub-journal file, then an IO error code is
-+** returned. Otherwise, SQLITE_OK.
++** Given cursor id iId, return a pointer to the corresponding Fts5Index 
++** object. Or NULL If the cursor id does not exist.
++**
++** If successful, set *ppConfig to point to the associated config object 
++** before returning.
 +*/
-+SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
-+  int rc = SQLITE_OK;                       /* Return code */
-+  int nCurrent = pPager->nSavepoint;        /* Current number of savepoints */
++static Fts5Index *sqlite3Fts5IndexFromCsrid(
++  Fts5Global *pGlobal,            /* FTS5 global context for db handle */
++  i64 iCsrId,                     /* Id of cursor to find */
++  Fts5Config **ppConfig           /* OUT: Configuration object */
++){
++  Fts5Cursor *pCsr;
++  Fts5Table *pTab;
 +
-+  assert( pPager->eState>=PAGER_WRITER_LOCKED );
-+  assert( assert_pager_state(pPager) );
++  pCsr = fts5CursorFromCsrid(pGlobal, iCsrId);
++  pTab = (Fts5Table*)pCsr->base.pVtab;
++  *ppConfig = pTab->pConfig;
 +
-+  if( nSavepoint>nCurrent && pPager->useJournal ){
-+    int ii;                                 /* Iterator variable */
-+    PagerSavepoint *aNew;                   /* New Pager.aSavepoint array */
++  return pTab->pIndex;
++}
 +
-+    /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
-+    ** if the allocation fails. Otherwise, zero the new portion in case a 
-+    ** malloc failure occurs while populating it in the for(...) loop below.
-+    */
-+    aNew = (PagerSavepoint *)sqlite3Realloc(
-+        pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
-+    );
-+    if( !aNew ){
-+      return SQLITE_NOMEM;
-+    }
-+    memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
-+    pPager->aSavepoint = aNew;
++/*
++** Return a "position-list blob" corresponding to the current position of
++** cursor pCsr via sqlite3_result_blob(). A position-list blob contains
++** the current position-list for each phrase in the query associated with
++** cursor pCsr.
++**
++** A position-list blob begins with (nPhrase-1) varints, where nPhrase is
++** the number of phrases in the query. Following the varints are the
++** concatenated position lists for each phrase, in order.
++**
++** The first varint (if it exists) contains the size of the position list
++** for phrase 0. The second (same disclaimer) contains the size of position
++** list 1. And so on. There is no size field for the final position list,
++** as it can be derived from the total size of the blob.
++*/
++static int fts5PoslistBlob(sqlite3_context *pCtx, Fts5Cursor *pCsr){
++  int i;
++  int rc = SQLITE_OK;
++  int nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
++  Fts5Buffer val;
++
++  memset(&val, 0, sizeof(Fts5Buffer));
++  switch( ((Fts5Table*)(pCsr->base.pVtab))->pConfig->eDetail ){
++    case FTS5_DETAIL_FULL:
++
++      /* Append the varints */
++      for(i=0; i<(nPhrase-1); i++){
++        const u8 *dummy;
++        int nByte = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &dummy);
++        sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
++      }
 +
-+    /* Populate the PagerSavepoint structures just allocated. */
-+    for(ii=nCurrent; ii<nSavepoint; ii++){
-+      aNew[ii].nOrig = pPager->dbSize;
-+      if( isOpen(pPager->jfd) && pPager->journalOff>0 ){
-+        aNew[ii].iOffset = pPager->journalOff;
-+      }else{
-+        aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager);
++      /* Append the position lists */
++      for(i=0; i<nPhrase; i++){
++        const u8 *pPoslist;
++        int nPoslist;
++        nPoslist = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &pPoslist);
++        sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
 +      }
-+      aNew[ii].iSubRec = pPager->nSubRec;
-+      aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
-+      if( !aNew[ii].pInSavepoint ){
-+        return SQLITE_NOMEM;
++      break;
++
++    case FTS5_DETAIL_COLUMNS:
++
++      /* Append the varints */
++      for(i=0; rc==SQLITE_OK && i<(nPhrase-1); i++){
++        const u8 *dummy;
++        int nByte;
++        rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &dummy, &nByte);
++        sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
 +      }
-+      if( pagerUseWal(pPager) ){
-+        sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
++
++      /* Append the position lists */
++      for(i=0; rc==SQLITE_OK && i<nPhrase; i++){
++        const u8 *pPoslist;
++        int nPoslist;
++        rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &pPoslist, &nPoslist);
++        sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
 +      }
-+      pPager->nSavepoint = ii+1;
-+    }
-+    assert( pPager->nSavepoint==nSavepoint );
-+    assertTruncateConstraint(pPager);
++      break;
++
++    default:
++      break;
 +  }
 +
++  sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
 +  return rc;
 +}
 +
-+/*
-+** This function is called to rollback or release (commit) a savepoint.
-+** The savepoint to release or rollback need not be the most recently 
-+** created savepoint.
- **
--**      iKey = (P * 383) % HASHTABLE_NSLOT
-+** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE.
-+** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with
-+** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes
-+** that have occurred since the specified savepoint was created.
- **
--** Then start scanning entries of the hash table, starting with iKey
--** (wrapping around to the beginning when the end of the hash table is
--** reached) until an unused hash slot is found. Let the first unused slot
--** be at index iUnused.  (iUnused might be less than iKey if there was
--** wrap-around.) Because the hash table is never more than half full,
--** the search is guaranteed to eventually hit an unused entry.  Let 
--** iMax be the value between iKey and iUnused, closest to iUnused,
--** where aHash[iMax]==P.  If there is no iMax entry (if there exists
--** no hash slot such that aHash[i]==p) then page P is not in the
--** current index block.  Otherwise the iMax-th mapping entry of the
--** current index block corresponds to the last entry that references 
--** page P.
-+** The savepoint to rollback or release is identified by parameter 
-+** iSavepoint. A value of 0 means to operate on the outermost savepoint
-+** (the first created). A value of (Pager.nSavepoint-1) means operate
-+** on the most recently created savepoint. If iSavepoint is greater than
-+** (Pager.nSavepoint-1), then this function is a no-op.
- **
--** A hash search begins with the last index block and moves toward the
--** first index block, looking for entries corresponding to page P.  On
--** average, only two or three slots in each index block need to be
--** examined in order to either find the last entry for page P, or to
--** establish that no such entry exists in the block.  Each index block
--** holds over 4000 entries.  So two or three index blocks are sufficient
--** to cover a typical 10 megabyte WAL file, assuming 1K pages.  8 or 10
--** comparisons (on average) suffice to either locate a frame in the
--** WAL or to establish that the frame does not exist in the WAL.  This
--** is much faster than scanning the entire 10MB WAL.
-+** If a negative value is passed to this function, then the current
-+** transaction is rolled back. This is different to calling 
-+** sqlite3PagerRollback() because this function does not terminate
-+** the transaction or unlock the database, it just restores the 
-+** contents of the database to its original state. 
- **
--** Note that entries are added in order of increasing K.  Hence, one
--** reader might be using some value K0 and a second reader that started
--** at a later time (after additional transactions were added to the WAL
--** and to the wal-index) might be using a different value K1, where K1>K0.
--** Both readers can use the same hash table and mapping section to get
--** the correct result.  There may be entries in the hash table with
--** K>K0 but to the first reader, those entries will appear to be unused
--** slots in the hash table and so the first reader will get an answer as
--** if no values greater than K0 had ever been inserted into the hash table
--** in the first place - which is what reader one wants.  Meanwhile, the
--** second reader using K1 will see additional values that were inserted
--** later, which is exactly what reader two wants.  
-+** In any case, all savepoints with an index greater than iSavepoint 
-+** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE),
-+** then savepoint iSavepoint is also destroyed.
- **
--** When a rollback occurs, the value of K is decreased. Hash table entries
--** that correspond to frames greater than the new K value are removed
--** from the hash table at this point.
--*/
--#ifndef SQLITE_OMIT_WAL
-+** This function may return SQLITE_NOMEM if a memory allocation fails,
-+** or an IO error code if an IO error occurs while rolling back a 
-+** savepoint. If no errors occur, SQLITE_OK is returned.
-+*/ 
-+SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
-+  int rc = pPager->errCode;       /* Return code */
-+
-+  assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
-+  assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
-+
-+  if( rc==SQLITE_OK && iSavepoint<pPager->nSavepoint ){
-+    int ii;            /* Iterator variable */
-+    int nNew;          /* Number of remaining savepoints after this op. */
++/* 
++** This is the xColumn method, called by SQLite to request a value from
++** the row that the supplied cursor currently points to.
++*/
++static int fts5ColumnMethod(
++  sqlite3_vtab_cursor *pCursor,   /* Cursor to retrieve value from */
++  sqlite3_context *pCtx,          /* Context for sqlite3_result_xxx() calls */
++  int iCol                        /* Index of column to read value from */
++){
++  Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
++  Fts5Config *pConfig = pTab->pConfig;
++  Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
++  int rc = SQLITE_OK;
++  
++  assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 );
 +
-+    /* Figure out how many savepoints will still be active after this
-+    ** operation. Store this value in nNew. Then free resources associated 
-+    ** with any savepoints that are destroyed by this operation.
-+    */
-+    nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1);
-+    for(ii=nNew; ii<pPager->nSavepoint; ii++){
-+      sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
++  if( pCsr->ePlan==FTS5_PLAN_SPECIAL ){
++    if( iCol==pConfig->nCol ){
++      sqlite3_result_int64(pCtx, pCsr->iSpecial);
 +    }
-+    pPager->nSavepoint = nNew;
++  }else
 +
-+    /* If this is a release of the outermost savepoint, truncate 
-+    ** the sub-journal to zero bytes in size. */
-+    if( op==SAVEPOINT_RELEASE ){
-+      if( nNew==0 && isOpen(pPager->sjfd) ){
-+        /* Only truncate if it is an in-memory sub-journal. */
-+        if( sqlite3IsMemJournal(pPager->sjfd) ){
-+          rc = sqlite3OsTruncate(pPager->sjfd, 0);
-+          assert( rc==SQLITE_OK );
-+        }
-+        pPager->nSubRec = 0;
++  if( iCol==pConfig->nCol ){
++    /* User is requesting the value of the special column with the same name
++    ** as the table. Return the cursor integer id number. This value is only
++    ** useful in that it may be passed as the first argument to an FTS5
++    ** auxiliary function.  */
++    sqlite3_result_int64(pCtx, pCsr->iCsrId);
++  }else if( iCol==pConfig->nCol+1 ){
++
++    /* The value of the "rank" column. */
++    if( pCsr->ePlan==FTS5_PLAN_SOURCE ){
++      fts5PoslistBlob(pCtx, pCsr);
++    }else if( 
++        pCsr->ePlan==FTS5_PLAN_MATCH
++     || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
++    ){
++      if( pCsr->pRank || SQLITE_OK==(rc = fts5FindRankFunction(pCsr)) ){
++        fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg);
 +      }
 +    }
-+    /* Else this is a rollback operation, playback the specified savepoint.
-+    ** If this is a temp-file, it is possible that the journal file has
-+    ** not yet been opened. In this case there have been no changes to
-+    ** the database file, so the playback operation can be skipped.
-+    */
-+    else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){
-+      PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1];
-+      rc = pagerPlaybackSavepoint(pPager, pSavepoint);
-+      assert(rc!=SQLITE_DONE);
++  }else if( !fts5IsContentless(pTab) ){
++    rc = fts5SeekCursor(pCsr, 1);
++    if( rc==SQLITE_OK ){
++      sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
 +    }
 +  }
- 
 +  return rc;
 +}
- 
- /*
--** Trace output macros
-+** Return the full pathname of the database file.
-+**
-+** Except, if the pager is in-memory only, then return an empty string if
-+** nullIfMemDb is true.  This routine is called with nullIfMemDb==1 when
-+** used to report the filename to the user, for compatibility with legacy
-+** behavior.  But when the Btree needs to know the filename for matching to
-+** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
-+** participate in shared-cache.
- */
--#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
--SQLITE_PRIVATE int sqlite3WalTrace = 0;
--# define WALTRACE(X)  if(sqlite3WalTrace) sqlite3DebugPrintf X
--#else
--# define WALTRACE(X)
--#endif
-+SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
-+  return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
++
++
++/*
++** This routine implements the xFindFunction method for the FTS3
++** virtual table.
++*/
++static int fts5FindFunctionMethod(
++  sqlite3_vtab *pVtab,            /* Virtual table handle */
++  int nUnused,                    /* Number of SQL function arguments */
++  const char *zName,              /* Name of SQL function */
++  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
++  void **ppArg                    /* OUT: User data for *pxFunc */
++){
++  Fts5Table *pTab = (Fts5Table*)pVtab;
++  Fts5Auxiliary *pAux;
++
++  UNUSED_PARAM(nUnused);
++  pAux = fts5FindAuxiliary(pTab, zName);
++  if( pAux ){
++    *pxFunc = fts5ApiCallback;
++    *ppArg = (void*)pAux;
++    return 1;
++  }
++
++  /* No function of the specified name was found. Return 0. */
++  return 0;
 +}
- 
- /*
--** The maximum (and only) versions of the wal and wal-index formats
--** that may be interpreted by this version of SQLite.
--**
--** If a client begins recovering a WAL file and finds that (a) the checksum
--** values in the wal-header are correct and (b) the version field is not
--** WAL_MAX_VERSION, recovery fails and SQLite returns SQLITE_CANTOPEN.
--**
--** Similarly, if a client successfully reads a wal-index header (i.e. the 
--** checksum test is successful) and finds that the version field is not
--** WALINDEX_MAX_VERSION, then no read-transaction is opened and SQLite
--** returns SQLITE_CANTOPEN.
-+** Return the VFS structure for the pager.
- */
--#define WAL_MAX_VERSION      3007000
--#define WALINDEX_MAX_VERSION 3007000
-+SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
-+  return pPager->pVfs;
++
++/*
++** Implementation of FTS5 xRename method. Rename an fts5 table.
++*/
++static int fts5RenameMethod(
++  sqlite3_vtab *pVtab,            /* Virtual table handle */
++  const char *zName               /* New name of table */
++){
++  Fts5Table *pTab = (Fts5Table*)pVtab;
++  return sqlite3Fts5StorageRename(pTab->pStorage, zName);
 +}
- 
- /*
--** Indices of various locking bytes.   WAL_NREADER is the number
--** of available reader locks and should be at least 3.
-+** Return the file handle for the database file associated
-+** with the pager.  This might return NULL if the file has
-+** not yet been opened.
- */
--#define WAL_WRITE_LOCK         0
--#define WAL_ALL_BUT_WRITE      1
--#define WAL_CKPT_LOCK          1
--#define WAL_RECOVER_LOCK       2
--#define WAL_READ_LOCK(I)       (3+(I))
--#define WAL_NREADER            (SQLITE_SHM_NLOCK-3)
-+SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
-+  return pPager->fd;
++
++/*
++** The xSavepoint() method.
++**
++** Flush the contents of the pending-terms table to disk.
++*/
++static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
++  Fts5Table *pTab = (Fts5Table*)pVtab;
++  UNUSED_PARAM(iSavepoint);  /* Call below is a no-op for NDEBUG builds */
++  fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
++  fts5TripCursors(pTab);
++  return sqlite3Fts5StorageSync(pTab->pStorage);
 +}
- 
++
 +/*
-+** Return the full pathname of the journal file.
++** The xRelease() method.
++**
++** This is a no-op.
 +*/
-+SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
-+  return pPager->zJournal;
++static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
++  Fts5Table *pTab = (Fts5Table*)pVtab;
++  UNUSED_PARAM(iSavepoint);  /* Call below is a no-op for NDEBUG builds */
++  fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
++  fts5TripCursors(pTab);
++  return sqlite3Fts5StorageSync(pTab->pStorage);
 +}
- 
--/* Object declarations */
--typedef struct WalIndexHdr WalIndexHdr;
--typedef struct WalIterator WalIterator;
--typedef struct WalCkptInfo WalCkptInfo;
++
 +/*
-+** Return true if fsync() calls are disabled for this pager.  Return FALSE
-+** if fsync()s are executed normally.
++** The xRollbackTo() method.
++**
++** Discard the contents of the pending terms table.
 +*/
-+SQLITE_PRIVATE int sqlite3PagerNosync(Pager *pPager){
-+  return pPager->noSync;
++static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
++  Fts5Table *pTab = (Fts5Table*)pVtab;
++  UNUSED_PARAM(iSavepoint);  /* Call below is a no-op for NDEBUG builds */
++  fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
++  fts5TripCursors(pTab);
++  return sqlite3Fts5StorageRollback(pTab->pStorage);
 +}
- 
-+#ifdef SQLITE_HAS_CODEC
++
 +/*
-+** Set or retrieve the codec for this pager
++** Register a new auxiliary function with global context pGlobal.
 +*/
-+SQLITE_PRIVATE void sqlite3PagerSetCodec(
-+  Pager *pPager,
-+  void *(*xCodec)(void*,void*,Pgno,int),
-+  void (*xCodecSizeChng)(void*,int,int),
-+  void (*xCodecFree)(void*),
-+  void *pCodec
++static int fts5CreateAux(
++  fts5_api *pApi,                 /* Global context (one per db handle) */
++  const char *zName,              /* Name of new function */
++  void *pUserData,                /* User data for aux. function */
++  fts5_extension_function xFunc,  /* Aux. function implementation */
++  void(*xDestroy)(void*)          /* Destructor for pUserData */
 +){
-+  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
-+  pPager->xCodec = pPager->memDb ? 0 : xCodec;
-+  pPager->xCodecSizeChng = xCodecSizeChng;
-+  pPager->xCodecFree = xCodecFree;
-+  pPager->pCodec = pCodec;
-+  pagerReportSize(pPager);
++  Fts5Global *pGlobal = (Fts5Global*)pApi;
++  int rc = sqlite3_overload_function(pGlobal->db, zName, -1);
++  if( rc==SQLITE_OK ){
++    Fts5Auxiliary *pAux;
++    int nName;                      /* Size of zName in bytes, including \0 */
++    int nByte;                      /* Bytes of space to allocate */
++
++    nName = (int)strlen(zName) + 1;
++    nByte = sizeof(Fts5Auxiliary) + nName;
++    pAux = (Fts5Auxiliary*)sqlite3_malloc(nByte);
++    if( pAux ){
++      memset(pAux, 0, nByte);
++      pAux->zFunc = (char*)&pAux[1];
++      memcpy(pAux->zFunc, zName, nName);
++      pAux->pGlobal = pGlobal;
++      pAux->pUserData = pUserData;
++      pAux->xFunc = xFunc;
++      pAux->xDestroy = xDestroy;
++      pAux->pNext = pGlobal->pAux;
++      pGlobal->pAux = pAux;
++    }else{
++      rc = SQLITE_NOMEM;
++    }
++  }
++
++  return rc;
 +}
-+SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
-+  return pPager->pCodec;
++
++/*
++** Register a new tokenizer. This is the implementation of the 
++** fts5_api.xCreateTokenizer() method.
++*/
++static int fts5CreateTokenizer(
++  fts5_api *pApi,                 /* Global context (one per db handle) */
++  const char *zName,              /* Name of new function */
++  void *pUserData,                /* User data for aux. function */
++  fts5_tokenizer *pTokenizer,     /* Tokenizer implementation */
++  void(*xDestroy)(void*)          /* Destructor for pUserData */
++){
++  Fts5Global *pGlobal = (Fts5Global*)pApi;
++  Fts5TokenizerModule *pNew;
++  int nName;                      /* Size of zName and its \0 terminator */
++  int nByte;                      /* Bytes of space to allocate */
++  int rc = SQLITE_OK;
++
++  nName = (int)strlen(zName) + 1;
++  nByte = sizeof(Fts5TokenizerModule) + nName;
++  pNew = (Fts5TokenizerModule*)sqlite3_malloc(nByte);
++  if( pNew ){
++    memset(pNew, 0, nByte);
++    pNew->zName = (char*)&pNew[1];
++    memcpy(pNew->zName, zName, nName);
++    pNew->pUserData = pUserData;
++    pNew->x = *pTokenizer;
++    pNew->xDestroy = xDestroy;
++    pNew->pNext = pGlobal->pTok;
++    pGlobal->pTok = pNew;
++    if( pNew->pNext==0 ){
++      pGlobal->pDfltTok = pNew;
++    }
++  }else{
++    rc = SQLITE_NOMEM;
++  }
++
++  return rc;
 +}
- 
- /*
--** The following object holds a copy of the wal-index header content.
--**
--** The actual header in the wal-index consists of two copies of this
--** object.
-+** This function is called by the wal module when writing page content
-+** into the log file.
- **
--** The szPage value can be any power of 2 between 512 and 32768, inclusive.
--** Or it can be 1 to represent a 65536-byte page.  The latter case was
--** added in 3.7.1 when support for 64K pages was added.  
-+** This function returns a pointer to a buffer containing the encrypted
-+** page content. If a malloc fails, this function may return NULL.
- */
--struct WalIndexHdr {
--  u32 iVersion;                   /* Wal-index version */
--  u32 unused;                     /* Unused (padding) field */
--  u32 iChange;                    /* Counter incremented each transaction */
--  u8 isInit;                      /* 1 when initialized */
--  u8 bigEndCksum;                 /* True if checksums in WAL are big-endian */
--  u16 szPage;                     /* Database page size in bytes. 1==64K */
--  u32 mxFrame;                    /* Index of last valid frame in the WAL */
--  u32 nPage;                      /* Size of database in pages */
--  u32 aFrameCksum[2];             /* Checksum of last frame in log */
--  u32 aSalt[2];                   /* Two salt values copied from WAL header */
--  u32 aCksum[2];                  /* Checksum over all prior fields */
--};
-+SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
-+  void *aData = 0;
-+  CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
-+  return aData;
++
++static Fts5TokenizerModule *fts5LocateTokenizer(
++  Fts5Global *pGlobal, 
++  const char *zName
++){
++  Fts5TokenizerModule *pMod = 0;
++
++  if( zName==0 ){
++    pMod = pGlobal->pDfltTok;
++  }else{
++    for(pMod=pGlobal->pTok; pMod; pMod=pMod->pNext){
++      if( sqlite3_stricmp(zName, pMod->zName)==0 ) break;
++    }
++  }
++
++  return pMod;
 +}
- 
- /*
--** A copy of the following object occurs in the wal-index immediately
--** following the second copy of the WalIndexHdr.  This object stores
--** information used by checkpoint.
--**
--** nBackfill is the number of frames in the WAL that have been written
--** back into the database. (We call the act of moving content from WAL to
--** database "backfilling".)  The nBackfill number is never greater than
--** WalIndexHdr.mxFrame.  nBackfill can only be increased by threads
--** holding the WAL_CKPT_LOCK lock (which includes a recovery thread).
--** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from
--** mxFrame back to zero when the WAL is reset.
-+** Return the current pager state
++
++/*
++** Find a tokenizer. This is the implementation of the 
++** fts5_api.xFindTokenizer() method.
 +*/
-+SQLITE_PRIVATE int sqlite3PagerState(Pager *pPager){
-+  return pPager->eState;
++static int fts5FindTokenizer(
++  fts5_api *pApi,                 /* Global context (one per db handle) */
++  const char *zName,              /* Name of new function */
++  void **ppUserData,
++  fts5_tokenizer *pTokenizer      /* Populate this object */
++){
++  int rc = SQLITE_OK;
++  Fts5TokenizerModule *pMod;
++
++  pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
++  if( pMod ){
++    *pTokenizer = pMod->x;
++    *ppUserData = pMod->pUserData;
++  }else{
++    memset(pTokenizer, 0, sizeof(fts5_tokenizer));
++    rc = SQLITE_ERROR;
++  }
++
++  return rc;
 +}
-+#endif /* SQLITE_HAS_CODEC */
 +
-+#ifndef SQLITE_OMIT_AUTOVACUUM
-+/*
-+** Move the page pPg to location pgno in the file.
- **
--** There is one entry in aReadMark[] for each reader lock.  If a reader
--** holds read-lock K, then the value in aReadMark[K] is no greater than
--** the mxFrame for that reader.  The value READMARK_NOT_USED (0xffffffff)
--** for any aReadMark[] means that entry is unused.  aReadMark[0] is 
--** a special case; its value is never used and it exists as a place-holder
--** to avoid having to offset aReadMark[] indexs by one.  Readers holding
--** WAL_READ_LOCK(0) always ignore the entire WAL and read all content
--** directly from the database.
-+** There must be no references to the page previously located at
-+** pgno (which we call pPgOld) though that page is allowed to be
-+** in cache.  If the page previously located at pgno is not already
-+** in the rollback journal, it is not put there by by this routine.
- **
--** The value of aReadMark[K] may only be changed by a thread that
--** is holding an exclusive lock on WAL_READ_LOCK(K).  Thus, the value of
--** aReadMark[K] cannot changed while there is a reader is using that mark
--** since the reader will be holding a shared lock on WAL_READ_LOCK(K).
-+** References to the page pPg remain valid. Updating any
-+** meta-data associated with pPg (i.e. data stored in the nExtra bytes
-+** allocated along with the page) is the responsibility of the caller.
- **
--** The checkpointer may only transfer frames from WAL to database where
--** the frame numbers are less than or equal to every aReadMark[] that is
--** in use (that is, every aReadMark[j] for which there is a corresponding
--** WAL_READ_LOCK(j)).  New readers (usually) pick the aReadMark[] with the
--** largest value and will increase an unused aReadMark[] to mxFrame if there
--** is not already an aReadMark[] equal to mxFrame.  The exception to the
--** previous sentence is when nBackfill equals mxFrame (meaning that everything
--** in the WAL has been backfilled into the database) then new readers
--** will choose aReadMark[0] which has value 0 and hence such reader will
--** get all their all content directly from the database file and ignore 
--** the WAL.
-+** A transaction must be active when this routine is called. It used to be
-+** required that a statement transaction was not active, but this restriction
-+** has been removed (CREATE INDEX needs to move a page when a statement
-+** transaction is active).
- **
--** Writers normally append new frames to the end of the WAL.  However,
--** if nBackfill equals mxFrame (meaning that all WAL content has been
--** written back into the database) and if no readers are using the WAL
--** (in other words, if there are no WAL_READ_LOCK(i) where i>0) then
--** the writer will first "reset" the WAL back to the beginning and start
--** writing new content beginning at frame 1.
-+** If the fourth argument, isCommit, is non-zero, then this page is being
-+** moved as part of a database reorganization just before the transaction 
-+** is being committed. In this case, it is guaranteed that the database page 
-+** pPg refers to will not be written to again within this transaction.
- **
--** We assume that 32-bit loads are atomic and so no locks are needed in
--** order to read from any aReadMark[] entries.
-+** This function may return SQLITE_NOMEM or an IO error code if an error
-+** occurs. Otherwise, it returns SQLITE_OK.
- */
--struct WalCkptInfo {
--  u32 nBackfill;                  /* Number of WAL frames backfilled into DB */
--  u32 aReadMark[WAL_NREADER];     /* Reader marks */
--};
--#define READMARK_NOT_USED  0xffffffff
-+SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
-+  PgHdr *pPgOld;               /* The page being overwritten. */
-+  Pgno needSyncPgno = 0;       /* Old value of pPg->pgno, if sync is required */
-+  int rc;                      /* Return code */
-+  Pgno origPgno;               /* The original page number */
- 
-+  assert( pPg->nRef>0 );
-+  assert( pPager->eState==PAGER_WRITER_CACHEMOD
-+       || pPager->eState==PAGER_WRITER_DBMOD
-+  );
-+  assert( assert_pager_state(pPager) );
- 
--/* A block of WALINDEX_LOCK_RESERVED bytes beginning at
--** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems
--** only support mandatory file-locks, we do not read or write data
--** from the region of the file on which locks are applied.
--*/
--#define WALINDEX_LOCK_OFFSET   (sizeof(WalIndexHdr)*2 + sizeof(WalCkptInfo))
--#define WALINDEX_LOCK_RESERVED 16
--#define WALINDEX_HDR_SIZE      (WALINDEX_LOCK_OFFSET+WALINDEX_LOCK_RESERVED)
-+  /* In order to be able to rollback, an in-memory database must journal
-+  ** the page we are moving from.
-+  */
-+  if( MEMDB ){
-+    rc = sqlite3PagerWrite(pPg);
-+    if( rc ) return rc;
++static int sqlite3Fts5GetTokenizer(
++  Fts5Global *pGlobal, 
++  const char **azArg,
++  int nArg,
++  Fts5Tokenizer **ppTok,
++  fts5_tokenizer **ppTokApi,
++  char **pzErr
++){
++  Fts5TokenizerModule *pMod;
++  int rc = SQLITE_OK;
++
++  pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]);
++  if( pMod==0 ){
++    assert( nArg>0 );
++    rc = SQLITE_ERROR;
++    *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
++  }else{
++    rc = pMod->x.xCreate(pMod->pUserData, &azArg[1], (nArg?nArg-1:0), ppTok);
++    *ppTokApi = &pMod->x;
++    if( rc!=SQLITE_OK && pzErr ){
++      *pzErr = sqlite3_mprintf("error in tokenizer constructor");
++    }
 +  }
- 
--/* Size of header before each frame in wal */
--#define WAL_FRAME_HDRSIZE 24
-+  /* If the page being moved is dirty and has not been saved by the latest
-+  ** savepoint, then save the current contents of the page into the 
-+  ** sub-journal now. This is required to handle the following scenario:
-+  **
-+  **   BEGIN;
-+  **     <journal page X, then modify it in memory>
-+  **     SAVEPOINT one;
-+  **       <Move page X to location Y>
-+  **     ROLLBACK TO one;
-+  **
-+  ** If page X were not written to the sub-journal here, it would not
-+  ** be possible to restore its contents when the "ROLLBACK TO one"
-+  ** statement were is processed.
-+  **
-+  ** subjournalPage() may need to allocate space to store pPg->pgno into
-+  ** one or more savepoint bitvecs. This is the reason this function
-+  ** may return SQLITE_NOMEM.
-+  */
-+  if( pPg->flags&PGHDR_DIRTY
-+   && subjRequiresPage(pPg)
-+   && SQLITE_OK!=(rc = subjournalPage(pPg))
-+  ){
-+    return rc;
++
++  if( rc!=SQLITE_OK ){
++    *ppTokApi = 0;
++    *ppTok = 0;
 +  }
- 
--/* Size of write ahead log header, including checksum. */
--/* #define WAL_HDRSIZE 24 */
--#define WAL_HDRSIZE 32
-+  PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", 
-+      PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno));
-+  IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno))
- 
--/* WAL magic value. Either this value, or the same value with the least
--** significant bit also set (WAL_MAGIC | 0x00000001) is stored in 32-bit
--** big-endian format in the first 4 bytes of a WAL file.
--**
--** If the LSB is set, then the checksums for each frame within the WAL
--** file are calculated by treating all data as an array of 32-bit 
--** big-endian words. Otherwise, they are calculated by interpreting 
--** all data as 32-bit little-endian words.
--*/
--#define WAL_MAGIC 0x377f0682
-+  /* If the journal needs to be sync()ed before page pPg->pgno can
-+  ** be written to, store pPg->pgno in local variable needSyncPgno.
-+  **
-+  ** If the isCommit flag is set, there is no need to remember that
-+  ** the journal needs to be sync()ed before database page pPg->pgno 
-+  ** can be written to. The caller has already promised not to write to it.
-+  */
-+  if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
-+    needSyncPgno = pPg->pgno;
-+    assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
-+            pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize );
-+    assert( pPg->flags&PGHDR_DIRTY );
++
++  return rc;
++}
++
++static void fts5ModuleDestroy(void *pCtx){
++  Fts5TokenizerModule *pTok, *pNextTok;
++  Fts5Auxiliary *pAux, *pNextAux;
++  Fts5Global *pGlobal = (Fts5Global*)pCtx;
++
++  for(pAux=pGlobal->pAux; pAux; pAux=pNextAux){
++    pNextAux = pAux->pNext;
++    if( pAux->xDestroy ) pAux->xDestroy(pAux->pUserData);
++    sqlite3_free(pAux);
 +  }
 +
-+  /* If the cache contains a page with page-number pgno, remove it
-+  ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for 
-+  ** page pgno before the 'move' operation, it needs to be retained 
-+  ** for the page moved there.
-+  */
-+  pPg->flags &= ~PGHDR_NEED_SYNC;
-+  pPgOld = sqlite3PagerLookup(pPager, pgno);
-+  assert( !pPgOld || pPgOld->nRef==1 );
-+  if( pPgOld ){
-+    pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
-+    if( MEMDB ){
-+      /* Do not discard pages from an in-memory database since we might
-+      ** need to rollback later.  Just move the page out of the way. */
-+      sqlite3PcacheMove(pPgOld, pPager->dbSize+1);
-+    }else{
-+      sqlite3PcacheDrop(pPgOld);
-+    }
++  for(pTok=pGlobal->pTok; pTok; pTok=pNextTok){
++    pNextTok = pTok->pNext;
++    if( pTok->xDestroy ) pTok->xDestroy(pTok->pUserData);
++    sqlite3_free(pTok);
 +  }
 +
-+  origPgno = pPg->pgno;
-+  sqlite3PcacheMove(pPg, pgno);
-+  sqlite3PcacheMakeDirty(pPg);
++  sqlite3_free(pGlobal);
++}
 +
-+  /* For an in-memory database, make sure the original page continues
-+  ** to exist, in case the transaction needs to roll back.  Use pPgOld
-+  ** as the original page since it has already been allocated.
-+  */
-+  if( MEMDB ){
-+    assert( pPgOld );
-+    sqlite3PcacheMove(pPgOld, origPgno);
-+    sqlite3PagerUnrefNotNull(pPgOld);
-+  }
-+
-+  if( needSyncPgno ){
-+    /* If needSyncPgno is non-zero, then the journal file needs to be 
-+    ** sync()ed before any data is written to database file page needSyncPgno.
-+    ** Currently, no such page exists in the page-cache and the 
-+    ** "is journaled" bitvec flag has been set. This needs to be remedied by
-+    ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC
-+    ** flag.
-+    **
-+    ** If the attempt to load the page into the page-cache fails, (due
-+    ** to a malloc() or IO failure), clear the bit in the pInJournal[]
-+    ** array. Otherwise, if the page is loaded and written again in
-+    ** this transaction, it may be written to the database file before
-+    ** it is synced into the journal file. This way, it may end up in
-+    ** the journal file twice, but that is not a problem.
-+    */
-+    PgHdr *pPgHdr;
-+    rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
-+    if( rc!=SQLITE_OK ){
-+      if( needSyncPgno<=pPager->dbOrigSize ){
-+        assert( pPager->pTmpSpace!=0 );
-+        sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace);
-+      }
-+      return rc;
++static void fts5Fts5Func(
++  sqlite3_context *pCtx,          /* Function call context */
++  int nArg,                       /* Number of args */
++  sqlite3_value **apArg           /* Function arguments */
++){
++  Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
++  fts5_api **ppApi;
++  UNUSED_PARAM(nArg);
++  assert( nArg==1 );
++  ppApi = (fts5_api**)sqlite3_value_pointer(apArg[0], "fts5_api_ptr");
++  if( ppApi ) *ppApi = &pGlobal->api;
++}
++
++/*
++** Implementation of fts5_source_id() function.
++*/
++static void fts5SourceIdFunc(
++  sqlite3_context *pCtx,          /* Function call context */
++  int nArg,                       /* Number of args */
++  sqlite3_value **apUnused        /* Function arguments */
++){
++  assert( nArg==0 );
++  UNUSED_PARAM2(nArg, apUnused);
++  sqlite3_result_text(pCtx, "fts5: 2017-08-24 16:21:36 
8d3a7ea6c5690d6b7c3767558f4f01b511c55463e3f9e64506801fe9b74dce34", -1, SQLITE_TRANSIENT);
++}
++
++static int fts5Init(sqlite3 *db){
++  static const sqlite3_module fts5Mod = {
++    /* iVersion      */ 2,
++    /* xCreate       */ fts5CreateMethod,
++    /* xConnect      */ fts5ConnectMethod,
++    /* xBestIndex    */ fts5BestIndexMethod,
++    /* xDisconnect   */ fts5DisconnectMethod,
++    /* xDestroy      */ fts5DestroyMethod,
++    /* xOpen         */ fts5OpenMethod,
++    /* xClose        */ fts5CloseMethod,
++    /* xFilter       */ fts5FilterMethod,
++    /* xNext         */ fts5NextMethod,
++    /* xEof          */ fts5EofMethod,
++    /* xColumn       */ fts5ColumnMethod,
++    /* xRowid        */ fts5RowidMethod,
++    /* xUpdate       */ fts5UpdateMethod,
++    /* xBegin        */ fts5BeginMethod,
++    /* xSync         */ fts5SyncMethod,
++    /* xCommit       */ fts5CommitMethod,
++    /* xRollback     */ fts5RollbackMethod,
++    /* xFindFunction */ fts5FindFunctionMethod,
++    /* xRename       */ fts5RenameMethod,
++    /* xSavepoint    */ fts5SavepointMethod,
++    /* xRelease      */ fts5ReleaseMethod,
++    /* xRollbackTo   */ fts5RollbackToMethod,
++  };
++
++  int rc;
++  Fts5Global *pGlobal = 0;
++
++  pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global));
++  if( pGlobal==0 ){
++    rc = SQLITE_NOMEM;
++  }else{
++    void *p = (void*)pGlobal;
++    memset(pGlobal, 0, sizeof(Fts5Global));
++    pGlobal->db = db;
++    pGlobal->api.iVersion = 2;
++    pGlobal->api.xCreateFunction = fts5CreateAux;
++    pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
++    pGlobal->api.xFindTokenizer = fts5FindTokenizer;
++    rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
++    if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
++    if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
++    if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
++    if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
++    if( rc==SQLITE_OK ) rc = sqlite3Fts5VocabInit(pGlobal, db);
++    if( rc==SQLITE_OK ){
++      rc = sqlite3_create_function(
++          db, "fts5", 1, SQLITE_UTF8, p, fts5Fts5Func, 0, 0
++      );
++    }
++    if( rc==SQLITE_OK ){
++      rc = sqlite3_create_function(
++          db, "fts5_source_id", 0, SQLITE_UTF8, p, fts5SourceIdFunc, 0, 0
++      );
 +    }
-+    pPgHdr->flags |= PGHDR_NEED_SYNC;
-+    sqlite3PcacheMakeDirty(pPgHdr);
-+    sqlite3PagerUnrefNotNull(pPgHdr);
 +  }
- 
--/*
--** Return the offset of frame iFrame in the write-ahead log file, 
--** assuming a database page size of szPage bytes. The offset returned
--** is to the start of the write-ahead log frame-header.
--*/
--#define walFrameOffset(iFrame, szPage) (                               \
--  WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE)         \
--)
-+  return SQLITE_OK;
++
++  /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
++  ** fts5_test_mi.c is compiled and linked into the executable. And call
++  ** its entry point to enable the matchinfo() demo.  */
++#ifdef SQLITE_FTS5_ENABLE_TEST_MI
++  if( rc==SQLITE_OK ){
++    extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*);
++    rc = sqlite3Fts5TestRegisterMatchinfo(db);
++  }
++#endif
++
++  return rc;
 +}
++
++/*
++** The following functions are used to register the module with SQLite. If
++** this module is being built as part of the SQLite core (SQLITE_CORE is
++** defined), then sqlite3_open() will call sqlite3Fts5Init() directly.
++**
++** Or, if this module is being built as a loadable extension, 
++** sqlite3Fts5Init() is omitted and the two standard entry points
++** sqlite3_fts_init() and sqlite3_fts5_init() defined instead.
++*/
++#ifndef SQLITE_CORE
++#ifdef _WIN32
++__declspec(dllexport)
 +#endif
- 
- /*
--** An open write-ahead log file is represented by an instance of the
--** following object.
-+** The page handle passed as the first argument refers to a dirty page 
-+** with a page number other than iNew. This function changes the page's 
-+** page number to iNew and sets the value of the PgHdr.flags field to 
-+** the value passed as the third parameter.
- */
--struct Wal {
--  sqlite3_vfs *pVfs;         /* The VFS used to create pDbFd */
--  sqlite3_file *pDbFd;       /* File handle for the database file */
--  sqlite3_file *pWalFd;      /* File handle for WAL file */
--  u32 iCallback;             /* Value to pass to log callback (or 0) */
--  i64 mxWalSize;             /* Truncate WAL to this size upon reset */
--  int nWiData;               /* Size of array apWiData */
--  int szFirstBlock;          /* Size of first block written to WAL file */
--  volatile u32 **apWiData;   /* Pointer to wal-index content in memory */
--  u32 szPage;                /* Database page size */
--  i16 readLock;              /* Which read lock is being held.  -1 for none */
--  u8 syncFlags;              /* Flags to use to sync header writes */
--  u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
--  u8 writeLock;              /* True if in a write transaction */
--  u8 ckptLock;               /* True if holding a checkpoint lock */
--  u8 readOnly;               /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
--  u8 truncateOnCommit;       /* True to truncate WAL file on commit */
--  u8 syncHeader;             /* Fsync the WAL header if true */
--  u8 padToSectorBoundary;    /* Pad transactions out to the next sector */
--  WalIndexHdr hdr;           /* Wal-index header for current transaction */
--  const char *zWalName;      /* Name of WAL file */
--  u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
--#ifdef SQLITE_DEBUG
--  u8 lockError;              /* True if a locking error has occurred */
--#endif
--};
-+SQLITE_PRIVATE void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){
-+  assert( pPg->pgno!=iNew );
-+  pPg->flags = flags;
-+  sqlite3PcacheMove(pPg, iNew);
++SQLITE_API int sqlite3_fts_init(
++  sqlite3 *db,
++  char **pzErrMsg,
++  const sqlite3_api_routines *pApi
++){
++  SQLITE_EXTENSION_INIT2(pApi);
++  (void)pzErrMsg;  /* Unused parameter */
++  return fts5Init(db);
 +}
- 
- /*
--** Candidate values for Wal.exclusiveMode.
-+** Return a pointer to the data for the specified page.
- */
--#define WAL_NORMAL_MODE     0
--#define WAL_EXCLUSIVE_MODE  1     
--#define WAL_HEAPMEMORY_MODE 2
-+SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){
-+  assert( pPg->nRef>0 || pPg->pPager->memDb );
-+  return pPg->pData;
++
++#ifdef _WIN32
++__declspec(dllexport)
++#endif
++SQLITE_API int sqlite3_fts5_init(
++  sqlite3 *db,
++  char **pzErrMsg,
++  const sqlite3_api_routines *pApi
++){
++  SQLITE_EXTENSION_INIT2(pApi);
++  (void)pzErrMsg;  /* Unused parameter */
++  return fts5Init(db);
 +}
- 
- /*
--** Possible values for WAL.readOnly
-+** Return a pointer to the Pager.nExtra bytes of "extra" space 
-+** allocated along with the specified page.
- */
--#define WAL_RDWR        0    /* Normal read/write connection */
--#define WAL_RDONLY      1    /* The WAL file is readonly */
--#define WAL_SHM_RDONLY  2    /* The SHM file is readonly */
-+SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){
-+  return pPg->pExtra;
++#else
++SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){
++  return fts5Init(db);
 +}
- 
- /*
--** Each page of the wal-index mapping contains a hash-table made up of
--** an array of HASHTABLE_NSLOT elements of the following type.
-+** Get/set the locking-mode for this pager. Parameter eMode must be one
-+** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or 
-+** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then
-+** the locking-mode is set to the value specified.
++#endif
++
++/*
++** 2014 May 31
 +**
-+** The returned value is either PAGER_LOCKINGMODE_NORMAL or
-+** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated)
-+** locking-mode.
- */
--typedef u16 ht_slot;
-+SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){
-+  assert( eMode==PAGER_LOCKINGMODE_QUERY
-+            || eMode==PAGER_LOCKINGMODE_NORMAL
-+            || eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
-+  assert( PAGER_LOCKINGMODE_QUERY<0 );
-+  assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 );
-+  assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) );
-+  if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){
-+    pPager->exclusiveMode = (u8)eMode;
-+  }
-+  return (int)pPager->exclusiveMode;
-+}
- 
- /*
--** This structure is used to implement an iterator that loops through
--** all frames in the WAL in database page order. Where two or more frames
--** correspond to the same database page, the iterator visits only the 
--** frame most recently written to the WAL (in other words, the frame with
--** the largest index).
-+** Set the journal-mode for this pager. Parameter eMode must be one of:
- **
--** The internals of this structure are only accessed by:
-+**    PAGER_JOURNALMODE_DELETE
-+**    PAGER_JOURNALMODE_TRUNCATE
-+**    PAGER_JOURNALMODE_PERSIST
-+**    PAGER_JOURNALMODE_OFF
-+**    PAGER_JOURNALMODE_MEMORY
-+**    PAGER_JOURNALMODE_WAL
- **
--**   walIteratorInit() - Create a new iterator,
--**   walIteratorNext() - Step an iterator,
--**   walIteratorFree() - Free an iterator.
-+** The journalmode is set to the value specified if the change is allowed.
-+** The change may be disallowed for the following reasons:
- **
--** This functionality is used by the checkpoint code (see walCheckpoint()).
--*/
--struct WalIterator {
--  int iPrior;                     /* Last result returned from the iterator */
--  int nSegment;                   /* Number of entries in aSegment[] */
--  struct WalSegment {
--    int iNext;                    /* Next slot in aIndex[] not yet returned */
--    ht_slot *aIndex;              /* i0, i1, i2... such that aPgno[iN] ascend */
--    u32 *aPgno;                   /* Array of page numbers. */
--    int nEntry;                   /* Nr. of entries in aPgno[] and aIndex[] */
--    int iZero;                    /* Frame number associated with aPgno[0] */
--  } aSegment[1];                  /* One for every 32KB page in the wal-index */
--};
--
--/*
--** Define the parameters of the hash tables in the wal-index file. There
--** is a hash-table following every HASHTABLE_NPAGE page numbers in the
--** wal-index.
-+**   *  An in-memory database can only have its journal_mode set to _OFF
-+**      or _MEMORY.
- **
--** Changing any of these constants will alter the wal-index format and
--** create incompatibilities.
-+**   *  Temporary databases cannot have _WAL journalmode.
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
 +**
-+** The returned indicate the current (possibly updated) journal-mode.
- */
--#define HASHTABLE_NPAGE      4096                 /* Must be power of 2 */
--#define HASHTABLE_HASH_1     383                  /* Should be prime */
--#define HASHTABLE_NSLOT      (HASHTABLE_NPAGE*2)  /* Must be a power of 2 */
-+SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
-+  u8 eOld = pPager->journalMode;    /* Prior journalmode */
- 
--/* 
--** The block of page numbers associated with the first hash-table in a
--** wal-index is smaller than usual. This is so that there is a complete
--** hash-table on each aligned 32KB page of the wal-index.
--*/
--#define HASHTABLE_NPAGE_ONE  (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32)))
-+#ifdef SQLITE_DEBUG
-+  /* The print_pager_state() routine is intended to be used by the debugger
-+  ** only.  We invoke it once here to suppress a compiler warning. */
-+  print_pager_state(pPager);
-+#endif
- 
--/* The wal-index is divided into pages of WALINDEX_PGSZ bytes each. */
--#define WALINDEX_PGSZ   (                                         \
--    sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \
--)
- 
--/*
--** Obtain a pointer to the iPage'th page of the wal-index. The wal-index
--** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are
--** numbered from zero.
--**
--** If this call is successful, *ppPage is set to point to the wal-index
--** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
--** then an SQLite error code is returned and *ppPage is set to 0.
--*/
--static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
--  int rc = SQLITE_OK;
-+  /* The eMode parameter is always valid */
-+  assert(      eMode==PAGER_JOURNALMODE_DELETE
-+            || eMode==PAGER_JOURNALMODE_TRUNCATE
-+            || eMode==PAGER_JOURNALMODE_PERSIST
-+            || eMode==PAGER_JOURNALMODE_OFF 
-+            || eMode==PAGER_JOURNALMODE_WAL 
-+            || eMode==PAGER_JOURNALMODE_MEMORY );
- 
--  /* Enlarge the pWal->apWiData[] array if required */
--  if( pWal->nWiData<=iPage ){
--    int nByte = sizeof(u32*)*(iPage+1);
--    volatile u32 **apNew;
--    apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
--    if( !apNew ){
--      *ppPage = 0;
--      return SQLITE_NOMEM;
-+  /* This routine is only called from the OP_JournalMode opcode, and
-+  ** the logic there will never allow a temporary file to be changed
-+  ** to WAL mode.
-+  */
-+  assert( pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL );
++**    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.
++**
++******************************************************************************
++**
++*/
 +
-+  /* Do allow the journalmode of an in-memory database to be set to
-+  ** anything other than MEMORY or OFF
-+  */
-+  if( MEMDB ){
-+    assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF );
-+    if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){
-+      eMode = eOld;
-     }
--    memset((void*)&apNew[pWal->nWiData], 0,
--           sizeof(u32*)*(iPage+1-pWal->nWiData));
--    pWal->apWiData = apNew;
--    pWal->nWiData = iPage+1;
-   }
- 
--  /* Request a pointer to the required page from the VFS */
--  if( pWal->apWiData[iPage]==0 ){
--    if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
--      pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
--      if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM;
--    }else{
--      rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
--          pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
--      );
--      if( rc==SQLITE_READONLY ){
--        pWal->readOnly |= WAL_SHM_RDONLY;
--        rc = SQLITE_OK;
-+  if( eMode!=eOld ){
-+
-+    /* Change the journal mode. */
-+    assert( pPager->eState!=PAGER_ERROR );
-+    pPager->journalMode = (u8)eMode;
-+
-+    /* When transistioning from TRUNCATE or PERSIST to any other journal
-+    ** mode except WAL, unless the pager is in locking_mode=exclusive mode,
-+    ** delete the journal file.
-+    */
-+    assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
-+    assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 );
-+    assert( (PAGER_JOURNALMODE_DELETE & 5)==0 );
-+    assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 );
-+    assert( (PAGER_JOURNALMODE_OFF & 5)==0 );
-+    assert( (PAGER_JOURNALMODE_WAL & 5)==5 );
-+
-+    assert( isOpen(pPager->fd) || pPager->exclusiveMode );
-+    if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){
-+
-+      /* In this case we would like to delete the journal file. If it is
-+      ** not possible, then that is not a problem. Deleting the journal file
-+      ** here is an optimization only.
-+      **
-+      ** Before deleting the journal file, obtain a RESERVED lock on the
-+      ** database file. This ensures that the journal file is not deleted
-+      ** while it is in use by some other client.
-+      */
-+      sqlite3OsClose(pPager->jfd);
-+      if( pPager->eLock>=RESERVED_LOCK ){
-+        sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
-+      }else{
-+        int rc = SQLITE_OK;
-+        int state = pPager->eState;
-+        assert( state==PAGER_OPEN || state==PAGER_READER );
-+        if( state==PAGER_OPEN ){
-+          rc = sqlite3PagerSharedLock(pPager);
-+        }
-+        if( pPager->eState==PAGER_READER ){
-+          assert( rc==SQLITE_OK );
-+          rc = pagerLockDb(pPager, RESERVED_LOCK);
-+        }
-+        if( rc==SQLITE_OK ){
-+          sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
-+        }
-+        if( rc==SQLITE_OK && state==PAGER_READER ){
-+          pagerUnlockDb(pPager, SHARED_LOCK);
-+        }else if( state==PAGER_OPEN ){
-+          pager_unlock(pPager);
-+        }
-+        assert( state==pPager->eState );
-       }
-+    }else if( eMode==PAGER_JOURNALMODE_OFF ){
-+      sqlite3OsClose(pPager->jfd);
-     }
-   }
- 
--  *ppPage = pWal->apWiData[iPage];
--  assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
--  return rc;
-+  /* Return the new journal mode */
-+  return (int)pPager->journalMode;
- }
- 
- /*
--** Return a pointer to the WalCkptInfo structure in the wal-index.
-+** Return the current journal mode.
- */
--static volatile WalCkptInfo *walCkptInfo(Wal *pWal){
--  assert( pWal->nWiData>0 && pWal->apWiData[0] );
--  return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]);
-+SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){
-+  return (int)pPager->journalMode;
- }
- 
- /*
--** Return a pointer to the WalIndexHdr structure in the wal-index.
-+** Return TRUE if the pager is in a state where it is OK to change the
-+** journalmode.  Journalmode changes can only happen when the database
-+** is unmodified.
- */
--static volatile WalIndexHdr *walIndexHdr(Wal *pWal){
--  assert( pWal->nWiData>0 && pWal->apWiData[0] );
--  return (volatile WalIndexHdr*)pWal->apWiData[0];
-+SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){
-+  assert( assert_pager_state(pPager) );
-+  if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0;
-+  if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0;
-+  return 1;
- }
- 
- /*
--** The argument to this macro must be of type u32. On a little-endian
--** architecture, it returns the u32 value that results from interpreting
--** the 4 bytes as a big-endian value. On a big-endian architecture, it
--** returns the value that would be produced by interpreting the 4 bytes
--** of the input value as a little-endian integer.
--*/
--#define BYTESWAP32(x) ( \
--    (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8)  \
--  + (((x)&0x00FF0000)>>8)  + (((x)&0xFF000000)>>24) \
--)
--
--/*
--** Generate or extend an 8 byte checksum based on the data in 
--** array aByte[] and the initial values of aIn[0] and aIn[1] (or
--** initial values of 0 and 0 if aIn==NULL).
--**
--** The checksum is written back into aOut[] before returning.
-+** Get/set the size-limit used for persistent journal files.
- **
--** nByte must be a positive multiple of 8.
-+** Setting the size limit to -1 means no limit is enforced.
-+** An attempt to set a limit smaller than -1 is a no-op.
- */
--static void walChecksumBytes(
--  int nativeCksum, /* True for native byte-order, false for non-native */
--  u8 *a,           /* Content to be checksummed */
--  int nByte,       /* Bytes of content in a[].  Must be a multiple of 8. */
--  const u32 *aIn,  /* Initial checksum value input */
--  u32 *aOut        /* OUT: Final checksum value output */
--){
--  u32 s1, s2;
--  u32 *aData = (u32 *)a;
--  u32 *aEnd = (u32 *)&a[nByte];
--
--  if( aIn ){
--    s1 = aIn[0];
--    s2 = aIn[1];
--  }else{
--    s1 = s2 = 0;
--  }
--
--  assert( nByte>=8 );
--  assert( (nByte&0x00000007)==0 );
--
--  if( nativeCksum ){
--    do {
--      s1 += *aData++ + s2;
--      s2 += *aData++ + s1;
--    }while( aData<aEnd );
--  }else{
--    do {
--      s1 += BYTESWAP32(aData[0]) + s2;
--      s2 += BYTESWAP32(aData[1]) + s1;
--      aData += 2;
--    }while( aData<aEnd );
--  }
--
--  aOut[0] = s1;
--  aOut[1] = s2;
--}
--
--static void walShmBarrier(Wal *pWal){
--  if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
--    sqlite3OsShmBarrier(pWal->pDbFd);
-+SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
-+  if( iLimit>=-1 ){
-+    pPager->journalSizeLimit = iLimit;
-+    sqlite3WalLimit(pPager->pWal, iLimit);
-   }
-+  return pPager->journalSizeLimit;
- }
- 
- /*
--** Write the header information in pWal->hdr into the wal-index.
--**
--** The checksum on pWal->hdr is updated before it is written.
-+** Return a pointer to the pPager->pBackup variable. The backup module
-+** in backup.c maintains the content of this variable. This module
-+** uses it opaquely as an argument to sqlite3BackupRestart() and
-+** sqlite3BackupUpdate() only.
- */
--static void walIndexWriteHdr(Wal *pWal){
--  volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
--  const int nCksum = offsetof(WalIndexHdr, aCksum);
--
--  assert( pWal->writeLock );
--  pWal->hdr.isInit = 1;
--  pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
--  walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
--  memcpy((void *)&aHdr[1], (void *)&pWal->hdr, sizeof(WalIndexHdr));
--  walShmBarrier(pWal);
--  memcpy((void *)&aHdr[0], (void *)&pWal->hdr, sizeof(WalIndexHdr));
-+SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
-+  return &pPager->pBackup;
- }
- 
-+#ifndef SQLITE_OMIT_VACUUM
- /*
--** This function encodes a single frame header and writes it to a buffer
--** supplied by the caller. A frame-header is made up of a series of 
--** 4-byte big-endian integers, as follows:
--**
--**     0: Page number.
--**     4: For commit records, the size of the database image in pages 
--**        after the commit. For all other records, zero.
--**     8: Salt-1 (copied from the wal-header)
--**    12: Salt-2 (copied from the wal-header)
--**    16: Checksum-1.
--**    20: Checksum-2.
-+** Unless this is an in-memory or temporary database, clear the pager cache.
- */
--static void walEncodeFrame(
--  Wal *pWal,                      /* The write-ahead log */
--  u32 iPage,                      /* Database page number for frame */
--  u32 nTruncate,                  /* New db size (or 0 for non-commit frames) */
--  u8 *aData,                      /* Pointer to page data */
--  u8 *aFrame                      /* OUT: Write encoded frame here */
--){
--  int nativeCksum;                /* True for native byte-order checksums */
--  u32 *aCksum = pWal->hdr.aFrameCksum;
--  assert( WAL_FRAME_HDRSIZE==24 );
--  sqlite3Put4byte(&aFrame[0], iPage);
--  sqlite3Put4byte(&aFrame[4], nTruncate);
--  memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
--
--  nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
--  walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
--  walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
--
--  sqlite3Put4byte(&aFrame[16], aCksum[0]);
--  sqlite3Put4byte(&aFrame[20], aCksum[1]);
-+SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
-+  if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager);
- }
++
++
++/* #include "fts5Int.h" */
++
++struct Fts5Storage {
++  Fts5Config *pConfig;
++  Fts5Index *pIndex;
++  int bTotalsValid;               /* True if nTotalRow/aTotalSize[] are valid */
++  i64 nTotalRow;                  /* Total number of rows in FTS table */
++  i64 *aTotalSize;                /* Total sizes of each column */ 
++  sqlite3_stmt *aStmt[11];
++};
++
++
++#if FTS5_STMT_SCAN_ASC!=0 
++# error "FTS5_STMT_SCAN_ASC mismatch" 
 +#endif
- 
-+#ifndef SQLITE_OMIT_WAL
- /*
--** Check to see if the frame with header in aFrame[] and content
--** in aData[] is valid.  If it is a valid frame, fill *piPage and
--** *pnTruncate and return true.  Return if the frame is not valid.
-+** This function is called when the user invokes "PRAGMA wal_checkpoint",
-+** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint()
-+** or wal_blocking_checkpoint() API functions.
-+**
-+** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
- */
--static int walDecodeFrame(
--  Wal *pWal,                      /* The write-ahead log */
--  u32 *piPage,                    /* OUT: Database page number for frame */
--  u32 *pnTruncate,                /* OUT: New db size (or 0 if not commit) */
--  u8 *aData,                      /* Pointer to page data (for checksum) */
--  u8 *aFrame                      /* Frame data */
--){
--  int nativeCksum;                /* True for native byte-order checksums */
--  u32 *aCksum = pWal->hdr.aFrameCksum;
--  u32 pgno;                       /* Page number of the frame */
--  assert( WAL_FRAME_HDRSIZE==24 );
--
--  /* A frame is only valid if the salt values in the frame-header
--  ** match the salt values in the wal-header. 
--  */
--  if( memcmp(&pWal->hdr.aSalt, &aFrame[8], 8)!=0 ){
--    return 0;
--  }
--
--  /* A frame is only valid if the page number is creater than zero.
--  */
--  pgno = sqlite3Get4byte(&aFrame[0]);
--  if( pgno==0 ){
--    return 0;
--  }
--
--  /* A frame is only valid if a checksum of the WAL header,
--  ** all prior frams, the first 16 bytes of this frame-header, 
--  ** and the frame-data matches the checksum in the last 8 
--  ** bytes of this frame-header.
--  */
--  nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
--  walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
--  walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
--  if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) 
--   || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) 
--  ){
--    /* Checksum failed. */
--    return 0;
-+SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
-+  int rc = SQLITE_OK;
-+  if( pPager->pWal ){
-+    rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
-+        (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
-+        pPager->pBusyHandlerArg,
-+        pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
-+        pnLog, pnCkpt
-+    );
-   }
--
--  /* If we reach this point, the frame is valid.  Return the page number
--  ** and the new database size.
--  */
--  *piPage = pgno;
--  *pnTruncate = sqlite3Get4byte(&aFrame[4]);
--  return 1;
-+  return rc;
- }
- 
--
--#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
--/*
--** Names of locks.  This routine is used to provide debugging output and is not
--** a part of an ordinary build.
--*/
--static const char *walLockName(int lockIdx){
--  if( lockIdx==WAL_WRITE_LOCK ){
--    return "WRITE-LOCK";
--  }else if( lockIdx==WAL_CKPT_LOCK ){
--    return "CKPT-LOCK";
--  }else if( lockIdx==WAL_RECOVER_LOCK ){
--    return "RECOVER-LOCK";
--  }else{
--    static char zName[15];
--    sqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]",
--                     lockIdx-WAL_READ_LOCK(0));
--    return zName;
--  }
-+SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
-+  return sqlite3WalCallback(pPager->pWal);
- }
--#endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */
--    
- 
- /*
--** Set or release locks on the WAL.  Locks are either shared or exclusive.
--** A lock cannot be moved directly between shared and exclusive - it must go
--** through the unlocked state first.
--**
--** In locking_mode=EXCLUSIVE, all of these routines become no-ops.
-+** Return true if the underlying VFS for the given pager supports the
-+** primitives necessary for write-ahead logging.
- */
--static int walLockShared(Wal *pWal, int lockIdx){
--  int rc;
--  if( pWal->exclusiveMode ) return SQLITE_OK;
--  rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
--                        SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
--  WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
--            walLockName(lockIdx), rc ? "failed" : "ok"));
--  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
--  return rc;
--}
--static void walUnlockShared(Wal *pWal, int lockIdx){
--  if( pWal->exclusiveMode ) return;
--  (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
--                         SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
--  WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
-+SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){
-+  const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
-+  return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap);
- }
--static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){
--  int rc;
--  if( pWal->exclusiveMode ) return SQLITE_OK;
--  if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0);
--  rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
--                        SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
--  WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
--            walLockName(lockIdx), n, rc ? "failed" : "ok"));
--  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
++#if FTS5_STMT_SCAN_DESC!=1 
++# error "FTS5_STMT_SCAN_DESC mismatch" 
++#endif
++#if FTS5_STMT_LOOKUP!=2
++# error "FTS5_STMT_LOOKUP mismatch" 
++#endif
++
++#define FTS5_STMT_INSERT_CONTENT  3
++#define FTS5_STMT_REPLACE_CONTENT 4
++#define FTS5_STMT_DELETE_CONTENT  5
++#define FTS5_STMT_REPLACE_DOCSIZE  6
++#define FTS5_STMT_DELETE_DOCSIZE  7
++#define FTS5_STMT_LOOKUP_DOCSIZE  8
++#define FTS5_STMT_REPLACE_CONFIG 9
++#define FTS5_STMT_SCAN 10
 +
 +/*
-+** Attempt to take an exclusive lock on the database file. If a PENDING lock
-+** is obtained instead, immediately release it.
++** Prepare the two insert statements - Fts5Storage.pInsertContent and
++** Fts5Storage.pInsertDocsize - if they have not already been prepared.
++** Return SQLITE_OK if successful, or an SQLite error code if an error
++** occurs.
 +*/
-+static int pagerExclusiveLock(Pager *pPager){
-+  int rc;                         /* Return code */
++static int fts5StorageGetStmt(
++  Fts5Storage *p,                 /* Storage handle */
++  int eStmt,                      /* FTS5_STMT_XXX constant */
++  sqlite3_stmt **ppStmt,          /* OUT: Prepared statement handle */
++  char **pzErrMsg                 /* OUT: Error message (if any) */
++){
++  int rc = SQLITE_OK;
 +
-+  assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
-+  rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
-+  if( rc!=SQLITE_OK ){
-+    /* If the attempt to grab the exclusive lock failed, release the 
-+    ** pending lock that may have been obtained instead.  */
-+    pagerUnlockDb(pPager, SHARED_LOCK);
++  /* If there is no %_docsize table, there should be no requests for 
++  ** statements to operate on it.  */
++  assert( p->pConfig->bColumnsize || (
++        eStmt!=FTS5_STMT_REPLACE_DOCSIZE 
++     && eStmt!=FTS5_STMT_DELETE_DOCSIZE 
++     && eStmt!=FTS5_STMT_LOOKUP_DOCSIZE 
++  ));
++
++  assert( eStmt>=0 && eStmt<ArraySize(p->aStmt) );
++  if( p->aStmt[eStmt]==0 ){
++    const char *azStmt[] = {
++      "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC",
++      "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC",
++      "SELECT %s FROM %s T WHERE T.%Q=?",               /* LOOKUP  */
++
++      "INSERT INTO %Q.'%q_content' VALUES(%s)",         /* INSERT_CONTENT  */
++      "REPLACE INTO %Q.'%q_content' VALUES(%s)",        /* REPLACE_CONTENT */
++      "DELETE FROM %Q.'%q_content' WHERE id=?",         /* DELETE_CONTENT  */
++      "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)",       /* REPLACE_DOCSIZE  */
++      "DELETE FROM %Q.'%q_docsize' WHERE id=?",         /* DELETE_DOCSIZE  */
++
++      "SELECT sz FROM %Q.'%q_docsize' WHERE id=?",      /* LOOKUP_DOCSIZE  */
++
++      "REPLACE INTO %Q.'%q_config' VALUES(?,?)",        /* REPLACE_CONFIG */
++      "SELECT %s FROM %s AS T",                         /* SCAN */
++    };
++    Fts5Config *pC = p->pConfig;
++    char *zSql = 0;
++
++    switch( eStmt ){
++      case FTS5_STMT_SCAN:
++        zSql = sqlite3_mprintf(azStmt[eStmt], 
++            pC->zContentExprlist, pC->zContent
++        );
++        break;
++
++      case FTS5_STMT_SCAN_ASC:
++      case FTS5_STMT_SCAN_DESC:
++        zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, 
++            pC->zContent, pC->zContentRowid, pC->zContentRowid,
++            pC->zContentRowid
++        );
++        break;
++
++      case FTS5_STMT_LOOKUP:
++        zSql = sqlite3_mprintf(azStmt[eStmt], 
++            pC->zContentExprlist, pC->zContent, pC->zContentRowid
++        );
++        break;
++
++      case FTS5_STMT_INSERT_CONTENT: 
++      case FTS5_STMT_REPLACE_CONTENT: {
++        int nCol = pC->nCol + 1;
++        char *zBind;
++        int i;
++
++        zBind = sqlite3_malloc(1 + nCol*2);
++        if( zBind ){
++          for(i=0; i<nCol; i++){
++            zBind[i*2] = '?';
++            zBind[i*2 + 1] = ',';
++          }
++          zBind[i*2-1] = '\0';
++          zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind);
++          sqlite3_free(zBind);
++        }
++        break;
++      }
++
++      default:
++        zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName);
++        break;
++    }
++
++    if( zSql==0 ){
++      rc = SQLITE_NOMEM;
++    }else{
++      rc = sqlite3_prepare_v3(pC->db, zSql, -1,
++                              SQLITE_PREPARE_PERSISTENT, &p->aStmt[eStmt], 0);
++      sqlite3_free(zSql);
++      if( rc!=SQLITE_OK && pzErrMsg ){
++        *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
++      }
++    }
++  }
++
++  *ppStmt = p->aStmt[eStmt];
++  sqlite3_reset(*ppStmt);
++  return rc;
++}
++
++
++static int fts5ExecPrintf(
++  sqlite3 *db,
++  char **pzErr,
++  const char *zFormat,
++  ...
++){
++  int rc;
++  va_list ap;                     /* ... printf arguments */
++  char *zSql;
++
++  va_start(ap, zFormat);
++  zSql = sqlite3_vmprintf(zFormat, ap);
++
++  if( zSql==0 ){
++    rc = SQLITE_NOMEM;
++  }else{
++    rc = sqlite3_exec(db, zSql, 0, 0, pzErr);
++    sqlite3_free(zSql);
++  }
++
++  va_end(ap);
++  return rc;
++}
++
++/*
++** Drop all shadow tables. Return SQLITE_OK if successful or an SQLite error
++** code otherwise.
++*/
++static int sqlite3Fts5DropAll(Fts5Config *pConfig){
++  int rc = fts5ExecPrintf(pConfig->db, 0, 
++      "DROP TABLE IF EXISTS %Q.'%q_data';"
++      "DROP TABLE IF EXISTS %Q.'%q_idx';"
++      "DROP TABLE IF EXISTS %Q.'%q_config';",
++      pConfig->zDb, pConfig->zName,
++      pConfig->zDb, pConfig->zName,
++      pConfig->zDb, pConfig->zName
++  );
++  if( rc==SQLITE_OK && pConfig->bColumnsize ){
++    rc = fts5ExecPrintf(pConfig->db, 0, 
++        "DROP TABLE IF EXISTS %Q.'%q_docsize';",
++        pConfig->zDb, pConfig->zName
++    );
++  }
++  if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
++    rc = fts5ExecPrintf(pConfig->db, 0, 
++        "DROP TABLE IF EXISTS %Q.'%q_content';",
++        pConfig->zDb, pConfig->zName
++    );
 +  }
++  return rc;
++}
 +
-   return rc;
- }
--static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
--  if( pWal->exclusiveMode ) return;
--  (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
--                         SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE);
--  WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal,
--             walLockName(lockIdx), n));
--}
- 
- /*
--** Compute a hash on a page number.  The resulting hash value must land
--** between 0 and (HASHTABLE_NSLOT-1).  The walHashNext() function advances
--** the hash to the next value in the event of a collision.
-+** Call sqlite3WalOpen() to open the WAL handle. If the pager is in 
-+** exclusive-locking mode when this function is called, take an EXCLUSIVE
-+** lock on the database file and use heap-memory to store the wal-index
-+** in. Otherwise, use the normal shared-memory.
- */
--static int walHash(u32 iPage){
--  assert( iPage>0 );
--  assert( (HASHTABLE_NSLOT & (HASHTABLE_NSLOT-1))==0 );
--  return (iPage*HASHTABLE_HASH_1) & (HASHTABLE_NSLOT-1);
--}
--static int walNextHash(int iPriorHash){
--  return (iPriorHash+1)&(HASHTABLE_NSLOT-1);
-+static int pagerOpenWal(Pager *pPager){
-+  int rc = SQLITE_OK;
++static void fts5StorageRenameOne(
++  Fts5Config *pConfig,            /* Current FTS5 configuration */
++  int *pRc,                       /* IN/OUT: Error code */
++  const char *zTail,              /* Tail of table name e.g. "data", "config" */
++  const char *zName               /* New name of FTS5 table */
++){
++  if( *pRc==SQLITE_OK ){
++    *pRc = fts5ExecPrintf(pConfig->db, 0, 
++        "ALTER TABLE %Q.'%q_%s' RENAME TO '%q_%s';",
++        pConfig->zDb, pConfig->zName, zTail, zName, zTail
++    );
++  }
++}
 +
-+  assert( pPager->pWal==0 && pPager->tempFile==0 );
-+  assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
++static int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){
++  Fts5Config *pConfig = pStorage->pConfig;
++  int rc = sqlite3Fts5StorageSync(pStorage);
 +
-+  /* If the pager is already in exclusive-mode, the WAL module will use 
-+  ** heap-memory for the wal-index instead of the VFS shared-memory 
-+  ** implementation. Take the exclusive lock now, before opening the WAL
-+  ** file, to make sure this is safe.
-+  */
-+  if( pPager->exclusiveMode ){
-+    rc = pagerExclusiveLock(pPager);
++  fts5StorageRenameOne(pConfig, &rc, "data", zName);
++  fts5StorageRenameOne(pConfig, &rc, "idx", zName);
++  fts5StorageRenameOne(pConfig, &rc, "config", zName);
++  if( pConfig->bColumnsize ){
++    fts5StorageRenameOne(pConfig, &rc, "docsize", zName);
 +  }
++  if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
++    fts5StorageRenameOne(pConfig, &rc, "content", zName);
++  }
++  return rc;
++}
 +
-+  /* Open the connection to the log file. If this operation fails, 
-+  ** (e.g. due to malloc() failure), return an error code.
-+  */
-+  if( rc==SQLITE_OK ){
-+    rc = sqlite3WalOpen(pPager->pVfs,
-+        pPager->fd, pPager->zWal, pPager->exclusiveMode,
-+        pPager->journalSizeLimit, &pPager->pWal
++/*
++** Create the shadow table named zPost, with definition zDefn. Return
++** SQLITE_OK if successful, or an SQLite error code otherwise.
++*/
++static int sqlite3Fts5CreateTable(
++  Fts5Config *pConfig,            /* FTS5 configuration */
++  const char *zPost,              /* Shadow table to create (e.g. "content") */
++  const char *zDefn,              /* Columns etc. for shadow table */
++  int bWithout,                   /* True for without rowid */
++  char **pzErr                    /* OUT: Error message */
++){
++  int rc;
++  char *zErr = 0;
++
++  rc = fts5ExecPrintf(pConfig->db, &zErr, "CREATE TABLE %Q.'%q_%q'(%s)%s",
++      pConfig->zDb, pConfig->zName, zPost, zDefn, 
++#ifndef SQLITE_FTS5_NO_WITHOUT_ROWID
++      bWithout?" WITHOUT ROWID":
++#endif
++      ""
++  );
++  if( zErr ){
++    *pzErr = sqlite3_mprintf(
++        "fts5: error creating shadow table %q_%s: %s", 
++        pConfig->zName, zPost, zErr
 +    );
++    sqlite3_free(zErr);
 +  }
-+  pagerFixMaplimit(pPager);
 +
 +  return rc;
- }
- 
--/* 
--** Return pointers to the hash table and page number array stored on
--** page iHash of the wal-index. The wal-index is broken into 32KB pages
--** numbered starting from 0.
-+
-+/*
-+** The caller must be holding a SHARED lock on the database file to call
-+** this function.
- **
--** Set output variable *paHash to point to the start of the hash table
--** in the wal-index file. Set *piZero to one less than the frame 
--** number of the first frame indexed by this hash table. If a
--** slot in the hash table is set to N, it refers to frame number 
--** (*piZero+N) in the log.
-+** If the pager passed as the first argument is open on a real database
-+** file (not a temp file or an in-memory database), and the WAL file
-+** is not already open, make an attempt to open it now. If successful,
-+** return SQLITE_OK. If an error occurs or the VFS used by the pager does 
-+** not support the xShmXXX() methods, return an error code. *pbOpen is
-+** not modified in either case.
- **
--** Finally, set *paPgno so that *paPgno[1] is the page number of the
--** first frame indexed by the hash table, frame (*piZero+1).
-+** If the pager is open on a temp-file (or in-memory database), or if
-+** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK
-+** without doing anything.
- */
--static int walHashGet(
--  Wal *pWal,                      /* WAL handle */
--  int iHash,                      /* Find the iHash'th table */
--  volatile ht_slot **paHash,      /* OUT: Pointer to hash index */
--  volatile u32 **paPgno,          /* OUT: Pointer to page number array */
--  u32 *piZero                     /* OUT: Frame associated with *paPgno[0] */
-+SQLITE_PRIVATE int sqlite3PagerOpenWal(
-+  Pager *pPager,                  /* Pager object */
-+  int *pbOpen                     /* OUT: Set to true if call is a no-op */
- ){
--  int rc;                         /* Return code */
--  volatile u32 *aPgno;
-+  int rc = SQLITE_OK;             /* Return code */
- 
--  rc = walIndexPage(pWal, iHash, &aPgno);
--  assert( rc==SQLITE_OK || iHash>0 );
-+  assert( assert_pager_state(pPager) );
-+  assert( pPager->eState==PAGER_OPEN   || pbOpen );
-+  assert( pPager->eState==PAGER_READER || !pbOpen );
-+  assert( pbOpen==0 || *pbOpen==0 );
-+  assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) );
- 
--  if( rc==SQLITE_OK ){
--    u32 iZero;
--    volatile ht_slot *aHash;
-+  if( !pPager->tempFile && !pPager->pWal ){
-+    if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;
- 
--    aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE];
--    if( iHash==0 ){
--      aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
--      iZero = 0;
--    }else{
--      iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
-+    /* Close any rollback journal previously open */
-+    sqlite3OsClose(pPager->jfd);
-+
-+    rc = pagerOpenWal(pPager);
-+    if( rc==SQLITE_OK ){
-+      pPager->journalMode = PAGER_JOURNALMODE_WAL;
-+      pPager->eState = PAGER_OPEN;
-     }
--  
--    *paPgno = &aPgno[-1];
--    *paHash = aHash;
--    *piZero = iZero;
-+  }else{
-+    *pbOpen = 1;
-   }
++}
 +
-   return rc;
- }
- 
- /*
--** Return the number of the wal-index page that contains the hash-table
--** and page-number array that contain entries corresponding to WAL frame
--** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages 
--** are numbered starting from 0.
-+** This function is called to close the connection to the log file prior
-+** to switching from WAL to rollback mode.
++/*
++** Open a new Fts5Index handle. If the bCreate argument is true, create
++** and initialize the underlying tables 
 +**
-+** Before closing the log file, this function attempts to take an 
-+** EXCLUSIVE lock on the database file. If this cannot be obtained, an
-+** error (SQLITE_BUSY) is returned and the log connection is not closed.
-+** If successful, the EXCLUSIVE lock is not released before returning.
- */
--static int walFramePage(u32 iFrame){
--  int iHash = (iFrame+HASHTABLE_NPAGE-HASHTABLE_NPAGE_ONE-1) / HASHTABLE_NPAGE;
--  assert( (iHash==0 || iFrame>HASHTABLE_NPAGE_ONE)
--       && (iHash>=1 || iFrame<=HASHTABLE_NPAGE_ONE)
--       && (iHash<=1 || iFrame>(HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE))
--       && (iHash>=2 || iFrame<=HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE)
--       && (iHash<=2 || iFrame>(HASHTABLE_NPAGE_ONE+2*HASHTABLE_NPAGE))
--  );
--  return iHash;
--}
-+SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
++** If successful, set *pp to point to the new object and return SQLITE_OK.
++** Otherwise, set *pp to NULL and return an SQLite error code.
++*/
++static int sqlite3Fts5StorageOpen(
++  Fts5Config *pConfig, 
++  Fts5Index *pIndex, 
++  int bCreate, 
++  Fts5Storage **pp,
++  char **pzErr                    /* OUT: Error message */
++){
 +  int rc = SQLITE_OK;
- 
--/*
--** Return the page number associated with frame iFrame in this WAL.
--*/
--static u32 walFramePgno(Wal *pWal, u32 iFrame){
--  int iHash = walFramePage(iFrame);
--  if( iHash==0 ){
--    return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1];
-+  assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
-+
-+  /* If the log file is not already open, but does exist in the file-system,
-+  ** it may need to be checkpointed before the connection can switch to
-+  ** rollback mode. Open it now so this can happen.
-+  */
-+  if( !pPager->pWal ){
-+    int logexists = 0;
-+    rc = pagerLockDb(pPager, SHARED_LOCK);
-+    if( rc==SQLITE_OK ){
-+      rc = sqlite3OsAccess(
-+          pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists
++  Fts5Storage *p;                 /* New object */
++  int nByte;                      /* Bytes of space to allocate */
++
++  nByte = sizeof(Fts5Storage)               /* Fts5Storage object */
++        + pConfig->nCol * sizeof(i64);      /* Fts5Storage.aTotalSize[] */
++  *pp = p = (Fts5Storage*)sqlite3_malloc(nByte);
++  if( !p ) return SQLITE_NOMEM;
++
++  memset(p, 0, nByte);
++  p->aTotalSize = (i64*)&p[1];
++  p->pConfig = pConfig;
++  p->pIndex = pIndex;
++
++  if( bCreate ){
++    if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
++      int nDefn = 32 + pConfig->nCol*10;
++      char *zDefn = sqlite3_malloc(32 + pConfig->nCol * 10);
++      if( zDefn==0 ){
++        rc = SQLITE_NOMEM;
++      }else{
++        int i;
++        int iOff;
++        sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY");
++        iOff = (int)strlen(zDefn);
++        for(i=0; i<pConfig->nCol; i++){
++          sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i);
++          iOff += (int)strlen(&zDefn[iOff]);
++        }
++        rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr);
++      }
++      sqlite3_free(zDefn);
++    }
++
++    if( rc==SQLITE_OK && pConfig->bColumnsize ){
++      rc = sqlite3Fts5CreateTable(
++          pConfig, "docsize", "id INTEGER PRIMARY KEY, sz BLOB", 0, pzErr
 +      );
 +    }
-+    if( rc==SQLITE_OK && logexists ){
-+      rc = pagerOpenWal(pPager);
++    if( rc==SQLITE_OK ){
++      rc = sqlite3Fts5CreateTable(
++          pConfig, "config", "k PRIMARY KEY, v", 1, pzErr
++      );
 +    }
-   }
--  return pWal->apWiData[iHash][(iFrame-1-HASHTABLE_NPAGE_ONE)%HASHTABLE_NPAGE];
-+    
-+  /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on
-+  ** the database file, the log and log-summary files will be deleted.
-+  */
-+  if( rc==SQLITE_OK && pPager->pWal ){
-+    rc = pagerExclusiveLock(pPager);
 +    if( rc==SQLITE_OK ){
-+      rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
-+                           pPager->pageSize, (u8*)pPager->pTmpSpace);
-+      pPager->pWal = 0;
-+      pagerFixMaplimit(pPager);
++      rc = sqlite3Fts5StorageConfigValue(p, "version", 0, FTS5_CURRENT_VERSION);
 +    }
 +  }
-+  return rc;
- }
- 
-+#endif /* !SQLITE_OMIT_WAL */
 +
-+#ifdef SQLITE_ENABLE_ZIPVFS
- /*
--** Remove entries from the hash table that point to WAL slots greater
--** than pWal->hdr.mxFrame.
--**
--** This function is called whenever pWal->hdr.mxFrame is decreased due
--** to a rollback or savepoint.
--**
--** At most only the hash table containing pWal->hdr.mxFrame needs to be
--** updated.  Any later hash tables will be automatically cleared when
--** pWal->hdr.mxFrame advances to the point where those hash tables are
--** actually needed.
-+** A read-lock must be held on the pager when this function is called. If
-+** the pager is in WAL mode and the WAL file currently contains one or more
-+** frames, return the size in bytes of the page images stored within the
-+** WAL frames. Otherwise, if this is not a WAL database or the WAL file
-+** is empty, return 0.
- */
--static void walCleanupHash(Wal *pWal){
--  volatile ht_slot *aHash = 0;    /* Pointer to hash table to clear */
--  volatile u32 *aPgno = 0;        /* Page number array for hash table */
--  u32 iZero = 0;                  /* frame == (aHash[x]+iZero) */
--  int iLimit = 0;                 /* Zero values greater than this */
--  int nByte;                      /* Number of bytes to zero in aPgno[] */
--  int i;                          /* Used to iterate through aHash[] */
-+SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
-+  assert( pPager->eState>=PAGER_READER );
-+  return sqlite3WalFramesize(pPager->pWal);
-+}
-+#endif
- 
--  assert( pWal->writeLock );
--  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 );
--  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE );
--  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE+1 );
- 
--  if( pWal->hdr.mxFrame==0 ) return;
-+#endif /* SQLITE_OMIT_DISKIO */
- 
--  /* Obtain pointers to the hash-table and page-number array containing 
--  ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed
--  ** that the page said hash-table and array reside on is already mapped.
--  */
--  assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
--  assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
--  walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero);
-+/* BEGIN SQLCIPHER */
-+#ifdef SQLITE_HAS_CODEC
-+SQLITE_PRIVATE void sqlite3pager_get_codec(Pager *pPager, void **ctx) {
-+  *ctx = pPager->pCodec;
-+}
- 
--  /* Zero all hash-table entries that correspond to frame numbers greater
--  ** than pWal->hdr.mxFrame.
--  */
--  iLimit = pWal->hdr.mxFrame - iZero;
--  assert( iLimit>0 );
--  for(i=0; i<HASHTABLE_NSLOT; i++){
--    if( aHash[i]>iLimit ){
--      aHash[i] = 0;
--    }
--  }
--  
--  /* Zero the entries in the aPgno array that correspond to frames with
--  ** frame numbers greater than pWal->hdr.mxFrame. 
--  */
--  nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]);
--  memset((void *)&aPgno[iLimit+1], 0, nByte);
-+SQLITE_PRIVATE int sqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno) {
-+  return (PAGER_MJ_PGNO(pPager) == pgno) ? 1 : 0;
++  if( rc ){
++    sqlite3Fts5StorageClose(p);
++    *pp = 0;
++  }
++  return rc;
 +}
- 
--#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
--  /* Verify that the every entry in the mapping region is still reachable
--  ** via the hash table even after the cleanup.
--  */
--  if( iLimit ){
--    int i;           /* Loop counter */
--    int iKey;        /* Hash key */
--    for(i=1; i<=iLimit; i++){
--      for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
--        if( aHash[iKey]==i ) break;
--      }
--      assert( aHash[iKey]==i );
--    }
--  }
--#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
-+SQLITE_PRIVATE sqlite3_file *sqlite3Pager_get_fd(Pager *pPager) {
-+  return (isOpen(pPager->fd)) ? pPager->fd : NULL;
++
++/*
++** Close a handle opened by an earlier call to sqlite3Fts5StorageOpen().
++*/
++static int sqlite3Fts5StorageClose(Fts5Storage *p){
++  int rc = SQLITE_OK;
++  if( p ){
++    int i;
++
++    /* Finalize all SQL statements */
++    for(i=0; i<ArraySize(p->aStmt); i++){
++      sqlite3_finalize(p->aStmt[i]);
++    }
++
++    sqlite3_free(p);
++  }
++  return rc;
 +}
 +
-+SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetCodec(
-+  Pager *pPager,
-+  void *(*xCodec)(void*,void*,Pgno,int),
-+  void (*xCodecSizeChng)(void*,int,int),
-+  void (*xCodecFree)(void*),
-+  void *pCodec
++typedef struct Fts5InsertCtx Fts5InsertCtx;
++struct Fts5InsertCtx {
++  Fts5Storage *pStorage;
++  int iCol;
++  int szCol;                      /* Size of column value in tokens */
++};
++
++/*
++** Tokenization callback used when inserting tokens into the FTS index.
++*/
++static int fts5StorageInsertCallback(
++  void *pContext,                 /* Pointer to Fts5InsertCtx object */
++  int tflags,
++  const char *pToken,             /* Buffer containing token */
++  int nToken,                     /* Size of token in bytes */
++  int iUnused1,                   /* Start offset of token */
++  int iUnused2                    /* End offset of token */
 +){
-+  sqlite3PagerSetCodec(pPager, xCodec, xCodecSizeChng, xCodecFree, pCodec); 
++  Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext;
++  Fts5Index *pIdx = pCtx->pStorage->pIndex;
++  UNUSED_PARAM2(iUnused1, iUnused2);
++  if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
++  if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
++    pCtx->szCol++;
++  }
++  return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken);
 +}
 +
-+SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetError( Pager *pPager, int error) {
-+  pPager->errCode = error;
- }
- 
-+#endif
-+/* END SQLCIPHER */
++/*
++** If a row with rowid iDel is present in the %_content table, add the
++** delete-markers to the FTS index necessary to delete it. Do not actually
++** remove the %_content row at this time though.
++*/
++static int fts5StorageDeleteFromIndex(
++  Fts5Storage *p, 
++  i64 iDel, 
++  sqlite3_value **apVal
++){
++  Fts5Config *pConfig = p->pConfig;
++  sqlite3_stmt *pSeek = 0;        /* SELECT to read row iDel from %_data */
++  int rc;                         /* Return code */
++  int rc2;                        /* sqlite3_reset() return code */
++  int iCol;
++  Fts5InsertCtx ctx;
++
++  if( apVal==0 ){
++    rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0);
++    if( rc!=SQLITE_OK ) return rc;
++    sqlite3_bind_int64(pSeek, 1, iDel);
++    if( sqlite3_step(pSeek)!=SQLITE_ROW ){
++      return sqlite3_reset(pSeek);
++    }
++  }
++
++  ctx.pStorage = p;
++  ctx.iCol = -1;
++  rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
++  for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
++    if( pConfig->abUnindexed[iCol-1]==0 ){
++      const char *zText;
++      int nText;
++      if( pSeek ){
++        zText = (const char*)sqlite3_column_text(pSeek, iCol);
++        nText = sqlite3_column_bytes(pSeek, iCol);
++      }else{
++        zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
++        nText = sqlite3_value_bytes(apVal[iCol-1]);
++      }
++      ctx.szCol = 0;
++      rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, 
++          zText, nText, (void*)&ctx, fts5StorageInsertCallback
++      );
++      p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
++    }
++  }
++  p->nTotalRow--;
++
++  rc2 = sqlite3_reset(pSeek);
++  if( rc==SQLITE_OK ) rc = rc2;
++  return rc;
++}
 +
 +
-+/************** End of pager.c ***********************************************/
-+/************** Begin file wal.c *********************************************/
 +/*
-+** 2010 February 1
-+**
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
-+**
-+**    May you do good and not evil.
-+**    May you find forgiveness for yourself and forgive others.
-+**    May you share freely, never taking more than you give.
++** Insert a record into the %_docsize table. Specifically, do:
 +**
-+*************************************************************************
++**   INSERT OR REPLACE INTO %_docsize(id, sz) VALUES(iRowid, pBuf);
 +**
-+** This file contains the implementation of a write-ahead log (WAL) used in 
-+** "journal_mode=WAL" mode.
-+**
-+** WRITE-AHEAD LOG (WAL) FILE FORMAT
-+**
-+** A WAL file consists of a header followed by zero or more "frames".
-+** Each frame records the revised content of a single page from the
-+** database file.  All changes to the database are recorded by writing
-+** frames into the WAL.  Transactions commit when a frame is written that
-+** contains a commit marker.  A single WAL can and usually does record 
-+** multiple transactions.  Periodically, the content of the WAL is
-+** transferred back into the database file in an operation called a
-+** "checkpoint".
-+**
-+** A single WAL file can be used multiple times.  In other words, the
-+** WAL can fill up with frames and then be checkpointed and then new
-+** frames can overwrite the old ones.  A WAL always grows from beginning
-+** toward the end.  Checksums and counters attached to each frame are
-+** used to determine which frames within the WAL are valid and which
-+** are leftovers from prior checkpoints.
-+**
-+** The WAL header is 32 bytes in size and consists of the following eight
-+** big-endian 32-bit unsigned integer values:
-+**
-+**     0: Magic number.  0x377f0682 or 0x377f0683
-+**     4: File format version.  Currently 3007000
-+**     8: Database page size.  Example: 1024
-+**    12: Checkpoint sequence number
-+**    16: Salt-1, random integer incremented with each checkpoint
-+**    20: Salt-2, a different random integer changing with each ckpt
-+**    24: Checksum-1 (first part of checksum for first 24 bytes of header).
-+**    28: Checksum-2 (second part of checksum for first 24 bytes of header).
-+**
-+** Immediately following the wal-header are zero or more frames. Each
-+** frame consists of a 24-byte frame-header followed by a <page-size> bytes
-+** of page data. The frame-header is six big-endian 32-bit unsigned 
-+** integer values, as follows:
-+**
-+**     0: Page number.
-+**     4: For commit records, the size of the database image in pages 
-+**        after the commit. For all other records, zero.
-+**     8: Salt-1 (copied from the header)
-+**    12: Salt-2 (copied from the header)
-+**    16: Checksum-1.
-+**    20: Checksum-2.
-+**
-+** A frame is considered valid if and only if the following conditions are
-+** true:
-+**
-+**    (1) The salt-1 and salt-2 values in the frame-header match
-+**        salt values in the wal-header
-+**
-+**    (2) The checksum values in the final 8 bytes of the frame-header
-+**        exactly match the checksum computed consecutively on the
-+**        WAL header and the first 8 bytes and the content of all frames
-+**        up to and including the current frame.
-+**
-+** The checksum is computed using 32-bit big-endian integers if the
-+** magic number in the first 4 bytes of the WAL is 0x377f0683 and it
-+** is computed using little-endian if the magic number is 0x377f0682.
-+** The checksum values are always stored in the frame header in a
-+** big-endian format regardless of which byte order is used to compute
-+** the checksum.  The checksum is computed by interpreting the input as
-+** an even number of unsigned 32-bit integers: x[0] through x[N].  The
-+** algorithm used for the checksum is as follows:
-+** 
-+**   for i from 0 to n-1 step 2:
-+**     s0 += x[i] + s1;
-+**     s1 += x[i+1] + s0;
-+**   endfor
-+**
-+** Note that s0 and s1 are both weighted checksums using fibonacci weights
-+** in reverse order (the largest fibonacci weight occurs on the first element
-+** of the sequence being summed.)  The s1 value spans all 32-bit 
-+** terms of the sequence whereas s0 omits the final term.
-+**
-+** On a checkpoint, the WAL is first VFS.xSync-ed, then valid content of the
-+** WAL is transferred into the database, then the database is VFS.xSync-ed.
-+** The VFS.xSync operations serve as write barriers - all writes launched
-+** before the xSync must complete before any write that launches after the
-+** xSync begins.
-+**
-+** After each checkpoint, the salt-1 value is incremented and the salt-2
-+** value is randomized.  This prevents old and new frames in the WAL from
-+** being considered valid at the same time and being checkpointing together
-+** following a crash.
-+**
-+** READER ALGORITHM
-+**
-+** To read a page from the database (call it page number P), a reader
-+** first checks the WAL to see if it contains page P.  If so, then the
-+** last valid instance of page P that is a followed by a commit frame
-+** or is a commit frame itself becomes the value read.  If the WAL
-+** contains no copies of page P that are valid and which are a commit
-+** frame or are followed by a commit frame, then page P is read from
-+** the database file.
-+**
-+** To start a read transaction, the reader records the index of the last
-+** valid frame in the WAL.  The reader uses this recorded "mxFrame" value
-+** for all subsequent read operations.  New transactions can be appended
-+** to the WAL, but as long as the reader uses its original mxFrame value
-+** and ignores the newly appended content, it will see a consistent snapshot
-+** of the database from a single point in time.  This technique allows
-+** multiple concurrent readers to view different versions of the database
-+** content simultaneously.
-+**
-+** The reader algorithm in the previous paragraphs works correctly, but 
-+** because frames for page P can appear anywhere within the WAL, the
-+** reader has to scan the entire WAL looking for page P frames.  If the
-+** WAL is large (multiple megabytes is typical) that scan can be slow,
-+** and read performance suffers.  To overcome this problem, a separate
-+** data structure called the wal-index is maintained to expedite the
-+** search for frames of a particular page.
-+** 
-+** WAL-INDEX FORMAT
-+**
-+** Conceptually, the wal-index is shared memory, though VFS implementations
-+** might choose to implement the wal-index using a mmapped file.  Because
-+** the wal-index is shared memory, SQLite does not support journal_mode=WAL 
-+** on a network filesystem.  All users of the database must be able to
-+** share memory.
-+**
-+** The wal-index is transient.  After a crash, the wal-index can (and should
-+** be) reconstructed from the original WAL file.  In fact, the VFS is required
-+** to either truncate or zero the header of the wal-index when the last
-+** connection to it closes.  Because the wal-index is transient, it can
-+** use an architecture-specific format; it does not have to be cross-platform.
-+** Hence, unlike the database and WAL file formats which store all values
-+** as big endian, the wal-index can store multi-byte values in the native
-+** byte order of the host computer.
-+**
-+** The purpose of the wal-index is to answer this question quickly:  Given
-+** a page number P and a maximum frame index M, return the index of the 
-+** last frame in the wal before frame M for page P in the WAL, or return
-+** NULL if there are no frames for page P in the WAL prior to M.
-+**
-+** The wal-index consists of a header region, followed by an one or
-+** more index blocks.  
-+**
-+** The wal-index header contains the total number of frames within the WAL
-+** in the mxFrame field.
-+**
-+** Each index block except for the first contains information on 
-+** HASHTABLE_NPAGE frames. The first index block contains information on
-+** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and 
-+** HASHTABLE_NPAGE are selected so that together the wal-index header and
-+** first index block are the same size as all other index blocks in the
-+** wal-index.
-+**
-+** Each index block contains two sections, a page-mapping that contains the
-+** database page number associated with each wal frame, and a hash-table 
-+** that allows readers to query an index block for a specific page number.
-+** The page-mapping is an array of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE
-+** for the first index block) 32-bit page numbers. The first entry in the 
-+** first index-block contains the database page number corresponding to the
-+** first frame in the WAL file. The first entry in the second index block
-+** in the WAL file corresponds to the (HASHTABLE_NPAGE_ONE+1)th frame in
-+** the log, and so on.
-+**
-+** The last index block in a wal-index usually contains less than the full
-+** complement of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE) page-numbers,
-+** depending on the contents of the WAL file. This does not change the
-+** allocated size of the page-mapping array - the page-mapping array merely
-+** contains unused entries.
-+**
-+** Even without using the hash table, the last frame for page P
-+** can be found by scanning the page-mapping sections of each index block
-+** starting with the last index block and moving toward the first, and
-+** within each index block, starting at the end and moving toward the
-+** beginning.  The first entry that equals P corresponds to the frame
-+** holding the content for that page.
-+**
-+** The hash table consists of HASHTABLE_NSLOT 16-bit unsigned integers.
-+** HASHTABLE_NSLOT = 2*HASHTABLE_NPAGE, and there is one entry in the
-+** hash table for each page number in the mapping section, so the hash 
-+** table is never more than half full.  The expected number of collisions 
-+** prior to finding a match is 1.  Each entry of the hash table is an
-+** 1-based index of an entry in the mapping section of the same
-+** index block.   Let K be the 1-based index of the largest entry in
-+** the mapping section.  (For index blocks other than the last, K will
-+** always be exactly HASHTABLE_NPAGE (4096) and for the last index block
-+** K will be (mxFrame%HASHTABLE_NPAGE).)  Unused slots of the hash table
-+** contain a value of 0.
-+**
-+** To look for page P in the hash table, first compute a hash iKey on
-+** P as follows:
-+**
-+**      iKey = (P * 383) % HASHTABLE_NSLOT
-+**
-+** Then start scanning entries of the hash table, starting with iKey
-+** (wrapping around to the beginning when the end of the hash table is
-+** reached) until an unused hash slot is found. Let the first unused slot
-+** be at index iUnused.  (iUnused might be less than iKey if there was
-+** wrap-around.) Because the hash table is never more than half full,
-+** the search is guaranteed to eventually hit an unused entry.  Let 
-+** iMax be the value between iKey and iUnused, closest to iUnused,
-+** where aHash[iMax]==P.  If there is no iMax entry (if there exists
-+** no hash slot such that aHash[i]==p) then page P is not in the
-+** current index block.  Otherwise the iMax-th mapping entry of the
-+** current index block corresponds to the last entry that references 
-+** page P.
-+**
-+** A hash search begins with the last index block and moves toward the
-+** first index block, looking for entries corresponding to page P.  On
-+** average, only two or three slots in each index block need to be
-+** examined in order to either find the last entry for page P, or to
-+** establish that no such entry exists in the block.  Each index block
-+** holds over 4000 entries.  So two or three index blocks are sufficient
-+** to cover a typical 10 megabyte WAL file, assuming 1K pages.  8 or 10
-+** comparisons (on average) suffice to either locate a frame in the
-+** WAL or to establish that the frame does not exist in the WAL.  This
-+** is much faster than scanning the entire 10MB WAL.
-+**
-+** Note that entries are added in order of increasing K.  Hence, one
-+** reader might be using some value K0 and a second reader that started
-+** at a later time (after additional transactions were added to the WAL
-+** and to the wal-index) might be using a different value K1, where K1>K0.
-+** Both readers can use the same hash table and mapping section to get
-+** the correct result.  There may be entries in the hash table with
-+** K>K0 but to the first reader, those entries will appear to be unused
-+** slots in the hash table and so the first reader will get an answer as
-+** if no values greater than K0 had ever been inserted into the hash table
-+** in the first place - which is what reader one wants.  Meanwhile, the
-+** second reader using K1 will see additional values that were inserted
-+** later, which is exactly what reader two wants.  
-+**
-+** When a rollback occurs, the value of K is decreased. Hash table entries
-+** that correspond to frames greater than the new K value are removed
-+** from the hash table at this point.
++** If there is no %_docsize table (as happens if the columnsize=0 option
++** is specified when the FTS5 table is created), this function is a no-op.
 +*/
-+#ifndef SQLITE_OMIT_WAL
++static int fts5StorageInsertDocsize(
++  Fts5Storage *p,                 /* Storage module to write to */
++  i64 iRowid,                     /* id value */
++  Fts5Buffer *pBuf                /* sz value */
++){
++  int rc = SQLITE_OK;
++  if( p->pConfig->bColumnsize ){
++    sqlite3_stmt *pReplace = 0;
++    rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0);
++    if( rc==SQLITE_OK ){
++      sqlite3_bind_int64(pReplace, 1, iRowid);
++      sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
++      sqlite3_step(pReplace);
++      rc = sqlite3_reset(pReplace);
++    }
++  }
++  return rc;
++}
 +
- 
- /*
--** Set an entry in the wal-index that will map database page number
--** pPage into WAL frame iFrame.
-+** Trace output macros
- */
--static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
--  int rc;                         /* Return code */
--  u32 iZero = 0;                  /* One less than frame number of aPgno[1] */
--  volatile u32 *aPgno = 0;        /* Page number array */
--  volatile ht_slot *aHash = 0;    /* Hash table */
--
--  rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero);
--
--  /* Assuming the wal-index file was successfully mapped, populate the
--  ** page number array and hash table entry.
--  */
--  if( rc==SQLITE_OK ){
--    int iKey;                     /* Hash table key */
--    int idx;                      /* Value to write to hash-table slot */
--    int nCollide;                 /* Number of hash collisions */
--
--    idx = iFrame - iZero;
--    assert( idx <= HASHTABLE_NSLOT/2 + 1 );
--    
--    /* If this is the first entry to be added to this hash-table, zero the
--    ** entire hash table and aPgno[] array before proceeding. 
--    */
--    if( idx==1 ){
--      int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
--      memset((void*)&aPgno[1], 0, nByte);
--    }
--
--    /* If the entry in aPgno[] is already set, then the previous writer
--    ** must have exited unexpectedly in the middle of a transaction (after
--    ** writing one or more dirty pages to the WAL to free up memory). 
--    ** Remove the remnants of that writers uncommitted transaction from 
--    ** the hash-table before writing any new entries.
--    */
--    if( aPgno[idx] ){
--      walCleanupHash(pWal);
--      assert( !aPgno[idx] );
--    }
--
--    /* Write the aPgno[] array entry and the hash-table slot. */
--    nCollide = idx;
--    for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){
--      if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
--    }
--    aPgno[idx] = iPage;
--    aHash[iKey] = (ht_slot)idx;
--
--#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
--    /* Verify that the number of entries in the hash table exactly equals
--    ** the number of entries in the mapping region.
--    */
--    {
--      int i;           /* Loop counter */
--      int nEntry = 0;  /* Number of entries in the hash table */
--      for(i=0; i<HASHTABLE_NSLOT; i++){ if( aHash[i] ) nEntry++; }
--      assert( nEntry==idx );
--    }
--
--    /* Verify that the every entry in the mapping region is reachable
--    ** via the hash table.  This turns out to be a really, really expensive
--    ** thing to check, so only do this occasionally - not on every
--    ** iteration.
--    */
--    if( (idx&0x3ff)==0 ){
--      int i;           /* Loop counter */
--      for(i=1; i<=idx; i++){
--        for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
--          if( aHash[iKey]==i ) break;
--        }
--        assert( aHash[iKey]==i );
--      }
--    }
--#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
--  }
--
--
--  return rc;
--}
--
-+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-+SQLITE_PRIVATE int sqlite3WalTrace = 0;
-+# define WALTRACE(X)  if(sqlite3WalTrace) sqlite3DebugPrintf X
-+#else
-+# define WALTRACE(X)
-+#endif
- 
- /*
--** Recover the wal-index by reading the write-ahead log file. 
-+** The maximum (and only) versions of the wal and wal-index formats
-+** that may be interpreted by this version of SQLite.
- **
--** This routine first tries to establish an exclusive lock on the
--** wal-index to prevent other threads/processes from doing anything
--** with the WAL or wal-index while recovery is running.  The
--** WAL_RECOVER_LOCK is also held so that other threads will know
--** that this thread is running recovery.  If unable to establish
--** the necessary locks, this routine returns SQLITE_BUSY.
-+** If a client begins recovering a WAL file and finds that (a) the checksum
-+** values in the wal-header are correct and (b) the version field is not
-+** WAL_MAX_VERSION, recovery fails and SQLite returns SQLITE_CANTOPEN.
-+**
-+** Similarly, if a client successfully reads a wal-index header (i.e. the 
-+** checksum test is successful) and finds that the version field is not
-+** WALINDEX_MAX_VERSION, then no read-transaction is opened and SQLite
-+** returns SQLITE_CANTOPEN.
- */
--static int walIndexRecover(Wal *pWal){
--  int rc;                         /* Return Code */
--  i64 nSize;                      /* Size of log file */
--  u32 aFrameCksum[2] = {0, 0};
--  int iLock;                      /* Lock offset to lock for checkpoint */
--  int nLock;                      /* Number of locks to hold */
--
--  /* Obtain an exclusive lock on all byte in the locking range not already
--  ** locked by the caller. The caller is guaranteed to have locked the
--  ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte.
--  ** If successful, the same bytes that are locked here are unlocked before
--  ** this function returns.
--  */
--  assert( pWal->ckptLock==1 || pWal->ckptLock==0 );
--  assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 );
--  assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE );
--  assert( pWal->writeLock );
--  iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
--  nLock = SQLITE_SHM_NLOCK - iLock;
--  rc = walLockExclusive(pWal, iLock, nLock, 0);
--  if( rc ){
--    return rc;
--  }
--  WALTRACE(("WAL%p: recovery begin...\n", pWal));
--
--  memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
--
--  rc = sqlite3OsFileSize(pWal->pWalFd, &nSize);
--  if( rc!=SQLITE_OK ){
--    goto recovery_error;
--  }
--
--  if( nSize>WAL_HDRSIZE ){
--    u8 aBuf[WAL_HDRSIZE];         /* Buffer to load WAL header into */
--    u8 *aFrame = 0;               /* Malloc'd buffer to load entire frame */
--    int szFrame;                  /* Number of bytes in buffer aFrame[] */
--    u8 *aData;                    /* Pointer to data part of aFrame buffer */
--    int iFrame;                   /* Index of last frame read */
--    i64 iOffset;                  /* Next offset to read from log file */
--    int szPage;                   /* Page size according to the log */
--    u32 magic;                    /* Magic value read from WAL header */
--    u32 version;                  /* Magic value read from WAL header */
--    int isValid;                  /* True if this frame is valid */
--
--    /* Read in the WAL header. */
--    rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
--    if( rc!=SQLITE_OK ){
--      goto recovery_error;
--    }
--
--    /* If the database page size is not a power of two, or is greater than
--    ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid 
--    ** data. Similarly, if the 'magic' value is invalid, ignore the whole
--    ** WAL file.
--    */
--    magic = sqlite3Get4byte(&aBuf[0]);
--    szPage = sqlite3Get4byte(&aBuf[8]);
--    if( (magic&0xFFFFFFFE)!=WAL_MAGIC 
--     || szPage&(szPage-1) 
--     || szPage>SQLITE_MAX_PAGE_SIZE 
--     || szPage<512 
--    ){
--      goto finished;
--    }
--    pWal->hdr.bigEndCksum = (u8)(magic&0x00000001);
--    pWal->szPage = szPage;
--    pWal->nCkpt = sqlite3Get4byte(&aBuf[12]);
--    memcpy(&pWal->hdr.aSalt, &aBuf[16], 8);
--
--    /* Verify that the WAL header checksum is correct */
--    walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, 
--        aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
--    );
--    if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24])
--     || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28])
--    ){
--      goto finished;
--    }
--
--    /* Verify that the version number on the WAL format is one that
--    ** are able to understand */
--    version = sqlite3Get4byte(&aBuf[4]);
--    if( version!=WAL_MAX_VERSION ){
--      rc = SQLITE_CANTOPEN_BKPT;
--      goto finished;
--    }
--
--    /* Malloc a buffer to read frames into. */
--    szFrame = szPage + WAL_FRAME_HDRSIZE;
--    aFrame = (u8 *)sqlite3_malloc64(szFrame);
--    if( !aFrame ){
--      rc = SQLITE_NOMEM;
--      goto recovery_error;
--    }
--    aData = &aFrame[WAL_FRAME_HDRSIZE];
--
--    /* Read all frames from the log file. */
--    iFrame = 0;
--    for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){
--      u32 pgno;                   /* Database page number for frame */
--      u32 nTruncate;              /* dbsize field from frame header */
--
--      /* Read and decode the next log frame. */
--      iFrame++;
--      rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
--      if( rc!=SQLITE_OK ) break;
--      isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame);
--      if( !isValid ) break;
--      rc = walIndexAppend(pWal, iFrame, pgno);
--      if( rc!=SQLITE_OK ) break;
--
--      /* If nTruncate is non-zero, this is a commit record. */
--      if( nTruncate ){
--        pWal->hdr.mxFrame = iFrame;
--        pWal->hdr.nPage = nTruncate;
--        pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
--        testcase( szPage<=32768 );
--        testcase( szPage>=65536 );
--        aFrameCksum[0] = pWal->hdr.aFrameCksum[0];
--        aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
--      }
--    }
--
--    sqlite3_free(aFrame);
--  }
-+#define WAL_MAX_VERSION      3007000
-+#define WALINDEX_MAX_VERSION 3007000
- 
--finished:
--  if( rc==SQLITE_OK ){
--    volatile WalCkptInfo *pInfo;
--    int i;
--    pWal->hdr.aFrameCksum[0] = aFrameCksum[0];
--    pWal->hdr.aFrameCksum[1] = aFrameCksum[1];
--    walIndexWriteHdr(pWal);
-+/*
-+** Indices of various locking bytes.   WAL_NREADER is the number
-+** of available reader locks and should be at least 3.
-+*/
-+#define WAL_WRITE_LOCK         0
-+#define WAL_ALL_BUT_WRITE      1
-+#define WAL_CKPT_LOCK          1
-+#define WAL_RECOVER_LOCK       2
-+#define WAL_READ_LOCK(I)       (3+(I))
-+#define WAL_NREADER            (SQLITE_SHM_NLOCK-3)
- 
--    /* Reset the checkpoint-header. This is safe because this thread is 
--    ** currently holding locks that exclude all other readers, writers and
--    ** checkpointers.
--    */
--    pInfo = walCkptInfo(pWal);
--    pInfo->nBackfill = 0;
--    pInfo->aReadMark[0] = 0;
--    for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
--    if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame;
- 
--    /* If more than one frame was recovered from the log file, report an
--    ** event via sqlite3_log(). This is to help with identifying performance
--    ** problems caused by applications routinely shutting down without
--    ** checkpointing the log file.
--    */
--    if( pWal->hdr.nPage ){
--      sqlite3_log(SQLITE_NOTICE_RECOVER_WAL,
--          "recovered %d frames from WAL file %s",
--          pWal->hdr.mxFrame, pWal->zWalName
--      );
--    }
--  }
-+/* Object declarations */
-+typedef struct WalIndexHdr WalIndexHdr;
-+typedef struct WalIterator WalIterator;
-+typedef struct WalCkptInfo WalCkptInfo;
- 
--recovery_error:
--  WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
--  walUnlockExclusive(pWal, iLock, nLock);
--  return rc;
--}
- 
- /*
--** Close an open wal-index.
-+** The following object holds a copy of the wal-index header content.
-+**
-+** The actual header in the wal-index consists of two copies of this
-+** object.
++/*
++** Load the contents of the "averages" record from disk into the 
++** p->nTotalRow and p->aTotalSize[] variables. If successful, and if
++** argument bCache is true, set the p->bTotalsValid flag to indicate
++** that the contents of aTotalSize[] and nTotalRow are valid until
++** further notice.
 +**
-+** The szPage value can be any power of 2 between 512 and 32768, inclusive.
-+** Or it can be 1 to represent a 65536-byte page.  The latter case was
-+** added in 3.7.1 when support for 64K pages was added.  
- */
--static void walIndexClose(Wal *pWal, int isDelete){
--  if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
--    int i;
--    for(i=0; i<pWal->nWiData; i++){
--      sqlite3_free((void *)pWal->apWiData[i]);
--      pWal->apWiData[i] = 0;
--    }
--  }else{
--    sqlite3OsShmUnmap(pWal->pDbFd, isDelete);
--  }
--}
-+struct WalIndexHdr {
-+  u32 iVersion;                   /* Wal-index version */
-+  u32 unused;                     /* Unused (padding) field */
-+  u32 iChange;                    /* Counter incremented each transaction */
-+  u8 isInit;                      /* 1 when initialized */
-+  u8 bigEndCksum;                 /* True if checksums in WAL are big-endian */
-+  u16 szPage;                     /* Database page size in bytes. 1==64K */
-+  u32 mxFrame;                    /* Index of last valid frame in the WAL */
-+  u32 nPage;                      /* Size of database in pages */
-+  u32 aFrameCksum[2];             /* Checksum of last frame in log */
-+  u32 aSalt[2];                   /* Two salt values copied from WAL header */
-+  u32 aCksum[2];                  /* Checksum over all prior fields */
-+};
- 
--/* 
--** Open a connection to the WAL file zWalName. The database file must 
--** already be opened on connection pDbFd. The buffer that zWalName points
--** to must remain valid for the lifetime of the returned Wal* handle.
-+/*
-+** A copy of the following object occurs in the wal-index immediately
-+** following the second copy of the WalIndexHdr.  This object stores
-+** information used by checkpoint.
- **
--** A SHARED lock should be held on the database file when this function
--** is called. The purpose of this SHARED lock is to prevent any other
--** client from unlinking the WAL or wal-index file. If another process
--** were to do this just after this client opened one of these files, the
--** system would be badly broken.
-+** nBackfill is the number of frames in the WAL that have been written
-+** back into the database. (We call the act of moving content from WAL to
-+** database "backfilling".)  The nBackfill number is never greater than
-+** WalIndexHdr.mxFrame.  nBackfill can only be increased by threads
-+** holding the WAL_CKPT_LOCK lock (which includes a recovery thread).
-+** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from
-+** mxFrame back to zero when the WAL is reset.
- **
--** If the log file is successfully opened, SQLITE_OK is returned and 
--** *ppWal is set to point to a new WAL handle. If an error occurs,
--** an SQLite error code is returned and *ppWal is left unmodified.
-+** There is one entry in aReadMark[] for each reader lock.  If a reader
-+** holds read-lock K, then the value in aReadMark[K] is no greater than
-+** the mxFrame for that reader.  The value READMARK_NOT_USED (0xffffffff)
-+** for any aReadMark[] means that entry is unused.  aReadMark[0] is 
-+** a special case; its value is never used and it exists as a place-holder
-+** to avoid having to offset aReadMark[] indexs by one.  Readers holding
-+** WAL_READ_LOCK(0) always ignore the entire WAL and read all content
-+** directly from the database.
-+**
-+** The value of aReadMark[K] may only be changed by a thread that
-+** is holding an exclusive lock on WAL_READ_LOCK(K).  Thus, the value of
-+** aReadMark[K] cannot changed while there is a reader is using that mark
-+** since the reader will be holding a shared lock on WAL_READ_LOCK(K).
-+**
-+** The checkpointer may only transfer frames from WAL to database where
-+** the frame numbers are less than or equal to every aReadMark[] that is
-+** in use (that is, every aReadMark[j] for which there is a corresponding
-+** WAL_READ_LOCK(j)).  New readers (usually) pick the aReadMark[] with the
-+** largest value and will increase an unused aReadMark[] to mxFrame if there
-+** is not already an aReadMark[] equal to mxFrame.  The exception to the
-+** previous sentence is when nBackfill equals mxFrame (meaning that everything
-+** in the WAL has been backfilled into the database) then new readers
-+** will choose aReadMark[0] which has value 0 and hence such reader will
-+** get all their all content directly from the database file and ignore 
-+** the WAL.
-+**
-+** Writers normally append new frames to the end of the WAL.  However,
-+** if nBackfill equals mxFrame (meaning that all WAL content has been
-+** written back into the database) and if no readers are using the WAL
-+** (in other words, if there are no WAL_READ_LOCK(i) where i>0) then
-+** the writer will first "reset" the WAL back to the beginning and start
-+** writing new content beginning at frame 1.
-+**
-+** We assume that 32-bit loads are atomic and so no locks are needed in
-+** order to read from any aReadMark[] entries.
- */
--SQLITE_PRIVATE int sqlite3WalOpen(
--  sqlite3_vfs *pVfs,              /* vfs module to open wal and wal-index */
--  sqlite3_file *pDbFd,            /* The open database file */
--  const char *zWalName,           /* Name of the WAL file */
--  int bNoShm,                     /* True to run in heap-memory mode */
--  i64 mxWalSize,                  /* Truncate WAL to this size on reset */
--  Wal **ppWal                     /* OUT: Allocated Wal handle */
--){
--  int rc;                         /* Return Code */
--  Wal *pRet;                      /* Object to allocate and return */
--  int flags;                      /* Flags passed to OsOpen() */
--
--  assert( zWalName && zWalName[0] );
--  assert( pDbFd );
-+struct WalCkptInfo {
-+  u32 nBackfill;                  /* Number of WAL frames backfilled into DB */
-+  u32 aReadMark[WAL_NREADER];     /* Reader marks */
-+};
-+#define READMARK_NOT_USED  0xffffffff
- 
--  /* In the amalgamation, the os_unix.c and os_win.c source files come before
--  ** this source file.  Verify that the #defines of the locking byte offsets
--  ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value.
--  */
--#ifdef WIN_SHM_BASE
--  assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET );
--#endif
--#ifdef UNIX_SHM_BASE
--  assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET );
--#endif
- 
-+/* A block of WALINDEX_LOCK_RESERVED bytes beginning at
-+** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems
-+** only support mandatory file-locks, we do not read or write data
-+** from the region of the file on which locks are applied.
++** Return SQLITE_OK if successful, or an SQLite error code if an error
++** occurs.
 +*/
-+#define WALINDEX_LOCK_OFFSET   (sizeof(WalIndexHdr)*2 + sizeof(WalCkptInfo))
-+#define WALINDEX_LOCK_RESERVED 16
-+#define WALINDEX_HDR_SIZE      (WALINDEX_LOCK_OFFSET+WALINDEX_LOCK_RESERVED)
- 
--  /* Allocate an instance of struct Wal to return. */
--  *ppWal = 0;
--  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile);
--  if( !pRet ){
--    return SQLITE_NOMEM;
--  }
-+/* Size of header before each frame in wal */
-+#define WAL_FRAME_HDRSIZE 24
- 
--  pRet->pVfs = pVfs;
--  pRet->pWalFd = (sqlite3_file *)&pRet[1];
--  pRet->pDbFd = pDbFd;
--  pRet->readLock = -1;
--  pRet->mxWalSize = mxWalSize;
--  pRet->zWalName = zWalName;
--  pRet->syncHeader = 1;
--  pRet->padToSectorBoundary = 1;
--  pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);
-+/* Size of write ahead log header, including checksum. */
-+/* #define WAL_HDRSIZE 24 */
-+#define WAL_HDRSIZE 32
- 
--  /* Open file handle on the write-ahead log file. */
--  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
--  rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
--  if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){
--    pRet->readOnly = WAL_RDONLY;
--  }
-+/* WAL magic value. Either this value, or the same value with the least
-+** significant bit also set (WAL_MAGIC | 0x00000001) is stored in 32-bit
-+** big-endian format in the first 4 bytes of a WAL file.
++static int fts5StorageLoadTotals(Fts5Storage *p, int bCache){
++  int rc = SQLITE_OK;
++  if( p->bTotalsValid==0 ){
++    rc = sqlite3Fts5IndexGetAverages(p->pIndex, &p->nTotalRow, p->aTotalSize);
++    p->bTotalsValid = bCache;
++  }
++  return rc;
++}
++
++/*
++** Store the current contents of the p->nTotalRow and p->aTotalSize[] 
++** variables in the "averages" record on disk.
 +**
-+** If the LSB is set, then the checksums for each frame within the WAL
-+** file are calculated by treating all data as an array of 32-bit 
-+** big-endian words. Otherwise, they are calculated by interpreting 
-+** all data as 32-bit little-endian words.
++** Return SQLITE_OK if successful, or an SQLite error code if an error
++** occurs.
 +*/
-+#define WAL_MAGIC 0x377f0682
- 
--  if( rc!=SQLITE_OK ){
--    walIndexClose(pRet, 0);
--    sqlite3OsClose(pRet->pWalFd);
--    sqlite3_free(pRet);
--  }else{
--    int iDC = sqlite3OsDeviceCharacteristics(pDbFd);
--    if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; }
--    if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){
--      pRet->padToSectorBoundary = 0;
--    }
--    *ppWal = pRet;
--    WALTRACE(("WAL%d: opened\n", pRet));
--  }
--  return rc;
--}
++static int fts5StorageSaveTotals(Fts5Storage *p){
++  int nCol = p->pConfig->nCol;
++  int i;
++  Fts5Buffer buf;
++  int rc = SQLITE_OK;
++  memset(&buf, 0, sizeof(buf));
++
++  sqlite3Fts5BufferAppendVarint(&rc, &buf, p->nTotalRow);
++  for(i=0; i<nCol; i++){
++    sqlite3Fts5BufferAppendVarint(&rc, &buf, p->aTotalSize[i]);
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5IndexSetAverages(p->pIndex, buf.p, buf.n);
++  }
++  sqlite3_free(buf.p);
++
++  return rc;
++}
++
 +/*
-+** Return the offset of frame iFrame in the write-ahead log file, 
-+** assuming a database page size of szPage bytes. The offset returned
-+** is to the start of the write-ahead log frame-header.
++** Remove a row from the FTS table.
 +*/
-+#define walFrameOffset(iFrame, szPage) (                               \
-+  WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE)         \
-+)
- 
- /*
--** Change the size to which the WAL file is trucated on each reset.
-+** An open write-ahead log file is represented by an instance of the
-+** following object.
- */
--SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){
--  if( pWal ) pWal->mxWalSize = iLimit;
--}
-+struct Wal {
-+  sqlite3_vfs *pVfs;         /* The VFS used to create pDbFd */
-+  sqlite3_file *pDbFd;       /* File handle for the database file */
-+  sqlite3_file *pWalFd;      /* File handle for WAL file */
-+  u32 iCallback;             /* Value to pass to log callback (or 0) */
-+  i64 mxWalSize;             /* Truncate WAL to this size upon reset */
-+  int nWiData;               /* Size of array apWiData */
-+  int szFirstBlock;          /* Size of first block written to WAL file */
-+  volatile u32 **apWiData;   /* Pointer to wal-index content in memory */
-+  u32 szPage;                /* Database page size */
-+  i16 readLock;              /* Which read lock is being held.  -1 for none */
-+  u8 syncFlags;              /* Flags to use to sync header writes */
-+  u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
-+  u8 writeLock;              /* True if in a write transaction */
-+  u8 ckptLock;               /* True if holding a checkpoint lock */
-+  u8 readOnly;               /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
-+  u8 truncateOnCommit;       /* True to truncate WAL file on commit */
-+  u8 syncHeader;             /* Fsync the WAL header if true */
-+  u8 padToSectorBoundary;    /* Pad transactions out to the next sector */
-+  WalIndexHdr hdr;           /* Wal-index header for current transaction */
-+  const char *zWalName;      /* Name of WAL file */
-+  u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
-+#ifdef SQLITE_DEBUG
-+  u8 lockError;              /* True if a locking error has occurred */
-+#endif
-+};
- 
- /*
--** Find the smallest page number out of all pages held in the WAL that
--** has not been returned by any prior invocation of this method on the
--** same WalIterator object.   Write into *piFrame the frame index where
--** that page was last written into the WAL.  Write into *piPage the page
--** number.
--**
--** Return 0 on success.  If there are no pages in the WAL with a page
--** number larger than *piPage, then return 1.
-+** Candidate values for Wal.exclusiveMode.
- */
--static int walIteratorNext(
--  WalIterator *p,               /* Iterator */
--  u32 *piPage,                  /* OUT: The page number of the next page */
--  u32 *piFrame                  /* OUT: Wal frame index of next page */
--){
--  u32 iMin;                     /* Result pgno must be greater than iMin */
--  u32 iRet = 0xFFFFFFFF;        /* 0xffffffff is never a valid page number */
--  int i;                        /* For looping through segments */
-+#define WAL_NORMAL_MODE     0
-+#define WAL_EXCLUSIVE_MODE  1     
-+#define WAL_HEAPMEMORY_MODE 2
- 
--  iMin = p->iPrior;
--  assert( iMin<0xffffffff );
--  for(i=p->nSegment-1; i>=0; i--){
--    struct WalSegment *pSegment = &p->aSegment[i];
--    while( pSegment->iNext<pSegment->nEntry ){
--      u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]];
--      if( iPg>iMin ){
--        if( iPg<iRet ){
--          iRet = iPg;
--          *piFrame = pSegment->iZero + pSegment->aIndex[pSegment->iNext];
--        }
--        break;
--      }
--      pSegment->iNext++;
--    }
--  }
++static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){
++  Fts5Config *pConfig = p->pConfig;
++  int rc;
++  sqlite3_stmt *pDel = 0;
++
++  assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 );
++  rc = fts5StorageLoadTotals(p, 1);
++
++  /* Delete the index records */
++  if( rc==SQLITE_OK ){
++    rc = fts5StorageDeleteFromIndex(p, iDel, apVal);
++  }
++
++  /* Delete the %_docsize record */
++  if( rc==SQLITE_OK && pConfig->bColumnsize ){
++    rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0);
++    if( rc==SQLITE_OK ){
++      sqlite3_bind_int64(pDel, 1, iDel);
++      sqlite3_step(pDel);
++      rc = sqlite3_reset(pDel);
++    }
++  }
++
++  /* Delete the %_content record */
++  if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
++    if( rc==SQLITE_OK ){
++      rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0);
++    }
++    if( rc==SQLITE_OK ){
++      sqlite3_bind_int64(pDel, 1, iDel);
++      sqlite3_step(pDel);
++      rc = sqlite3_reset(pDel);
++    }
++  }
++
++  return rc;
++}
++
 +/*
-+** Possible values for WAL.readOnly
++** Delete all entries in the FTS5 index.
 +*/
-+#define WAL_RDWR        0    /* Normal read/write connection */
-+#define WAL_RDONLY      1    /* The WAL file is readonly */
-+#define WAL_SHM_RDONLY  2    /* The SHM file is readonly */
- 
--  *piPage = p->iPrior = iRet;
--  return (iRet==0xFFFFFFFF);
--}
++static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){
++  Fts5Config *pConfig = p->pConfig;
++  int rc;
++
++  /* Delete the contents of the %_data and %_docsize tables. */
++  rc = fts5ExecPrintf(pConfig->db, 0,
++      "DELETE FROM %Q.'%q_data';" 
++      "DELETE FROM %Q.'%q_idx';",
++      pConfig->zDb, pConfig->zName,
++      pConfig->zDb, pConfig->zName
++  );
++  if( rc==SQLITE_OK && pConfig->bColumnsize ){
++    rc = fts5ExecPrintf(pConfig->db, 0,
++        "DELETE FROM %Q.'%q_docsize';",
++        pConfig->zDb, pConfig->zName
++    );
++  }
++
++  /* Reinitialize the %_data table. This call creates the initial structure
++  ** and averages records.  */
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5IndexReinit(p->pIndex);
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5StorageConfigValue(p, "version", 0, FTS5_CURRENT_VERSION);
++  }
++  return rc;
++}
++
++static int sqlite3Fts5StorageRebuild(Fts5Storage *p){
++  Fts5Buffer buf = {0,0,0};
++  Fts5Config *pConfig = p->pConfig;
++  sqlite3_stmt *pScan = 0;
++  Fts5InsertCtx ctx;
++  int rc;
++
++  memset(&ctx, 0, sizeof(Fts5InsertCtx));
++  ctx.pStorage = p;
++  rc = sqlite3Fts5StorageDeleteAll(p);
++  if( rc==SQLITE_OK ){
++    rc = fts5StorageLoadTotals(p, 1);
++  }
++
++  if( rc==SQLITE_OK ){
++    rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
++  }
++
++  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){
++    i64 iRowid = sqlite3_column_int64(pScan, 0);
++
++    sqlite3Fts5BufferZero(&buf);
++    rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
++    for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
++      ctx.szCol = 0;
++      if( pConfig->abUnindexed[ctx.iCol]==0 ){
++        rc = sqlite3Fts5Tokenize(pConfig, 
++            FTS5_TOKENIZE_DOCUMENT,
++            (const char*)sqlite3_column_text(pScan, ctx.iCol+1),
++            sqlite3_column_bytes(pScan, ctx.iCol+1),
++            (void*)&ctx,
++            fts5StorageInsertCallback
++        );
++      }
++      sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
++      p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
++    }
++    p->nTotalRow++;
++
++    if( rc==SQLITE_OK ){
++      rc = fts5StorageInsertDocsize(p, iRowid, &buf);
++    }
++  }
++  sqlite3_free(buf.p);
++
++  /* Write the averages record */
++  if( rc==SQLITE_OK ){
++    rc = fts5StorageSaveTotals(p);
++  }
++  return rc;
++}
++
++static int sqlite3Fts5StorageOptimize(Fts5Storage *p){
++  return sqlite3Fts5IndexOptimize(p->pIndex);
++}
++
++static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){
++  return sqlite3Fts5IndexMerge(p->pIndex, nMerge);
++}
++
++static int sqlite3Fts5StorageReset(Fts5Storage *p){
++  return sqlite3Fts5IndexReset(p->pIndex);
++}
++
 +/*
-+** Each page of the wal-index mapping contains a hash-table made up of
-+** an array of HASHTABLE_NSLOT elements of the following type.
++** Allocate a new rowid. This is used for "external content" tables when
++** a NULL value is inserted into the rowid column. The new rowid is allocated
++** by inserting a dummy row into the %_docsize table. The dummy will be
++** overwritten later.
++**
++** If the %_docsize table does not exist, SQLITE_MISMATCH is returned. In
++** this case the user is required to provide a rowid explicitly.
 +*/
-+typedef u16 ht_slot;
- 
- /*
--** This function merges two sorted lists into a single sorted list.
--**
--** aLeft[] and aRight[] are arrays of indices.  The sort key is
--** aContent[aLeft[]] and aContent[aRight[]].  Upon entry, the following
--** is guaranteed for all J<K:
-+** This structure is used to implement an iterator that loops through
-+** all frames in the WAL in database page order. Where two or more frames
-+** correspond to the same database page, the iterator visits only the 
-+** frame most recently written to the WAL (in other words, the frame with
-+** the largest index).
- **
--**        aContent[aLeft[J]] < aContent[aLeft[K]]
--**        aContent[aRight[J]] < aContent[aRight[K]]
-+** The internals of this structure are only accessed by:
- **
--** This routine overwrites aRight[] with a new (probably longer) sequence
--** of indices such that the aRight[] contains every index that appears in
--** either aLeft[] or the old aRight[] and such that the second condition
--** above is still met.
-+**   walIteratorInit() - Create a new iterator,
-+**   walIteratorNext() - Step an iterator,
-+**   walIteratorFree() - Free an iterator.
- **
--** The aContent[aLeft[X]] values will be unique for all X.  And the
--** aContent[aRight[X]] values will be unique too.  But there might be
--** one or more combinations of X and Y such that
-+** This functionality is used by the checkpoint code (see walCheckpoint()).
-+*/
-+struct WalIterator {
-+  int iPrior;                     /* Last result returned from the iterator */
-+  int nSegment;                   /* Number of entries in aSegment[] */
-+  struct WalSegment {
-+    int iNext;                    /* Next slot in aIndex[] not yet returned */
-+    ht_slot *aIndex;              /* i0, i1, i2... such that aPgno[iN] ascend */
-+    u32 *aPgno;                   /* Array of page numbers. */
-+    int nEntry;                   /* Nr. of entries in aPgno[] and aIndex[] */
-+    int iZero;                    /* Frame number associated with aPgno[0] */
-+  } aSegment[1];                  /* One for every 32KB page in the wal-index */
-+};
++static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){
++  int rc = SQLITE_MISMATCH;
++  if( p->pConfig->bColumnsize ){
++    sqlite3_stmt *pReplace = 0;
++    rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0);
++    if( rc==SQLITE_OK ){
++      sqlite3_bind_null(pReplace, 1);
++      sqlite3_bind_null(pReplace, 2);
++      sqlite3_step(pReplace);
++      rc = sqlite3_reset(pReplace);
++    }
++    if( rc==SQLITE_OK ){
++      *piRowid = sqlite3_last_insert_rowid(p->pConfig->db);
++    }
++  }
++  return rc;
++}
 +
 +/*
-+** Define the parameters of the hash tables in the wal-index file. There
-+** is a hash-table following every HASHTABLE_NPAGE page numbers in the
-+** wal-index.
- **
--**      aLeft[X]!=aRight[Y]  &&  aContent[aLeft[X]] == aContent[aRight[Y]]
-+** Changing any of these constants will alter the wal-index format and
-+** create incompatibilities.
++** Insert a new row into the FTS content table.
 +*/
-+#define HASHTABLE_NPAGE      4096                 /* Must be power of 2 */
-+#define HASHTABLE_HASH_1     383                  /* Should be prime */
-+#define HASHTABLE_NSLOT      (HASHTABLE_NPAGE*2)  /* Must be a power of 2 */
++static int sqlite3Fts5StorageContentInsert(
++  Fts5Storage *p, 
++  sqlite3_value **apVal, 
++  i64 *piRowid
++){
++  Fts5Config *pConfig = p->pConfig;
++  int rc = SQLITE_OK;
 +
-+/* 
-+** The block of page numbers associated with the first hash-table in a
-+** wal-index is smaller than usual. This is so that there is a complete
-+** hash-table on each aligned 32KB page of the wal-index.
++  /* Insert the new row into the %_content table. */
++  if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
++    if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){
++      *piRowid = sqlite3_value_int64(apVal[1]);
++    }else{
++      rc = fts5StorageNewRowid(p, piRowid);
++    }
++  }else{
++    sqlite3_stmt *pInsert = 0;    /* Statement to write %_content table */
++    int i;                        /* Counter variable */
++    rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
++    for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
++      rc = sqlite3_bind_value(pInsert, i, apVal[i]);
++    }
++    if( rc==SQLITE_OK ){
++      sqlite3_step(pInsert);
++      rc = sqlite3_reset(pInsert);
++    }
++    *piRowid = sqlite3_last_insert_rowid(pConfig->db);
++  }
++
++  return rc;
++}
++
++/*
++** Insert new entries into the FTS index and %_docsize table.
 +*/
-+#define HASHTABLE_NPAGE_ONE  (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32)))
++static int sqlite3Fts5StorageIndexInsert(
++  Fts5Storage *p, 
++  sqlite3_value **apVal, 
++  i64 iRowid
++){
++  Fts5Config *pConfig = p->pConfig;
++  int rc = SQLITE_OK;             /* Return code */
++  Fts5InsertCtx ctx;              /* Tokenization callback context object */
++  Fts5Buffer buf;                 /* Buffer used to build up %_docsize blob */
 +
-+/* The wal-index is divided into pages of WALINDEX_PGSZ bytes each. */
-+#define WALINDEX_PGSZ   (                                         \
-+    sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \
-+)
++  memset(&buf, 0, sizeof(Fts5Buffer));
++  ctx.pStorage = p;
++  rc = fts5StorageLoadTotals(p, 1);
++
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
++  }
++  for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
++    ctx.szCol = 0;
++    if( pConfig->abUnindexed[ctx.iCol]==0 ){
++      rc = sqlite3Fts5Tokenize(pConfig, 
++          FTS5_TOKENIZE_DOCUMENT,
++          (const char*)sqlite3_value_text(apVal[ctx.iCol+2]),
++          sqlite3_value_bytes(apVal[ctx.iCol+2]),
++          (void*)&ctx,
++          fts5StorageInsertCallback
++      );
++    }
++    sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
++    p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
++  }
++  p->nTotalRow++;
++
++  /* Write the %_docsize record */
++  if( rc==SQLITE_OK ){
++    rc = fts5StorageInsertDocsize(p, iRowid, &buf);
++  }
++  sqlite3_free(buf.p);
++
++  return rc;
++}
++
++static int fts5StorageCount(Fts5Storage *p, const char *zSuffix, i64 *pnRow){
++  Fts5Config *pConfig = p->pConfig;
++  char *zSql;
++  int rc;
++
++  zSql = sqlite3_mprintf("SELECT count(*) FROM %Q.'%q_%s'", 
++      pConfig->zDb, pConfig->zName, zSuffix
++  );
++  if( zSql==0 ){
++    rc = SQLITE_NOMEM;
++  }else{
++    sqlite3_stmt *pCnt = 0;
++    rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pCnt, 0);
++    if( rc==SQLITE_OK ){
++      if( SQLITE_ROW==sqlite3_step(pCnt) ){
++        *pnRow = sqlite3_column_int64(pCnt, 0);
++      }
++      rc = sqlite3_finalize(pCnt);
++    }
++  }
++
++  sqlite3_free(zSql);
++  return rc;
++}
 +
 +/*
-+** Obtain a pointer to the iPage'th page of the wal-index. The wal-index
-+** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are
-+** numbered from zero.
- **
--** When that happens, omit the aLeft[X] and use the aRight[Y] index.
-+** If this call is successful, *ppPage is set to point to the wal-index
-+** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
-+** then an SQLite error code is returned and *ppPage is set to 0.
- */
--static void walMerge(
--  const u32 *aContent,            /* Pages in wal - keys for the sort */
--  ht_slot *aLeft,                 /* IN: Left hand input list */
--  int nLeft,                      /* IN: Elements in array *paLeft */
--  ht_slot **paRight,              /* IN/OUT: Right hand input list */
--  int *pnRight,                   /* IN/OUT: Elements in *paRight */
--  ht_slot *aTmp                   /* Temporary buffer */
--){
--  int iLeft = 0;                  /* Current index in aLeft */
--  int iRight = 0;                 /* Current index in aRight */
--  int iOut = 0;                   /* Current index in output buffer */
--  int nRight = *pnRight;
--  ht_slot *aRight = *paRight;
-+static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
++** Context object used by sqlite3Fts5StorageIntegrity().
++*/
++typedef struct Fts5IntegrityCtx Fts5IntegrityCtx;
++struct Fts5IntegrityCtx {
++  i64 iRowid;
++  int iCol;
++  int szCol;
++  u64 cksum;
++  Fts5Termset *pTermset;
++  Fts5Config *pConfig;
++};
++
++
++/*
++** Tokenization callback used by integrity check.
++*/
++static int fts5StorageIntegrityCallback(
++  void *pContext,                 /* Pointer to Fts5IntegrityCtx object */
++  int tflags,
++  const char *pToken,             /* Buffer containing token */
++  int nToken,                     /* Size of token in bytes */
++  int iUnused1,                   /* Start offset of token */
++  int iUnused2                    /* End offset of token */
++){
++  Fts5IntegrityCtx *pCtx = (Fts5IntegrityCtx*)pContext;
++  Fts5Termset *pTermset = pCtx->pTermset;
++  int bPresent;
++  int ii;
 +  int rc = SQLITE_OK;
- 
--  assert( nLeft>0 && nRight>0 );
--  while( iRight<nRight || iLeft<nLeft ){
--    ht_slot logpage;
--    Pgno dbpage;
-+  /* Enlarge the pWal->apWiData[] array if required */
-+  if( pWal->nWiData<=iPage ){
-+    int nByte = sizeof(u32*)*(iPage+1);
-+    volatile u32 **apNew;
-+    apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
-+    if( !apNew ){
-+      *ppPage = 0;
-+      return SQLITE_NOMEM;
++  int iPos;
++  int iCol;
++
++  UNUSED_PARAM2(iUnused1, iUnused2);
++  if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
++
++  if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
++    pCtx->szCol++;
++  }
++
++  switch( pCtx->pConfig->eDetail ){
++    case FTS5_DETAIL_FULL:
++      iPos = pCtx->szCol-1;
++      iCol = pCtx->iCol;
++      break;
++
++    case FTS5_DETAIL_COLUMNS:
++      iPos = pCtx->iCol;
++      iCol = 0;
++      break;
++
++    default:
++      assert( pCtx->pConfig->eDetail==FTS5_DETAIL_NONE );
++      iPos = 0;
++      iCol = 0;
++      break;
++  }
++
++  rc = sqlite3Fts5TermsetAdd(pTermset, 0, pToken, nToken, &bPresent);
++  if( rc==SQLITE_OK && bPresent==0 ){
++    pCtx->cksum ^= sqlite3Fts5IndexEntryCksum(
++        pCtx->iRowid, iCol, iPos, 0, pToken, nToken
++    );
++  }
++
++  for(ii=0; rc==SQLITE_OK && ii<pCtx->pConfig->nPrefix; ii++){
++    const int nChar = pCtx->pConfig->aPrefix[ii];
++    int nByte = sqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar);
++    if( nByte ){
++      rc = sqlite3Fts5TermsetAdd(pTermset, ii+1, pToken, nByte, &bPresent);
++      if( bPresent==0 ){
++        pCtx->cksum ^= sqlite3Fts5IndexEntryCksum(
++            pCtx->iRowid, iCol, iPos, ii+1, pToken, nByte
++        );
++      }
 +    }
-+    memset((void*)&apNew[pWal->nWiData], 0,
-+           sizeof(u32*)*(iPage+1-pWal->nWiData));
-+    pWal->apWiData = apNew;
-+    pWal->nWiData = iPage+1;
 +  }
- 
--    if( (iLeft<nLeft) 
--     && (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]])
--    ){
--      logpage = aLeft[iLeft++];
-+  /* Request a pointer to the required page from the VFS */
-+  if( pWal->apWiData[iPage]==0 ){
-+    if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
-+      pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
-+      if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM;
-     }else{
--      logpage = aRight[iRight++];
-+      rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
-+          pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
-+      );
-+      if( rc==SQLITE_READONLY ){
-+        pWal->readOnly |= WAL_SHM_RDONLY;
-+        rc = SQLITE_OK;
++
++  return rc;
++}
++
++/*
++** Check that the contents of the FTS index match that of the %_content
++** table. Return SQLITE_OK if they do, or SQLITE_CORRUPT if not. Return
++** some other SQLite error code if an error occurs while attempting to
++** determine this.
++*/
++static int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
++  Fts5Config *pConfig = p->pConfig;
++  int rc;                         /* Return code */
++  int *aColSize;                  /* Array of size pConfig->nCol */
++  i64 *aTotalSize;                /* Array of size pConfig->nCol */
++  Fts5IntegrityCtx ctx;
++  sqlite3_stmt *pScan;
++
++  memset(&ctx, 0, sizeof(Fts5IntegrityCtx));
++  ctx.pConfig = p->pConfig;
++  aTotalSize = (i64*)sqlite3_malloc(pConfig->nCol * (sizeof(int)+sizeof(i64)));
++  if( !aTotalSize ) return SQLITE_NOMEM;
++  aColSize = (int*)&aTotalSize[pConfig->nCol];
++  memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol);
++
++  /* Generate the expected index checksum based on the contents of the
++  ** %_content table. This block stores the checksum in ctx.cksum. */
++  rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
++  if( rc==SQLITE_OK ){
++    int rc2;
++    while( SQLITE_ROW==sqlite3_step(pScan) ){
++      int i;
++      ctx.iRowid = sqlite3_column_int64(pScan, 0);
++      ctx.szCol = 0;
++      if( pConfig->bColumnsize ){
++        rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
 +      }
-     }
--    dbpage = aContent[logpage];
++      if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
++        rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
++      }
++      for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
++        if( pConfig->abUnindexed[i] ) continue;
++        ctx.iCol = i;
++        ctx.szCol = 0;
++        if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
++          rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
++        }
++        if( rc==SQLITE_OK ){
++          rc = sqlite3Fts5Tokenize(pConfig, 
++              FTS5_TOKENIZE_DOCUMENT,
++              (const char*)sqlite3_column_text(pScan, i+1),
++              sqlite3_column_bytes(pScan, i+1),
++              (void*)&ctx,
++              fts5StorageIntegrityCallback
++          );
++        }
++        if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
++          rc = FTS5_CORRUPT;
++        }
++        aTotalSize[i] += ctx.szCol;
++        if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
++          sqlite3Fts5TermsetFree(ctx.pTermset);
++          ctx.pTermset = 0;
++        }
++      }
++      sqlite3Fts5TermsetFree(ctx.pTermset);
++      ctx.pTermset = 0;
++
++      if( rc!=SQLITE_OK ) break;
++    }
++    rc2 = sqlite3_reset(pScan);
++    if( rc==SQLITE_OK ) rc = rc2;
 +  }
- 
--    aTmp[iOut++] = logpage;
--    if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++;
-+  *ppPage = pWal->apWiData[iPage];
-+  assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
++
++  /* Test that the "totals" (sometimes called "averages") record looks Ok */
++  if( rc==SQLITE_OK ){
++    int i;
++    rc = fts5StorageLoadTotals(p, 0);
++    for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
++      if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT;
++    }
++  }
++
++  /* Check that the %_docsize and %_content tables contain the expected
++  ** number of rows.  */
++  if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
++    i64 nRow = 0;
++    rc = fts5StorageCount(p, "content", &nRow);
++    if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
++  }
++  if( rc==SQLITE_OK && pConfig->bColumnsize ){
++    i64 nRow = 0;
++    rc = fts5StorageCount(p, "docsize", &nRow);
++    if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
++  }
++
++  /* Pass the expected checksum down to the FTS index module. It will
++  ** verify, amongst other things, that it matches the checksum generated by
++  ** inspecting the index itself.  */
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum);
++  }
++
++  sqlite3_free(aTotalSize);
 +  return rc;
 +}
- 
--    assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage );
--    assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage );
--  }
++
 +/*
-+** Return a pointer to the WalCkptInfo structure in the wal-index.
++** Obtain an SQLite statement handle that may be used to read data from the
++** %_content table.
 +*/
-+static volatile WalCkptInfo *walCkptInfo(Wal *pWal){
-+  assert( pWal->nWiData>0 && pWal->apWiData[0] );
-+  return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]);
++static int sqlite3Fts5StorageStmt(
++  Fts5Storage *p, 
++  int eStmt, 
++  sqlite3_stmt **pp, 
++  char **pzErrMsg
++){
++  int rc;
++  assert( eStmt==FTS5_STMT_SCAN_ASC 
++       || eStmt==FTS5_STMT_SCAN_DESC
++       || eStmt==FTS5_STMT_LOOKUP
++  );
++  rc = fts5StorageGetStmt(p, eStmt, pp, pzErrMsg);
++  if( rc==SQLITE_OK ){
++    assert( p->aStmt[eStmt]==*pp );
++    p->aStmt[eStmt] = 0;
++  }
++  return rc;
 +}
- 
--  *paRight = aLeft;
--  *pnRight = iOut;
--  memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut);
-+/*
-+** Return a pointer to the WalIndexHdr structure in the wal-index.
-+*/
-+static volatile WalIndexHdr *walIndexHdr(Wal *pWal){
-+  assert( pWal->nWiData>0 && pWal->apWiData[0] );
-+  return (volatile WalIndexHdr*)pWal->apWiData[0];
- }
- 
- /*
--** Sort the elements in list aList using aContent[] as the sort key.
--** Remove elements with duplicate keys, preferring to keep the
--** larger aList[] values.
--**
--** The aList[] entries are indices into aContent[].  The values in
--** aList[] are to be sorted so that for all J<K:
--**
--**      aContent[aList[J]] < aContent[aList[K]]
--**
--** For any X and Y such that
-+** The argument to this macro must be of type u32. On a little-endian
-+** architecture, it returns the u32 value that results from interpreting
-+** the 4 bytes as a big-endian value. On a big-endian architecture, it
-+** returns the value that would be produced by interpreting the 4 bytes
-+** of the input value as a little-endian integer.
-+*/
-+#define BYTESWAP32(x) ( \
-+    (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8)  \
-+  + (((x)&0x00FF0000)>>8)  + (((x)&0xFF000000)>>24) \
-+)
 +
 +/*
-+** Generate or extend an 8 byte checksum based on the data in 
-+** array aByte[] and the initial values of aIn[0] and aIn[1] (or
-+** initial values of 0 and 0 if aIn==NULL).
- **
--**      aContent[aList[X]] == aContent[aList[Y]]
-+** The checksum is written back into aOut[] before returning.
- **
--** Keep the larger of the two values aList[X] and aList[Y] and discard
--** the smaller.
-+** nByte must be a positive multiple of 8.
- */
--static void walMergesort(
--  const u32 *aContent,            /* Pages in wal */
--  ht_slot *aBuffer,               /* Buffer of at least *pnList items to use */
--  ht_slot *aList,                 /* IN/OUT: List to sort */
--  int *pnList                     /* IN/OUT: Number of elements in aList[] */
-+static void walChecksumBytes(
-+  int nativeCksum, /* True for native byte-order, false for non-native */
-+  u8 *a,           /* Content to be checksummed */
-+  int nByte,       /* Bytes of content in a[].  Must be a multiple of 8. */
-+  const u32 *aIn,  /* Initial checksum value input */
-+  u32 *aOut        /* OUT: Final checksum value output */
- ){
--  struct Sublist {
--    int nList;                    /* Number of elements in aList */
--    ht_slot *aList;               /* Pointer to sub-list content */
--  };
-+  u32 s1, s2;
-+  u32 *aData = (u32 *)a;
-+  u32 *aEnd = (u32 *)&a[nByte];
- 
--  const int nList = *pnList;      /* Size of input list */
--  int nMerge = 0;                 /* Number of elements in list aMerge */
--  ht_slot *aMerge = 0;            /* List to be merged */
--  int iList;                      /* Index into input list */
--  int iSub = 0;                   /* Index into aSub array */
--  struct Sublist aSub[13];        /* Array of sub-lists */
-+  if( aIn ){
-+    s1 = aIn[0];
-+    s2 = aIn[1];
++** Release an SQLite statement handle obtained via an earlier call to
++** sqlite3Fts5StorageStmt(). The eStmt parameter passed to this function
++** must match that passed to the sqlite3Fts5StorageStmt() call.
++*/
++static void sqlite3Fts5StorageStmtRelease(
++  Fts5Storage *p, 
++  int eStmt, 
++  sqlite3_stmt *pStmt
++){
++  assert( eStmt==FTS5_STMT_SCAN_ASC
++       || eStmt==FTS5_STMT_SCAN_DESC
++       || eStmt==FTS5_STMT_LOOKUP
++  );
++  if( p->aStmt[eStmt]==0 ){
++    sqlite3_reset(pStmt);
++    p->aStmt[eStmt] = pStmt;
 +  }else{
-+    s1 = s2 = 0;
++    sqlite3_finalize(pStmt);
 +  }
- 
--  memset(aSub, 0, sizeof(aSub));
--  assert( nList<=HASHTABLE_NPAGE && nList>0 );
--  assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) );
-+  assert( nByte>=8 );
-+  assert( (nByte&0x00000007)==0 );
- 
--  for(iList=0; iList<nList; iList++){
--    nMerge = 1;
--    aMerge = &aList[iList];
--    for(iSub=0; iList & (1<<iSub); iSub++){
--      struct Sublist *p = &aSub[iSub];
--      assert( p->aList && p->nList<=(1<<iSub) );
--      assert( p->aList==&aList[iList&~((2<<iSub)-1)] );
--      walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
--    }
--    aSub[iSub].aList = aMerge;
--    aSub[iSub].nList = nMerge;
-+  if( nativeCksum ){
-+    do {
-+      s1 += *aData++ + s2;
-+      s2 += *aData++ + s1;
-+    }while( aData<aEnd );
-+  }else{
-+    do {
-+      s1 += BYTESWAP32(aData[0]) + s2;
-+      s2 += BYTESWAP32(aData[1]) + s1;
-+      aData += 2;
-+    }while( aData<aEnd );
-   }
- 
--  for(iSub++; iSub<ArraySize(aSub); iSub++){
--    if( nList & (1<<iSub) ){
--      struct Sublist *p = &aSub[iSub];
--      assert( p->nList<=(1<<iSub) );
--      assert( p->aList==&aList[nList&~((2<<iSub)-1)] );
--      walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
--    }
--  }
--  assert( aMerge==aList );
--  *pnList = nMerge;
-+  aOut[0] = s1;
-+  aOut[1] = s2;
 +}
- 
--#ifdef SQLITE_DEBUG
--  {
--    int i;
--    for(i=1; i<*pnList; i++){
--      assert( aContent[aList[i]] > aContent[aList[i-1]] );
--    }
-+static void walShmBarrier(Wal *pWal){
-+  if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
-+    sqlite3OsShmBarrier(pWal->pDbFd);
-   }
--#endif
- }
- 
--/* 
--** Free an iterator allocated by walIteratorInit().
-+/*
-+** Write the header information in pWal->hdr into the wal-index.
-+**
-+** The checksum on pWal->hdr is updated before it is written.
- */
--static void walIteratorFree(WalIterator *p){
--  sqlite3_free(p);
-+static void walIndexWriteHdr(Wal *pWal){
-+  volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
-+  const int nCksum = offsetof(WalIndexHdr, aCksum);
 +
-+  assert( pWal->writeLock );
-+  pWal->hdr.isInit = 1;
-+  pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
-+  walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
-+  memcpy((void *)&aHdr[1], (void *)&pWal->hdr, sizeof(WalIndexHdr));
-+  walShmBarrier(pWal);
-+  memcpy((void *)&aHdr[0], (void *)&pWal->hdr, sizeof(WalIndexHdr));
- }
- 
- /*
--** Construct a WalInterator object that can be used to loop over all 
--** pages in the WAL in ascending order. The caller must hold the checkpoint
--** lock.
--**
--** On success, make *pp point to the newly allocated WalInterator object
--** return SQLITE_OK. Otherwise, return an error code. If this routine
--** returns an error, the value of *pp is undefined.
-+** This function encodes a single frame header and writes it to a buffer
-+** supplied by the caller. A frame-header is made up of a series of 
-+** 4-byte big-endian integers, as follows:
- **
--** The calling routine should invoke walIteratorFree() to destroy the
--** WalIterator object when it has finished with it.
-+**     0: Page number.
-+**     4: For commit records, the size of the database image in pages 
-+**        after the commit. For all other records, zero.
-+**     8: Salt-1 (copied from the wal-header)
-+**    12: Salt-2 (copied from the wal-header)
-+**    16: Checksum-1.
-+**    20: Checksum-2.
- */
--static int walIteratorInit(Wal *pWal, WalIterator **pp){
--  WalIterator *p;                 /* Return value */
--  int nSegment;                   /* Number of segments to merge */
--  u32 iLast;                      /* Last frame in log */
--  int nByte;                      /* Number of bytes to allocate */
--  int i;                          /* Iterator variable */
--  ht_slot *aTmp;                  /* Temp space used by merge-sort */
--  int rc = SQLITE_OK;             /* Return Code */
-+static void walEncodeFrame(
-+  Wal *pWal,                      /* The write-ahead log */
-+  u32 iPage,                      /* Database page number for frame */
-+  u32 nTruncate,                  /* New db size (or 0 for non-commit frames) */
-+  u8 *aData,                      /* Pointer to page data */
-+  u8 *aFrame                      /* OUT: Write encoded frame here */
-+){
-+  int nativeCksum;                /* True for native byte-order checksums */
-+  u32 *aCksum = pWal->hdr.aFrameCksum;
-+  assert( WAL_FRAME_HDRSIZE==24 );
-+  sqlite3Put4byte(&aFrame[0], iPage);
-+  sqlite3Put4byte(&aFrame[4], nTruncate);
-+  memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
- 
--  /* This routine only runs while holding the checkpoint lock. And
--  ** it only runs if there is actually content in the log (mxFrame>0).
--  */
--  assert( pWal->ckptLock && pWal->hdr.mxFrame>0 );
--  iLast = pWal->hdr.mxFrame;
-+  nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
-+  walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
-+  walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
- 
--  /* Allocate space for the WalIterator object. */
--  nSegment = walFramePage(iLast) + 1;
--  nByte = sizeof(WalIterator) 
--        + (nSegment-1)*sizeof(struct WalSegment)
--        + iLast*sizeof(ht_slot);
--  p = (WalIterator *)sqlite3_malloc64(nByte);
--  if( !p ){
--    return SQLITE_NOMEM;
-+  sqlite3Put4byte(&aFrame[16], aCksum[0]);
-+  sqlite3Put4byte(&aFrame[20], aCksum[1]);
++static int fts5StorageDecodeSizeArray(
++  int *aCol, int nCol,            /* Array to populate */
++  const u8 *aBlob, int nBlob      /* Record to read varints from */
++){
++  int i;
++  int iOff = 0;
++  for(i=0; i<nCol; i++){
++    if( iOff>=nBlob ) return 1;
++    iOff += fts5GetVarint32(&aBlob[iOff], aCol[i]);
++  }
++  return (iOff!=nBlob);
 +}
 +
 +/*
-+** Check to see if the frame with header in aFrame[] and content
-+** in aData[] is valid.  If it is a valid frame, fill *piPage and
-+** *pnTruncate and return true.  Return if the frame is not valid.
++** Argument aCol points to an array of integers containing one entry for
++** each table column. This function reads the %_docsize record for the
++** specified rowid and populates aCol[] with the results.
++**
++** An SQLite error code is returned if an error occurs, or SQLITE_OK
++** otherwise.
 +*/
-+static int walDecodeFrame(
-+  Wal *pWal,                      /* The write-ahead log */
-+  u32 *piPage,                    /* OUT: Database page number for frame */
-+  u32 *pnTruncate,                /* OUT: New db size (or 0 if not commit) */
-+  u8 *aData,                      /* Pointer to page data (for checksum) */
-+  u8 *aFrame                      /* Frame data */
-+){
-+  int nativeCksum;                /* True for native byte-order checksums */
-+  u32 *aCksum = pWal->hdr.aFrameCksum;
-+  u32 pgno;                       /* Page number of the frame */
-+  assert( WAL_FRAME_HDRSIZE==24 );
++static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){
++  int nCol = p->pConfig->nCol;    /* Number of user columns in table */
++  sqlite3_stmt *pLookup = 0;      /* Statement to query %_docsize */
++  int rc;                         /* Return Code */
 +
-+  /* A frame is only valid if the salt values in the frame-header
-+  ** match the salt values in the wal-header. 
-+  */
-+  if( memcmp(&pWal->hdr.aSalt, &aFrame[8], 8)!=0 ){
-+    return 0;
-   }
--  memset(p, 0, nByte);
--  p->nSegment = nSegment;
- 
--  /* Allocate temporary space used by the merge-sort routine. This block
--  ** of memory will be freed before this function returns.
-+  /* A frame is only valid if the page number is creater than zero.
-   */
--  aTmp = (ht_slot *)sqlite3_malloc64(
--      sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
--  );
--  if( !aTmp ){
--    rc = SQLITE_NOMEM;
-+  pgno = sqlite3Get4byte(&aFrame[0]);
-+  if( pgno==0 ){
-+    return 0;
-   }
- 
--  for(i=0; rc==SQLITE_OK && i<nSegment; i++){
--    volatile ht_slot *aHash;
--    u32 iZero;
--    volatile u32 *aPgno;
-+  /* A frame is only valid if a checksum of the WAL header,
-+  ** all prior frams, the first 16 bytes of this frame-header, 
-+  ** and the frame-data matches the checksum in the last 8 
-+  ** bytes of this frame-header.
-+  */
-+  nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
-+  walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
-+  walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
-+  if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) 
-+   || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) 
-+  ){
-+    /* Checksum failed. */
-+    return 0;
++  assert( p->pConfig->bColumnsize );
++  rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
++  if( rc==SQLITE_OK ){
++    int bCorrupt = 1;
++    sqlite3_bind_int64(pLookup, 1, iRowid);
++    if( SQLITE_ROW==sqlite3_step(pLookup) ){
++      const u8 *aBlob = sqlite3_column_blob(pLookup, 0);
++      int nBlob = sqlite3_column_bytes(pLookup, 0);
++      if( 0==fts5StorageDecodeSizeArray(aCol, nCol, aBlob, nBlob) ){
++        bCorrupt = 0;
++      }
++    }
++    rc = sqlite3_reset(pLookup);
++    if( bCorrupt && rc==SQLITE_OK ){
++      rc = FTS5_CORRUPT;
++    }
 +  }
- 
--    rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero);
--    if( rc==SQLITE_OK ){
--      int j;                      /* Counter variable */
--      int nEntry;                 /* Number of entries in this segment */
--      ht_slot *aIndex;            /* Sorted index for this segment */
-+  /* If we reach this point, the frame is valid.  Return the page number
-+  ** and the new database size.
-+  */
-+  *piPage = pgno;
-+  *pnTruncate = sqlite3Get4byte(&aFrame[4]);
-+  return 1;
-+}
- 
--      aPgno++;
--      if( (i+1)==nSegment ){
--        nEntry = (int)(iLast - iZero);
--      }else{
--        nEntry = (int)((u32*)aHash - (u32*)aPgno);
--      }
--      aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero];
--      iZero++;
--  
--      for(j=0; j<nEntry; j++){
--        aIndex[j] = (ht_slot)j;
--      }
--      walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
--      p->aSegment[i].iZero = iZero;
--      p->aSegment[i].nEntry = nEntry;
--      p->aSegment[i].aIndex = aIndex;
--      p->aSegment[i].aPgno = (u32 *)aPgno;
--    }
--  }
--  sqlite3_free(aTmp);
- 
--  if( rc!=SQLITE_OK ){
--    walIteratorFree(p);
-+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-+/*
-+** Names of locks.  This routine is used to provide debugging output and is not
-+** a part of an ordinary build.
-+*/
-+static const char *walLockName(int lockIdx){
-+  if( lockIdx==WAL_WRITE_LOCK ){
-+    return "WRITE-LOCK";
-+  }else if( lockIdx==WAL_CKPT_LOCK ){
-+    return "CKPT-LOCK";
-+  }else if( lockIdx==WAL_RECOVER_LOCK ){
-+    return "RECOVER-LOCK";
-+  }else{
-+    static char zName[15];
-+    sqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]",
-+                     lockIdx-WAL_READ_LOCK(0));
-+    return zName;
-   }
--  *pp = p;
--  return rc;
- }
-+#endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */
-+    
- 
- /*
--** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
--** n. If the attempt fails and parameter xBusy is not NULL, then it is a
--** busy-handler function. Invoke it and retry the lock until either the
--** lock is successfully obtained or the busy-handler returns 0.
-+** Set or release locks on the WAL.  Locks are either shared or exclusive.
-+** A lock cannot be moved directly between shared and exclusive - it must go
-+** through the unlocked state first.
-+**
-+** In locking_mode=EXCLUSIVE, all of these routines become no-ops.
- */
--static int walBusyLock(
--  Wal *pWal,                      /* WAL connection */
--  int (*xBusy)(void*),            /* Function to call when busy */
--  void *pBusyArg,                 /* Context argument for xBusyHandler */
--  int lockIdx,                    /* Offset of first byte to lock */
--  int n                           /* Number of bytes to lock */
--){
-+static int walLockShared(Wal *pWal, int lockIdx){
-   int rc;
--  do {
--    rc = walLockExclusive(pWal, lockIdx, n, 0);
--  }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
-+  if( pWal->exclusiveMode ) return SQLITE_OK;
-+  rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
-+                        SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
-+  WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
-+            walLockName(lockIdx), rc ? "failed" : "ok"));
-+  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
-   return rc;
- }
--
--/*
--** The cache of the wal-index header must be valid to call this function.
--** Return the page-size in bytes used by the database.
--*/
--static int walPagesize(Wal *pWal){
--  return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
-+static void walUnlockShared(Wal *pWal, int lockIdx){
-+  if( pWal->exclusiveMode ) return;
-+  (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
-+                         SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
-+  WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
-+}
-+static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){
-+  int rc;
-+  if( pWal->exclusiveMode ) return SQLITE_OK;
-+  if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0);
-+  rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
-+                        SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
-+  WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
-+            walLockName(lockIdx), n, rc ? "failed" : "ok"));
-+  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
++
 +  return rc;
 +}
-+static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
-+  if( pWal->exclusiveMode ) return;
-+  (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
-+                         SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE);
-+  WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal,
-+             walLockName(lockIdx), n));
- }
- 
- /*
--** The following is guaranteed when this function is called:
--**
--**   a) the WRITER lock is held,
--**   b) the entire log file has been checkpointed, and
--**   c) any existing readers are reading exclusively from the database
--**      file - there are no readers that may attempt to read a frame from
--**      the log file.
--**
--** This function updates the shared-memory structures so that the next
--** client to write to the database (which may be this one) does so by
--** writing frames into the start of the log file.
--**
--** The value of parameter salt1 is used as the aSalt[1] value in the 
--** new wal-index header. It should be passed a pseudo-random value (i.e. 
--** one obtained from sqlite3_randomness()).
-+** Compute a hash on a page number.  The resulting hash value must land
-+** between 0 and (HASHTABLE_NSLOT-1).  The walHashNext() function advances
-+** the hash to the next value in the event of a collision.
- */
--static void walRestartHdr(Wal *pWal, u32 salt1){
--  volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
--  int i;                          /* Loop counter */
--  u32 *aSalt = pWal->hdr.aSalt;   /* Big-endian salt values */
--  pWal->nCkpt++;
--  pWal->hdr.mxFrame = 0;
--  sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
--  memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
--  walIndexWriteHdr(pWal);
--  pInfo->nBackfill = 0;
--  pInfo->aReadMark[1] = 0;
--  for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
--  assert( pInfo->aReadMark[0]==0 );
-+static int walHash(u32 iPage){
-+  assert( iPage>0 );
-+  assert( (HASHTABLE_NSLOT & (HASHTABLE_NSLOT-1))==0 );
-+  return (iPage*HASHTABLE_HASH_1) & (HASHTABLE_NSLOT-1);
-+}
-+static int walNextHash(int iPriorHash){
-+  return (iPriorHash+1)&(HASHTABLE_NSLOT-1);
- }
- 
--/*
--** Copy as much content as we can from the WAL back into the database file
--** in response to an sqlite3_wal_checkpoint() request or the equivalent.
--**
--** The amount of information copies from WAL to database might be limited
--** by active readers.  This routine will never overwrite a database page
--** that a concurrent reader might be using.
--**
--** All I/O barrier operations (a.k.a fsyncs) occur in this routine when
--** SQLite is in WAL-mode in synchronous=NORMAL.  That means that if 
--** checkpoints are always run by a background thread or background 
--** process, foreground threads will never block on a lengthy fsync call.
--**
--** Fsync is called on the WAL before writing content out of the WAL and
--** into the database.  This ensures that if the new content is persistent
--** in the WAL and can be recovered following a power-loss or hard reset.
--**
--** Fsync is also called on the database file if (and only if) the entire
--** WAL content is copied into the database file.  This second fsync makes
--** it safe to delete the WAL since the new content will persist in the
--** database file.
-+/* 
-+** Return pointers to the hash table and page number array stored on
-+** page iHash of the wal-index. The wal-index is broken into 32KB pages
-+** numbered starting from 0.
- **
--** This routine uses and updates the nBackfill field of the wal-index header.
--** This is the only routine that will increase the value of nBackfill.  
--** (A WAL reset or recovery will revert nBackfill to zero, but not increase
--** its value.)
-+** Set output variable *paHash to point to the start of the hash table
-+** in the wal-index file. Set *piZero to one less than the frame 
-+** number of the first frame indexed by this hash table. If a
-+** slot in the hash table is set to N, it refers to frame number 
-+** (*piZero+N) in the log.
- **
--** The caller must be holding sufficient locks to ensure that no other
--** checkpoint is running (in any other thread or process) at the same
--** time.
-+** Finally, set *paPgno so that *paPgno[1] is the page number of the
-+** first frame indexed by the hash table, frame (*piZero+1).
- */
--static int walCheckpoint(
--  Wal *pWal,                      /* Wal connection */
--  int eMode,                      /* One of PASSIVE, FULL or RESTART */
--  int (*xBusy)(void*),            /* Function to call when busy */
--  void *pBusyArg,                 /* Context argument for xBusyHandler */
--  int sync_flags,                 /* Flags for OsSync() (or 0) */
--  u8 *zBuf                        /* Temporary buffer to use */
-+static int walHashGet(
-+  Wal *pWal,                      /* WAL handle */
-+  int iHash,                      /* Find the iHash'th table */
-+  volatile ht_slot **paHash,      /* OUT: Pointer to hash index */
-+  volatile u32 **paPgno,          /* OUT: Pointer to page number array */
-+  u32 *piZero                     /* OUT: Frame associated with *paPgno[0] */
- ){
--  int rc = SQLITE_OK;             /* Return code */
--  int szPage;                     /* Database page-size */
--  WalIterator *pIter = 0;         /* Wal iterator context */
--  u32 iDbpage = 0;                /* Next database page to write */
--  u32 iFrame = 0;                 /* Wal frame containing data for iDbpage */
--  u32 mxSafeFrame;                /* Max frame that can be backfilled */
--  u32 mxPage;                     /* Max database page to write */
--  int i;                          /* Loop counter */
--  volatile WalCkptInfo *pInfo;    /* The checkpoint status information */
--
--  szPage = walPagesize(pWal);
--  testcase( szPage<=32768 );
--  testcase( szPage>=65536 );
--  pInfo = walCkptInfo(pWal);
--  if( pInfo->nBackfill<pWal->hdr.mxFrame ){
-+  int rc;                         /* Return code */
-+  volatile u32 *aPgno;
- 
--    /* Allocate the iterator */
--    rc = walIteratorInit(pWal, &pIter);
--    if( rc!=SQLITE_OK ){
--      return rc;
--    }
--    assert( pIter );
-+  rc = walIndexPage(pWal, iHash, &aPgno);
-+  assert( rc==SQLITE_OK || iHash>0 );
- 
--    /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
--    ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
--    assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
++
++static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnToken){
++  int rc = fts5StorageLoadTotals(p, 0);
 +  if( rc==SQLITE_OK ){
-+    u32 iZero;
-+    volatile ht_slot *aHash;
- 
--    /* Compute in mxSafeFrame the index of the last frame of the WAL that is
--    ** safe to write into the database.  Frames beyond mxSafeFrame might
--    ** overwrite database pages that are in use by active readers and thus
--    ** cannot be backfilled from the WAL.
--    */
--    mxSafeFrame = pWal->hdr.mxFrame;
--    mxPage = pWal->hdr.nPage;
--    for(i=1; i<WAL_NREADER; i++){
--      /* Thread-sanitizer reports that the following is an unsafe read,
--      ** as some other thread may be in the process of updating the value
--      ** of the aReadMark[] slot. The assumption here is that if that is
--      ** happening, the other client may only be increasing the value,
--      ** not decreasing it. So assuming either that either the "old" or
--      ** "new" version of the value is read, and not some arbitrary value
--      ** that would never be written by a real client, things are still 
--      ** safe.  */
--      u32 y = pInfo->aReadMark[i];
--      if( mxSafeFrame>y ){
--        assert( y<=pWal->hdr.mxFrame );
--        rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
--        if( rc==SQLITE_OK ){
--          pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
--          walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
--        }else if( rc==SQLITE_BUSY ){
--          mxSafeFrame = y;
--          xBusy = 0;
--        }else{
--          goto walcheckpoint_out;
--        }
--      }
-+    aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE];
-+    if( iHash==0 ){
-+      aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
-+      iZero = 0;
++    *pnToken = 0;
++    if( iCol<0 ){
++      int i;
++      for(i=0; i<p->pConfig->nCol; i++){
++        *pnToken += p->aTotalSize[i];
++      }
++    }else if( iCol<p->pConfig->nCol ){
++      *pnToken = p->aTotalSize[iCol];
 +    }else{
-+      iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
-     }
-+  
-+    *paPgno = &aPgno[-1];
-+    *paHash = aHash;
-+    *piZero = iZero;
++      rc = SQLITE_RANGE;
++    }
 +  }
 +  return rc;
 +}
- 
--    if( pInfo->nBackfill<mxSafeFrame
--     && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
--    ){
--      i64 nSize;                    /* Current size of database file */
--      u32 nBackfill = pInfo->nBackfill;
--
--      /* Sync the WAL to disk */
--      if( sync_flags ){
--        rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
--      }
-+/*
-+** Return the number of the wal-index page that contains the hash-table
-+** and page-number array that contain entries corresponding to WAL frame
-+** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages 
-+** are numbered starting from 0.
-+*/
-+static int walFramePage(u32 iFrame){
-+  int iHash = (iFrame+HASHTABLE_NPAGE-HASHTABLE_NPAGE_ONE-1) / HASHTABLE_NPAGE;
-+  assert( (iHash==0 || iFrame>HASHTABLE_NPAGE_ONE)
-+       && (iHash>=1 || iFrame<=HASHTABLE_NPAGE_ONE)
-+       && (iHash<=1 || iFrame>(HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE))
-+       && (iHash>=2 || iFrame<=HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE)
-+       && (iHash<=2 || iFrame>(HASHTABLE_NPAGE_ONE+2*HASHTABLE_NPAGE))
-+  );
-+  return iHash;
++
++static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
++  int rc = fts5StorageLoadTotals(p, 0);
++  if( rc==SQLITE_OK ){
++    *pnRow = p->nTotalRow;
++  }
++  return rc;
 +}
- 
--      /* If the database may grow as a result of this checkpoint, hint
--      ** about the eventual size of the db file to the VFS layer.
--      */
--      if( rc==SQLITE_OK ){
--        i64 nReq = ((i64)mxPage * szPage);
--        rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
--        if( rc==SQLITE_OK && nSize<nReq ){
--          sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
--        }
--      }
++
 +/*
-+** Return the page number associated with frame iFrame in this WAL.
++** Flush any data currently held in-memory to disk.
 +*/
-+static u32 walFramePgno(Wal *pWal, u32 iFrame){
-+  int iHash = walFramePage(iFrame);
-+  if( iHash==0 ){
-+    return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1];
++static int sqlite3Fts5StorageSync(Fts5Storage *p){
++  int rc = SQLITE_OK;
++  i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db);
++  if( p->bTotalsValid ){
++    rc = fts5StorageSaveTotals(p);
++    p->bTotalsValid = 0;
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5IndexSync(p->pIndex);
 +  }
-+  return pWal->apWiData[iHash][(iFrame-1-HASHTABLE_NPAGE_ONE)%HASHTABLE_NPAGE];
++  sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid);
++  return rc;
 +}
- 
++
++static int sqlite3Fts5StorageRollback(Fts5Storage *p){
++  p->bTotalsValid = 0;
++  return sqlite3Fts5IndexRollback(p->pIndex);
++}
++
++static int sqlite3Fts5StorageConfigValue(
++  Fts5Storage *p, 
++  const char *z,
++  sqlite3_value *pVal,
++  int iVal
++){
++  sqlite3_stmt *pReplace = 0;
++  int rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_CONFIG, &pReplace, 0);
++  if( rc==SQLITE_OK ){
++    sqlite3_bind_text(pReplace, 1, z, -1, SQLITE_STATIC);
++    if( pVal ){
++      sqlite3_bind_value(pReplace, 2, pVal);
++    }else{
++      sqlite3_bind_int(pReplace, 2, iVal);
++    }
++    sqlite3_step(pReplace);
++    rc = sqlite3_reset(pReplace);
++  }
++  if( rc==SQLITE_OK && pVal ){
++    int iNew = p->pConfig->iCookie + 1;
++    rc = sqlite3Fts5IndexSetCookie(p->pIndex, iNew);
++    if( rc==SQLITE_OK ){
++      p->pConfig->iCookie = iNew;
++    }
++  }
++  return rc;
++}
++
 +/*
-+** Remove entries from the hash table that point to WAL slots greater
-+** than pWal->hdr.mxFrame.
++** 2014 May 31
 +**
-+** This function is called whenever pWal->hdr.mxFrame is decreased due
-+** to a rollback or savepoint.
++** 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.
 +**
-+** At most only the hash table containing pWal->hdr.mxFrame needs to be
-+** updated.  Any later hash tables will be automatically cleared when
-+** pWal->hdr.mxFrame advances to the point where those hash tables are
-+** actually needed.
++******************************************************************************
 +*/
-+static void walCleanupHash(Wal *pWal){
-+  volatile ht_slot *aHash = 0;    /* Pointer to hash table to clear */
-+  volatile u32 *aPgno = 0;        /* Page number array for hash table */
-+  u32 iZero = 0;                  /* frame == (aHash[x]+iZero) */
-+  int iLimit = 0;                 /* Zero values greater than this */
-+  int nByte;                      /* Number of bytes to zero in aPgno[] */
-+  int i;                          /* Used to iterate through aHash[] */
- 
--      /* Iterate through the contents of the WAL, copying data to the db file */
--      while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
--        i64 iOffset;
--        assert( walFramePgno(pWal, iFrame)==iDbpage );
--        if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
--          continue;
--        }
--        iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
--        /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
--        rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
--        if( rc!=SQLITE_OK ) break;
--        iOffset = (iDbpage-1)*(i64)szPage;
--        testcase( IS_BIG_INT(iOffset) );
--        rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
--        if( rc!=SQLITE_OK ) break;
--      }
-+  assert( pWal->writeLock );
-+  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 );
-+  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE );
-+  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE+1 );
- 
--      /* If work was actually accomplished... */
--      if( rc==SQLITE_OK ){
--        if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
--          i64 szDb = pWal->hdr.nPage*(i64)szPage;
--          testcase( IS_BIG_INT(szDb) );
--          rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
--          if( rc==SQLITE_OK && sync_flags ){
--            rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
--          }
--        }
--        if( rc==SQLITE_OK ){
--          pInfo->nBackfill = mxSafeFrame;
--        }
--      }
-+  if( pWal->hdr.mxFrame==0 ) return;
- 
--      /* Release the reader lock held while backfilling */
--      walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
--    }
-+  /* Obtain pointers to the hash-table and page-number array containing 
-+  ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed
-+  ** that the page said hash-table and array reside on is already mapped.
-+  */
-+  assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
-+  assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
-+  walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero);
- 
--    if( rc==SQLITE_BUSY ){
--      /* Reset the return code so as not to report a checkpoint failure
--      ** just because there are active readers.  */
--      rc = SQLITE_OK;
-+  /* Zero all hash-table entries that correspond to frame numbers greater
-+  ** than pWal->hdr.mxFrame.
-+  */
-+  iLimit = pWal->hdr.mxFrame - iZero;
-+  assert( iLimit>0 );
-+  for(i=0; i<HASHTABLE_NSLOT; i++){
-+    if( aHash[i]>iLimit ){
-+      aHash[i] = 0;
-     }
-   }
-+  
-+  /* Zero the entries in the aPgno array that correspond to frames with
-+  ** frame numbers greater than pWal->hdr.mxFrame. 
-+  */
-+  nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]);
-+  memset((void *)&aPgno[iLimit+1], 0, nByte);
- 
--  /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
--  ** entire wal file has been copied into the database file, then block 
--  ** until all readers have finished using the wal file. This ensures that 
--  ** the next process to write to the database restarts the wal file.
-+#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
-+  /* Verify that the every entry in the mapping region is still reachable
-+  ** via the hash table even after the cleanup.
-   */
--  if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){
--    assert( pWal->writeLock );
--    if( pInfo->nBackfill<pWal->hdr.mxFrame ){
--      rc = SQLITE_BUSY;
--    }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
--      u32 salt1;
--      sqlite3_randomness(4, &salt1);
--      assert( pInfo->nBackfill==pWal->hdr.mxFrame );
--      rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
--      if( rc==SQLITE_OK ){
--        if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
--          /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as
--          ** SQLITE_CHECKPOINT_RESTART with the addition that it also
--          ** truncates the log file to zero bytes just prior to a
--          ** successful return.
--          **
--          ** In theory, it might be safe to do this without updating the
--          ** wal-index header in shared memory, as all subsequent reader or
--          ** writer clients should see that the entire log file has been
--          ** checkpointed and behave accordingly. This seems unsafe though,
--          ** as it would leave the system in a state where the contents of
--          ** the wal-index header do not match the contents of the 
--          ** file-system. To avoid this, update the wal-index header to
--          ** indicate that the log file contains zero valid frames.  */
--          walRestartHdr(pWal, salt1);
--          rc = sqlite3OsTruncate(pWal->pWalFd, 0);
--        }
--        walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
-+  if( iLimit ){
-+    int i;           /* Loop counter */
-+    int iKey;        /* Hash key */
-+    for(i=1; i<=iLimit; i++){
-+      for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
-+        if( aHash[iKey]==i ) break;
-       }
-+      assert( aHash[iKey]==i );
-     }
-   }
--
-- walcheckpoint_out:
--  walIteratorFree(pIter);
--  return rc;
-+#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
- }
- 
--/*
--** If the WAL file is currently larger than nMax bytes in size, truncate
--** it to exactly nMax bytes. If an error occurs while doing so, ignore it.
--*/
--static void walLimitSize(Wal *pWal, i64 nMax){
--  i64 sz;
--  int rx;
--  sqlite3BeginBenignMalloc();
--  rx = sqlite3OsFileSize(pWal->pWalFd, &sz);
--  if( rx==SQLITE_OK && (sz > nMax ) ){
--    rx = sqlite3OsTruncate(pWal->pWalFd, nMax);
--  }
--  sqlite3EndBenignMalloc();
--  if( rx ){
--    sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
--  }
--}
- 
- /*
--** Close a connection to a log file.
-+** Set an entry in the wal-index that will map database page number
-+** pPage into WAL frame iFrame.
- */
--SQLITE_PRIVATE int sqlite3WalClose(
--  Wal *pWal,                      /* Wal to close */
--  int sync_flags,                 /* Flags to pass to OsSync() (or 0) */
--  int nBuf,
--  u8 *zBuf                        /* Buffer of at least nBuf bytes */
--){
--  int rc = SQLITE_OK;
--  if( pWal ){
--    int isDelete = 0;             /* True to unlink wal and wal-index files */
-+static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
-+  int rc;                         /* Return code */
-+  u32 iZero = 0;                  /* One less than frame number of aPgno[1] */
-+  volatile u32 *aPgno = 0;        /* Page number array */
-+  volatile ht_slot *aHash = 0;    /* Hash table */
- 
--    /* If an EXCLUSIVE lock can be obtained on the database file (using the
--    ** ordinary, rollback-mode locking methods, this guarantees that the
--    ** connection associated with this log file is the only connection to
--    ** the database. In this case checkpoint the database and unlink both
--    ** the wal and wal-index files.
--    **
--    ** The EXCLUSIVE lock is not released before returning.
-+  rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero);
 +
-+  /* Assuming the wal-index file was successfully mapped, populate the
-+  ** page number array and hash table entry.
-+  */
-+  if( rc==SQLITE_OK ){
-+    int iKey;                     /* Hash table key */
-+    int idx;                      /* Value to write to hash-table slot */
-+    int nCollide;                 /* Number of hash collisions */
 +
-+    idx = iFrame - iZero;
-+    assert( idx <= HASHTABLE_NSLOT/2 + 1 );
-+    
-+    /* If this is the first entry to be added to this hash-table, zero the
-+    ** entire hash table and aPgno[] array before proceeding. 
-     */
--    rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
--    if( rc==SQLITE_OK ){
--      if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
--        pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
--      }
--      rc = sqlite3WalCheckpoint(
--          pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
--      );
--      if( rc==SQLITE_OK ){
--        int bPersist = -1;
--        sqlite3OsFileControlHint(
--            pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist
--        );
--        if( bPersist!=1 ){
--          /* Try to delete the WAL file if the checkpoint completed and
--          ** fsyned (rc==SQLITE_OK) and if we are not in persistent-wal
--          ** mode (!bPersist) */
--          isDelete = 1;
--        }else if( pWal->mxWalSize>=0 ){
--          /* Try to truncate the WAL file to zero bytes if the checkpoint
--          ** completed and fsynced (rc==SQLITE_OK) and we are in persistent
--          ** WAL mode (bPersist) and if the PRAGMA journal_size_limit is a
--          ** non-negative value (pWal->mxWalSize>=0).  Note that we truncate
--          ** to zero bytes as truncating to the journal_size_limit might
--          ** leave a corrupt WAL file on disk. */
--          walLimitSize(pWal, 0);
--        }
--      }
-+    if( idx==1 ){
-+      int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
-+      memset((void*)&aPgno[1], 0, nByte);
++/* #include "fts5Int.h" */
++
++/**************************************************************************
++** Start of ascii tokenizer implementation.
++*/
++
++/*
++** For tokenizers with no "unicode" modifier, the set of token characters
++** is the same as the set of ASCII range alphanumeric characters. 
++*/
++static unsigned char aAsciiTokenChar[128] = {
++  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,   /* 0x00..0x0F */
++  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,   /* 0x10..0x1F */
++  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,   /* 0x20..0x2F */
++  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 0, 0, 0, 0, 0, 0,   /* 0x30..0x3F */
++  0, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   /* 0x40..0x4F */
++  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 0, 0,   /* 0x50..0x5F */
++  0, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   /* 0x60..0x6F */
++  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 0, 0,   /* 0x70..0x7F */
++};
++
++typedef struct AsciiTokenizer AsciiTokenizer;
++struct AsciiTokenizer {
++  unsigned char aTokenChar[128];
++};
++
++static void fts5AsciiAddExceptions(
++  AsciiTokenizer *p, 
++  const char *zArg, 
++  int bTokenChars
++){
++  int i;
++  for(i=0; zArg[i]; i++){
++    if( (zArg[i] & 0x80)==0 ){
++      p->aTokenChar[(int)zArg[i]] = (unsigned char)bTokenChars;
 +    }
++  }
++}
 +
-+    /* If the entry in aPgno[] is already set, then the previous writer
-+    ** must have exited unexpectedly in the middle of a transaction (after
-+    ** writing one or more dirty pages to the WAL to free up memory). 
-+    ** Remove the remnants of that writers uncommitted transaction from 
-+    ** the hash-table before writing any new entries.
-+    */
-+    if( aPgno[idx] ){
-+      walCleanupHash(pWal);
-+      assert( !aPgno[idx] );
-+    }
-+
-+    /* Write the aPgno[] array entry and the hash-table slot. */
-+    nCollide = idx;
-+    for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){
-+      if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
-     }
-+    aPgno[idx] = iPage;
-+    aHash[iKey] = (ht_slot)idx;
- 
--    walIndexClose(pWal, isDelete);
--    sqlite3OsClose(pWal->pWalFd);
--    if( isDelete ){
--      sqlite3BeginBenignMalloc();
--      sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0);
--      sqlite3EndBenignMalloc();
-+#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
-+    /* Verify that the number of entries in the hash table exactly equals
-+    ** the number of entries in the mapping region.
-+    */
-+    {
-+      int i;           /* Loop counter */
-+      int nEntry = 0;  /* Number of entries in the hash table */
-+      for(i=0; i<HASHTABLE_NSLOT; i++){ if( aHash[i] ) nEntry++; }
-+      assert( nEntry==idx );
-     }
--    WALTRACE(("WAL%p: closed\n", pWal));
--    sqlite3_free((void *)pWal->apWiData);
--    sqlite3_free(pWal);
-+
-+    /* Verify that the every entry in the mapping region is reachable
-+    ** via the hash table.  This turns out to be a really, really expensive
-+    ** thing to check, so only do this occasionally - not on every
-+    ** iteration.
-+    */
-+    if( (idx&0x3ff)==0 ){
-+      int i;           /* Loop counter */
-+      for(i=1; i<=idx; i++){
-+        for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
-+          if( aHash[iKey]==i ) break;
++/*
++** Delete a "ascii" tokenizer.
++*/
++static void fts5AsciiDelete(Fts5Tokenizer *p){
++  sqlite3_free(p);
++}
++
++/*
++** Create an "ascii" tokenizer.
++*/
++static int fts5AsciiCreate(
++  void *pUnused, 
++  const char **azArg, int nArg,
++  Fts5Tokenizer **ppOut
++){
++  int rc = SQLITE_OK;
++  AsciiTokenizer *p = 0;
++  UNUSED_PARAM(pUnused);
++  if( nArg%2 ){
++    rc = SQLITE_ERROR;
++  }else{
++    p = sqlite3_malloc(sizeof(AsciiTokenizer));
++    if( p==0 ){
++      rc = SQLITE_NOMEM;
++    }else{
++      int i;
++      memset(p, 0, sizeof(AsciiTokenizer));
++      memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
++      for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
++        const char *zArg = azArg[i+1];
++        if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
++          fts5AsciiAddExceptions(p, zArg, 1);
++        }else
++        if( 0==sqlite3_stricmp(azArg[i], "separators") ){
++          fts5AsciiAddExceptions(p, zArg, 0);
++        }else{
++          rc = SQLITE_ERROR;
 +        }
-+        assert( aHash[iKey]==i );
++      }
++      if( rc!=SQLITE_OK ){
++        fts5AsciiDelete((Fts5Tokenizer*)p);
++        p = 0;
 +      }
 +    }
-+#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
-   }
++  }
 +
++  *ppOut = (Fts5Tokenizer*)p;
++  return rc;
++}
 +
-   return rc;
- }
- 
 +
- /*
--** Try to read the wal-index header.  Return 0 on success and 1 if
--** there is a problem.
--**
--** The wal-index is in shared memory.  Another thread or process might
--** be writing the header at the same time this procedure is trying to
--** read it, which might result in inconsistency.  A dirty read is detected
--** by verifying that both copies of the header are the same and also by
--** a checksum on the header.
--**
--** If and only if the read is consistent and the header is different from
--** pWal->hdr, then pWal->hdr is updated to the content of the new header
--** and *pChanged is set to 1.
-+** Recover the wal-index by reading the write-ahead log file. 
- **
--** If the checksum cannot be verified return non-zero. If the header
--** is read successfully and the checksum verified, return zero.
-+** This routine first tries to establish an exclusive lock on the
-+** wal-index to prevent other threads/processes from doing anything
-+** with the WAL or wal-index while recovery is running.  The
-+** WAL_RECOVER_LOCK is also held so that other threads will know
-+** that this thread is running recovery.  If unable to establish
-+** the necessary locks, this routine returns SQLITE_BUSY.
- */
--static int walIndexTryHdr(Wal *pWal, int *pChanged){
--  u32 aCksum[2];                  /* Checksum on the header content */
--  WalIndexHdr h1, h2;             /* Two copies of the header content */
--  WalIndexHdr volatile *aHdr;     /* Header in shared memory */
--
--  /* The first page of the wal-index must be mapped at this point. */
--  assert( pWal->nWiData>0 && pWal->apWiData[0] );
-+static int walIndexRecover(Wal *pWal){
-+  int rc;                         /* Return Code */
-+  i64 nSize;                      /* Size of log file */
-+  u32 aFrameCksum[2] = {0, 0};
-+  int iLock;                      /* Lock offset to lock for checkpoint */
-+  int nLock;                      /* Number of locks to hold */
- 
--  /* Read the header. This might happen concurrently with a write to the
--  ** same area of shared memory on a different CPU in a SMP,
--  ** meaning it is possible that an inconsistent snapshot is read
--  ** from the file. If this happens, return non-zero.
--  **
--  ** There are two copies of the header at the beginning of the wal-index.
--  ** When reading, read [0] first then [1].  Writes are in the reverse order.
--  ** Memory barriers are used to prevent the compiler or the hardware from
--  ** reordering the reads and writes.
-+  /* Obtain an exclusive lock on all byte in the locking range not already
-+  ** locked by the caller. The caller is guaranteed to have locked the
-+  ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte.
-+  ** If successful, the same bytes that are locked here are unlocked before
-+  ** this function returns.
-   */
--  aHdr = walIndexHdr(pWal);
--  memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
--  walShmBarrier(pWal);
--  memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
--
--  if( memcmp(&h1, &h2, sizeof(h1))!=0 ){
--    return 1;   /* Dirty read */
--  }  
--  if( h1.isInit==0 ){
--    return 1;   /* Malformed header - probably all zeros */
--  }
--  walChecksumBytes(1, (u8*)&h1, sizeof(h1)-sizeof(h1.aCksum), 0, aCksum);
--  if( aCksum[0]!=h1.aCksum[0] || aCksum[1]!=h1.aCksum[1] ){
--    return 1;   /* Checksum does not match */
-+  assert( pWal->ckptLock==1 || pWal->ckptLock==0 );
-+  assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 );
-+  assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE );
-+  assert( pWal->writeLock );
-+  iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
-+  nLock = SQLITE_SHM_NLOCK - iLock;
-+  rc = walLockExclusive(pWal, iLock, nLock, 0);
-+  if( rc ){
-+    return rc;
-   }
-+  WALTRACE(("WAL%p: recovery begin...\n", pWal));
- 
--  if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){
--    *pChanged = 1;
--    memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr));
--    pWal->szPage = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
--    testcase( pWal->szPage<=32768 );
--    testcase( pWal->szPage>=65536 );
-+  memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
++static void asciiFold(char *aOut, const char *aIn, int nByte){
++  int i;
++  for(i=0; i<nByte; i++){
++    char c = aIn[i];
++    if( c>='A' && c<='Z' ) c += 32;
++    aOut[i] = c;
++  }
++}
 +
-+  rc = sqlite3OsFileSize(pWal->pWalFd, &nSize);
-+  if( rc!=SQLITE_OK ){
-+    goto recovery_error;
-   }
- 
--  /* The header was successfully read. Return zero. */
--  return 0;
--}
-+  if( nSize>WAL_HDRSIZE ){
-+    u8 aBuf[WAL_HDRSIZE];         /* Buffer to load WAL header into */
-+    u8 *aFrame = 0;               /* Malloc'd buffer to load entire frame */
-+    int szFrame;                  /* Number of bytes in buffer aFrame[] */
-+    u8 *aData;                    /* Pointer to data part of aFrame buffer */
-+    int iFrame;                   /* Index of last frame read */
-+    i64 iOffset;                  /* Next offset to read from log file */
-+    int szPage;                   /* Page size according to the log */
-+    u32 magic;                    /* Magic value read from WAL header */
-+    u32 version;                  /* Magic value read from WAL header */
-+    int isValid;                  /* True if this frame is valid */
- 
--/*
--** Read the wal-index header from the wal-index and into pWal->hdr.
--** If the wal-header appears to be corrupt, try to reconstruct the
--** wal-index from the WAL before returning.
--**
--** Set *pChanged to 1 if the wal-index header value in pWal->hdr is
--** changed by this operation.  If pWal->hdr is unchanged, set *pChanged
--** to 0.
--**
--** If the wal-index header is successfully read, return SQLITE_OK. 
--** Otherwise an SQLite error code.
--*/
--static int walIndexReadHdr(Wal *pWal, int *pChanged){
--  int rc;                         /* Return code */
--  int badHdr;                     /* True if a header read failed */
--  volatile u32 *page0;            /* Chunk of wal-index containing header */
-+    /* Read in the WAL header. */
-+    rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
-+    if( rc!=SQLITE_OK ){
-+      goto recovery_error;
-+    }
- 
--  /* Ensure that page 0 of the wal-index (the page that contains the 
--  ** wal-index header) is mapped. Return early if an error occurs here.
--  */
--  assert( pChanged );
--  rc = walIndexPage(pWal, 0, &page0);
--  if( rc!=SQLITE_OK ){
--    return rc;
--  };
--  assert( page0 || pWal->writeLock==0 );
-+    /* If the database page size is not a power of two, or is greater than
-+    ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid 
-+    ** data. Similarly, if the 'magic' value is invalid, ignore the whole
-+    ** WAL file.
-+    */
-+    magic = sqlite3Get4byte(&aBuf[0]);
-+    szPage = sqlite3Get4byte(&aBuf[8]);
-+    if( (magic&0xFFFFFFFE)!=WAL_MAGIC 
-+     || szPage&(szPage-1) 
-+     || szPage>SQLITE_MAX_PAGE_SIZE 
-+     || szPage<512 
-+    ){
-+      goto finished;
++/*
++** Tokenize some text using the ascii tokenizer.
++*/
++static int fts5AsciiTokenize(
++  Fts5Tokenizer *pTokenizer,
++  void *pCtx,
++  int iUnused,
++  const char *pText, int nText,
++  int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
++){
++  AsciiTokenizer *p = (AsciiTokenizer*)pTokenizer;
++  int rc = SQLITE_OK;
++  int ie;
++  int is = 0;
++
++  char aFold[64];
++  int nFold = sizeof(aFold);
++  char *pFold = aFold;
++  unsigned char *a = p->aTokenChar;
++
++  UNUSED_PARAM(iUnused);
++
++  while( is<nText && rc==SQLITE_OK ){
++    int nByte;
++
++    /* Skip any leading divider characters. */
++    while( is<nText && ((pText[is]&0x80)==0 && a[(int)pText[is]]==0) ){
++      is++;
 +    }
-+    pWal->hdr.bigEndCksum = (u8)(magic&0x00000001);
-+    pWal->szPage = szPage;
-+    pWal->nCkpt = sqlite3Get4byte(&aBuf[12]);
-+    memcpy(&pWal->hdr.aSalt, &aBuf[16], 8);
- 
--  /* If the first page of the wal-index has been mapped, try to read the
--  ** wal-index header immediately, without holding any lock. This usually
--  ** works, but may fail if the wal-index header is corrupt or currently 
--  ** being modified by another thread or process.
--  */
--  badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1);
-+    /* Verify that the WAL header checksum is correct */
-+    walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, 
-+        aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
-+    );
-+    if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24])
-+     || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28])
-+    ){
-+      goto finished;
++    if( is==nText ) break;
++
++    /* Count the token characters */
++    ie = is+1;
++    while( ie<nText && ((pText[ie]&0x80) || a[(int)pText[ie]] ) ){
++      ie++;
 +    }
- 
--  /* If the first attempt failed, it might have been due to a race
--  ** with a writer.  So get a WRITE lock and try again.
--  */
--  assert( badHdr==0 || pWal->writeLock==0 );
--  if( badHdr ){
--    if( pWal->readOnly & WAL_SHM_RDONLY ){
--      if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
--        walUnlockShared(pWal, WAL_WRITE_LOCK);
--        rc = SQLITE_READONLY_RECOVERY;
--      }
--    }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 1)) ){
--      pWal->writeLock = 1;
--      if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
--        badHdr = walIndexTryHdr(pWal, pChanged);
--        if( badHdr ){
--          /* If the wal-index header is still malformed even while holding
--          ** a WRITE lock, it can only mean that the header is corrupted and
--          ** needs to be reconstructed.  So run recovery to do exactly that.
--          */
--          rc = walIndexRecover(pWal);
--          *pChanged = 1;
--        }
-+    /* Verify that the version number on the WAL format is one that
-+    ** are able to understand */
-+    version = sqlite3Get4byte(&aBuf[4]);
-+    if( version!=WAL_MAX_VERSION ){
-+      rc = SQLITE_CANTOPEN_BKPT;
-+      goto finished;
-+    }
-+
-+    /* Malloc a buffer to read frames into. */
-+    szFrame = szPage + WAL_FRAME_HDRSIZE;
-+    aFrame = (u8 *)sqlite3_malloc64(szFrame);
-+    if( !aFrame ){
-+      rc = SQLITE_NOMEM;
-+      goto recovery_error;
++
++    /* Fold to lower case */
++    nByte = ie-is;
++    if( nByte>nFold ){
++      if( pFold!=aFold ) sqlite3_free(pFold);
++      pFold = sqlite3_malloc(nByte*2);
++      if( pFold==0 ){
++        rc = SQLITE_NOMEM;
++        break;
++      }
++      nFold = nByte*2;
 +    }
-+    aData = &aFrame[WAL_FRAME_HDRSIZE];
++    asciiFold(pFold, &pText[is], nByte);
 +
-+    /* Read all frames from the log file. */
-+    iFrame = 0;
-+    for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){
-+      u32 pgno;                   /* Database page number for frame */
-+      u32 nTruncate;              /* dbsize field from frame header */
++    /* Invoke the token callback */
++    rc = xToken(pCtx, 0, pFold, nByte, is, ie);
++    is = ie+1;
++  }
++  
++  if( pFold!=aFold ) sqlite3_free(pFold);
++  if( rc==SQLITE_DONE ) rc = SQLITE_OK;
++  return rc;
++}
 +
-+      /* Read and decode the next log frame. */
-+      iFrame++;
-+      rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
-+      if( rc!=SQLITE_OK ) break;
-+      isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame);
-+      if( !isValid ) break;
-+      rc = walIndexAppend(pWal, iFrame, pgno);
-+      if( rc!=SQLITE_OK ) break;
++/**************************************************************************
++** Start of unicode61 tokenizer implementation.
++*/
 +
-+      /* If nTruncate is non-zero, this is a commit record. */
-+      if( nTruncate ){
-+        pWal->hdr.mxFrame = iFrame;
-+        pWal->hdr.nPage = nTruncate;
-+        pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
-+        testcase( szPage<=32768 );
-+        testcase( szPage>=65536 );
-+        aFrameCksum[0] = pWal->hdr.aFrameCksum[0];
-+        aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
-       }
--      pWal->writeLock = 0;
--      walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
-     }
 +
-+    sqlite3_free(aFrame);
-   }
- 
--  /* If the header is read successfully, check the version number to make
--  ** sure the wal-index was not constructed with some future format that
--  ** this version of SQLite cannot understand.
--  */
--  if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){
--    rc = SQLITE_CANTOPEN_BKPT;
-+finished:
-+  if( rc==SQLITE_OK ){
-+    volatile WalCkptInfo *pInfo;
-+    int i;
-+    pWal->hdr.aFrameCksum[0] = aFrameCksum[0];
-+    pWal->hdr.aFrameCksum[1] = aFrameCksum[1];
-+    walIndexWriteHdr(pWal);
++/*
++** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied
++** from the sqlite3 source file utf.c. If this file is compiled as part
++** of the amalgamation, they are not required.
++*/
++#ifndef SQLITE_AMALGAMATION
++
++static const unsigned char sqlite3Utf8Trans1[] = {
++  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
++  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
++  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
++  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
++  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++  0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
++};
 +
-+    /* Reset the checkpoint-header. This is safe because this thread is 
-+    ** currently holding locks that exclude all other readers, writers and
-+    ** checkpointers.
-+    */
-+    pInfo = walCkptInfo(pWal);
-+    pInfo->nBackfill = 0;
-+    pInfo->aReadMark[0] = 0;
-+    for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
-+    if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame;
-+
-+    /* If more than one frame was recovered from the log file, report an
-+    ** event via sqlite3_log(). This is to help with identifying performance
-+    ** problems caused by applications routinely shutting down without
-+    ** checkpointing the log file.
-+    */
-+    if( pWal->hdr.nPage ){
-+      sqlite3_log(SQLITE_NOTICE_RECOVER_WAL,
-+          "recovered %d frames from WAL file %s",
-+          pWal->hdr.mxFrame, pWal->zWalName
-+      );
++#define READ_UTF8(zIn, zTerm, c)                           \
++  c = *(zIn++);                                            \
++  if( c>=0xc0 ){                                           \
++    c = sqlite3Utf8Trans1[c-0xc0];                         \
++    while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){            \
++      c = (c<<6) + (0x3f & *(zIn++));                      \
++    }                                                      \
++    if( c<0x80                                             \
++        || (c&0xFFFFF800)==0xD800                          \
++        || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }        \
++  }
++
++
++#define WRITE_UTF8(zOut, c) {                          \
++  if( c<0x00080 ){                                     \
++    *zOut++ = (unsigned char)(c&0xFF);                 \
++  }                                                    \
++  else if( c<0x00800 ){                                \
++    *zOut++ = 0xC0 + (unsigned char)((c>>6)&0x1F);     \
++    *zOut++ = 0x80 + (unsigned char)(c & 0x3F);        \
++  }                                                    \
++  else if( c<0x10000 ){                                \
++    *zOut++ = 0xE0 + (unsigned char)((c>>12)&0x0F);    \
++    *zOut++ = 0x80 + (unsigned char)((c>>6) & 0x3F);   \
++    *zOut++ = 0x80 + (unsigned char)(c & 0x3F);        \
++  }else{                                               \
++    *zOut++ = 0xF0 + (unsigned char)((c>>18) & 0x07);  \
++    *zOut++ = 0x80 + (unsigned char)((c>>12) & 0x3F);  \
++    *zOut++ = 0x80 + (unsigned char)((c>>6) & 0x3F);   \
++    *zOut++ = 0x80 + (unsigned char)(c & 0x3F);        \
++  }                                                    \
++}
++
++#endif /* ifndef SQLITE_AMALGAMATION */
++
++typedef struct Unicode61Tokenizer Unicode61Tokenizer;
++struct Unicode61Tokenizer {
++  unsigned char aTokenChar[128];  /* ASCII range token characters */
++  char *aFold;                    /* Buffer to fold text into */
++  int nFold;                      /* Size of aFold[] in bytes */
++  int bRemoveDiacritic;           /* True if remove_diacritics=1 is set */
++  int nException;
++  int *aiException;
++};
++
++static int fts5UnicodeAddExceptions(
++  Unicode61Tokenizer *p,          /* Tokenizer object */
++  const char *z,                  /* Characters to treat as exceptions */
++  int bTokenChars                 /* 1 for 'tokenchars', 0 for 'separators' */
++){
++  int rc = SQLITE_OK;
++  int n = (int)strlen(z);
++  int *aNew;
++
++  if( n>0 ){
++    aNew = (int*)sqlite3_realloc(p->aiException, (n+p->nException)*sizeof(int));
++    if( aNew ){
++      int nNew = p->nException;
++      const unsigned char *zCsr = (const unsigned char*)z;
++      const unsigned char *zTerm = (const unsigned char*)&z[n];
++      while( zCsr<zTerm ){
++        int iCode;
++        int bToken;
++        READ_UTF8(zCsr, zTerm, iCode);
++        if( iCode<128 ){
++          p->aTokenChar[iCode] = (unsigned char)bTokenChars;
++        }else{
++          bToken = sqlite3Fts5UnicodeIsalnum(iCode);
++          assert( (bToken==0 || bToken==1) ); 
++          assert( (bTokenChars==0 || bTokenChars==1) );
++          if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
++            int i;
++            for(i=0; i<nNew; i++){
++              if( aNew[i]>iCode ) break;
++            }
++            memmove(&aNew[i+1], &aNew[i], (nNew-i)*sizeof(int));
++            aNew[i] = iCode;
++            nNew++;
++          }
++        }
++      }
++      p->aiException = aNew;
++      p->nException = nNew;
++    }else{
++      rc = SQLITE_NOMEM;
 +    }
-   }
- 
-+recovery_error:
-+  WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
-+  walUnlockExclusive(pWal, iLock, nLock);
-   return rc;
- }
- 
- /*
--** This is the value that walTryBeginRead returns when it needs to
--** be retried.
-+** Close an open wal-index.
- */
--#define WAL_RETRY  (-1)
-+static void walIndexClose(Wal *pWal, int isDelete){
-+  if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
-+    int i;
-+    for(i=0; i<pWal->nWiData; i++){
-+      sqlite3_free((void *)pWal->apWiData[i]);
-+      pWal->apWiData[i] = 0;
++  }
++
++  return rc;
++}
++
++/*
++** Return true if the p->aiException[] array contains the value iCode.
++*/
++static int fts5UnicodeIsException(Unicode61Tokenizer *p, int iCode){
++  if( p->nException>0 ){
++    int *a = p->aiException;
++    int iLo = 0;
++    int iHi = p->nException-1;
++
++    while( iHi>=iLo ){
++      int iTest = (iHi + iLo) / 2;
++      if( iCode==a[iTest] ){
++        return 1;
++      }else if( iCode>a[iTest] ){
++        iLo = iTest+1;
++      }else{
++        iHi = iTest-1;
++      }
 +    }
-+  }else{
-+    sqlite3OsShmUnmap(pWal->pDbFd, isDelete);
 +  }
++
++  return 0;
 +}
- 
--/*
--** Attempt to start a read transaction.  This might fail due to a race or
--** other transient condition.  When that happens, it returns WAL_RETRY to
--** indicate to the caller that it is safe to retry immediately.
--**
--** On success return SQLITE_OK.  On a permanent failure (such an
--** I/O error or an SQLITE_BUSY because another process is running
--** recovery) return a positive error code.
--**
--** The useWal parameter is true to force the use of the WAL and disable
--** the case where the WAL is bypassed because it has been completely
--** checkpointed.  If useWal==0 then this routine calls walIndexReadHdr() 
--** to make a copy of the wal-index header into pWal->hdr.  If the 
--** wal-index header has changed, *pChanged is set to 1 (as an indication 
--** to the caller that the local paget cache is obsolete and needs to be 
--** flushed.)  When useWal==1, the wal-index header is assumed to already
--** be loaded and the pChanged parameter is unused.
--**
--** The caller must set the cnt parameter to the number of prior calls to
--** this routine during the current read attempt that returned WAL_RETRY.
--** This routine will start taking more aggressive measures to clear the
--** race conditions after multiple WAL_RETRY returns, and after an excessive
--** number of errors will ultimately return SQLITE_PROTOCOL.  The
--** SQLITE_PROTOCOL return indicates that some other process has gone rogue
--** and is not honoring the locking protocol.  There is a vanishingly small
--** chance that SQLITE_PROTOCOL could be returned because of a run of really
--** bad luck when there is lots of contention for the wal-index, but that
--** possibility is so small that it can be safely neglected, we believe.
-+/* 
-+** Open a connection to the WAL file zWalName. The database file must 
-+** already be opened on connection pDbFd. The buffer that zWalName points
-+** to must remain valid for the lifetime of the returned Wal* handle.
- **
--** On success, this routine obtains a read lock on 
--** WAL_READ_LOCK(pWal->readLock).  The pWal->readLock integer is
--** in the range 0 <= pWal->readLock < WAL_NREADER.  If pWal->readLock==(-1)
--** that means the Wal does not hold any read lock.  The reader must not
--** access any database page that is modified by a WAL frame up to and
--** including frame number aReadMark[pWal->readLock].  The reader will
--** use WAL frames up to and including pWal->hdr.mxFrame if pWal->readLock>0
--** Or if pWal->readLock==0, then the reader will ignore the WAL
--** completely and get all content directly from the database file.
--** If the useWal parameter is 1 then the WAL will never be ignored and
--** this routine will always set pWal->readLock>0 on success.
--** When the read transaction is completed, the caller must release the
--** lock on WAL_READ_LOCK(pWal->readLock) and set pWal->readLock to -1.
-+** A SHARED lock should be held on the database file when this function
-+** is called. The purpose of this SHARED lock is to prevent any other
-+** client from unlinking the WAL or wal-index file. If another process
-+** were to do this just after this client opened one of these files, the
-+** system would be badly broken.
- **
--** This routine uses the nBackfill and aReadMark[] fields of the header
--** to select a particular WAL_READ_LOCK() that strives to let the
--** checkpoint process do as much work as possible.  This routine might
--** update values of the aReadMark[] array in the header, but if it does
--** so it takes care to hold an exclusive lock on the corresponding
--** WAL_READ_LOCK() while changing values.
-+** If the log file is successfully opened, SQLITE_OK is returned and 
-+** *ppWal is set to point to a new WAL handle. If an error occurs,
-+** an SQLite error code is returned and *ppWal is left unmodified.
- */
--static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
--  volatile WalCkptInfo *pInfo;    /* Checkpoint information in wal-index */
--  u32 mxReadMark;                 /* Largest aReadMark[] value */
--  int mxI;                        /* Index of largest aReadMark[] value */
--  int i;                          /* Loop counter */
--  int rc = SQLITE_OK;             /* Return code  */
-+SQLITE_PRIVATE int sqlite3WalOpen(
-+  sqlite3_vfs *pVfs,              /* vfs module to open wal and wal-index */
-+  sqlite3_file *pDbFd,            /* The open database file */
-+  const char *zWalName,           /* Name of the WAL file */
-+  int bNoShm,                     /* True to run in heap-memory mode */
-+  i64 mxWalSize,                  /* Truncate WAL to this size on reset */
-+  Wal **ppWal                     /* OUT: Allocated Wal handle */
-+){
-+  int rc;                         /* Return Code */
-+  Wal *pRet;                      /* Object to allocate and return */
-+  int flags;                      /* Flags passed to OsOpen() */
- 
--  assert( pWal->readLock<0 );     /* Not currently locked */
-+  assert( zWalName && zWalName[0] );
-+  assert( pDbFd );
- 
--  /* Take steps to avoid spinning forever if there is a protocol error.
--  **
--  ** Circumstances that cause a RETRY should only last for the briefest
--  ** instances of time.  No I/O or other system calls are done while the
--  ** locks are held, so the locks should not be held for very long. But 
--  ** if we are unlucky, another process that is holding a lock might get
--  ** paged out or take a page-fault that is time-consuming to resolve, 
--  ** during the few nanoseconds that it is holding the lock.  In that case,
--  ** it might take longer than normal for the lock to free.
--  **
--  ** After 5 RETRYs, we begin calling sqlite3OsSleep().  The first few
--  ** calls to sqlite3OsSleep() have a delay of 1 microsecond.  Really this
--  ** is more of a scheduler yield than an actual delay.  But on the 10th
--  ** an subsequent retries, the delays start becoming longer and longer, 
--  ** so that on the 100th (and last) RETRY we delay for 323 milliseconds.
--  ** The total delay time before giving up is less than 10 seconds.
-+  /* In the amalgamation, the os_unix.c and os_win.c source files come before
-+  ** this source file.  Verify that the #defines of the locking byte offsets
-+  ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value.
-   */
--  if( cnt>5 ){
--    int nDelay = 1;                      /* Pause time in microseconds */
--    if( cnt>100 ){
--      VVA_ONLY( pWal->lockError = 1; )
--      return SQLITE_PROTOCOL;
--    }
--    if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
--    sqlite3OsSleep(pWal->pVfs, nDelay);
--  }
-+#ifdef WIN_SHM_BASE
-+  assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET );
-+#endif
-+#ifdef UNIX_SHM_BASE
-+  assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET );
-+#endif
- 
--  if( !useWal ){
--    rc = walIndexReadHdr(pWal, pChanged);
--    if( rc==SQLITE_BUSY ){
--      /* If there is not a recovery running in another thread or process
--      ** then convert BUSY errors to WAL_RETRY.  If recovery is known to
--      ** be running, convert BUSY to BUSY_RECOVERY.  There is a race here
--      ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY
--      ** would be technically correct.  But the race is benign since with
--      ** WAL_RETRY this routine will be called again and will probably be
--      ** right on the second iteration.
--      */
--      if( pWal->apWiData[0]==0 ){
--        /* This branch is taken when the xShmMap() method returns SQLITE_BUSY.
--        ** We assume this is a transient condition, so return WAL_RETRY. The
--        ** xShmMap() implementation used by the default unix and win32 VFS 
--        ** modules may return SQLITE_BUSY due to a race condition in the 
--        ** code that determines whether or not the shared-memory region 
--        ** must be zeroed before the requested page is returned.
--        */
--        rc = WAL_RETRY;
--      }else if( SQLITE_OK==(rc = walLockShared(pWal, WAL_RECOVER_LOCK)) ){
--        walUnlockShared(pWal, WAL_RECOVER_LOCK);
--        rc = WAL_RETRY;
--      }else if( rc==SQLITE_BUSY ){
--        rc = SQLITE_BUSY_RECOVERY;
--      }
--    }
--    if( rc!=SQLITE_OK ){
--      return rc;
--    }
--  }
- 
--  pInfo = walCkptInfo(pWal);
--  if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame ){
--    /* The WAL has been completely backfilled (or it is empty).
--    ** and can be safely ignored.
--    */
--    rc = walLockShared(pWal, WAL_READ_LOCK(0));
--    walShmBarrier(pWal);
--    if( rc==SQLITE_OK ){
--      if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){
--        /* It is not safe to allow the reader to continue here if frames
--        ** may have been appended to the log before READ_LOCK(0) was obtained.
--        ** When holding READ_LOCK(0), the reader ignores the entire log file,
--        ** which implies that the database file contains a trustworthy
--        ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from
--        ** happening, this is usually correct.
--        **
--        ** However, if frames have been appended to the log (or if the log 
--        ** is wrapped and written for that matter) before the READ_LOCK(0)
--        ** is obtained, that is not necessarily true. A checkpointer may
--        ** have started to backfill the appended frames but crashed before
--        ** it finished. Leaving a corrupt image in the database file.
--        */
--        walUnlockShared(pWal, WAL_READ_LOCK(0));
--        return WAL_RETRY;
--      }
--      pWal->readLock = 0;
--      return SQLITE_OK;
--    }else if( rc!=SQLITE_BUSY ){
--      return rc;
--    }
-+  /* Allocate an instance of struct Wal to return. */
-+  *ppWal = 0;
-+  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile);
-+  if( !pRet ){
-+    return SQLITE_NOMEM;
-   }
- 
--  /* If we get this far, it means that the reader will want to use
--  ** the WAL to get at content from recent commits.  The job now is
--  ** to select one of the aReadMark[] entries that is closest to
--  ** but not exceeding pWal->hdr.mxFrame and lock that entry.
--  */
--  mxReadMark = 0;
--  mxI = 0;
--  for(i=1; i<WAL_NREADER; i++){
--    u32 thisMark = pInfo->aReadMark[i];
--    if( mxReadMark<=thisMark && thisMark<=pWal->hdr.mxFrame ){
--      assert( thisMark!=READMARK_NOT_USED );
--      mxReadMark = thisMark;
--      mxI = i;
--    }
-+  pRet->pVfs = pVfs;
-+  pRet->pWalFd = (sqlite3_file *)&pRet[1];
-+  pRet->pDbFd = pDbFd;
-+  pRet->readLock = -1;
-+  pRet->mxWalSize = mxWalSize;
-+  pRet->zWalName = zWalName;
-+  pRet->syncHeader = 1;
-+  pRet->padToSectorBoundary = 1;
-+  pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);
-+
-+  /* Open file handle on the write-ahead log file. */
-+  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
-+  rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
-+  if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){
-+    pRet->readOnly = WAL_RDONLY;
-   }
--  /* There was once an "if" here. The extra "{" is to preserve indentation. */
--  {
--    if( (pWal->readOnly & WAL_SHM_RDONLY)==0
--     && (mxReadMark<pWal->hdr.mxFrame || mxI==0)
--    ){
--      for(i=1; i<WAL_NREADER; i++){
--        rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1, 0);
--        if( rc==SQLITE_OK ){
--          mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame;
--          mxI = i;
--          walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
--          break;
--        }else if( rc!=SQLITE_BUSY ){
--          return rc;
--        }
--      }
--    }
--    if( mxI==0 ){
--      assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
--      return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
--    }
- 
--    rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
--    if( rc ){
--      return rc==SQLITE_BUSY ? WAL_RETRY : rc;
--    }
--    /* Now that the read-lock has been obtained, check that neither the
--    ** value in the aReadMark[] array or the contents of the wal-index
--    ** header have changed.
--    **
--    ** It is necessary to check that the wal-index header did not change
--    ** between the time it was read and when the shared-lock was obtained
--    ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility
--    ** that the log file may have been wrapped by a writer, or that frames
--    ** that occur later in the log than pWal->hdr.mxFrame may have been
--    ** copied into the database by a checkpointer. If either of these things
--    ** happened, then reading the database with the current value of
--    ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry
--    ** instead.
--    **
--    ** This does not guarantee that the copy of the wal-index header is up to
--    ** date before proceeding. That would not be possible without somehow
--    ** blocking writers. It only guarantees that a dangerous checkpoint or 
--    ** log-wrap (either of which would require an exclusive lock on
--    ** WAL_READ_LOCK(mxI)) has not occurred since the snapshot was valid.
--    */
--    walShmBarrier(pWal);
--    if( pInfo->aReadMark[mxI]!=mxReadMark
--     || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
--    ){
--      walUnlockShared(pWal, WAL_READ_LOCK(mxI));
--      return WAL_RETRY;
--    }else{
--      assert( mxReadMark<=pWal->hdr.mxFrame );
--      pWal->readLock = (i16)mxI;
-+  if( rc!=SQLITE_OK ){
-+    walIndexClose(pRet, 0);
-+    sqlite3OsClose(pRet->pWalFd);
-+    sqlite3_free(pRet);
++
++/*
++** Delete a "unicode61" tokenizer.
++*/
++static void fts5UnicodeDelete(Fts5Tokenizer *pTok){
++  if( pTok ){
++    Unicode61Tokenizer *p = (Unicode61Tokenizer*)pTok;
++    sqlite3_free(p->aiException);
++    sqlite3_free(p->aFold);
++    sqlite3_free(p);
++  }
++  return;
++}
++
++/*
++** Create a "unicode61" tokenizer.
++*/
++static int fts5UnicodeCreate(
++  void *pUnused, 
++  const char **azArg, int nArg,
++  Fts5Tokenizer **ppOut
++){
++  int rc = SQLITE_OK;             /* Return code */
++  Unicode61Tokenizer *p = 0;      /* New tokenizer object */ 
++
++  UNUSED_PARAM(pUnused);
++
++  if( nArg%2 ){
++    rc = SQLITE_ERROR;
 +  }else{
-+    int iDC = sqlite3OsDeviceCharacteristics(pDbFd);
-+    if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; }
-+    if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){
-+      pRet->padToSectorBoundary = 0;
-     }
-+    *ppWal = pRet;
-+    WALTRACE(("WAL%d: opened\n", pRet));
-   }
-   return rc;
- }
- 
- /*
--** Begin a read transaction on the database.
--**
--** This routine used to be called sqlite3OpenSnapshot() and with good reason:
--** it takes a snapshot of the state of the WAL and wal-index for the current
--** instant in time.  The current thread will continue to use this snapshot.
--** Other threads might append new content to the WAL and wal-index but
--** that extra content is ignored by the current thread.
--**
--** If the database contents have changes since the previous read
--** transaction, then *pChanged is set to 1 before returning.  The
--** Pager layer will use this to know that is cache is stale and
--** needs to be flushed.
-+** Change the size to which the WAL file is trucated on each reset.
- */
--SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
--  int rc;                         /* Return code */
--  int cnt = 0;                    /* Number of TryBeginRead attempts */
--
--  do{
--    rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
--  }while( rc==WAL_RETRY );
--  testcase( (rc&0xff)==SQLITE_BUSY );
--  testcase( (rc&0xff)==SQLITE_IOERR );
--  testcase( rc==SQLITE_PROTOCOL );
--  testcase( rc==SQLITE_OK );
--  return rc;
-+SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){
-+  if( pWal ) pWal->mxWalSize = iLimit;
- }
- 
- /*
--** Finish with a read transaction.  All this does is release the
--** read-lock.
-+** Find the smallest page number out of all pages held in the WAL that
-+** has not been returned by any prior invocation of this method on the
-+** same WalIterator object.   Write into *piFrame the frame index where
-+** that page was last written into the WAL.  Write into *piPage the page
-+** number.
-+**
-+** Return 0 on success.  If there are no pages in the WAL with a page
-+** number larger than *piPage, then return 1.
- */
--SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){
--  sqlite3WalEndWriteTransaction(pWal);
--  if( pWal->readLock>=0 ){
--    walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
--    pWal->readLock = -1;
-+static int walIteratorNext(
-+  WalIterator *p,               /* Iterator */
-+  u32 *piPage,                  /* OUT: The page number of the next page */
-+  u32 *piFrame                  /* OUT: Wal frame index of next page */
-+){
-+  u32 iMin;                     /* Result pgno must be greater than iMin */
-+  u32 iRet = 0xFFFFFFFF;        /* 0xffffffff is never a valid page number */
-+  int i;                        /* For looping through segments */
-+
-+  iMin = p->iPrior;
-+  assert( iMin<0xffffffff );
-+  for(i=p->nSegment-1; i>=0; i--){
-+    struct WalSegment *pSegment = &p->aSegment[i];
-+    while( pSegment->iNext<pSegment->nEntry ){
-+      u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]];
-+      if( iPg>iMin ){
-+        if( iPg<iRet ){
-+          iRet = iPg;
-+          *piFrame = pSegment->iZero + pSegment->aIndex[pSegment->iNext];
++    p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer));
++    if( p ){
++      int i;
++      memset(p, 0, sizeof(Unicode61Tokenizer));
++      memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
++      p->bRemoveDiacritic = 1;
++      p->nFold = 64;
++      p->aFold = sqlite3_malloc(p->nFold * sizeof(char));
++      if( p->aFold==0 ){
++        rc = SQLITE_NOMEM;
++      }
++      for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
++        const char *zArg = azArg[i+1];
++        if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
++          if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
++            rc = SQLITE_ERROR;
++          }
++          p->bRemoveDiacritic = (zArg[0]=='1');
++        }else
++        if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
++          rc = fts5UnicodeAddExceptions(p, zArg, 1);
++        }else
++        if( 0==sqlite3_stricmp(azArg[i], "separators") ){
++          rc = fts5UnicodeAddExceptions(p, zArg, 0);
++        }else{
++          rc = SQLITE_ERROR;
 +        }
-+        break;
 +      }
-+      pSegment->iNext++;
++    }else{
++      rc = SQLITE_NOMEM;
 +    }
-   }
++    if( rc!=SQLITE_OK ){
++      fts5UnicodeDelete((Fts5Tokenizer*)p);
++      p = 0;
++    }
++    *ppOut = (Fts5Tokenizer*)p;
++  }
++  return rc;
++}
 +
-+  *piPage = p->iPrior = iRet;
-+  return (iRet==0xFFFFFFFF);
- }
- 
- /*
--** Search the wal file for page pgno. If found, set *piRead to the frame that
--** contains the page. Otherwise, if pgno is not in the wal file, set *piRead
--** to zero.
-+** This function merges two sorted lists into a single sorted list.
- **
--** Return SQLITE_OK if successful, or an error code if an error occurs. If an
--** error does occur, the final value of *piRead is undefined.
-+** aLeft[] and aRight[] are arrays of indices.  The sort key is
-+** aContent[aLeft[]] and aContent[aRight[]].  Upon entry, the following
-+** is guaranteed for all J<K:
-+**
-+**        aContent[aLeft[J]] < aContent[aLeft[K]]
-+**        aContent[aRight[J]] < aContent[aRight[K]]
-+**
-+** This routine overwrites aRight[] with a new (probably longer) sequence
-+** of indices such that the aRight[] contains every index that appears in
-+** either aLeft[] or the old aRight[] and such that the second condition
-+** above is still met.
-+**
-+** The aContent[aLeft[X]] values will be unique for all X.  And the
-+** aContent[aRight[X]] values will be unique too.  But there might be
-+** one or more combinations of X and Y such that
-+**
-+**      aLeft[X]!=aRight[Y]  &&  aContent[aLeft[X]] == aContent[aRight[Y]]
-+**
-+** When that happens, omit the aLeft[X] and use the aRight[Y] index.
- */
--SQLITE_PRIVATE int sqlite3WalFindFrame(
--  Wal *pWal,                      /* WAL handle */
--  Pgno pgno,                      /* Database page number to read data for */
--  u32 *piRead                     /* OUT: Frame number (or zero) */
-+static void walMerge(
-+  const u32 *aContent,            /* Pages in wal - keys for the sort */
-+  ht_slot *aLeft,                 /* IN: Left hand input list */
-+  int nLeft,                      /* IN: Elements in array *paLeft */
-+  ht_slot **paRight,              /* IN/OUT: Right hand input list */
-+  int *pnRight,                   /* IN/OUT: Elements in *paRight */
-+  ht_slot *aTmp                   /* Temporary buffer */
- ){
--  u32 iRead = 0;                  /* If !=0, WAL frame to return data from */
--  u32 iLast = pWal->hdr.mxFrame;  /* Last page in WAL for this reader */
--  int iHash;                      /* Used to loop through N hash tables */
-+  int iLeft = 0;                  /* Current index in aLeft */
-+  int iRight = 0;                 /* Current index in aRight */
-+  int iOut = 0;                   /* Current index in output buffer */
-+  int nRight = *pnRight;
-+  ht_slot *aRight = *paRight;
- 
--  /* This routine is only be called from within a read transaction. */
--  assert( pWal->readLock>=0 || pWal->lockError );
-+  assert( nLeft>0 && nRight>0 );
-+  while( iRight<nRight || iLeft<nLeft ){
-+    ht_slot logpage;
-+    Pgno dbpage;
- 
--  /* If the "last page" field of the wal-index header snapshot is 0, then
--  ** no data will be read from the wal under any circumstances. Return early
--  ** in this case as an optimization.  Likewise, if pWal->readLock==0, 
--  ** then the WAL is ignored by the reader so return early, as if the 
--  ** WAL were empty.
--  */
--  if( iLast==0 || pWal->readLock==0 ){
--    *piRead = 0;
--    return SQLITE_OK;
-+    if( (iLeft<nLeft) 
-+     && (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]])
-+    ){
-+      logpage = aLeft[iLeft++];
-+    }else{
-+      logpage = aRight[iRight++];
++/*
++** Return true if, for the purposes of tokenizing with the tokenizer
++** passed as the first argument, codepoint iCode is considered a token 
++** character (not a separator).
++*/
++static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
++  assert( (sqlite3Fts5UnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
++  return sqlite3Fts5UnicodeIsalnum(iCode) ^ fts5UnicodeIsException(p, iCode);
++}
++
++static int fts5UnicodeTokenize(
++  Fts5Tokenizer *pTokenizer,
++  void *pCtx,
++  int iUnused,
++  const char *pText, int nText,
++  int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
++){
++  Unicode61Tokenizer *p = (Unicode61Tokenizer*)pTokenizer;
++  int rc = SQLITE_OK;
++  unsigned char *a = p->aTokenChar;
++
++  unsigned char *zTerm = (unsigned char*)&pText[nText];
++  unsigned char *zCsr = (unsigned char *)pText;
++
++  /* Output buffer */
++  char *aFold = p->aFold;
++  int nFold = p->nFold;
++  const char *pEnd = &aFold[nFold-6];
++
++  UNUSED_PARAM(iUnused);
++
++  /* Each iteration of this loop gobbles up a contiguous run of separators,
++  ** then the next token.  */
++  while( rc==SQLITE_OK ){
++    int iCode;                    /* non-ASCII codepoint read from input */
++    char *zOut = aFold;
++    int is;
++    int ie;
++
++    /* Skip any separator characters. */
++    while( 1 ){
++      if( zCsr>=zTerm ) goto tokenize_done;
++      if( *zCsr & 0x80 ) {
++        /* A character outside of the ascii range. Skip past it if it is
++        ** a separator character. Or break out of the loop if it is not. */
++        is = zCsr - (unsigned char*)pText;
++        READ_UTF8(zCsr, zTerm, iCode);
++        if( fts5UnicodeIsAlnum(p, iCode) ){
++          goto non_ascii_tokenchar;
++        }
++      }else{
++        if( a[*zCsr] ){
++          is = zCsr - (unsigned char*)pText;
++          goto ascii_tokenchar;
++        }
++        zCsr++;
++      }
 +    }
-+    dbpage = aContent[logpage];
 +
-+    aTmp[iOut++] = logpage;
-+    if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++;
++    /* Run through the tokenchars. Fold them into the output buffer along
++    ** the way.  */
++    while( zCsr<zTerm ){
++
++      /* Grow the output buffer so that there is sufficient space to fit the
++      ** largest possible utf-8 character.  */
++      if( zOut>pEnd ){
++        aFold = sqlite3_malloc(nFold*2);
++        if( aFold==0 ){
++          rc = SQLITE_NOMEM;
++          goto tokenize_done;
++        }
++        zOut = &aFold[zOut - p->aFold];
++        memcpy(aFold, p->aFold, nFold);
++        sqlite3_free(p->aFold);
++        p->aFold = aFold;
++        p->nFold = nFold = nFold*2;
++        pEnd = &aFold[nFold-6];
++      }
++
++      if( *zCsr & 0x80 ){
++        /* An non-ascii-range character. Fold it into the output buffer if
++        ** it is a token character, or break out of the loop if it is not. */
++        READ_UTF8(zCsr, zTerm, iCode);
++        if( fts5UnicodeIsAlnum(p,iCode)||sqlite3Fts5UnicodeIsdiacritic(iCode) ){
++ non_ascii_tokenchar:
++          iCode = sqlite3Fts5UnicodeFold(iCode, p->bRemoveDiacritic);
++          if( iCode ) WRITE_UTF8(zOut, iCode);
++        }else{
++          break;
++        }
++      }else if( a[*zCsr]==0 ){
++        /* An ascii-range separator character. End of token. */
++        break; 
++      }else{
++ ascii_tokenchar:
++        if( *zCsr>='A' && *zCsr<='Z' ){
++          *zOut++ = *zCsr + 32;
++        }else{
++          *zOut++ = *zCsr;
++        }
++        zCsr++;
++      }
++      ie = zCsr - (unsigned char*)pText;
++    }
++
++    /* Invoke the token callback */
++    rc = xToken(pCtx, 0, aFold, zOut-aFold, is, ie); 
++  }
++  
++ tokenize_done:
++  if( rc==SQLITE_DONE ) rc = SQLITE_OK;
++  return rc;
++}
++
++/**************************************************************************
++** Start of porter stemmer implementation.
++*/
++
++/* Any tokens larger than this (in bytes) are passed through without
++** stemming. */
++#define FTS5_PORTER_MAX_TOKEN 64
++
++typedef struct PorterTokenizer PorterTokenizer;
++struct PorterTokenizer {
++  fts5_tokenizer tokenizer;       /* Parent tokenizer module */
++  Fts5Tokenizer *pTokenizer;      /* Parent tokenizer instance */
++  char aBuf[FTS5_PORTER_MAX_TOKEN + 64];
++};
 +
-+    assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage );
-+    assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage );
-   }
- 
--  /* Search the hash table or tables for an entry matching page number
--  ** pgno. Each iteration of the following for() loop searches one
--  ** hash table (each hash table indexes up to HASHTABLE_NPAGE frames).
--  **
--  ** This code might run concurrently to the code in walIndexAppend()
--  ** that adds entries to the wal-index (and possibly to this hash 
--  ** table). This means the value just read from the hash 
--  ** slot (aHash[iKey]) may have been added before or after the 
--  ** current read transaction was opened. Values added after the
--  ** read transaction was opened may have been written incorrectly -
--  ** i.e. these slots may contain garbage data. However, we assume
--  ** that any slots written before the current read transaction was
--  ** opened remain unmodified.
--  **
--  ** For the reasons above, the if(...) condition featured in the inner
--  ** loop of the following block is more stringent that would be required 
--  ** if we had exclusive access to the hash-table:
--  **
--  **   (aPgno[iFrame]==pgno): 
--  **     This condition filters out normal hash-table collisions.
--  **
--  **   (iFrame<=iLast): 
--  **     This condition filters out entries that were added to the hash
--  **     table after the current read-transaction had started.
--  */
--  for(iHash=walFramePage(iLast); iHash>=0 && iRead==0; iHash--){
--    volatile ht_slot *aHash;      /* Pointer to hash table */
--    volatile u32 *aPgno;          /* Pointer to array of page numbers */
--    u32 iZero;                    /* Frame number corresponding to aPgno[0] */
--    int iKey;                     /* Hash slot index */
--    int nCollide;                 /* Number of hash collisions remaining */
--    int rc;                       /* Error code */
-+  *paRight = aLeft;
-+  *pnRight = iOut;
-+  memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut);
-+}
- 
--    rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero);
--    if( rc!=SQLITE_OK ){
--      return rc;
 +/*
-+** Sort the elements in list aList using aContent[] as the sort key.
-+** Remove elements with duplicate keys, preferring to keep the
-+** larger aList[] values.
-+**
-+** The aList[] entries are indices into aContent[].  The values in
-+** aList[] are to be sorted so that for all J<K:
-+**
-+**      aContent[aList[J]] < aContent[aList[K]]
-+**
-+** For any X and Y such that
-+**
-+**      aContent[aList[X]] == aContent[aList[Y]]
-+**
-+** Keep the larger of the two values aList[X] and aList[Y] and discard
-+** the smaller.
++** Delete a "porter" tokenizer.
++*/
++static void fts5PorterDelete(Fts5Tokenizer *pTok){
++  if( pTok ){
++    PorterTokenizer *p = (PorterTokenizer*)pTok;
++    if( p->pTokenizer ){
++      p->tokenizer.xDelete(p->pTokenizer);
++    }
++    sqlite3_free(p);
++  }
++}
++
++/*
++** Create a "porter" tokenizer.
 +*/
-+static void walMergesort(
-+  const u32 *aContent,            /* Pages in wal */
-+  ht_slot *aBuffer,               /* Buffer of at least *pnList items to use */
-+  ht_slot *aList,                 /* IN/OUT: List to sort */
-+  int *pnList                     /* IN/OUT: Number of elements in aList[] */
++static int fts5PorterCreate(
++  void *pCtx, 
++  const char **azArg, int nArg,
++  Fts5Tokenizer **ppOut
 +){
-+  struct Sublist {
-+    int nList;                    /* Number of elements in aList */
-+    ht_slot *aList;               /* Pointer to sub-list content */
-+  };
++  fts5_api *pApi = (fts5_api*)pCtx;
++  int rc = SQLITE_OK;
++  PorterTokenizer *pRet;
++  void *pUserdata = 0;
++  const char *zBase = "unicode61";
 +
-+  const int nList = *pnList;      /* Size of input list */
-+  int nMerge = 0;                 /* Number of elements in list aMerge */
-+  ht_slot *aMerge = 0;            /* List to be merged */
-+  int iList;                      /* Index into input list */
-+  int iSub = 0;                   /* Index into aSub array */
-+  struct Sublist aSub[13];        /* Array of sub-lists */
-+
-+  memset(aSub, 0, sizeof(aSub));
-+  assert( nList<=HASHTABLE_NPAGE && nList>0 );
-+  assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) );
-+
-+  for(iList=0; iList<nList; iList++){
-+    nMerge = 1;
-+    aMerge = &aList[iList];
-+    for(iSub=0; iList & (1<<iSub); iSub++){
-+      struct Sublist *p = &aSub[iSub];
-+      assert( p->aList && p->nList<=(1<<iSub) );
-+      assert( p->aList==&aList[iList&~((2<<iSub)-1)] );
-+      walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
-     }
--    nCollide = HASHTABLE_NSLOT;
--    for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
--      u32 iFrame = aHash[iKey] + iZero;
--      if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){
--        assert( iFrame>iRead || CORRUPT_DB );
--        iRead = iFrame;
--      }
--      if( (nCollide--)==0 ){
--        return SQLITE_CORRUPT_BKPT;
--      }
-+    aSub[iSub].aList = aMerge;
-+    aSub[iSub].nList = nMerge;
++  if( nArg>0 ){
++    zBase = azArg[0];
 +  }
 +
-+  for(iSub++; iSub<ArraySize(aSub); iSub++){
-+    if( nList & (1<<iSub) ){
-+      struct Sublist *p = &aSub[iSub];
-+      assert( p->nList<=(1<<iSub) );
-+      assert( p->aList==&aList[nList&~((2<<iSub)-1)] );
-+      walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
-     }
-   }
-+  assert( aMerge==aList );
-+  *pnList = nMerge;
- 
--#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
--  /* If expensive assert() statements are available, do a linear search
--  ** of the wal-index file content. Make sure the results agree with the
--  ** result obtained using the hash indexes above.  */
-+#ifdef SQLITE_DEBUG
-   {
--    u32 iRead2 = 0;
--    u32 iTest;
--    for(iTest=iLast; iTest>0; iTest--){
--      if( walFramePgno(pWal, iTest)==pgno ){
--        iRead2 = iTest;
--        break;
--      }
-+    int i;
-+    for(i=1; i<*pnList; i++){
-+      assert( aContent[aList[i]] > aContent[aList[i-1]] );
-     }
--    assert( iRead==iRead2 );
-   }
- #endif
--
--  *piRead = iRead;
--  return SQLITE_OK;
--}
--
--/*
--** Read the contents of frame iRead from the wal file into buffer pOut
--** (which is nOut bytes in size). Return SQLITE_OK if successful, or an
--** error code otherwise.
--*/
--SQLITE_PRIVATE int sqlite3WalReadFrame(
--  Wal *pWal,                      /* WAL handle */
--  u32 iRead,                      /* Frame to read */
--  int nOut,                       /* Size of buffer pOut in bytes */
--  u8 *pOut                        /* Buffer to write page data to */
--){
--  int sz;
--  i64 iOffset;
--  sz = pWal->hdr.szPage;
--  sz = (sz&0xfe00) + ((sz&0x0001)<<16);
--  testcase( sz<=32768 );
--  testcase( sz>=65536 );
--  iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
--  /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
--  return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset);
- }
- 
- /* 
--** Return the size of the database in pages (or zero, if unknown).
-+** Free an iterator allocated by walIteratorInit().
- */
--SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){
--  if( pWal && ALWAYS(pWal->readLock>=0) ){
--    return pWal->hdr.nPage;
--  }
--  return 0;
-+static void walIteratorFree(WalIterator *p){
-+  sqlite3_free(p);
- }
- 
--
--/* 
--** This function starts a write transaction on the WAL.
--**
--** A read transaction must have already been started by a prior call
--** to sqlite3WalBeginReadTransaction().
-+/*
-+** Construct a WalInterator object that can be used to loop over all 
-+** pages in the WAL in ascending order. The caller must hold the checkpoint
-+** lock.
- **
--** If another thread or process has written into the database since
--** the read transaction was started, then it is not possible for this
--** thread to write as doing so would cause a fork.  So this routine
--** returns SQLITE_BUSY in that case and no write transaction is started.
-+** On success, make *pp point to the newly allocated WalInterator object
-+** return SQLITE_OK. Otherwise, return an error code. If this routine
-+** returns an error, the value of *pp is undefined.
- **
--** There can only be a single writer active at a time.
-+** The calling routine should invoke walIteratorFree() to destroy the
-+** WalIterator object when it has finished with it.
- */
--SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
--  int rc;
-+static int walIteratorInit(Wal *pWal, WalIterator **pp){
-+  WalIterator *p;                 /* Return value */
-+  int nSegment;                   /* Number of segments to merge */
-+  u32 iLast;                      /* Last frame in log */
-+  int nByte;                      /* Number of bytes to allocate */
-+  int i;                          /* Iterator variable */
-+  ht_slot *aTmp;                  /* Temp space used by merge-sort */
-+  int rc = SQLITE_OK;             /* Return Code */
- 
--  /* Cannot start a write transaction without first holding a read
--  ** transaction. */
--  assert( pWal->readLock>=0 );
-+  /* This routine only runs while holding the checkpoint lock. And
-+  ** it only runs if there is actually content in the log (mxFrame>0).
-+  */
-+  assert( pWal->ckptLock && pWal->hdr.mxFrame>0 );
-+  iLast = pWal->hdr.mxFrame;
- 
--  if( pWal->readOnly ){
--    return SQLITE_READONLY;
-+  /* Allocate space for the WalIterator object. */
-+  nSegment = walFramePage(iLast) + 1;
-+  nByte = sizeof(WalIterator) 
-+        + (nSegment-1)*sizeof(struct WalSegment)
-+        + iLast*sizeof(ht_slot);
-+  p = (WalIterator *)sqlite3_malloc64(nByte);
-+  if( !p ){
-+    return SQLITE_NOMEM;
-   }
-+  memset(p, 0, nByte);
-+  p->nSegment = nSegment;
- 
--  /* Only one writer allowed at a time.  Get the write lock.  Return
--  ** SQLITE_BUSY if unable.
-+  /* Allocate temporary space used by the merge-sort routine. This block
-+  ** of memory will be freed before this function returns.
-   */
--  rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0);
--  if( rc ){
--    return rc;
-+  aTmp = (ht_slot *)sqlite3_malloc64(
-+      sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
-+  );
-+  if( !aTmp ){
++  pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer));
++  if( pRet ){
++    memset(pRet, 0, sizeof(PorterTokenizer));
++    rc = pApi->xFindTokenizer(pApi, zBase, &pUserdata, &pRet->tokenizer);
++  }else{
 +    rc = SQLITE_NOMEM;
-   }
--  pWal->writeLock = 1;
- 
--  /* If another connection has written to the database file since the
--  ** time the read transaction on this connection was started, then
--  ** the write is disallowed.
--  */
--  if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
--    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
--    pWal->writeLock = 0;
--    rc = SQLITE_BUSY_SNAPSHOT;
-+  for(i=0; rc==SQLITE_OK && i<nSegment; i++){
-+    volatile ht_slot *aHash;
-+    u32 iZero;
-+    volatile u32 *aPgno;
-+
-+    rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero);
-+    if( rc==SQLITE_OK ){
-+      int j;                      /* Counter variable */
-+      int nEntry;                 /* Number of entries in this segment */
-+      ht_slot *aIndex;            /* Sorted index for this segment */
++  }
++  if( rc==SQLITE_OK ){
++    int nArg2 = (nArg>0 ? nArg-1 : 0);
++    const char **azArg2 = (nArg2 ? &azArg[1] : 0);
++    rc = pRet->tokenizer.xCreate(pUserdata, azArg2, nArg2, &pRet->pTokenizer);
++  }
 +
-+      aPgno++;
-+      if( (i+1)==nSegment ){
-+        nEntry = (int)(iLast - iZero);
-+      }else{
-+        nEntry = (int)((u32*)aHash - (u32*)aPgno);
++  if( rc!=SQLITE_OK ){
++    fts5PorterDelete((Fts5Tokenizer*)pRet);
++    pRet = 0;
++  }
++  *ppOut = (Fts5Tokenizer*)pRet;
++  return rc;
++}
++
++typedef struct PorterContext PorterContext;
++struct PorterContext {
++  void *pCtx;
++  int (*xToken)(void*, int, const char*, int, int, int);
++  char *aBuf;
++};
++
++typedef struct PorterRule PorterRule;
++struct PorterRule {
++  const char *zSuffix;
++  int nSuffix;
++  int (*xCond)(char *zStem, int nStem);
++  const char *zOutput;
++  int nOutput;
++};
++
++#if 0
++static int fts5PorterApply(char *aBuf, int *pnBuf, PorterRule *aRule){
++  int ret = -1;
++  int nBuf = *pnBuf;
++  PorterRule *p;
++
++  for(p=aRule; p->zSuffix; p++){
++    assert( strlen(p->zSuffix)==p->nSuffix );
++    assert( strlen(p->zOutput)==p->nOutput );
++    if( nBuf<p->nSuffix ) continue;
++    if( 0==memcmp(&aBuf[nBuf - p->nSuffix], p->zSuffix, p->nSuffix) ) break;
++  }
++
++  if( p->zSuffix ){
++    int nStem = nBuf - p->nSuffix;
++    if( p->xCond==0 || p->xCond(aBuf, nStem) ){
++      memcpy(&aBuf[nStem], p->zOutput, p->nOutput);
++      *pnBuf = nStem + p->nOutput;
++      ret = p - aRule;
++    }
++  }
++
++  return ret;
++}
++#endif
++
++static int fts5PorterIsVowel(char c, int bYIsVowel){
++  return (
++      c=='a' || c=='e' || c=='i' || c=='o' || c=='u' || (bYIsVowel && c=='y')
++  );
++}
++
++static int fts5PorterGobbleVC(char *zStem, int nStem, int bPrevCons){
++  int i;
++  int bCons = bPrevCons;
++
++  /* Scan for a vowel */
++  for(i=0; i<nStem; i++){
++    if( 0==(bCons = !fts5PorterIsVowel(zStem[i], bCons)) ) break;
++  }
++
++  /* Scan for a consonent */
++  for(i++; i<nStem; i++){
++    if( (bCons = !fts5PorterIsVowel(zStem[i], bCons)) ) return i+1;
++  }
++  return 0;
++}
++
++/* porter rule condition: (m > 0) */
++static int fts5Porter_MGt0(char *zStem, int nStem){
++  return !!fts5PorterGobbleVC(zStem, nStem, 0);
++}
++
++/* porter rule condition: (m > 1) */
++static int fts5Porter_MGt1(char *zStem, int nStem){
++  int n;
++  n = fts5PorterGobbleVC(zStem, nStem, 0);
++  if( n && fts5PorterGobbleVC(&zStem[n], nStem-n, 1) ){
++    return 1;
++  }
++  return 0;
++}
++
++/* porter rule condition: (m = 1) */
++static int fts5Porter_MEq1(char *zStem, int nStem){
++  int n;
++  n = fts5PorterGobbleVC(zStem, nStem, 0);
++  if( n && 0==fts5PorterGobbleVC(&zStem[n], nStem-n, 1) ){
++    return 1;
++  }
++  return 0;
++}
++
++/* porter rule condition: (*o) */
++static int fts5Porter_Ostar(char *zStem, int nStem){
++  if( zStem[nStem-1]=='w' || zStem[nStem-1]=='x' || zStem[nStem-1]=='y' ){
++    return 0;
++  }else{
++    int i;
++    int mask = 0;
++    int bCons = 0;
++    for(i=0; i<nStem; i++){
++      bCons = !fts5PorterIsVowel(zStem[i], bCons);
++      assert( bCons==0 || bCons==1 );
++      mask = (mask << 1) + bCons;
++    }
++    return ((mask & 0x0007)==0x0005);
++  }
++}
++
++/* porter rule condition: (m > 1 and (*S or *T)) */
++static int fts5Porter_MGt1_and_S_or_T(char *zStem, int nStem){
++  assert( nStem>0 );
++  return (zStem[nStem-1]=='s' || zStem[nStem-1]=='t') 
++      && fts5Porter_MGt1(zStem, nStem);
++}
++
++/* porter rule condition: (*v*) */
++static int fts5Porter_Vowel(char *zStem, int nStem){
++  int i;
++  for(i=0; i<nStem; i++){
++    if( fts5PorterIsVowel(zStem[i], i>0) ){
++      return 1;
++    }
++  }
++  return 0;
++}
++
++
++/**************************************************************************
++***************************************************************************
++** GENERATED CODE STARTS HERE (mkportersteps.tcl)
++*/
++
++static int fts5PorterStep4(char *aBuf, int *pnBuf){
++  int ret = 0;
++  int nBuf = *pnBuf;
++  switch( aBuf[nBuf-2] ){
++    
++    case 'a': 
++      if( nBuf>2 && 0==memcmp("al", &aBuf[nBuf-2], 2) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-2) ){
++          *pnBuf = nBuf - 2;
++        }
++      }
++      break;
++  
++    case 'c': 
++      if( nBuf>4 && 0==memcmp("ance", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-4) ){
++          *pnBuf = nBuf - 4;
++        }
++      }else if( nBuf>4 && 0==memcmp("ence", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-4) ){
++          *pnBuf = nBuf - 4;
++        }
++      }
++      break;
++  
++    case 'e': 
++      if( nBuf>2 && 0==memcmp("er", &aBuf[nBuf-2], 2) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-2) ){
++          *pnBuf = nBuf - 2;
++        }
++      }
++      break;
++  
++    case 'i': 
++      if( nBuf>2 && 0==memcmp("ic", &aBuf[nBuf-2], 2) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-2) ){
++          *pnBuf = nBuf - 2;
++        }
++      }
++      break;
++  
++    case 'l': 
++      if( nBuf>4 && 0==memcmp("able", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-4) ){
++          *pnBuf = nBuf - 4;
++        }
++      }else if( nBuf>4 && 0==memcmp("ible", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-4) ){
++          *pnBuf = nBuf - 4;
++        }
++      }
++      break;
++  
++    case 'n': 
++      if( nBuf>3 && 0==memcmp("ant", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-3) ){
++          *pnBuf = nBuf - 3;
++        }
++      }else if( nBuf>5 && 0==memcmp("ement", &aBuf[nBuf-5], 5) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-5) ){
++          *pnBuf = nBuf - 5;
++        }
++      }else if( nBuf>4 && 0==memcmp("ment", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-4) ){
++          *pnBuf = nBuf - 4;
++        }
++      }else if( nBuf>3 && 0==memcmp("ent", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-3) ){
++          *pnBuf = nBuf - 3;
++        }
++      }
++      break;
++  
++    case 'o': 
++      if( nBuf>3 && 0==memcmp("ion", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt1_and_S_or_T(aBuf, nBuf-3) ){
++          *pnBuf = nBuf - 3;
++        }
++      }else if( nBuf>2 && 0==memcmp("ou", &aBuf[nBuf-2], 2) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-2) ){
++          *pnBuf = nBuf - 2;
++        }
++      }
++      break;
++  
++    case 's': 
++      if( nBuf>3 && 0==memcmp("ism", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-3) ){
++          *pnBuf = nBuf - 3;
++        }
 +      }
-+      aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero];
-+      iZero++;
++      break;
 +  
-+      for(j=0; j<nEntry; j++){
-+        aIndex[j] = (ht_slot)j;
++    case 't': 
++      if( nBuf>3 && 0==memcmp("ate", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-3) ){
++          *pnBuf = nBuf - 3;
++        }
++      }else if( nBuf>3 && 0==memcmp("iti", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-3) ){
++          *pnBuf = nBuf - 3;
++        }
 +      }
-+      walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
-+      p->aSegment[i].iZero = iZero;
-+      p->aSegment[i].nEntry = nEntry;
-+      p->aSegment[i].aIndex = aIndex;
-+      p->aSegment[i].aPgno = (u32 *)aPgno;
-+    }
++      break;
++  
++    case 'u': 
++      if( nBuf>3 && 0==memcmp("ous", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-3) ){
++          *pnBuf = nBuf - 3;
++        }
++      }
++      break;
++  
++    case 'v': 
++      if( nBuf>3 && 0==memcmp("ive", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-3) ){
++          *pnBuf = nBuf - 3;
++        }
++      }
++      break;
++  
++    case 'z': 
++      if( nBuf>3 && 0==memcmp("ize", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt1(aBuf, nBuf-3) ){
++          *pnBuf = nBuf - 3;
++        }
++      }
++      break;
++  
 +  }
-+  sqlite3_free(aTmp);
-+
-+  if( rc!=SQLITE_OK ){
-+    walIteratorFree(p);
-   }
-+  *pp = p;
-+  return rc;
-+}
- 
-+/*
-+** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
-+** n. If the attempt fails and parameter xBusy is not NULL, then it is a
-+** busy-handler function. Invoke it and retry the lock until either the
-+** lock is successfully obtained or the busy-handler returns 0.
-+*/
-+static int walBusyLock(
-+  Wal *pWal,                      /* WAL connection */
-+  int (*xBusy)(void*),            /* Function to call when busy */
-+  void *pBusyArg,                 /* Context argument for xBusyHandler */
-+  int lockIdx,                    /* Offset of first byte to lock */
-+  int n                           /* Number of bytes to lock */
-+){
-+  int rc;
-+  do {
-+    rc = walLockExclusive(pWal, lockIdx, n, 0);
-+  }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
-   return rc;
- }
- 
- /*
--** End a write transaction.  The commit has already been done.  This
--** routine merely releases the lock.
-+** The cache of the wal-index header must be valid to call this function.
-+** Return the page-size in bytes used by the database.
-+*/
-+static int walPagesize(Wal *pWal){
-+  return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
++  return ret;
 +}
++  
 +
-+/*
-+** The following is guaranteed when this function is called:
-+**
-+**   a) the WRITER lock is held,
-+**   b) the entire log file has been checkpointed, and
-+**   c) any existing readers are reading exclusively from the database
-+**      file - there are no readers that may attempt to read a frame from
-+**      the log file.
-+**
-+** This function updates the shared-memory structures so that the next
-+** client to write to the database (which may be this one) does so by
-+** writing frames into the start of the log file.
-+**
-+** The value of parameter salt1 is used as the aSalt[1] value in the 
-+** new wal-index header. It should be passed a pseudo-random value (i.e. 
-+** one obtained from sqlite3_randomness()).
- */
--SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){
--  if( pWal->writeLock ){
--    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
--    pWal->writeLock = 0;
--    pWal->truncateOnCommit = 0;
--  }
--  return SQLITE_OK;
-+static void walRestartHdr(Wal *pWal, u32 salt1){
-+  volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
-+  int i;                          /* Loop counter */
-+  u32 *aSalt = pWal->hdr.aSalt;   /* Big-endian salt values */
-+  pWal->nCkpt++;
-+  pWal->hdr.mxFrame = 0;
-+  sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
-+  memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
-+  walIndexWriteHdr(pWal);
-+  pInfo->nBackfill = 0;
-+  pInfo->aReadMark[1] = 0;
-+  for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
-+  assert( pInfo->aReadMark[0]==0 );
- }
- 
- /*
--** If any data has been written (but not committed) to the log file, this
--** function moves the write-pointer back to the start of the transaction.
-+** Copy as much content as we can from the WAL back into the database file
-+** in response to an sqlite3_wal_checkpoint() request or the equivalent.
- **
--** Additionally, the callback function is invoked for each frame written
--** to the WAL since the start of the transaction. If the callback returns
--** other than SQLITE_OK, it is not invoked again and the error code is
--** returned to the caller.
-+** The amount of information copies from WAL to database might be limited
-+** by active readers.  This routine will never overwrite a database page
-+** that a concurrent reader might be using.
- **
--** Otherwise, if the callback function does not return an error, this
--** function returns SQLITE_OK.
-+** All I/O barrier operations (a.k.a fsyncs) occur in this routine when
-+** SQLite is in WAL-mode in synchronous=NORMAL.  That means that if 
-+** checkpoints are always run by a background thread or background 
-+** process, foreground threads will never block on a lengthy fsync call.
-+**
-+** Fsync is called on the WAL before writing content out of the WAL and
-+** into the database.  This ensures that if the new content is persistent
-+** in the WAL and can be recovered following a power-loss or hard reset.
-+**
-+** Fsync is also called on the database file if (and only if) the entire
-+** WAL content is copied into the database file.  This second fsync makes
-+** it safe to delete the WAL since the new content will persist in the
-+** database file.
-+**
-+** This routine uses and updates the nBackfill field of the wal-index header.
-+** This is the only routine that will increase the value of nBackfill.  
-+** (A WAL reset or recovery will revert nBackfill to zero, but not increase
-+** its value.)
-+**
-+** The caller must be holding sufficient locks to ensure that no other
-+** checkpoint is running (in any other thread or process) at the same
-+** time.
- */
--SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){
--  int rc = SQLITE_OK;
--  if( ALWAYS(pWal->writeLock) ){
--    Pgno iMax = pWal->hdr.mxFrame;
--    Pgno iFrame;
--  
--    /* Restore the clients cache of the wal-index header to the state it
--    ** was in before the client began writing to the database. 
-+static int walCheckpoint(
-+  Wal *pWal,                      /* Wal connection */
-+  int eMode,                      /* One of PASSIVE, FULL or RESTART */
-+  int (*xBusy)(void*),            /* Function to call when busy */
-+  void *pBusyArg,                 /* Context argument for xBusyHandler */
-+  int sync_flags,                 /* Flags for OsSync() (or 0) */
-+  u8 *zBuf                        /* Temporary buffer to use */
-+){
-+  int rc = SQLITE_OK;             /* Return code */
-+  int szPage;                     /* Database page-size */
-+  WalIterator *pIter = 0;         /* Wal iterator context */
-+  u32 iDbpage = 0;                /* Next database page to write */
-+  u32 iFrame = 0;                 /* Wal frame containing data for iDbpage */
-+  u32 mxSafeFrame;                /* Max frame that can be backfilled */
-+  u32 mxPage;                     /* Max database page to write */
-+  int i;                          /* Loop counter */
-+  volatile WalCkptInfo *pInfo;    /* The checkpoint status information */
-+
-+  szPage = walPagesize(pWal);
-+  testcase( szPage<=32768 );
-+  testcase( szPage>=65536 );
-+  pInfo = walCkptInfo(pWal);
-+  if( pInfo->nBackfill<pWal->hdr.mxFrame ){
-+
-+    /* Allocate the iterator */
-+    rc = walIteratorInit(pWal, &pIter);
-+    if( rc!=SQLITE_OK ){
-+      return rc;
-+    }
-+    assert( pIter );
-+
-+    /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
-+    ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
-+    assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
++static int fts5PorterStep1B2(char *aBuf, int *pnBuf){
++  int ret = 0;
++  int nBuf = *pnBuf;
++  switch( aBuf[nBuf-2] ){
++    
++    case 'a': 
++      if( nBuf>2 && 0==memcmp("at", &aBuf[nBuf-2], 2) ){
++        memcpy(&aBuf[nBuf-2], "ate", 3);
++        *pnBuf = nBuf - 2 + 3;
++        ret = 1;
++      }
++      break;
++  
++    case 'b': 
++      if( nBuf>2 && 0==memcmp("bl", &aBuf[nBuf-2], 2) ){
++        memcpy(&aBuf[nBuf-2], "ble", 3);
++        *pnBuf = nBuf - 2 + 3;
++        ret = 1;
++      }
++      break;
++  
++    case 'i': 
++      if( nBuf>2 && 0==memcmp("iz", &aBuf[nBuf-2], 2) ){
++        memcpy(&aBuf[nBuf-2], "ize", 3);
++        *pnBuf = nBuf - 2 + 3;
++        ret = 1;
++      }
++      break;
++  
++  }
++  return ret;
++}
++  
 +
-+    /* Compute in mxSafeFrame the index of the last frame of the WAL that is
-+    ** safe to write into the database.  Frames beyond mxSafeFrame might
-+    ** overwrite database pages that are in use by active readers and thus
-+    ** cannot be backfilled from the WAL.
-     */
--    memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr));
-+    mxSafeFrame = pWal->hdr.mxFrame;
-+    mxPage = pWal->hdr.nPage;
-+    for(i=1; i<WAL_NREADER; i++){
-+      /* Thread-sanitizer reports that the following is an unsafe read,
-+      ** as some other thread may be in the process of updating the value
-+      ** of the aReadMark[] slot. The assumption here is that if that is
-+      ** happening, the other client may only be increasing the value,
-+      ** not decreasing it. So assuming either that either the "old" or
-+      ** "new" version of the value is read, and not some arbitrary value
-+      ** that would never be written by a real client, things are still 
-+      ** safe.  */
-+      u32 y = pInfo->aReadMark[i];
-+      if( mxSafeFrame>y ){
-+        assert( y<=pWal->hdr.mxFrame );
-+        rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
-+        if( rc==SQLITE_OK ){
-+          pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
-+          walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
-+        }else if( rc==SQLITE_BUSY ){
-+          mxSafeFrame = y;
-+          xBusy = 0;
-+        }else{
-+          goto walcheckpoint_out;
++static int fts5PorterStep2(char *aBuf, int *pnBuf){
++  int ret = 0;
++  int nBuf = *pnBuf;
++  switch( aBuf[nBuf-2] ){
++    
++    case 'a': 
++      if( nBuf>7 && 0==memcmp("ational", &aBuf[nBuf-7], 7) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-7) ){
++          memcpy(&aBuf[nBuf-7], "ate", 3);
++          *pnBuf = nBuf - 7 + 3;
++        }
++      }else if( nBuf>6 && 0==memcmp("tional", &aBuf[nBuf-6], 6) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-6) ){
++          memcpy(&aBuf[nBuf-6], "tion", 4);
++          *pnBuf = nBuf - 6 + 4;
 +        }
 +      }
-+    }
- 
--    for(iFrame=pWal->hdr.mxFrame+1; 
--        ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; 
--        iFrame++
-+    if( pInfo->nBackfill<mxSafeFrame
-+     && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
-     ){
--      /* This call cannot fail. Unless the page for which the page number
--      ** is passed as the second argument is (a) in the cache and 
--      ** (b) has an outstanding reference, then xUndo is either a no-op
--      ** (if (a) is false) or simply expels the page from the cache (if (b)
--      ** is false).
--      **
--      ** If the upper layer is doing a rollback, it is guaranteed that there
--      ** are no outstanding references to any page other than page 1. And
--      ** page 1 is never written to the log until the transaction is
--      ** committed. As a result, the call to xUndo may not fail.
--      */
--      assert( walFramePgno(pWal, iFrame)!=1 );
--      rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame));
--    }
--    if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
--  }
--  return rc;
--}
-+      i64 nSize;                    /* Current size of database file */
-+      u32 nBackfill = pInfo->nBackfill;
- 
--/* 
--** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 
--** values. This function populates the array with values required to 
--** "rollback" the write position of the WAL handle back to the current 
--** point in the event of a savepoint rollback (via WalSavepointUndo()).
--*/
--SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){
--  assert( pWal->writeLock );
--  aWalData[0] = pWal->hdr.mxFrame;
--  aWalData[1] = pWal->hdr.aFrameCksum[0];
--  aWalData[2] = pWal->hdr.aFrameCksum[1];
--  aWalData[3] = pWal->nCkpt;
--}
-+      /* Sync the WAL to disk */
-+      if( sync_flags ){
-+        rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
++      break;
++  
++    case 'c': 
++      if( nBuf>4 && 0==memcmp("enci", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-4) ){
++          memcpy(&aBuf[nBuf-4], "ence", 4);
++          *pnBuf = nBuf - 4 + 4;
++        }
++      }else if( nBuf>4 && 0==memcmp("anci", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-4) ){
++          memcpy(&aBuf[nBuf-4], "ance", 4);
++          *pnBuf = nBuf - 4 + 4;
++        }
 +      }
- 
--/* 
--** Move the write position of the WAL back to the point identified by
--** the values in the aWalData[] array. aWalData must point to an array
--** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated
--** by a call to WalSavepoint().
--*/
--SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
--  int rc = SQLITE_OK;
-+      /* If the database may grow as a result of this checkpoint, hint
-+      ** about the eventual size of the db file to the VFS layer.
-+      */
-+      if( rc==SQLITE_OK ){
-+        i64 nReq = ((i64)mxPage * szPage);
-+        rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
-+        if( rc==SQLITE_OK && nSize<nReq ){
-+          sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
++      break;
++  
++    case 'e': 
++      if( nBuf>4 && 0==memcmp("izer", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-4) ){
++          memcpy(&aBuf[nBuf-4], "ize", 3);
++          *pnBuf = nBuf - 4 + 3;
 +        }
 +      }
- 
--  assert( pWal->writeLock );
--  assert( aWalData[3]!=pWal->nCkpt || aWalData[0]<=pWal->hdr.mxFrame );
- 
--  if( aWalData[3]!=pWal->nCkpt ){
--    /* This savepoint was opened immediately after the write-transaction
--    ** was started. Right after that, the writer decided to wrap around
--    ** to the start of the log. Update the savepoint values to match.
--    */
--    aWalData[0] = 0;
--    aWalData[3] = pWal->nCkpt;
--  }
-+      /* Iterate through the contents of the WAL, copying data to the db file */
-+      while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
-+        i64 iOffset;
-+        assert( walFramePgno(pWal, iFrame)==iDbpage );
-+        if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
-+          continue;
++      break;
++  
++    case 'g': 
++      if( nBuf>4 && 0==memcmp("logi", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-4) ){
++          memcpy(&aBuf[nBuf-4], "log", 3);
++          *pnBuf = nBuf - 4 + 3;
 +        }
-+        iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
-+        /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
-+        rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
-+        if( rc!=SQLITE_OK ) break;
-+        iOffset = (iDbpage-1)*(i64)szPage;
-+        testcase( IS_BIG_INT(iOffset) );
-+        rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
-+        if( rc!=SQLITE_OK ) break;
 +      }
- 
--  if( aWalData[0]<pWal->hdr.mxFrame ){
--    pWal->hdr.mxFrame = aWalData[0];
--    pWal->hdr.aFrameCksum[0] = aWalData[1];
--    pWal->hdr.aFrameCksum[1] = aWalData[2];
--    walCleanupHash(pWal);
--  }
-+      /* If work was actually accomplished... */
-+      if( rc==SQLITE_OK ){
-+        if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
-+          i64 szDb = pWal->hdr.nPage*(i64)szPage;
-+          testcase( IS_BIG_INT(szDb) );
-+          rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
-+          if( rc==SQLITE_OK && sync_flags ){
-+            rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
-+          }
++      break;
++  
++    case 'l': 
++      if( nBuf>3 && 0==memcmp("bli", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-3) ){
++          memcpy(&aBuf[nBuf-3], "ble", 3);
++          *pnBuf = nBuf - 3 + 3;
 +        }
-+        if( rc==SQLITE_OK ){
-+          pInfo->nBackfill = mxSafeFrame;
++      }else if( nBuf>4 && 0==memcmp("alli", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-4) ){
++          memcpy(&aBuf[nBuf-4], "al", 2);
++          *pnBuf = nBuf - 4 + 2;
++        }
++      }else if( nBuf>5 && 0==memcmp("entli", &aBuf[nBuf-5], 5) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-5) ){
++          memcpy(&aBuf[nBuf-5], "ent", 3);
++          *pnBuf = nBuf - 5 + 3;
++        }
++      }else if( nBuf>3 && 0==memcmp("eli", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-3) ){
++          memcpy(&aBuf[nBuf-3], "e", 1);
++          *pnBuf = nBuf - 3 + 1;
++        }
++      }else if( nBuf>5 && 0==memcmp("ousli", &aBuf[nBuf-5], 5) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-5) ){
++          memcpy(&aBuf[nBuf-5], "ous", 3);
++          *pnBuf = nBuf - 5 + 3;
 +        }
 +      }
- 
--  return rc;
--}
-+      /* Release the reader lock held while backfilling */
-+      walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
-+    }
- 
--/*
--** This function is called just before writing a set of frames to the log
--** file (see sqlite3WalFrames()). It checks to see if, instead of appending
--** to the current log file, it is possible to overwrite the start of the
--** existing log file with the new frames (i.e. "reset" the log). If so,
--** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left
--** unchanged.
--**
--** SQLITE_OK is returned if no error is encountered (regardless of whether
--** or not pWal->hdr.mxFrame is modified). An SQLite error code is returned
--** if an error occurs.
--*/
--static int walRestartLog(Wal *pWal){
--  int rc = SQLITE_OK;
--  int cnt;
-+    if( rc==SQLITE_BUSY ){
-+      /* Reset the return code so as not to report a checkpoint failure
-+      ** just because there are active readers.  */
-+      rc = SQLITE_OK;
-+    }
++      break;
++  
++    case 'o': 
++      if( nBuf>7 && 0==memcmp("ization", &aBuf[nBuf-7], 7) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-7) ){
++          memcpy(&aBuf[nBuf-7], "ize", 3);
++          *pnBuf = nBuf - 7 + 3;
++        }
++      }else if( nBuf>5 && 0==memcmp("ation", &aBuf[nBuf-5], 5) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-5) ){
++          memcpy(&aBuf[nBuf-5], "ate", 3);
++          *pnBuf = nBuf - 5 + 3;
++        }
++      }else if( nBuf>4 && 0==memcmp("ator", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-4) ){
++          memcpy(&aBuf[nBuf-4], "ate", 3);
++          *pnBuf = nBuf - 4 + 3;
++        }
++      }
++      break;
++  
++    case 's': 
++      if( nBuf>5 && 0==memcmp("alism", &aBuf[nBuf-5], 5) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-5) ){
++          memcpy(&aBuf[nBuf-5], "al", 2);
++          *pnBuf = nBuf - 5 + 2;
++        }
++      }else if( nBuf>7 && 0==memcmp("iveness", &aBuf[nBuf-7], 7) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-7) ){
++          memcpy(&aBuf[nBuf-7], "ive", 3);
++          *pnBuf = nBuf - 7 + 3;
++        }
++      }else if( nBuf>7 && 0==memcmp("fulness", &aBuf[nBuf-7], 7) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-7) ){
++          memcpy(&aBuf[nBuf-7], "ful", 3);
++          *pnBuf = nBuf - 7 + 3;
++        }
++      }else if( nBuf>7 && 0==memcmp("ousness", &aBuf[nBuf-7], 7) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-7) ){
++          memcpy(&aBuf[nBuf-7], "ous", 3);
++          *pnBuf = nBuf - 7 + 3;
++        }
++      }
++      break;
++  
++    case 't': 
++      if( nBuf>5 && 0==memcmp("aliti", &aBuf[nBuf-5], 5) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-5) ){
++          memcpy(&aBuf[nBuf-5], "al", 2);
++          *pnBuf = nBuf - 5 + 2;
++        }
++      }else if( nBuf>5 && 0==memcmp("iviti", &aBuf[nBuf-5], 5) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-5) ){
++          memcpy(&aBuf[nBuf-5], "ive", 3);
++          *pnBuf = nBuf - 5 + 3;
++        }
++      }else if( nBuf>6 && 0==memcmp("biliti", &aBuf[nBuf-6], 6) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-6) ){
++          memcpy(&aBuf[nBuf-6], "ble", 3);
++          *pnBuf = nBuf - 6 + 3;
++        }
++      }
++      break;
++  
 +  }
- 
--  if( pWal->readLock==0 ){
--    volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
--    assert( pInfo->nBackfill==pWal->hdr.mxFrame );
--    if( pInfo->nBackfill>0 ){
-+  /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
-+  ** entire wal file has been copied into the database file, then block 
-+  ** until all readers have finished using the wal file. This ensures that 
-+  ** the next process to write to the database restarts the wal file.
-+  */
-+  if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){
-+    assert( pWal->writeLock );
-+    if( pInfo->nBackfill<pWal->hdr.mxFrame ){
-+      rc = SQLITE_BUSY;
-+    }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
-       u32 salt1;
-       sqlite3_randomness(4, &salt1);
--      rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0);
-+      assert( pInfo->nBackfill==pWal->hdr.mxFrame );
-+      rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
-       if( rc==SQLITE_OK ){
--        /* If all readers are using WAL_READ_LOCK(0) (in other words if no
--        ** readers are currently using the WAL), then the transactions
--        ** frames will overwrite the start of the existing log. Update the
--        ** wal-index header to reflect this.
--        **
--        ** In theory it would be Ok to update the cache of the header only
--        ** at this point. But updating the actual wal-index header is also
--        ** safe and means there is no special case for sqlite3WalUndo()
--        ** to handle if this transaction is rolled back.  */
--        walRestartHdr(pWal, salt1);
-+        if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
-+          /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as
-+          ** SQLITE_CHECKPOINT_RESTART with the addition that it also
-+          ** truncates the log file to zero bytes just prior to a
-+          ** successful return.
-+          **
-+          ** In theory, it might be safe to do this without updating the
-+          ** wal-index header in shared memory, as all subsequent reader or
-+          ** writer clients should see that the entire log file has been
-+          ** checkpointed and behave accordingly. This seems unsafe though,
-+          ** as it would leave the system in a state where the contents of
-+          ** the wal-index header do not match the contents of the 
-+          ** file-system. To avoid this, update the wal-index header to
-+          ** indicate that the log file contains zero valid frames.  */
-+          walRestartHdr(pWal, salt1);
-+          rc = sqlite3OsTruncate(pWal->pWalFd, 0);
-+        }
-         walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
--      }else if( rc!=SQLITE_BUSY ){
--        return rc;
-       }
-     }
--    walUnlockShared(pWal, WAL_READ_LOCK(0));
--    pWal->readLock = -1;
--    cnt = 0;
--    do{
--      int notUsed;
--      rc = walTryBeginRead(pWal, &notUsed, 1, ++cnt);
--    }while( rc==WAL_RETRY );
--    assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */
--    testcase( (rc&0xff)==SQLITE_IOERR );
--    testcase( rc==SQLITE_PROTOCOL );
--    testcase( rc==SQLITE_OK );
-   }
++  return ret;
++}
++  
 +
-+ walcheckpoint_out:
-+  walIteratorFree(pIter);
-   return rc;
- }
- 
- /*
--** Information about the current state of the WAL file and where
--** the next fsync should occur - passed from sqlite3WalFrames() into
--** walWriteToLog().
-+** If the WAL file is currently larger than nMax bytes in size, truncate
-+** it to exactly nMax bytes. If an error occurs while doing so, ignore it.
- */
--typedef struct WalWriter {
--  Wal *pWal;                   /* The complete WAL information */
--  sqlite3_file *pFd;           /* The WAL file to which we write */
--  sqlite3_int64 iSyncPoint;    /* Fsync at this offset */
--  int syncFlags;               /* Flags for the fsync */
--  int szPage;                  /* Size of one page */
--} WalWriter;
-+static void walLimitSize(Wal *pWal, i64 nMax){
-+  i64 sz;
-+  int rx;
-+  sqlite3BeginBenignMalloc();
-+  rx = sqlite3OsFileSize(pWal->pWalFd, &sz);
-+  if( rx==SQLITE_OK && (sz > nMax ) ){
-+    rx = sqlite3OsTruncate(pWal->pWalFd, nMax);
-+  }
-+  sqlite3EndBenignMalloc();
-+  if( rx ){
-+    sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
++static int fts5PorterStep3(char *aBuf, int *pnBuf){
++  int ret = 0;
++  int nBuf = *pnBuf;
++  switch( aBuf[nBuf-2] ){
++    
++    case 'a': 
++      if( nBuf>4 && 0==memcmp("ical", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-4) ){
++          memcpy(&aBuf[nBuf-4], "ic", 2);
++          *pnBuf = nBuf - 4 + 2;
++        }
++      }
++      break;
++  
++    case 's': 
++      if( nBuf>4 && 0==memcmp("ness", &aBuf[nBuf-4], 4) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-4) ){
++          *pnBuf = nBuf - 4;
++        }
++      }
++      break;
++  
++    case 't': 
++      if( nBuf>5 && 0==memcmp("icate", &aBuf[nBuf-5], 5) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-5) ){
++          memcpy(&aBuf[nBuf-5], "ic", 2);
++          *pnBuf = nBuf - 5 + 2;
++        }
++      }else if( nBuf>5 && 0==memcmp("iciti", &aBuf[nBuf-5], 5) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-5) ){
++          memcpy(&aBuf[nBuf-5], "ic", 2);
++          *pnBuf = nBuf - 5 + 2;
++        }
++      }
++      break;
++  
++    case 'u': 
++      if( nBuf>3 && 0==memcmp("ful", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-3) ){
++          *pnBuf = nBuf - 3;
++        }
++      }
++      break;
++  
++    case 'v': 
++      if( nBuf>5 && 0==memcmp("ative", &aBuf[nBuf-5], 5) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-5) ){
++          *pnBuf = nBuf - 5;
++        }
++      }
++      break;
++  
++    case 'z': 
++      if( nBuf>5 && 0==memcmp("alize", &aBuf[nBuf-5], 5) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-5) ){
++          memcpy(&aBuf[nBuf-5], "al", 2);
++          *pnBuf = nBuf - 5 + 2;
++        }
++      }
++      break;
++  
 +  }
++  return ret;
 +}
- 
- /*
--** Write iAmt bytes of content into the WAL file beginning at iOffset.
--** Do a sync when crossing the p->iSyncPoint boundary.
--**
--** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt,
--** first write the part before iSyncPoint, then sync, then write the
--** rest.
-+** Close a connection to a log file.
- */
--static int walWriteToLog(
--  WalWriter *p,              /* WAL to write to */
--  void *pContent,            /* Content to be written */
--  int iAmt,                  /* Number of bytes to write */
--  sqlite3_int64 iOffset      /* Start writing at this offset */
-+SQLITE_PRIVATE int sqlite3WalClose(
-+  Wal *pWal,                      /* Wal to close */
-+  int sync_flags,                 /* Flags to pass to OsSync() (or 0) */
-+  int nBuf,
-+  u8 *zBuf                        /* Buffer of at least nBuf bytes */
- ){
--  int rc;
--  if( iOffset<p->iSyncPoint && iOffset+iAmt>=p->iSyncPoint ){
--    int iFirstAmt = (int)(p->iSyncPoint - iOffset);
--    rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset);
--    if( rc ) return rc;
--    iOffset += iFirstAmt;
--    iAmt -= iFirstAmt;
--    pContent = (void*)(iFirstAmt + (char*)pContent);
--    assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) );
--    rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK);
--    if( iAmt==0 || rc ) return rc;
-+  int rc = SQLITE_OK;
-+  if( pWal ){
-+    int isDelete = 0;             /* True to unlink wal and wal-index files */
-+
-+    /* If an EXCLUSIVE lock can be obtained on the database file (using the
-+    ** ordinary, rollback-mode locking methods, this guarantees that the
-+    ** connection associated with this log file is the only connection to
-+    ** the database. In this case checkpoint the database and unlink both
-+    ** the wal and wal-index files.
-+    **
-+    ** The EXCLUSIVE lock is not released before returning.
-+    */
-+    rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
-+    if( rc==SQLITE_OK ){
-+      if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
-+        pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
++  
++
++static int fts5PorterStep1B(char *aBuf, int *pnBuf){
++  int ret = 0;
++  int nBuf = *pnBuf;
++  switch( aBuf[nBuf-2] ){
++    
++    case 'e': 
++      if( nBuf>3 && 0==memcmp("eed", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_MGt0(aBuf, nBuf-3) ){
++          memcpy(&aBuf[nBuf-3], "ee", 2);
++          *pnBuf = nBuf - 3 + 2;
++        }
++      }else if( nBuf>2 && 0==memcmp("ed", &aBuf[nBuf-2], 2) ){
++        if( fts5Porter_Vowel(aBuf, nBuf-2) ){
++          *pnBuf = nBuf - 2;
++          ret = 1;
++        }
 +      }
-+      rc = sqlite3WalCheckpoint(
-+          pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
-+      );
-+      if( rc==SQLITE_OK ){
-+        int bPersist = -1;
-+        sqlite3OsFileControlHint(
-+            pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist
-+        );
-+        if( bPersist!=1 ){
-+          /* Try to delete the WAL file if the checkpoint completed and
-+          ** fsyned (rc==SQLITE_OK) and if we are not in persistent-wal
-+          ** mode (!bPersist) */
-+          isDelete = 1;
-+        }else if( pWal->mxWalSize>=0 ){
-+          /* Try to truncate the WAL file to zero bytes if the checkpoint
-+          ** completed and fsynced (rc==SQLITE_OK) and we are in persistent
-+          ** WAL mode (bPersist) and if the PRAGMA journal_size_limit is a
-+          ** non-negative value (pWal->mxWalSize>=0).  Note that we truncate
-+          ** to zero bytes as truncating to the journal_size_limit might
-+          ** leave a corrupt WAL file on disk. */
-+          walLimitSize(pWal, 0);
-+        }
-+      }
-+    }
-+
-+    walIndexClose(pWal, isDelete);
-+    sqlite3OsClose(pWal->pWalFd);
-+    if( isDelete ){
-+      sqlite3BeginBenignMalloc();
-+      sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0);
-+      sqlite3EndBenignMalloc();
-+    }
-+    WALTRACE(("WAL%p: closed\n", pWal));
-+    sqlite3_free((void *)pWal->apWiData);
-+    sqlite3_free(pWal);
-   }
--  rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset);
-   return rc;
- }
- 
- /*
--** Write out a single frame of the WAL
-+** Try to read the wal-index header.  Return 0 on success and 1 if
-+** there is a problem.
-+**
-+** The wal-index is in shared memory.  Another thread or process might
-+** be writing the header at the same time this procedure is trying to
-+** read it, which might result in inconsistency.  A dirty read is detected
-+** by verifying that both copies of the header are the same and also by
-+** a checksum on the header.
-+**
-+** If and only if the read is consistent and the header is different from
-+** pWal->hdr, then pWal->hdr is updated to the content of the new header
-+** and *pChanged is set to 1.
-+**
-+** If the checksum cannot be verified return non-zero. If the header
-+** is read successfully and the checksum verified, return zero.
- */
--static int walWriteOneFrame(
--  WalWriter *p,               /* Where to write the frame */
--  PgHdr *pPage,               /* The page of the frame to be written */
--  int nTruncate,              /* The commit flag.  Usually 0.  >0 for commit */
--  sqlite3_int64 iOffset       /* Byte offset at which to write */
--){
--  int rc;                         /* Result code from subfunctions */
--  void *pData;                    /* Data actually written */
--  u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-header in */
--#if defined(SQLITE_HAS_CODEC)
--  if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM;
--#else
--  pData = pPage->pData;
--#endif
--  walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame);
--  rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
--  if( rc ) return rc;
--  /* Write the page data */
--  rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame));
--  return rc;
--}
-+static int walIndexTryHdr(Wal *pWal, int *pChanged){
-+  u32 aCksum[2];                  /* Checksum on the header content */
-+  WalIndexHdr h1, h2;             /* Two copies of the header content */
-+  WalIndexHdr volatile *aHdr;     /* Header in shared memory */
- 
--/* 
--** Write a set of frames to the log. The caller must hold the write-lock
--** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
--*/
--SQLITE_PRIVATE int sqlite3WalFrames(
--  Wal *pWal,                      /* Wal handle to write to */
--  int szPage,                     /* Database page-size in bytes */
--  PgHdr *pList,                   /* List of dirty pages to write */
--  Pgno nTruncate,                 /* Database size after this commit */
--  int isCommit,                   /* True if this is a commit */
--  int sync_flags                  /* Flags to pass to OsSync() (or 0) */
--){
--  int rc;                         /* Used to catch return codes */
--  u32 iFrame;                     /* Next frame address */
--  PgHdr *p;                       /* Iterator to run through pList with. */
--  PgHdr *pLast = 0;               /* Last frame in list */
--  int nExtra = 0;                 /* Number of extra copies of last page */
--  int szFrame;                    /* The size of a single frame */
--  i64 iOffset;                    /* Next byte to write in WAL file */
--  WalWriter w;                    /* The writer */
-+  /* The first page of the wal-index must be mapped at this point. */
-+  assert( pWal->nWiData>0 && pWal->apWiData[0] );
- 
--  assert( pList );
--  assert( pWal->writeLock );
-+  /* Read the header. This might happen concurrently with a write to the
-+  ** same area of shared memory on a different CPU in a SMP,
-+  ** meaning it is possible that an inconsistent snapshot is read
-+  ** from the file. If this happens, return non-zero.
-+  **
-+  ** There are two copies of the header at the beginning of the wal-index.
-+  ** When reading, read [0] first then [1].  Writes are in the reverse order.
-+  ** Memory barriers are used to prevent the compiler or the hardware from
-+  ** reordering the reads and writes.
-+  */
-+  aHdr = walIndexHdr(pWal);
-+  memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
-+  walShmBarrier(pWal);
-+  memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
- 
--  /* If this frame set completes a transaction, then nTruncate>0.  If
--  ** nTruncate==0 then this frame set does not complete the transaction. */
--  assert( (isCommit!=0)==(nTruncate!=0) );
-+  if( memcmp(&h1, &h2, sizeof(h1))!=0 ){
-+    return 1;   /* Dirty read */
-+  }  
-+  if( h1.isInit==0 ){
-+    return 1;   /* Malformed header - probably all zeros */
++      break;
++  
++    case 'n': 
++      if( nBuf>3 && 0==memcmp("ing", &aBuf[nBuf-3], 3) ){
++        if( fts5Porter_Vowel(aBuf, nBuf-3) ){
++          *pnBuf = nBuf - 3;
++          ret = 1;
++        }
++      }
++      break;
++  
++  }
++  return ret;
++}
++  
++/* 
++** GENERATED CODE ENDS HERE (mkportersteps.tcl)
++***************************************************************************
++**************************************************************************/
++
++static void fts5PorterStep1A(char *aBuf, int *pnBuf){
++  int nBuf = *pnBuf;
++  if( aBuf[nBuf-1]=='s' ){
++    if( aBuf[nBuf-2]=='e' ){
++      if( (nBuf>4 && aBuf[nBuf-4]=='s' && aBuf[nBuf-3]=='s') 
++       || (nBuf>3 && aBuf[nBuf-3]=='i' )
++      ){
++        *pnBuf = nBuf-2;
++      }else{
++        *pnBuf = nBuf-1;
++      }
++    }
++    else if( aBuf[nBuf-2]!='s' ){
++      *pnBuf = nBuf-1;
++    }
 +  }
-+  walChecksumBytes(1, (u8*)&h1, sizeof(h1)-sizeof(h1.aCksum), 0, aCksum);
-+  if( aCksum[0]!=h1.aCksum[0] || aCksum[1]!=h1.aCksum[1] ){
-+    return 1;   /* Checksum does not match */
++}
++
++static int fts5PorterCb(
++  void *pCtx, 
++  int tflags,
++  const char *pToken, 
++  int nToken, 
++  int iStart, 
++  int iEnd
++){
++  PorterContext *p = (PorterContext*)pCtx;
++
++  char *aBuf;
++  int nBuf;
++
++  if( nToken>FTS5_PORTER_MAX_TOKEN || nToken<3 ) goto pass_through;
++  aBuf = p->aBuf;
++  nBuf = nToken;
++  memcpy(aBuf, pToken, nBuf);
++
++  /* Step 1. */
++  fts5PorterStep1A(aBuf, &nBuf);
++  if( fts5PorterStep1B(aBuf, &nBuf) ){
++    if( fts5PorterStep1B2(aBuf, &nBuf)==0 ){
++      char c = aBuf[nBuf-1];
++      if( fts5PorterIsVowel(c, 0)==0 
++       && c!='l' && c!='s' && c!='z' && c==aBuf[nBuf-2] 
++      ){
++        nBuf--;
++      }else if( fts5Porter_MEq1(aBuf, nBuf) && fts5Porter_Ostar(aBuf, nBuf) ){
++        aBuf[nBuf++] = 'e';
++      }
++    }
 +  }
- 
--#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
--  { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){}
--    WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n",
--              pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill"));
-+  if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){
-+    *pChanged = 1;
-+    memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr));
-+    pWal->szPage = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
-+    testcase( pWal->szPage<=32768 );
-+    testcase( pWal->szPage>=65536 );
-   }
--#endif
- 
--  /* See if it is possible to write these frames into the start of the
--  ** log file, instead of appending to it at pWal->hdr.mxFrame.
-+  /* The header was successfully read. Return zero. */
-+  return 0;
++
++  /* Step 1C. */
++  if( aBuf[nBuf-1]=='y' && fts5Porter_Vowel(aBuf, nBuf-1) ){
++    aBuf[nBuf-1] = 'i';
++  }
++
++  /* Steps 2 through 4. */
++  fts5PorterStep2(aBuf, &nBuf);
++  fts5PorterStep3(aBuf, &nBuf);
++  fts5PorterStep4(aBuf, &nBuf);
++
++  /* Step 5a. */
++  assert( nBuf>0 );
++  if( aBuf[nBuf-1]=='e' ){
++    if( fts5Porter_MGt1(aBuf, nBuf-1) 
++     || (fts5Porter_MEq1(aBuf, nBuf-1) && !fts5Porter_Ostar(aBuf, nBuf-1))
++    ){
++      nBuf--;
++    }
++  }
++
++  /* Step 5b. */
++  if( nBuf>1 && aBuf[nBuf-1]=='l' 
++   && aBuf[nBuf-2]=='l' && fts5Porter_MGt1(aBuf, nBuf-1) 
++  ){
++    nBuf--;
++  }
++
++  return p->xToken(p->pCtx, tflags, aBuf, nBuf, iStart, iEnd);
++
++ pass_through:
++  return p->xToken(p->pCtx, tflags, pToken, nToken, iStart, iEnd);
 +}
 +
 +/*
-+** Read the wal-index header from the wal-index and into pWal->hdr.
-+** If the wal-header appears to be corrupt, try to reconstruct the
-+** wal-index from the WAL before returning.
-+**
-+** Set *pChanged to 1 if the wal-index header value in pWal->hdr is
-+** changed by this operation.  If pWal->hdr is unchanged, set *pChanged
-+** to 0.
-+**
-+** If the wal-index header is successfully read, return SQLITE_OK. 
-+** Otherwise an SQLite error code.
++** Tokenize using the porter tokenizer.
 +*/
-+static int walIndexReadHdr(Wal *pWal, int *pChanged){
-+  int rc;                         /* Return code */
-+  int badHdr;                     /* True if a header read failed */
-+  volatile u32 *page0;            /* Chunk of wal-index containing header */
++static int fts5PorterTokenize(
++  Fts5Tokenizer *pTokenizer,
++  void *pCtx,
++  int flags,
++  const char *pText, int nText,
++  int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
++){
++  PorterTokenizer *p = (PorterTokenizer*)pTokenizer;
++  PorterContext sCtx;
++  sCtx.xToken = xToken;
++  sCtx.pCtx = pCtx;
++  sCtx.aBuf = p->aBuf;
++  return p->tokenizer.xTokenize(
++      p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb
++  );
++}
 +
-+  /* Ensure that page 0 of the wal-index (the page that contains the 
-+  ** wal-index header) is mapped. Return early if an error occurs here.
-   */
--  if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){
-+  assert( pChanged );
-+  rc = walIndexPage(pWal, 0, &page0);
-+  if( rc!=SQLITE_OK ){
-     return rc;
--  }
++/*
++** Register all built-in tokenizers with FTS5.
++*/
++static int sqlite3Fts5TokenizerInit(fts5_api *pApi){
++  struct BuiltinTokenizer {
++    const char *zName;
++    fts5_tokenizer x;
++  } aBuiltin[] = {
++    { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
++    { "ascii",     {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
++    { "porter",    {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
 +  };
-+  assert( page0 || pWal->writeLock==0 );
- 
--  /* If this is the first frame written into the log, write the WAL
--  ** header to the start of the WAL file. See comments at the top of
--  ** this source file for a description of the WAL header format.
-+  /* If the first page of the wal-index has been mapped, try to read the
-+  ** wal-index header immediately, without holding any lock. This usually
-+  ** works, but may fail if the wal-index header is corrupt or currently 
-+  ** being modified by another thread or process.
-   */
--  iFrame = pWal->hdr.mxFrame;
--  if( iFrame==0 ){
--    u8 aWalHdr[WAL_HDRSIZE];      /* Buffer to assemble wal-header in */
--    u32 aCksum[2];                /* Checksum for wal-header */
--
--    sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN));
--    sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION);
--    sqlite3Put4byte(&aWalHdr[8], szPage);
--    sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt);
--    if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt);
--    memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8);
--    walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum);
--    sqlite3Put4byte(&aWalHdr[24], aCksum[0]);
--    sqlite3Put4byte(&aWalHdr[28], aCksum[1]);
--    
--    pWal->szPage = szPage;
--    pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN;
--    pWal->hdr.aFrameCksum[0] = aCksum[0];
--    pWal->hdr.aFrameCksum[1] = aCksum[1];
--    pWal->truncateOnCommit = 1;
-+  badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1);
- 
--    rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0);
--    WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok"));
--    if( rc!=SQLITE_OK ){
--      return rc;
-+  /* If the first attempt failed, it might have been due to a race
-+  ** with a writer.  So get a WRITE lock and try again.
-+  */
-+  assert( badHdr==0 || pWal->writeLock==0 );
-+  if( badHdr ){
-+    if( pWal->readOnly & WAL_SHM_RDONLY ){
-+      if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
-+        walUnlockShared(pWal, WAL_WRITE_LOCK);
-+        rc = SQLITE_READONLY_RECOVERY;
-+      }
-+    }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 1)) ){
-+      pWal->writeLock = 1;
-+      if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
-+        badHdr = walIndexTryHdr(pWal, pChanged);
-+        if( badHdr ){
-+          /* If the wal-index header is still malformed even while holding
-+          ** a WRITE lock, it can only mean that the header is corrupted and
-+          ** needs to be reconstructed.  So run recovery to do exactly that.
-+          */
-+          rc = walIndexRecover(pWal);
-+          *pChanged = 1;
-+        }
-+      }
-+      pWal->writeLock = 0;
-+      walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
-     }
++  
++  int rc = SQLITE_OK;             /* Return code */
++  int i;                          /* To iterate through builtin functions */
++
++  for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
++    rc = pApi->xCreateTokenizer(pApi,
++        aBuiltin[i].zName,
++        (void*)pApi,
++        &aBuiltin[i].x,
++        0
++    );
 +  }
- 
--    /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless
--    ** all syncing is turned off by PRAGMA synchronous=OFF).  Otherwise
--    ** an out-of-order write following a WAL restart could result in
--    ** database corruption.  See the ticket:
--    **
--    **     http://localhost:591/sqlite/info/ff5be73dee
--    */
--    if( pWal->syncHeader && sync_flags ){
--      rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK);
--      if( rc ) return rc;
--    }
-+  /* If the header is read successfully, check the version number to make
-+  ** sure the wal-index was not constructed with some future format that
-+  ** this version of SQLite cannot understand.
-+  */
-+  if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){
-+    rc = SQLITE_CANTOPEN_BKPT;
-   }
--  assert( (int)pWal->szPage==szPage );
- 
--  /* Setup information needed to write frames into the WAL */
--  w.pWal = pWal;
--  w.pFd = pWal->pWalFd;
--  w.iSyncPoint = 0;
--  w.syncFlags = sync_flags;
--  w.szPage = szPage;
--  iOffset = walFrameOffset(iFrame+1, szPage);
--  szFrame = szPage + WAL_FRAME_HDRSIZE;
++
 +  return rc;
 +}
- 
--  /* Write all frames into the log file exactly once */
--  for(p=pList; p; p=p->pDirty){
--    int nDbSize;   /* 0 normally.  Positive == commit flag */
--    iFrame++;
--    assert( iOffset==walFrameOffset(iFrame, szPage) );
--    nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0;
--    rc = walWriteOneFrame(&w, p, nDbSize, iOffset);
--    if( rc ) return rc;
--    pLast = p;
--    iOffset += szFrame;
--  }
++
++
++
 +/*
-+** This is the value that walTryBeginRead returns when it needs to
-+** be retried.
-+*/
-+#define WAL_RETRY  (-1)
- 
--  /* If this is the end of a transaction, then we might need to pad
--  ** the transaction and/or sync the WAL file.
-+/*
-+** Attempt to start a read transaction.  This might fail due to a race or
-+** other transient condition.  When that happens, it returns WAL_RETRY to
-+** indicate to the caller that it is safe to retry immediately.
-+**
-+** On success return SQLITE_OK.  On a permanent failure (such an
-+** I/O error or an SQLITE_BUSY because another process is running
-+** recovery) return a positive error code.
-+**
-+** The useWal parameter is true to force the use of the WAL and disable
-+** the case where the WAL is bypassed because it has been completely
-+** checkpointed.  If useWal==0 then this routine calls walIndexReadHdr() 
-+** to make a copy of the wal-index header into pWal->hdr.  If the 
-+** wal-index header has changed, *pChanged is set to 1 (as an indication 
-+** to the caller that the local paget cache is obsolete and needs to be 
-+** flushed.)  When useWal==1, the wal-index header is assumed to already
-+** be loaded and the pChanged parameter is unused.
-+**
-+** The caller must set the cnt parameter to the number of prior calls to
-+** this routine during the current read attempt that returned WAL_RETRY.
-+** This routine will start taking more aggressive measures to clear the
-+** race conditions after multiple WAL_RETRY returns, and after an excessive
-+** number of errors will ultimately return SQLITE_PROTOCOL.  The
-+** SQLITE_PROTOCOL return indicates that some other process has gone rogue
-+** and is not honoring the locking protocol.  There is a vanishingly small
-+** chance that SQLITE_PROTOCOL could be returned because of a run of really
-+** bad luck when there is lots of contention for the wal-index, but that
-+** possibility is so small that it can be safely neglected, we believe.
-+**
-+** On success, this routine obtains a read lock on 
-+** WAL_READ_LOCK(pWal->readLock).  The pWal->readLock integer is
-+** in the range 0 <= pWal->readLock < WAL_NREADER.  If pWal->readLock==(-1)
-+** that means the Wal does not hold any read lock.  The reader must not
-+** access any database page that is modified by a WAL frame up to and
-+** including frame number aReadMark[pWal->readLock].  The reader will
-+** use WAL frames up to and including pWal->hdr.mxFrame if pWal->readLock>0
-+** Or if pWal->readLock==0, then the reader will ignore the WAL
-+** completely and get all content directly from the database file.
-+** If the useWal parameter is 1 then the WAL will never be ignored and
-+** this routine will always set pWal->readLock>0 on success.
-+** When the read transaction is completed, the caller must release the
-+** lock on WAL_READ_LOCK(pWal->readLock) and set pWal->readLock to -1.
-+**
-+** This routine uses the nBackfill and aReadMark[] fields of the header
-+** to select a particular WAL_READ_LOCK() that strives to let the
-+** checkpoint process do as much work as possible.  This routine might
-+** update values of the aReadMark[] array in the header, but if it does
-+** so it takes care to hold an exclusive lock on the corresponding
-+** WAL_READ_LOCK() while changing values.
-+*/
-+static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
-+  volatile WalCkptInfo *pInfo;    /* Checkpoint information in wal-index */
-+  u32 mxReadMark;                 /* Largest aReadMark[] value */
-+  int mxI;                        /* Index of largest aReadMark[] value */
-+  int i;                          /* Loop counter */
-+  int rc = SQLITE_OK;             /* Return code  */
-+
-+  assert( pWal->readLock<0 );     /* Not currently locked */
-+
-+  /* Take steps to avoid spinning forever if there is a protocol error.
-   **
--  ** Padding and syncing only occur if this set of frames complete a
--  ** transaction and if PRAGMA synchronous=FULL.  If synchronous==NORMAL
--  ** or synchronous==OFF, then no padding or syncing are needed.
-+  ** Circumstances that cause a RETRY should only last for the briefest
-+  ** instances of time.  No I/O or other system calls are done while the
-+  ** locks are held, so the locks should not be held for very long. But 
-+  ** if we are unlucky, another process that is holding a lock might get
-+  ** paged out or take a page-fault that is time-consuming to resolve, 
-+  ** during the few nanoseconds that it is holding the lock.  In that case,
-+  ** it might take longer than normal for the lock to free.
-   **
--  ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not
--  ** needed and only the sync is done.  If padding is needed, then the
--  ** final frame is repeated (with its commit mark) until the next sector
--  ** boundary is crossed.  Only the part of the WAL prior to the last
--  ** sector boundary is synced; the part of the last frame that extends
--  ** past the sector boundary is written after the sync.
-+  ** After 5 RETRYs, we begin calling sqlite3OsSleep().  The first few
-+  ** calls to sqlite3OsSleep() have a delay of 1 microsecond.  Really this
-+  ** is more of a scheduler yield than an actual delay.  But on the 10th
-+  ** an subsequent retries, the delays start becoming longer and longer, 
-+  ** so that on the 100th (and last) RETRY we delay for 323 milliseconds.
-+  ** The total delay time before giving up is less than 10 seconds.
-   */
--  if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
--    if( pWal->padToSectorBoundary ){
--      int sectorSize = sqlite3SectorSize(pWal->pWalFd);
--      w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
--      while( iOffset<w.iSyncPoint ){
--        rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
--        if( rc ) return rc;
--        iOffset += szFrame;
--        nExtra++;
-+  if( cnt>5 ){
-+    int nDelay = 1;                      /* Pause time in microseconds */
-+    if( cnt>100 ){
-+      VVA_ONLY( pWal->lockError = 1; )
-+      return SQLITE_PROTOCOL;
-+    }
-+    if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
-+    sqlite3OsSleep(pWal->pVfs, nDelay);
-+  }
-+
-+  if( !useWal ){
-+    rc = walIndexReadHdr(pWal, pChanged);
-+    if( rc==SQLITE_BUSY ){
-+      /* If there is not a recovery running in another thread or process
-+      ** then convert BUSY errors to WAL_RETRY.  If recovery is known to
-+      ** be running, convert BUSY to BUSY_RECOVERY.  There is a race here
-+      ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY
-+      ** would be technically correct.  But the race is benign since with
-+      ** WAL_RETRY this routine will be called again and will probably be
-+      ** right on the second iteration.
-+      */
-+      if( pWal->apWiData[0]==0 ){
-+        /* This branch is taken when the xShmMap() method returns SQLITE_BUSY.
-+        ** We assume this is a transient condition, so return WAL_RETRY. The
-+        ** xShmMap() implementation used by the default unix and win32 VFS 
-+        ** modules may return SQLITE_BUSY due to a race condition in the 
-+        ** code that determines whether or not the shared-memory region 
-+        ** must be zeroed before the requested page is returned.
-+        */
-+        rc = WAL_RETRY;
-+      }else if( SQLITE_OK==(rc = walLockShared(pWal, WAL_RECOVER_LOCK)) ){
-+        walUnlockShared(pWal, WAL_RECOVER_LOCK);
-+        rc = WAL_RETRY;
-+      }else if( rc==SQLITE_BUSY ){
-+        rc = SQLITE_BUSY_RECOVERY;
-       }
--    }else{
--      rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK);
-+    }
-+    if( rc!=SQLITE_OK ){
-+      return rc;
-     }
-   }
- 
--  /* If this frame set completes the first transaction in the WAL and
--  ** if PRAGMA journal_size_limit is set, then truncate the WAL to the
--  ** journal size limit, if possible.
--  */
--  if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){
--    i64 sz = pWal->mxWalSize;
--    if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){
--      sz = walFrameOffset(iFrame+nExtra+1, szPage);
-+  pInfo = walCkptInfo(pWal);
-+  if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame ){
-+    /* The WAL has been completely backfilled (or it is empty).
-+    ** and can be safely ignored.
-+    */
-+    rc = walLockShared(pWal, WAL_READ_LOCK(0));
-+    walShmBarrier(pWal);
-+    if( rc==SQLITE_OK ){
-+      if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){
-+        /* It is not safe to allow the reader to continue here if frames
-+        ** may have been appended to the log before READ_LOCK(0) was obtained.
-+        ** When holding READ_LOCK(0), the reader ignores the entire log file,
-+        ** which implies that the database file contains a trustworthy
-+        ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from
-+        ** happening, this is usually correct.
-+        **
-+        ** However, if frames have been appended to the log (or if the log 
-+        ** is wrapped and written for that matter) before the READ_LOCK(0)
-+        ** is obtained, that is not necessarily true. A checkpointer may
-+        ** have started to backfill the appended frames but crashed before
-+        ** it finished. Leaving a corrupt image in the database file.
-+        */
-+        walUnlockShared(pWal, WAL_READ_LOCK(0));
-+        return WAL_RETRY;
-+      }
-+      pWal->readLock = 0;
-+      return SQLITE_OK;
-+    }else if( rc!=SQLITE_BUSY ){
-+      return rc;
-     }
--    walLimitSize(pWal, sz);
--    pWal->truncateOnCommit = 0;
-   }
- 
--  /* Append data to the wal-index. It is not necessary to lock the 
--  ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index
--  ** guarantees that there are no other writers, and no data that may
--  ** be in use by existing readers is being overwritten.
-+  /* If we get this far, it means that the reader will want to use
-+  ** the WAL to get at content from recent commits.  The job now is
-+  ** to select one of the aReadMark[] entries that is closest to
-+  ** but not exceeding pWal->hdr.mxFrame and lock that entry.
-   */
--  iFrame = pWal->hdr.mxFrame;
--  for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){
--    iFrame++;
--    rc = walIndexAppend(pWal, iFrame, p->pgno);
--  }
--  while( rc==SQLITE_OK && nExtra>0 ){
--    iFrame++;
--    nExtra--;
--    rc = walIndexAppend(pWal, iFrame, pLast->pgno);
-+  mxReadMark = 0;
-+  mxI = 0;
-+  for(i=1; i<WAL_NREADER; i++){
-+    u32 thisMark = pInfo->aReadMark[i];
-+    if( mxReadMark<=thisMark && thisMark<=pWal->hdr.mxFrame ){
-+      assert( thisMark!=READMARK_NOT_USED );
-+      mxReadMark = thisMark;
-+      mxI = i;
-+    }
-   }
-+  /* There was once an "if" here. The extra "{" is to preserve indentation. */
-+  {
-+    if( (pWal->readOnly & WAL_SHM_RDONLY)==0
-+     && (mxReadMark<pWal->hdr.mxFrame || mxI==0)
-+    ){
-+      for(i=1; i<WAL_NREADER; i++){
-+        rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1, 0);
-+        if( rc==SQLITE_OK ){
-+          mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame;
-+          mxI = i;
-+          walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
-+          break;
-+        }else if( rc!=SQLITE_BUSY ){
-+          return rc;
-+        }
++** 2012 May 25
++**
++** 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.
++**
++******************************************************************************
++*/
++
++/*
++** DO NOT EDIT THIS MACHINE GENERATED FILE.
++*/
++
++
++/* #include <assert.h> */
++
++/*
++** Return true if the argument corresponds to a unicode codepoint
++** classified as either a letter or a number. Otherwise false.
++**
++** The results are undefined if the value passed to this function
++** is less than zero.
++*/
++static int sqlite3Fts5UnicodeIsalnum(int c){
++  /* Each unsigned integer in the following array corresponds to a contiguous
++  ** range of unicode codepoints that are not either letters or numbers (i.e.
++  ** codepoints for which this function should return 0).
++  **
++  ** The most significant 22 bits in each 32-bit value contain the first 
++  ** codepoint in the range. The least significant 10 bits are used to store
++  ** the size of the range (always at least 1). In other words, the value 
++  ** ((C<<22) + N) represents a range of N codepoints starting with codepoint 
++  ** C. It is not possible to represent a range larger than 1023 codepoints 
++  ** using this format.
++  */
++  static const unsigned int aEntry[] = {
++    0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
++    0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
++    0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
++    0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
++    0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01,
++    0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802,
++    0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F,
++    0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401,
++    0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804,
++    0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403,
++    0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812,
++    0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001,
++    0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802,
++    0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805,
++    0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401,
++    0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03,
++    0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807,
++    0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001,
++    0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01,
++    0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804,
++    0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001,
++    0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802,
++    0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01,
++    0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06,
++    0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007,
++    0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006,
++    0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417,
++    0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14,
++    0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07,
++    0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01,
++    0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001,
++    0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802,
++    0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F,
++    0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002,
++    0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802,
++    0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006,
++    0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D,
++    0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802,
++    0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027,
++    0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403,
++    0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805,
++    0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04,
++    0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401,
++    0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005,
++    0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B,
++    0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A,
++    0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001,
++    0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59,
++    0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807,
++    0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01,
++    0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E,
++    0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100,
++    0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10,
++    0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402,
++    0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804,
++    0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012,
++    0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004,
++    0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002,
++    0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803,
++    0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07,
++    0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
++    0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802,
++    0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013,
++    0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06,
++    0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003,
++    0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01,
++    0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403,
++    0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009,
++    0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003,
++    0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003,
++    0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E,
++    0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046,
++    0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401,
++    0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401,
++    0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F,
++    0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C,
++    0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002,
++    0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025,
++    0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6,
++    0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46,
++    0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060,
++    0x380400F0,
++  };
++  static const unsigned int aAscii[4] = {
++    0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
++  };
++
++  if( (unsigned int)c<128 ){
++    return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
++  }else if( (unsigned int)c<(1<<22) ){
++    unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
++    int iRes = 0;
++    int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
++    int iLo = 0;
++    while( iHi>=iLo ){
++      int iTest = (iHi + iLo) / 2;
++      if( key >= aEntry[iTest] ){
++        iRes = iTest;
++        iLo = iTest+1;
++      }else{
++        iHi = iTest-1;
 +      }
 +    }
-+    if( mxI==0 ){
-+      assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
-+      return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
-+    }
- 
--  if( rc==SQLITE_OK ){
--    /* Update the private copy of the header. */
--    pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
--    testcase( szPage<=32768 );
--    testcase( szPage>=65536 );
--    pWal->hdr.mxFrame = iFrame;
--    if( isCommit ){
--      pWal->hdr.iChange++;
--      pWal->hdr.nPage = nTruncate;
-+    rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
-+    if( rc ){
-+      return rc==SQLITE_BUSY ? WAL_RETRY : rc;
-     }
--    /* If this is a commit, update the wal-index header too. */
--    if( isCommit ){
--      walIndexWriteHdr(pWal);
--      pWal->iCallback = iFrame;
-+    /* Now that the read-lock has been obtained, check that neither the
-+    ** value in the aReadMark[] array or the contents of the wal-index
-+    ** header have changed.
-+    **
-+    ** It is necessary to check that the wal-index header did not change
-+    ** between the time it was read and when the shared-lock was obtained
-+    ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility
-+    ** that the log file may have been wrapped by a writer, or that frames
-+    ** that occur later in the log than pWal->hdr.mxFrame may have been
-+    ** copied into the database by a checkpointer. If either of these things
-+    ** happened, then reading the database with the current value of
-+    ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry
-+    ** instead.
-+    **
-+    ** This does not guarantee that the copy of the wal-index header is up to
-+    ** date before proceeding. That would not be possible without somehow
-+    ** blocking writers. It only guarantees that a dangerous checkpoint or 
-+    ** log-wrap (either of which would require an exclusive lock on
-+    ** WAL_READ_LOCK(mxI)) has not occurred since the snapshot was valid.
-+    */
-+    walShmBarrier(pWal);
-+    if( pInfo->aReadMark[mxI]!=mxReadMark
-+     || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
-+    ){
-+      walUnlockShared(pWal, WAL_READ_LOCK(mxI));
-+      return WAL_RETRY;
-+    }else{
-+      assert( mxReadMark<=pWal->hdr.mxFrame );
-+      pWal->readLock = (i16)mxI;
-     }
-   }
--
--  WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok"));
-   return rc;
- }
- 
--/* 
--** This routine is called to implement sqlite3_wal_checkpoint() and
--** related interfaces.
-+/*
-+** Begin a read transaction on the database.
- **
--** Obtain a CHECKPOINT lock and then backfill as much information as
--** we can from WAL into the database.
-+** This routine used to be called sqlite3OpenSnapshot() and with good reason:
-+** it takes a snapshot of the state of the WAL and wal-index for the current
-+** instant in time.  The current thread will continue to use this snapshot.
-+** Other threads might append new content to the WAL and wal-index but
-+** that extra content is ignored by the current thread.
- **
--** If parameter xBusy is not NULL, it is a pointer to a busy-handler
--** callback. In this case this function runs a blocking checkpoint.
-+** If the database contents have changes since the previous read
-+** transaction, then *pChanged is set to 1 before returning.  The
-+** Pager layer will use this to know that is cache is stale and
-+** needs to be flushed.
- */
--SQLITE_PRIVATE int sqlite3WalCheckpoint(
--  Wal *pWal,                      /* Wal connection */
--  int eMode,                      /* PASSIVE, FULL, RESTART, or TRUNCATE */
--  int (*xBusy)(void*),            /* Function to call when busy */
--  void *pBusyArg,                 /* Context argument for xBusyHandler */
--  int sync_flags,                 /* Flags to sync db file with (or 0) */
--  int nBuf,                       /* Size of temporary buffer */
--  u8 *zBuf,                       /* Temporary buffer to use */
--  int *pnLog,                     /* OUT: Number of frames in WAL */
--  int *pnCkpt                     /* OUT: Number of backfilled frames in WAL */
--){
-+SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
-   int rc;                         /* Return code */
--  int isChanged = 0;              /* True if a new wal-index header is loaded */
--  int eMode2 = eMode;             /* Mode to pass to walCheckpoint() */
--  int (*xBusy2)(void*) = xBusy;   /* Busy handler for eMode2 */
-+  int cnt = 0;                    /* Number of TryBeginRead attempts */
- 
--  assert( pWal->ckptLock==0 );
--  assert( pWal->writeLock==0 );
-+  do{
-+    rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
-+  }while( rc==WAL_RETRY );
-+  testcase( (rc&0xff)==SQLITE_BUSY );
-+  testcase( (rc&0xff)==SQLITE_IOERR );
-+  testcase( rc==SQLITE_PROTOCOL );
-+  testcase( rc==SQLITE_OK );
-+  return rc;
++    assert( aEntry[0]<key );
++    assert( key>=aEntry[iRes] );
++    return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
++  }
++  return 1;
 +}
- 
--  /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
--  ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
--  assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
++
++
 +/*
-+** Finish with a read transaction.  All this does is release the
-+** read-lock.
++** If the argument is a codepoint corresponding to a lowercase letter
++** in the ASCII range with a diacritic added, return the codepoint
++** of the ASCII letter only. For example, if passed 235 - "LATIN
++** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER
++** E"). The resuls of passing a codepoint that corresponds to an
++** uppercase letter are undefined.
 +*/
-+SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){
-+  sqlite3WalEndWriteTransaction(pWal);
-+  if( pWal->readLock>=0 ){
-+    walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
-+    pWal->readLock = -1;
++static int fts5_remove_diacritic(int c){
++  unsigned short aDia[] = {
++        0,  1797,  1848,  1859,  1891,  1928,  1940,  1995, 
++     2024,  2040,  2060,  2110,  2168,  2206,  2264,  2286, 
++     2344,  2383,  2472,  2488,  2516,  2596,  2668,  2732, 
++     2782,  2842,  2894,  2954,  2984,  3000,  3028,  3336, 
++     3456,  3696,  3712,  3728,  3744,  3896,  3912,  3928, 
++     3968,  4008,  4040,  4106,  4138,  4170,  4202,  4234, 
++     4266,  4296,  4312,  4344,  4408,  4424,  4472,  4504, 
++     6148,  6198,  6264,  6280,  6360,  6429,  6505,  6529, 
++    61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726, 
++    61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122, 
++    62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536, 
++    62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, 
++    62924, 63050, 63082, 63274, 63390, 
++  };
++  char aChar[] = {
++    '\0', 'a',  'c',  'e',  'i',  'n',  'o',  'u',  'y',  'y',  'a',  'c',  
++    'd',  'e',  'e',  'g',  'h',  'i',  'j',  'k',  'l',  'n',  'o',  'r',  
++    's',  't',  'u',  'u',  'w',  'y',  'z',  'o',  'u',  'a',  'i',  'o',  
++    'u',  'g',  'k',  'o',  'j',  'g',  'n',  'a',  'e',  'i',  'o',  'r',  
++    'u',  's',  't',  'h',  'a',  'e',  'o',  'y',  '\0', '\0', '\0', '\0', 
++    '\0', '\0', '\0', '\0', 'a',  'b',  'd',  'd',  'e',  'f',  'g',  'h',  
++    'h',  'i',  'k',  'l',  'l',  'm',  'n',  'p',  'r',  'r',  's',  't',  
++    'u',  'v',  'w',  'w',  'x',  'y',  'z',  'h',  't',  'w',  'y',  'a',  
++    'e',  'i',  'o',  'u',  'y',  
++  };
++
++  unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
++  int iRes = 0;
++  int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
++  int iLo = 0;
++  while( iHi>=iLo ){
++    int iTest = (iHi + iLo) / 2;
++    if( key >= aDia[iTest] ){
++      iRes = iTest;
++      iLo = iTest+1;
++    }else{
++      iHi = iTest-1;
++    }
 +  }
++  assert( key>=aDia[iRes] );
++  return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
++}
++
++
++/*
++** Return true if the argument interpreted as a unicode codepoint
++** is a diacritical modifier character.
++*/
++static int sqlite3Fts5UnicodeIsdiacritic(int c){
++  unsigned int mask0 = 0x08029FDF;
++  unsigned int mask1 = 0x000361F8;
++  if( c<768 || c>817 ) return 0;
++  return (c < 768+32) ?
++      (mask0 & (1 << (c-768))) :
++      (mask1 & (1 << (c-768-32)));
 +}
 +
++
 +/*
-+** Search the wal file for page pgno. If found, set *piRead to the frame that
-+** contains the page. Otherwise, if pgno is not in the wal file, set *piRead
-+** to zero.
++** Interpret the argument as a unicode codepoint. If the codepoint
++** is an upper case character that has a lower case equivalent,
++** return the codepoint corresponding to the lower case version.
++** Otherwise, return a copy of the argument.
 +**
-+** Return SQLITE_OK if successful, or an error code if an error occurs. If an
-+** error does occur, the final value of *piRead is undefined.
++** The results are undefined if the value passed to this function
++** is less than zero.
 +*/
-+SQLITE_PRIVATE int sqlite3WalFindFrame(
-+  Wal *pWal,                      /* WAL handle */
-+  Pgno pgno,                      /* Database page number to read data for */
-+  u32 *piRead                     /* OUT: Frame number (or zero) */
-+){
-+  u32 iRead = 0;                  /* If !=0, WAL frame to return data from */
-+  u32 iLast = pWal->hdr.mxFrame;  /* Last page in WAL for this reader */
-+  int iHash;                      /* Used to loop through N hash tables */
- 
--  if( pWal->readOnly ) return SQLITE_READONLY;
--  WALTRACE(("WAL%p: checkpoint begins\n", pWal));
-+  /* This routine is only be called from within a read transaction. */
-+  assert( pWal->readLock>=0 || pWal->lockError );
- 
--  /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive 
--  ** "checkpoint" lock on the database file. */
--  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0);
--  if( rc ){
--    /* EVIDENCE-OF: R-10421-19736 If any other process is running a
--    ** checkpoint operation at the same time, the lock cannot be obtained and
--    ** SQLITE_BUSY is returned.
--    ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
--    ** it will not be invoked in this case.
--    */
--    testcase( rc==SQLITE_BUSY );
--    testcase( xBusy!=0 );
--    return rc;
-+  /* If the "last page" field of the wal-index header snapshot is 0, then
-+  ** no data will be read from the wal under any circumstances. Return early
-+  ** in this case as an optimization.  Likewise, if pWal->readLock==0, 
-+  ** then the WAL is ignored by the reader so return early, as if the 
-+  ** WAL were empty.
-+  */
-+  if( iLast==0 || pWal->readLock==0 ){
-+    *piRead = 0;
-+    return SQLITE_OK;
-   }
--  pWal->ckptLock = 1;
- 
--  /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
--  ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
--  ** file.
-+  /* Search the hash table or tables for an entry matching page number
-+  ** pgno. Each iteration of the following for() loop searches one
-+  ** hash table (each hash table indexes up to HASHTABLE_NPAGE frames).
-   **
--  ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
--  ** immediately, and a busy-handler is configured, it is invoked and the
--  ** writer lock retried until either the busy-handler returns 0 or the
--  ** lock is successfully obtained.
-+  ** This code might run concurrently to the code in walIndexAppend()
-+  ** that adds entries to the wal-index (and possibly to this hash 
-+  ** table). This means the value just read from the hash 
-+  ** slot (aHash[iKey]) may have been added before or after the 
-+  ** current read transaction was opened. Values added after the
-+  ** read transaction was opened may have been written incorrectly -
-+  ** i.e. these slots may contain garbage data. However, we assume
-+  ** that any slots written before the current read transaction was
-+  ** opened remain unmodified.
++static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
++  /* Each entry in the following array defines a rule for folding a range
++  ** of codepoints to lower case. The rule applies to a range of nRange
++  ** codepoints starting at codepoint iCode.
 +  **
-+  ** For the reasons above, the if(...) condition featured in the inner
-+  ** loop of the following block is more stringent that would be required 
-+  ** if we had exclusive access to the hash-table:
++  ** If the least significant bit in flags is clear, then the rule applies
++  ** to all nRange codepoints (i.e. all nRange codepoints are upper case and
++  ** need to be folded). Or, if it is set, then the rule only applies to
++  ** every second codepoint in the range, starting with codepoint C.
 +  **
-+  **   (aPgno[iFrame]==pgno): 
-+  **     This condition filters out normal hash-table collisions.
++  ** The 7 most significant bits in flags are an index into the aiOff[]
++  ** array. If a specific codepoint C does require folding, then its lower
++  ** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF).
 +  **
-+  **   (iFrame<=iLast): 
-+  **     This condition filters out entries that were added to the hash
-+  **     table after the current read-transaction had started.
-   */
--  if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
--    rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
--    if( rc==SQLITE_OK ){
--      pWal->writeLock = 1;
--    }else if( rc==SQLITE_BUSY ){
--      eMode2 = SQLITE_CHECKPOINT_PASSIVE;
--      xBusy2 = 0;
--      rc = SQLITE_OK;
--    }
--  }
-+  for(iHash=walFramePage(iLast); iHash>=0 && iRead==0; iHash--){
-+    volatile ht_slot *aHash;      /* Pointer to hash table */
-+    volatile u32 *aPgno;          /* Pointer to array of page numbers */
-+    u32 iZero;                    /* Frame number corresponding to aPgno[0] */
-+    int iKey;                     /* Hash slot index */
-+    int nCollide;                 /* Number of hash collisions remaining */
-+    int rc;                       /* Error code */
- 
--  /* Read the wal-index header. */
--  if( rc==SQLITE_OK ){
--    rc = walIndexReadHdr(pWal, &isChanged);
--    if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
--      sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
-+    rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero);
-+    if( rc!=SQLITE_OK ){
-+      return rc;
-     }
--  }
--
--  /* Copy data from the log to the database file. */
--  if( rc==SQLITE_OK ){
--    if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
--      rc = SQLITE_CORRUPT_BKPT;
--    }else{
--      rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
-+    nCollide = HASHTABLE_NSLOT;
-+    for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
-+      u32 iFrame = aHash[iKey] + iZero;
-+      if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){
-+        assert( iFrame>iRead || CORRUPT_DB );
-+        iRead = iFrame;
-+      }
-+      if( (nCollide--)==0 ){
-+        return SQLITE_CORRUPT_BKPT;
++  ** The contents of this array are generated by parsing the CaseFolding.txt
++  ** file distributed as part of the "Unicode Character Database". See
++  ** http://www.unicode.org for details.
++  */
++  static const struct TableEntry {
++    unsigned short iCode;
++    unsigned char flags;
++    unsigned char nRange;
++  } aEntry[] = {
++    {65, 14, 26},          {181, 64, 1},          {192, 14, 23},
++    {216, 14, 7},          {256, 1, 48},          {306, 1, 6},
++    {313, 1, 16},          {330, 1, 46},          {376, 116, 1},
++    {377, 1, 6},           {383, 104, 1},         {385, 50, 1},
++    {386, 1, 4},           {390, 44, 1},          {391, 0, 1},
++    {393, 42, 2},          {395, 0, 1},           {398, 32, 1},
++    {399, 38, 1},          {400, 40, 1},          {401, 0, 1},
++    {403, 42, 1},          {404, 46, 1},          {406, 52, 1},
++    {407, 48, 1},          {408, 0, 1},           {412, 52, 1},
++    {413, 54, 1},          {415, 56, 1},          {416, 1, 6},
++    {422, 60, 1},          {423, 0, 1},           {425, 60, 1},
++    {428, 0, 1},           {430, 60, 1},          {431, 0, 1},
++    {433, 58, 2},          {435, 1, 4},           {439, 62, 1},
++    {440, 0, 1},           {444, 0, 1},           {452, 2, 1},
++    {453, 0, 1},           {455, 2, 1},           {456, 0, 1},
++    {458, 2, 1},           {459, 1, 18},          {478, 1, 18},
++    {497, 2, 1},           {498, 1, 4},           {502, 122, 1},
++    {503, 134, 1},         {504, 1, 40},          {544, 110, 1},
++    {546, 1, 18},          {570, 70, 1},          {571, 0, 1},
++    {573, 108, 1},         {574, 68, 1},          {577, 0, 1},
++    {579, 106, 1},         {580, 28, 1},          {581, 30, 1},
++    {582, 1, 10},          {837, 36, 1},          {880, 1, 4},
++    {886, 0, 1},           {902, 18, 1},          {904, 16, 3},
++    {908, 26, 1},          {910, 24, 2},          {913, 14, 17},
++    {931, 14, 9},          {962, 0, 1},           {975, 4, 1},
++    {976, 140, 1},         {977, 142, 1},         {981, 146, 1},
++    {982, 144, 1},         {984, 1, 24},          {1008, 136, 1},
++    {1009, 138, 1},        {1012, 130, 1},        {1013, 128, 1},
++    {1015, 0, 1},          {1017, 152, 1},        {1018, 0, 1},
++    {1021, 110, 3},        {1024, 34, 16},        {1040, 14, 32},
++    {1120, 1, 34},         {1162, 1, 54},         {1216, 6, 1},
++    {1217, 1, 14},         {1232, 1, 88},         {1329, 22, 38},
++    {4256, 66, 38},        {4295, 66, 1},         {4301, 66, 1},
++    {7680, 1, 150},        {7835, 132, 1},        {7838, 96, 1},
++    {7840, 1, 96},         {7944, 150, 8},        {7960, 150, 6},
++    {7976, 150, 8},        {7992, 150, 8},        {8008, 150, 6},
++    {8025, 151, 8},        {8040, 150, 8},        {8072, 150, 8},
++    {8088, 150, 8},        {8104, 150, 8},        {8120, 150, 2},
++    {8122, 126, 2},        {8124, 148, 1},        {8126, 100, 1},
++    {8136, 124, 4},        {8140, 148, 1},        {8152, 150, 2},
++    {8154, 120, 2},        {8168, 150, 2},        {8170, 118, 2},
++    {8172, 152, 1},        {8184, 112, 2},        {8186, 114, 2},
++    {8188, 148, 1},        {8486, 98, 1},         {8490, 92, 1},
++    {8491, 94, 1},         {8498, 12, 1},         {8544, 8, 16},
++    {8579, 0, 1},          {9398, 10, 26},        {11264, 22, 47},
++    {11360, 0, 1},         {11362, 88, 1},        {11363, 102, 1},
++    {11364, 90, 1},        {11367, 1, 6},         {11373, 84, 1},
++    {11374, 86, 1},        {11375, 80, 1},        {11376, 82, 1},
++    {11378, 0, 1},         {11381, 0, 1},         {11390, 78, 2},
++    {11392, 1, 100},       {11499, 1, 4},         {11506, 0, 1},
++    {42560, 1, 46},        {42624, 1, 24},        {42786, 1, 14},
++    {42802, 1, 62},        {42873, 1, 4},         {42877, 76, 1},
++    {42878, 1, 10},        {42891, 0, 1},         {42893, 74, 1},
++    {42896, 1, 4},         {42912, 1, 10},        {42922, 72, 1},
++    {65313, 14, 26},       
++  };
++  static const unsigned short aiOff[] = {
++   1,     2,     8,     15,    16,    26,    28,    32,    
++   37,    38,    40,    48,    63,    64,    69,    71,    
++   79,    80,    116,   202,   203,   205,   206,   207,   
++   209,   210,   211,   213,   214,   217,   218,   219,   
++   775,   7264,  10792, 10795, 23228, 23256, 30204, 54721, 
++   54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274, 
++   57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406, 
++   65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462, 
++   65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511, 
++   65514, 65521, 65527, 65528, 65529, 
++  };
++
++  int ret = c;
++
++  assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
++
++  if( c<128 ){
++    if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
++  }else if( c<65536 ){
++    const struct TableEntry *p;
++    int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
++    int iLo = 0;
++    int iRes = -1;
++
++    assert( c>aEntry[0].iCode );
++    while( iHi>=iLo ){
++      int iTest = (iHi + iLo) / 2;
++      int cmp = (c - aEntry[iTest].iCode);
++      if( cmp>=0 ){
++        iRes = iTest;
++        iLo = iTest+1;
++      }else{
++        iHi = iTest-1;
 +      }
-     }
++    }
++
++    assert( iRes>=0 && c>=aEntry[iRes].iCode );
++    p = &aEntry[iRes];
++    if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
++      ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
++      assert( ret>0 );
++    }
++
++    if( bRemoveDiacritic ) ret = fts5_remove_diacritic(ret);
 +  }
- 
--    /* If no error occurred, set the output variables. */
--    if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
--      if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
--      if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill);
-+#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
-+  /* If expensive assert() statements are available, do a linear search
-+  ** of the wal-index file content. Make sure the results agree with the
-+  ** result obtained using the hash indexes above.  */
-+  {
-+    u32 iRead2 = 0;
-+    u32 iTest;
-+    for(iTest=iLast; iTest>0; iTest--){
-+      if( walFramePgno(pWal, iTest)==pgno ){
-+        iRead2 = iTest;
-+        break;
-+      }
-     }
-+    assert( iRead==iRead2 );
-   }
-+#endif
- 
--  if( isChanged ){
--    /* If a new wal-index header was loaded before the checkpoint was 
--    ** performed, then the pager-cache associated with pWal is now
--    ** out of date. So zero the cached wal-index header to ensure that
--    ** next time the pager opens a snapshot on this database it knows that
--    ** the cache needs to be reset.
--    */
--    memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
--  }
-+  *piRead = iRead;
-+  return SQLITE_OK;
++  
++  else if( c>=66560 && c<66600 ){
++    ret = c + 40;
++  }
++
++  return ret;
 +}
- 
--  /* Release the locks. */
--  sqlite3WalEndWriteTransaction(pWal);
--  walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
--  pWal->ckptLock = 0;
--  WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
--  return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
-+/*
-+** Read the contents of frame iRead from the wal file into buffer pOut
-+** (which is nOut bytes in size). Return SQLITE_OK if successful, or an
-+** error code otherwise.
-+*/
-+SQLITE_PRIVATE int sqlite3WalReadFrame(
-+  Wal *pWal,                      /* WAL handle */
-+  u32 iRead,                      /* Frame to read */
-+  int nOut,                       /* Size of buffer pOut in bytes */
-+  u8 *pOut                        /* Buffer to write page data to */
-+){
-+  int sz;
-+  i64 iOffset;
-+  sz = pWal->hdr.szPage;
-+  sz = (sz&0xfe00) + ((sz&0x0001)<<16);
-+  testcase( sz<=32768 );
-+  testcase( sz>=65536 );
-+  iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
-+  /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
-+  return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset);
- }
- 
--/* Return the value to pass to a sqlite3_wal_hook callback, the
--** number of frames in the WAL at the point of the last commit since
--** sqlite3WalCallback() was called.  If no commits have occurred since
--** the last call, then return 0.
-+/* 
-+** Return the size of the database in pages (or zero, if unknown).
- */
--SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){
--  u32 ret = 0;
--  if( pWal ){
--    ret = pWal->iCallback;
--    pWal->iCallback = 0;
-+SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){
-+  if( pWal && ALWAYS(pWal->readLock>=0) ){
-+    return pWal->hdr.nPage;
-   }
--  return (int)ret;
-+  return 0;
- }
- 
--/*
--** This function is called to change the WAL subsystem into or out
--** of locking_mode=EXCLUSIVE.
 +
-+/* 
-+** This function starts a write transaction on the WAL.
- **
--** If op is zero, then attempt to change from locking_mode=EXCLUSIVE
--** into locking_mode=NORMAL.  This means that we must acquire a lock
--** on the pWal->readLock byte.  If the WAL is already in locking_mode=NORMAL
--** or if the acquisition of the lock fails, then return 0.  If the
--** transition out of exclusive-mode is successful, return 1.  This
--** operation must occur while the pager is still holding the exclusive
--** lock on the main database file.
-+** A read transaction must have already been started by a prior call
-+** to sqlite3WalBeginReadTransaction().
- **
--** If op is one, then change from locking_mode=NORMAL into 
--** locking_mode=EXCLUSIVE.  This means that the pWal->readLock must
--** be released.  Return 1 if the transition is made and 0 if the
--** WAL is already in exclusive-locking mode - meaning that this
--** routine is a no-op.  The pager must already hold the exclusive lock
--** on the main database file before invoking this operation.
-+** If another thread or process has written into the database since
-+** the read transaction was started, then it is not possible for this
-+** thread to write as doing so would cause a fork.  So this routine
-+** returns SQLITE_BUSY in that case and no write transaction is started.
- **
--** If op is negative, then do a dry-run of the op==1 case but do
--** not actually change anything. The pager uses this to see if it
--** should acquire the database exclusive lock prior to invoking
--** the op==1 case.
-+** There can only be a single writer active at a time.
- */
--SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){
-+SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
-   int rc;
--  assert( pWal->writeLock==0 );
--  assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 );
- 
--  /* pWal->readLock is usually set, but might be -1 if there was a 
--  ** prior error while attempting to acquire are read-lock. This cannot 
--  ** happen if the connection is actually in exclusive mode (as no xShmLock
--  ** locks are taken in this case). Nor should the pager attempt to
--  ** upgrade to exclusive-mode following such an error.
--  */
--  assert( pWal->readLock>=0 || pWal->lockError );
--  assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) );
-+  /* Cannot start a write transaction without first holding a read
-+  ** transaction. */
-+  assert( pWal->readLock>=0 );
- 
--  if( op==0 ){
--    if( pWal->exclusiveMode ){
--      pWal->exclusiveMode = 0;
--      if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){
--        pWal->exclusiveMode = 1;
--      }
--      rc = pWal->exclusiveMode==0;
--    }else{
--      /* Already in locking_mode=NORMAL */
--      rc = 0;
--    }
--  }else if( op>0 ){
--    assert( pWal->exclusiveMode==0 );
--    assert( pWal->readLock>=0 );
--    walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
--    pWal->exclusiveMode = 1;
--    rc = 1;
--  }else{
--    rc = pWal->exclusiveMode==0;
-+  if( pWal->readOnly ){
-+    return SQLITE_READONLY;
-   }
--  return rc;
--}
- 
--/* 
--** Return true if the argument is non-NULL and the WAL module is using
--** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
--** WAL module is using shared-memory, return false. 
--*/
--SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){
--  return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
--}
-+  /* Only one writer allowed at a time.  Get the write lock.  Return
-+  ** SQLITE_BUSY if unable.
-+  */
-+  rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0);
-+  if( rc ){
-+    return rc;
++/*
++** 2015 May 30
++**
++** 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.
++**
++******************************************************************************
++**
++** Routines for varint serialization and deserialization.
++*/
++
++
++/* #include "fts5Int.h" */
++
++/*
++** This is a copy of the sqlite3GetVarint32() routine from the SQLite core.
++** Except, this version does handle the single byte case that the core
++** version depends on being handled before its function is called.
++*/
++static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){
++  u32 a,b;
++
++  /* The 1-byte case. Overwhelmingly the most common. */
++  a = *p;
++  /* a: p0 (unmasked) */
++  if (!(a&0x80))
++  {
++    /* Values between 0 and 127 */
++    *v = a;
++    return 1;
 +  }
-+  pWal->writeLock = 1;
- 
--#ifdef SQLITE_ENABLE_ZIPVFS
--/*
--** If the argument is not NULL, it points to a Wal object that holds a
--** read-lock. This function returns the database page-size if it is known,
--** or zero if it is not (or if pWal is NULL).
--*/
--SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
--  assert( pWal==0 || pWal->readLock>=0 );
--  return (pWal ? pWal->szPage : 0);
--}
--#endif
-+  /* If another connection has written to the database file since the
-+  ** time the read transaction on this connection was started, then
-+  ** the write is disallowed.
++
++  /* The 2-byte case */
++  p++;
++  b = *p;
++  /* b: p1 (unmasked) */
++  if (!(b&0x80))
++  {
++    /* Values between 128 and 16383 */
++    a &= 0x7f;
++    a = a<<7;
++    *v = a | b;
++    return 2;
++  }
++
++  /* The 3-byte case */
++  p++;
++  a = a<<14;
++  a |= *p;
++  /* a: p0<<14 | p2 (unmasked) */
++  if (!(a&0x80))
++  {
++    /* Values between 16384 and 2097151 */
++    a &= (0x7f<<14)|(0x7f);
++    b &= 0x7f;
++    b = b<<7;
++    *v = a | b;
++    return 3;
++  }
++
++  /* A 32-bit varint is used to store size information in btrees.
++  ** Objects are rarely larger than 2MiB limit of a 3-byte varint.
++  ** A 3-byte varint is sufficient, for example, to record the size
++  ** of a 1048569-byte BLOB or string.
++  **
++  ** We only unroll the first 1-, 2-, and 3- byte cases.  The very
++  ** rare larger cases can be handled by the slower 64-bit varint
++  ** routine.
 +  */
-+  if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
-+    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
-+    pWal->writeLock = 0;
-+    rc = SQLITE_BUSY_SNAPSHOT;
++  {
++    u64 v64;
++    u8 n;
++    p -= 2;
++    n = sqlite3Fts5GetVarint(p, &v64);
++    *v = (u32)v64;
++    assert( n>3 && n<=9 );
++    return n;
 +  }
- 
--#endif /* #ifndef SQLITE_OMIT_WAL */
-+  return rc;
 +}
- 
--/************** End of wal.c *************************************************/
--/************** Begin file btmutex.c *****************************************/
- /*
--** 2007 August 27
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
--**
--**    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 used to implement mutexes on Btree objects.
--** This code really belongs in btree.c.  But btree.c is getting too
--** big and we want to break it down some.  This packaged seemed like
--** a good breakout.
-+** End a write transaction.  The commit has already been done.  This
-+** routine merely releases the lock.
- */
--/************** Include btreeInt.h in the middle of btmutex.c ****************/
--/************** Begin file btreeInt.h ****************************************/
--/*
--** 2004 April 6
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
--**
--**    May you do good and not evil.
--**    May you find forgiveness for yourself and forgive others.
--**    May you share freely, never taking more than you give.
--**
--*************************************************************************
--** This file implements an external (disk-based) database using BTrees.
--** For a detailed discussion of BTrees, refer to
--**
--**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
--**     "Sorting And Searching", pages 473-480. Addison-Wesley
--**     Publishing Company, Reading, Massachusetts.
--**
--** The basic idea is that each page of the file contains N database
--** entries and N+1 pointers to subpages.
--**
--**   ----------------------------------------------------------------
--**   |  Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) |
--**   ----------------------------------------------------------------
--**
--** All of the keys on the page that Ptr(0) points to have values less
--** than Key(0).  All of the keys on page Ptr(1) and its subpages have
--** values greater than Key(0) and less than Key(1).  All of the keys
--** on Ptr(N) and its subpages have values greater than Key(N-1).  And
--** so forth.
--**
--** Finding a particular key requires reading O(log(M)) pages from the 
--** disk where M is the number of entries in the tree.
--**
--** In this implementation, a single file can hold one or more separate 
--** BTrees.  Each BTree is identified by the index of its root page.  The
--** key and data for any entry are combined to form the "payload".  A
--** fixed amount of payload can be carried directly on the database
--** page.  If the payload is larger than the preset amount then surplus
--** bytes are stored on overflow pages.  The payload for an entry
--** and the preceding pointer are combined to form a "Cell".  Each 
--** page has a small header which contains the Ptr(N) pointer and other
--** information such as the size of key and data.
--**
--** FORMAT DETAILS
--**
--** The file is divided into pages.  The first page is called page 1,
--** the second is page 2, and so forth.  A page number of zero indicates
--** "no such page".  The page size can be any power of 2 between 512 and 65536.
--** Each page can be either a btree page, a freelist page, an overflow
--** page, or a pointer-map page.
--**
--** The first page is always a btree page.  The first 100 bytes of the first
--** page contain a special header (the "file header") that describes the file.
--** The format of the file header is as follows:
--**
--**   OFFSET   SIZE    DESCRIPTION
--**      0      16     Header string: "SQLite format 3\000"
--**     16       2     Page size in bytes.  (1 means 65536)
--**     18       1     File format write version
--**     19       1     File format read version
--**     20       1     Bytes of unused space at the end of each page
--**     21       1     Max embedded payload fraction (must be 64)
--**     22       1     Min embedded payload fraction (must be 32)
--**     23       1     Min leaf payload fraction (must be 32)
--**     24       4     File change counter
--**     28       4     Reserved for future use
--**     32       4     First freelist page
--**     36       4     Number of freelist pages in the file
--**     40      60     15 4-byte meta values passed to higher layers
--**
--**     40       4     Schema cookie
--**     44       4     File format of schema layer
--**     48       4     Size of page cache
--**     52       4     Largest root-page (auto/incr_vacuum)
--**     56       4     1=UTF-8 2=UTF16le 3=UTF16be
--**     60       4     User version
--**     64       4     Incremental vacuum mode
--**     68       4     Application-ID
--**     72      20     unused
--**     92       4     The version-valid-for number
--**     96       4     SQLITE_VERSION_NUMBER
--**
--** All of the integer values are big-endian (most significant byte first).
--**
--** The file change counter is incremented when the database is changed
--** This counter allows other processes to know when the file has changed
--** and thus when they need to flush their cache.
--**
--** The max embedded payload fraction is the amount of the total usable
--** space in a page that can be consumed by a single cell for standard
--** B-tree (non-LEAFDATA) tables.  A value of 255 means 100%.  The default
--** is to limit the maximum cell size so that at least 4 cells will fit
--** on one page.  Thus the default max embedded payload fraction is 64.
--**
--** If the payload for a cell is larger than the max payload, then extra
--** payload is spilled to overflow pages.  Once an overflow page is allocated,
--** as many bytes as possible are moved into the overflow pages without letting
--** the cell size drop below the min embedded payload fraction.
--**
--** The min leaf payload fraction is like the min embedded payload fraction
--** except that it applies to leaf nodes in a LEAFDATA tree.  The maximum
--** payload fraction for a LEAFDATA tree is always 100% (or 255) and it
--** not specified in the header.
--**
--** Each btree pages is divided into three sections:  The header, the
--** cell pointer array, and the cell content area.  Page 1 also has a 100-byte
--** file header that occurs before the page header.
--**
--**      |----------------|
--**      | file header    |   100 bytes.  Page 1 only.
--**      |----------------|
--**      | page header    |   8 bytes for leaves.  12 bytes for interior nodes
--**      |----------------|
--**      | cell pointer   |   |  2 bytes per cell.  Sorted order.
--**      | array          |   |  Grows downward
--**      |                |   v
--**      |----------------|
--**      | unallocated    |
--**      | space          |
--**      |----------------|   ^  Grows upwards
--**      | cell content   |   |  Arbitrary order interspersed with freeblocks.
--**      | area           |   |  and free space fragments.
--**      |----------------|
--**
--** The page headers looks like this:
--**
--**   OFFSET   SIZE     DESCRIPTION
--**      0       1      Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf
--**      1       2      byte offset to the first freeblock
--**      3       2      number of cells on this page
--**      5       2      first byte of the cell content area
--**      7       1      number of fragmented free bytes
--**      8       4      Right child (the Ptr(N) value).  Omitted on leaves.
--**
--** The flags define the format of this btree page.  The leaf flag means that
--** this page has no children.  The zerodata flag means that this page carries
--** only keys and no data.  The intkey flag means that the key is an integer
--** which is stored in the key size entry of the cell header rather than in
--** the payload area.
--**
--** The cell pointer array begins on the first byte after the page header.
--** The cell pointer array contains zero or more 2-byte numbers which are
--** offsets from the beginning of the page to the cell content in the cell
--** content area.  The cell pointers occur in sorted order.  The system strives
--** to keep free space after the last cell pointer so that new cells can
--** be easily added without having to defragment the page.
--**
--** Cell content is stored at the very end of the page and grows toward the
--** beginning of the page.
--**
--** Unused space within the cell content area is collected into a linked list of
--** freeblocks.  Each freeblock is at least 4 bytes in size.  The byte offset
--** to the first freeblock is given in the header.  Freeblocks occur in
--** increasing order.  Because a freeblock must be at least 4 bytes in size,
--** any group of 3 or fewer unused bytes in the cell content area cannot
--** exist on the freeblock chain.  A group of 3 or fewer free bytes is called
--** a fragment.  The total number of bytes in all fragments is recorded.
--** in the page header at offset 7.
--**
--**    SIZE    DESCRIPTION
--**      2     Byte offset of the next freeblock
--**      2     Bytes in this freeblock
--**
--** Cells are of variable length.  Cells are stored in the cell content area at
--** the end of the page.  Pointers to the cells are in the cell pointer array
--** that immediately follows the page header.  Cells is not necessarily
--** contiguous or in order, but cell pointers are contiguous and in order.
--**
--** Cell content makes use of variable length integers.  A variable
--** length integer is 1 to 9 bytes where the lower 7 bits of each 
--** byte are used.  The integer consists of all bytes that have bit 8 set and
--** the first byte with bit 8 clear.  The most significant byte of the integer
--** appears first.  A variable-length integer may not be more than 9 bytes long.
--** As a special case, all 8 bytes of the 9th byte are used as data.  This
--** allows a 64-bit integer to be encoded in 9 bytes.
--**
--**    0x00                      becomes  0x00000000
--**    0x7f                      becomes  0x0000007f
--**    0x81 0x00                 becomes  0x00000080
--**    0x82 0x00                 becomes  0x00000100
--**    0x80 0x7f                 becomes  0x0000007f
--**    0x8a 0x91 0xd1 0xac 0x78  becomes  0x12345678
--**    0x81 0x81 0x81 0x81 0x01  becomes  0x10204081
--**
--** Variable length integers are used for rowids and to hold the number of
--** bytes of key and data in a btree cell.
--**
--** The content of a cell looks like this:
--**
--**    SIZE    DESCRIPTION
--**      4     Page number of the left child. Omitted if leaf flag is set.
--**     var    Number of bytes of data. Omitted if the zerodata flag is set.
--**     var    Number of bytes of key. Or the key itself if intkey flag is set.
--**      *     Payload
--**      4     First page of the overflow chain.  Omitted if no overflow
--**
--** Overflow pages form a linked list.  Each page except the last is completely
--** filled with data (pagesize - 4 bytes).  The last page can have as little
--** as 1 byte of data.
--**
--**    SIZE    DESCRIPTION
--**      4     Page number of next overflow page
--**      *     Data
-+SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){
-+  if( pWal->writeLock ){
-+    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
-+    pWal->writeLock = 0;
-+    pWal->truncateOnCommit = 0;
++
++
++/*
++** Bitmasks used by sqlite3GetVarint().  These precomputed constants
++** are defined here rather than simply putting the constant expressions
++** inline in order to work around bugs in the RVT compiler.
++**
++** SLOT_2_0     A mask for  (0x7f<<14) | 0x7f
++**
++** SLOT_4_2_0   A mask for  (0x7f<<28) | SLOT_2_0
++*/
++#define SLOT_2_0     0x001fc07f
++#define SLOT_4_2_0   0xf01fc07f
++
++/*
++** Read a 64-bit variable-length integer from memory starting at p[0].
++** Return the number of bytes read.  The value is stored in *v.
++*/
++static u8 sqlite3Fts5GetVarint(const unsigned char *p, u64 *v){
++  u32 a,b,s;
++
++  a = *p;
++  /* a: p0 (unmasked) */
++  if (!(a&0x80))
++  {
++    *v = a;
++    return 1;
++  }
++
++  p++;
++  b = *p;
++  /* b: p1 (unmasked) */
++  if (!(b&0x80))
++  {
++    a &= 0x7f;
++    a = a<<7;
++    a |= b;
++    *v = a;
++    return 2;
++  }
++
++  /* Verify that constants are precomputed correctly */
++  assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
++  assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
++
++  p++;
++  a = a<<14;
++  a |= *p;
++  /* a: p0<<14 | p2 (unmasked) */
++  if (!(a&0x80))
++  {
++    a &= SLOT_2_0;
++    b &= 0x7f;
++    b = b<<7;
++    a |= b;
++    *v = a;
++    return 3;
 +  }
-+  return SQLITE_OK;
-+}
 +
-+/*
-+** If any data has been written (but not committed) to the log file, this
-+** function moves the write-pointer back to the start of the transaction.
- **
--** Freelist pages come in two subtypes: trunk pages and leaf pages.  The
--** file header points to the first in a linked list of trunk page.  Each trunk
--** page points to multiple leaf pages.  The content of a leaf page is
--** unspecified.  A trunk page looks like this:
-+** Additionally, the callback function is invoked for each frame written
-+** to the WAL since the start of the transaction. If the callback returns
-+** other than SQLITE_OK, it is not invoked again and the error code is
-+** returned to the caller.
- **
--**    SIZE    DESCRIPTION
--**      4     Page number of next trunk page
--**      4     Number of leaf pointers on this page
--**      *     zero or more pages numbers of leaves
-+** Otherwise, if the callback function does not return an error, this
-+** function returns SQLITE_OK.
- */
-+SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){
-+  int rc = SQLITE_OK;
-+  if( ALWAYS(pWal->writeLock) ){
-+    Pgno iMax = pWal->hdr.mxFrame;
-+    Pgno iFrame;
-+  
-+    /* Restore the clients cache of the wal-index header to the state it
-+    ** was in before the client began writing to the database. 
-+    */
-+    memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr));
- 
-+    for(iFrame=pWal->hdr.mxFrame+1; 
-+        ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; 
-+        iFrame++
-+    ){
-+      /* This call cannot fail. Unless the page for which the page number
-+      ** is passed as the second argument is (a) in the cache and 
-+      ** (b) has an outstanding reference, then xUndo is either a no-op
-+      ** (if (a) is false) or simply expels the page from the cache (if (b)
-+      ** is false).
-+      **
-+      ** If the upper layer is doing a rollback, it is guaranteed that there
-+      ** are no outstanding references to any page other than page 1. And
-+      ** page 1 is never written to the log until the transaction is
-+      ** committed. As a result, the call to xUndo may not fail.
-+      */
-+      assert( walFramePgno(pWal, iFrame)!=1 );
-+      rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame));
-+    }
-+    if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
++  /* CSE1 from below */
++  a &= SLOT_2_0;
++  p++;
++  b = b<<14;
++  b |= *p;
++  /* b: p1<<14 | p3 (unmasked) */
++  if (!(b&0x80))
++  {
++    b &= SLOT_2_0;
++    /* moved CSE1 up */
++    /* a &= (0x7f<<14)|(0x7f); */
++    a = a<<7;
++    a |= b;
++    *v = a;
++    return 4;
 +  }
-+  return rc;
-+}
- 
--/* The following value is the maximum cell size assuming a maximum page
--** size give above.
-+/* 
-+** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 
-+** values. This function populates the array with values required to 
-+** "rollback" the write position of the WAL handle back to the current 
-+** point in the event of a savepoint rollback (via WalSavepointUndo()).
- */
--#define MX_CELL_SIZE(pBt)  ((int)(pBt->pageSize-8))
-+SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){
-+  assert( pWal->writeLock );
-+  aWalData[0] = pWal->hdr.mxFrame;
-+  aWalData[1] = pWal->hdr.aFrameCksum[0];
-+  aWalData[2] = pWal->hdr.aFrameCksum[1];
-+  aWalData[3] = pWal->nCkpt;
-+}
- 
--/* The maximum number of cells on a single page of the database.  This
--** assumes a minimum cell size of 6 bytes  (4 bytes for the cell itself
--** plus 2 bytes for the index to the cell in the page header).  Such
--** small cells will be rare, but they are possible.
-+/* 
-+** Move the write position of the WAL back to the point identified by
-+** the values in the aWalData[] array. aWalData must point to an array
-+** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated
-+** by a call to WalSavepoint().
- */
--#define MX_CELL(pBt) ((pBt->pageSize-8)/6)
-+SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
-+  int rc = SQLITE_OK;
- 
--/* Forward declarations */
--typedef struct MemPage MemPage;
--typedef struct BtLock BtLock;
-+  assert( pWal->writeLock );
-+  assert( aWalData[3]!=pWal->nCkpt || aWalData[0]<=pWal->hdr.mxFrame );
 +
-+  if( aWalData[3]!=pWal->nCkpt ){
-+    /* This savepoint was opened immediately after the write-transaction
-+    ** was started. Right after that, the writer decided to wrap around
-+    ** to the start of the log. Update the savepoint values to match.
-+    */
-+    aWalData[0] = 0;
-+    aWalData[3] = pWal->nCkpt;
++  /* a: p0<<14 | p2 (masked) */
++  /* b: p1<<14 | p3 (unmasked) */
++  /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
++  /* moved CSE1 up */
++  /* a &= (0x7f<<14)|(0x7f); */
++  b &= SLOT_2_0;
++  s = a;
++  /* s: p0<<14 | p2 (masked) */
++
++  p++;
++  a = a<<14;
++  a |= *p;
++  /* a: p0<<28 | p2<<14 | p4 (unmasked) */
++  if (!(a&0x80))
++  {
++    /* we can skip these cause they were (effectively) done above in calc'ing s */
++    /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
++    /* b &= (0x7f<<14)|(0x7f); */
++    b = b<<7;
++    a |= b;
++    s = s>>18;
++    *v = ((u64)s)<<32 | a;
++    return 5;
 +  }
 +
-+  if( aWalData[0]<pWal->hdr.mxFrame ){
-+    pWal->hdr.mxFrame = aWalData[0];
-+    pWal->hdr.aFrameCksum[0] = aWalData[1];
-+    pWal->hdr.aFrameCksum[1] = aWalData[2];
-+    walCleanupHash(pWal);
++  /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
++  s = s<<7;
++  s |= b;
++  /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
++
++  p++;
++  b = b<<14;
++  b |= *p;
++  /* b: p1<<28 | p3<<14 | p5 (unmasked) */
++  if (!(b&0x80))
++  {
++    /* we can skip this cause it was (effectively) done above in calc'ing s */
++    /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
++    a &= SLOT_2_0;
++    a = a<<7;
++    a |= b;
++    s = s>>18;
++    *v = ((u64)s)<<32 | a;
++    return 6;
 +  }
 +
-+  return rc;
++  p++;
++  a = a<<14;
++  a |= *p;
++  /* a: p2<<28 | p4<<14 | p6 (unmasked) */
++  if (!(a&0x80))
++  {
++    a &= SLOT_4_2_0;
++    b &= SLOT_2_0;
++    b = b<<7;
++    a |= b;
++    s = s>>11;
++    *v = ((u64)s)<<32 | a;
++    return 7;
++  }
++
++  /* CSE2 from below */
++  a &= SLOT_2_0;
++  p++;
++  b = b<<14;
++  b |= *p;
++  /* b: p3<<28 | p5<<14 | p7 (unmasked) */
++  if (!(b&0x80))
++  {
++    b &= SLOT_4_2_0;
++    /* moved CSE2 up */
++    /* a &= (0x7f<<14)|(0x7f); */
++    a = a<<7;
++    a |= b;
++    s = s>>4;
++    *v = ((u64)s)<<32 | a;
++    return 8;
++  }
++
++  p++;
++  a = a<<15;
++  a |= *p;
++  /* a: p4<<29 | p6<<15 | p8 (unmasked) */
++
++  /* moved CSE2 up */
++  /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */
++  b &= SLOT_2_0;
++  b = b<<8;
++  a |= b;
++
++  s = s<<4;
++  b = p[-4];
++  b &= 0x7f;
++  b = b>>3;
++  s |= b;
++
++  *v = ((u64)s)<<32 | a;
++
++  return 9;
 +}
- 
- /*
--** This is a magic string that appears at the beginning of every
--** SQLite database in order to identify the file as a real database.
-+** This function is called just before writing a set of frames to the log
-+** file (see sqlite3WalFrames()). It checks to see if, instead of appending
-+** to the current log file, it is possible to overwrite the start of the
-+** existing log file with the new frames (i.e. "reset" the log). If so,
-+** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left
-+** unchanged.
- **
--** You can change this value at compile-time by specifying a
--** -DSQLITE_FILE_HEADER="..." on the compiler command-line.  The
--** header must be exactly 16 bytes including the zero-terminator so
--** the string itself should be 15 characters long.  If you change
--** the header, then your custom library will not be able to read 
--** databases generated by the standard tools and the standard tools
--** will not be able to read databases created by your custom library.
-+** SQLITE_OK is returned if no error is encountered (regardless of whether
-+** or not pWal->hdr.mxFrame is modified). An SQLite error code is returned
-+** if an error occurs.
- */
--#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */
--#  define SQLITE_FILE_HEADER "SQLite format 3"
--#endif
-+static int walRestartLog(Wal *pWal){
-+  int rc = SQLITE_OK;
-+  int cnt;
 +
-+  if( pWal->readLock==0 ){
-+    volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
-+    assert( pInfo->nBackfill==pWal->hdr.mxFrame );
-+    if( pInfo->nBackfill>0 ){
-+      u32 salt1;
-+      sqlite3_randomness(4, &salt1);
-+      rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0);
-+      if( rc==SQLITE_OK ){
-+        /* If all readers are using WAL_READ_LOCK(0) (in other words if no
-+        ** readers are currently using the WAL), then the transactions
-+        ** frames will overwrite the start of the existing log. Update the
-+        ** wal-index header to reflect this.
-+        **
-+        ** In theory it would be Ok to update the cache of the header only
-+        ** at this point. But updating the actual wal-index header is also
-+        ** safe and means there is no special case for sqlite3WalUndo()
-+        ** to handle if this transaction is rolled back.  */
-+        walRestartHdr(pWal, salt1);
-+        walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
-+      }else if( rc!=SQLITE_BUSY ){
-+        return rc;
-+      }
++/*
++** The variable-length integer encoding is as follows:
++**
++** KEY:
++**         A = 0xxxxxxx    7 bits of data and one flag bit
++**         B = 1xxxxxxx    7 bits of data and one flag bit
++**         C = xxxxxxxx    8 bits of data
++**
++**  7 bits - A
++** 14 bits - BA
++** 21 bits - BBA
++** 28 bits - BBBA
++** 35 bits - BBBBA
++** 42 bits - BBBBBA
++** 49 bits - BBBBBBA
++** 56 bits - BBBBBBBA
++** 64 bits - BBBBBBBBC
++*/
++
++#ifdef SQLITE_NOINLINE
++# define FTS5_NOINLINE SQLITE_NOINLINE
++#else
++# define FTS5_NOINLINE
++#endif
++
++/*
++** Write a 64-bit variable-length integer to memory starting at p[0].
++** The length of data write will be between 1 and 9 bytes.  The number
++** of bytes written is returned.
++**
++** A variable-length integer consists of the lower 7 bits of each byte
++** for all bytes that have the 8th bit set and one byte with the 8th
++** bit clear.  Except, if we get to the 9th byte, it stores the full
++** 8 bits and is the last byte.
++*/
++static int FTS5_NOINLINE fts5PutVarint64(unsigned char *p, u64 v){
++  int i, j, n;
++  u8 buf[10];
++  if( v & (((u64)0xff000000)<<32) ){
++    p[8] = (u8)v;
++    v >>= 8;
++    for(i=7; i>=0; i--){
++      p[i] = (u8)((v & 0x7f) | 0x80);
++      v >>= 7;
 +    }
-+    walUnlockShared(pWal, WAL_READ_LOCK(0));
-+    pWal->readLock = -1;
-+    cnt = 0;
-+    do{
-+      int notUsed;
-+      rc = walTryBeginRead(pWal, &notUsed, 1, ++cnt);
-+    }while( rc==WAL_RETRY );
-+    assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */
-+    testcase( (rc&0xff)==SQLITE_IOERR );
-+    testcase( rc==SQLITE_PROTOCOL );
-+    testcase( rc==SQLITE_OK );
++    return 9;
++  }    
++  n = 0;
++  do{
++    buf[n++] = (u8)((v & 0x7f) | 0x80);
++    v >>= 7;
++  }while( v!=0 );
++  buf[0] &= 0x7f;
++  assert( n<=9 );
++  for(i=0, j=n-1; j>=0; j--, i++){
++    p[i] = buf[j];
 +  }
-+  return rc;
++  return n;
 +}
- 
- /*
--** Page type flags.  An ORed combination of these flags appear as the
--** first byte of on-disk image of every BTree page.
-+** Information about the current state of the WAL file and where
-+** the next fsync should occur - passed from sqlite3WalFrames() into
-+** walWriteToLog().
- */
--#define PTF_INTKEY    0x01
--#define PTF_ZERODATA  0x02
--#define PTF_LEAFDATA  0x04
--#define PTF_LEAF      0x08
-+typedef struct WalWriter {
-+  Wal *pWal;                   /* The complete WAL information */
-+  sqlite3_file *pFd;           /* The WAL file to which we write */
-+  sqlite3_int64 iSyncPoint;    /* Fsync at this offset */
-+  int syncFlags;               /* Flags for the fsync */
-+  int szPage;                  /* Size of one page */
-+} WalWriter;
- 
- /*
--** As each page of the file is loaded into memory, an instance of the following
--** structure is appended and initialized to zero.  This structure stores
--** information about the page that is decoded from the raw file page.
--**
--** The pParent field points back to the parent page.  This allows us to
--** walk up the BTree from any leaf to the root.  Care must be taken to
--** unref() the parent page pointer when this page is no longer referenced.
--** The pageDestructor() routine handles that chore.
-+** Write iAmt bytes of content into the WAL file beginning at iOffset.
-+** Do a sync when crossing the p->iSyncPoint boundary.
- **
--** Access to all fields of this structure is controlled by the mutex
--** stored in MemPage.pBt->mutex.
-+** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt,
-+** first write the part before iSyncPoint, then sync, then write the
-+** rest.
- */
--struct MemPage {
--  u8 isInit;           /* True if previously initialized. MUST BE FIRST! */
--  u8 nOverflow;        /* Number of overflow cell bodies in aCell[] */
--  u8 intKey;           /* True if table b-trees.  False for index b-trees */
--  u8 intKeyLeaf;       /* True if the leaf of an intKey table */
--  u8 noPayload;        /* True if internal intKey page (thus w/o data) */
--  u8 leaf;             /* True if a leaf page */
--  u8 hdrOffset;        /* 100 for page 1.  0 otherwise */
--  u8 childPtrSize;     /* 0 if leaf==1.  4 if leaf==0 */
--  u8 max1bytePayload;  /* min(maxLocal,127) */
--  u8 bBusy;            /* Prevent endless loops on corrupt database files */
--  u16 maxLocal;        /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
--  u16 minLocal;        /* Copy of BtShared.minLocal or BtShared.minLeaf */
--  u16 cellOffset;      /* Index in aData of first cell pointer */
--  u16 nFree;           /* Number of free bytes on the page */
--  u16 nCell;           /* Number of cells on this page, local and ovfl */
--  u16 maskPage;        /* Mask for page offset */
--  u16 aiOvfl[5];       /* Insert the i-th overflow cell before the aiOvfl-th
--                       ** non-overflow cell */
--  u8 *apOvfl[5];       /* Pointers to the body of overflow cells */
--  BtShared *pBt;       /* Pointer to BtShared that this page is part of */
--  u8 *aData;           /* Pointer to disk image of the page data */
--  u8 *aDataEnd;        /* One byte past the end of usable data */
--  u8 *aCellIdx;        /* The cell index area */
--  DbPage *pDbPage;     /* Pager page handle */
--  Pgno pgno;           /* Page number for this page */
--};
-+static int walWriteToLog(
-+  WalWriter *p,              /* WAL to write to */
-+  void *pContent,            /* Content to be written */
-+  int iAmt,                  /* Number of bytes to write */
-+  sqlite3_int64 iOffset      /* Start writing at this offset */
-+){
-+  int rc;
-+  if( iOffset<p->iSyncPoint && iOffset+iAmt>=p->iSyncPoint ){
-+    int iFirstAmt = (int)(p->iSyncPoint - iOffset);
-+    rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset);
-+    if( rc ) return rc;
-+    iOffset += iFirstAmt;
-+    iAmt -= iFirstAmt;
-+    pContent = (void*)(iFirstAmt + (char*)pContent);
-+    assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) );
-+    rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK);
-+    if( iAmt==0 || rc ) return rc;
-+  }
-+  rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset);
-+  return rc;
++
++static int sqlite3Fts5PutVarint(unsigned char *p, u64 v){
++  if( v<=0x7f ){
++    p[0] = v&0x7f;
++    return 1;
++  }
++  if( v<=0x3fff ){
++    p[0] = ((v>>7)&0x7f)|0x80;
++    p[1] = v&0x7f;
++    return 2;
++  }
++  return fts5PutVarint64(p,v);
 +}
- 
- /*
--** The in-memory image of a disk page has the auxiliary information appended
--** to the end.  EXTRA_SIZE is the number of bytes of space needed to hold
--** that extra information.
-+** Write out a single frame of the WAL
- */
--#define EXTRA_SIZE sizeof(MemPage)
-+static int walWriteOneFrame(
-+  WalWriter *p,               /* Where to write the frame */
-+  PgHdr *pPage,               /* The page of the frame to be written */
-+  int nTruncate,              /* The commit flag.  Usually 0.  >0 for commit */
-+  sqlite3_int64 iOffset       /* Byte offset at which to write */
-+){
-+  int rc;                         /* Result code from subfunctions */
-+  void *pData;                    /* Data actually written */
-+  u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-header in */
-+#if defined(SQLITE_HAS_CODEC)
-+  if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM;
-+#else
-+  pData = pPage->pData;
++
++
++static int sqlite3Fts5GetVarintLen(u32 iVal){
++#if 0
++  if( iVal<(1 << 7 ) ) return 1;
 +#endif
-+  walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame);
-+  rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
-+  if( rc ) return rc;
-+  /* Write the page data */
-+  rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame));
-+  return rc;
++  assert( iVal>=(1 << 7) );
++  if( iVal<(1 << 14) ) return 2;
++  if( iVal<(1 << 21) ) return 3;
++  if( iVal<(1 << 28) ) return 4;
++  return 5;
 +}
- 
--/*
--** A linked list of the following structures is stored at BtShared.pLock.
--** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor 
--** is opened on the table with root page BtShared.iTable. Locks are removed
--** from this list when a transaction is committed or rolled back, or when
--** a btree handle is closed.
-+/* 
-+** Write a set of frames to the log. The caller must hold the write-lock
-+** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
- */
--struct BtLock {
--  Btree *pBtree;        /* Btree handle holding this lock */
--  Pgno iTable;          /* Root page of table */
--  u8 eLock;             /* READ_LOCK or WRITE_LOCK */
--  BtLock *pNext;        /* Next in BtShared.pLock list */
--};
-+SQLITE_PRIVATE int sqlite3WalFrames(
-+  Wal *pWal,                      /* Wal handle to write to */
-+  int szPage,                     /* Database page-size in bytes */
-+  PgHdr *pList,                   /* List of dirty pages to write */
-+  Pgno nTruncate,                 /* Database size after this commit */
-+  int isCommit,                   /* True if this is a commit */
-+  int sync_flags                  /* Flags to pass to OsSync() (or 0) */
-+){
-+  int rc;                         /* Used to catch return codes */
-+  u32 iFrame;                     /* Next frame address */
-+  PgHdr *p;                       /* Iterator to run through pList with. */
-+  PgHdr *pLast = 0;               /* Last frame in list */
-+  int nExtra = 0;                 /* Number of extra copies of last page */
-+  int szFrame;                    /* The size of a single frame */
-+  i64 iOffset;                    /* Next byte to write in WAL file */
-+  WalWriter w;                    /* The writer */
- 
--/* Candidate values for BtLock.eLock */
--#define READ_LOCK     1
--#define WRITE_LOCK    2
-+  assert( pList );
-+  assert( pWal->writeLock );
- 
--/* A Btree handle
--**
--** A database connection contains a pointer to an instance of
--** this object for every database file that it has open.  This structure
--** is opaque to the database connection.  The database connection cannot
--** see the internals of this structure and only deals with pointers to
--** this structure.
--**
--** For some database files, the same underlying database cache might be 
--** shared between multiple connections.  In that case, each connection
--** has it own instance of this object.  But each instance of this object
--** points to the same BtShared object.  The database cache and the
--** schema associated with the database file are all contained within
--** the BtShared object.
--**
--** All fields in this structure are accessed under sqlite3.mutex.
--** The pBt pointer itself may not be changed while there exists cursors 
--** in the referenced BtShared that point back to this Btree since those
--** cursors have to go through this Btree to find their BtShared and
--** they often do so without holding sqlite3.mutex.
--*/
--struct Btree {
--  sqlite3 *db;       /* The database connection holding this btree */
--  BtShared *pBt;     /* Sharable content of this btree */
--  u8 inTrans;        /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
--  u8 sharable;       /* True if we can share pBt with another db */
--  u8 locked;         /* True if db currently has pBt locked */
--  int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
--  int nBackup;       /* Number of backup operations reading this btree */
--  u32 iDataVersion;  /* Combines with pBt->pPager->iDataVersion */
--  Btree *pNext;      /* List of other sharable Btrees from the same db */
--  Btree *pPrev;      /* Back pointer of the same list */
--#ifndef SQLITE_OMIT_SHARED_CACHE
--  BtLock lock;       /* Object used to lock page 1 */
-+  /* If this frame set completes a transaction, then nTruncate>0.  If
-+  ** nTruncate==0 then this frame set does not complete the transaction. */
-+  assert( (isCommit!=0)==(nTruncate!=0) );
 +
-+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-+  { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){}
-+    WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n",
-+              pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill"));
-+  }
- #endif
--};
- 
--/*
--** Btree.inTrans may take one of the following values.
--**
--** If the shared-data extension is enabled, there may be multiple users
--** of the Btree structure. At most one of these may open a write transaction,
--** but any number may have active read transactions.
--*/
--#define TRANS_NONE  0
--#define TRANS_READ  1
--#define TRANS_WRITE 2
-+  /* See if it is possible to write these frames into the start of the
-+  ** log file, instead of appending to it at pWal->hdr.mxFrame.
-+  */
-+  if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){
-+    return rc;
-+  }
 +
-+  /* If this is the first frame written into the log, write the WAL
-+  ** header to the start of the WAL file. See comments at the top of
-+  ** this source file for a description of the WAL header format.
-+  */
-+  iFrame = pWal->hdr.mxFrame;
-+  if( iFrame==0 ){
-+    u8 aWalHdr[WAL_HDRSIZE];      /* Buffer to assemble wal-header in */
-+    u32 aCksum[2];                /* Checksum for wal-header */
-+
-+    sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN));
-+    sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION);
-+    sqlite3Put4byte(&aWalHdr[8], szPage);
-+    sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt);
-+    if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt);
-+    memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8);
-+    walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum);
-+    sqlite3Put4byte(&aWalHdr[24], aCksum[0]);
-+    sqlite3Put4byte(&aWalHdr[28], aCksum[1]);
-+    
-+    pWal->szPage = szPage;
-+    pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN;
-+    pWal->hdr.aFrameCksum[0] = aCksum[0];
-+    pWal->hdr.aFrameCksum[1] = aCksum[1];
-+    pWal->truncateOnCommit = 1;
-+
-+    rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0);
-+    WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok"));
-+    if( rc!=SQLITE_OK ){
-+      return rc;
-+    }
++/*
++** 2015 May 08
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This is an SQLite virtual table module implementing direct access to an
++** existing FTS5 index. The module may create several different types of 
++** tables:
++**
++** col:
++**     CREATE TABLE vocab(term, col, doc, cnt, PRIMARY KEY(term, col));
++**
++**   One row for each term/column combination. The value of $doc is set to
++**   the number of fts5 rows that contain at least one instance of term
++**   $term within column $col. Field $cnt is set to the total number of 
++**   instances of term $term in column $col (in any row of the fts5 table). 
++**
++** row:
++**     CREATE TABLE vocab(term, doc, cnt, PRIMARY KEY(term));
++**
++**   One row for each term in the database. The value of $doc is set to
++**   the number of fts5 rows that contain at least one instance of term
++**   $term. Field $cnt is set to the total number of instances of term 
++**   $term in the database.
++*/
++
++
++/* #include "fts5Int.h" */
++
++
++typedef struct Fts5VocabTable Fts5VocabTable;
++typedef struct Fts5VocabCursor Fts5VocabCursor;
++
++struct Fts5VocabTable {
++  sqlite3_vtab base;
++  char *zFts5Tbl;                 /* Name of fts5 table */
++  char *zFts5Db;                  /* Db containing fts5 table */
++  sqlite3 *db;                    /* Database handle */
++  Fts5Global *pGlobal;            /* FTS5 global object for this database */
++  int eType;                      /* FTS5_VOCAB_COL or ROW */
++};
++
++struct Fts5VocabCursor {
++  sqlite3_vtab_cursor base;
++  sqlite3_stmt *pStmt;            /* Statement holding lock on pIndex */
++  Fts5Index *pIndex;              /* Associated FTS5 index */
++
++  int bEof;                       /* True if this cursor is at EOF */
++  Fts5IndexIter *pIter;           /* Term/rowid iterator object */
++
++  int nLeTerm;                    /* Size of zLeTerm in bytes */
++  char *zLeTerm;                  /* (term <= $zLeTerm) paramater, or NULL */
++
++  /* These are used by 'col' tables only */
++  Fts5Config *pConfig;            /* Fts5 table configuration */
++  int iCol;
++  i64 *aCnt;
++  i64 *aDoc;
++
++  /* Output values used by 'row' and 'col' tables */
++  i64 rowid;                      /* This table's current rowid value */
++  Fts5Buffer term;                /* Current value of 'term' column */
++};
++
++#define FTS5_VOCAB_COL    0
++#define FTS5_VOCAB_ROW    1
 +
-+    /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless
-+    ** all syncing is turned off by PRAGMA synchronous=OFF).  Otherwise
-+    ** an out-of-order write following a WAL restart could result in
-+    ** database corruption.  See the ticket:
-+    **
-+    **     http://localhost:591/sqlite/info/ff5be73dee
-+    */
-+    if( pWal->syncHeader && sync_flags ){
-+      rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK);
-+      if( rc ) return rc;
-+    }
-+  }
-+  assert( (int)pWal->szPage==szPage );
-+
-+  /* Setup information needed to write frames into the WAL */
-+  w.pWal = pWal;
-+  w.pFd = pWal->pWalFd;
-+  w.iSyncPoint = 0;
-+  w.syncFlags = sync_flags;
-+  w.szPage = szPage;
-+  iOffset = walFrameOffset(iFrame+1, szPage);
-+  szFrame = szPage + WAL_FRAME_HDRSIZE;
-+
-+  /* Write all frames into the log file exactly once */
-+  for(p=pList; p; p=p->pDirty){
-+    int nDbSize;   /* 0 normally.  Positive == commit flag */
-+    iFrame++;
-+    assert( iOffset==walFrameOffset(iFrame, szPage) );
-+    nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0;
-+    rc = walWriteOneFrame(&w, p, nDbSize, iOffset);
-+    if( rc ) return rc;
-+    pLast = p;
-+    iOffset += szFrame;
-+  }
++#define FTS5_VOCAB_COL_SCHEMA  "term, col, doc, cnt"
++#define FTS5_VOCAB_ROW_SCHEMA  "term, doc, cnt"
 +
-+  /* If this is the end of a transaction, then we might need to pad
-+  ** the transaction and/or sync the WAL file.
-+  **
-+  ** Padding and syncing only occur if this set of frames complete a
-+  ** transaction and if PRAGMA synchronous=FULL.  If synchronous==NORMAL
-+  ** or synchronous==OFF, then no padding or syncing are needed.
-+  **
-+  ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not
-+  ** needed and only the sync is done.  If padding is needed, then the
-+  ** final frame is repeated (with its commit mark) until the next sector
-+  ** boundary is crossed.  Only the part of the WAL prior to the last
-+  ** sector boundary is synced; the part of the last frame that extends
-+  ** past the sector boundary is written after the sync.
-+  */
-+  if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
-+    if( pWal->padToSectorBoundary ){
-+      int sectorSize = sqlite3SectorSize(pWal->pWalFd);
-+      w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
-+      while( iOffset<w.iSyncPoint ){
-+        rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
-+        if( rc ) return rc;
-+        iOffset += szFrame;
-+        nExtra++;
-+      }
-+    }else{
-+      rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK);
-+    }
-+  }
++/*
++** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
++*/
++#define FTS5_VOCAB_TERM_EQ 0x01
++#define FTS5_VOCAB_TERM_GE 0x02
++#define FTS5_VOCAB_TERM_LE 0x04
 +
-+  /* If this frame set completes the first transaction in the WAL and
-+  ** if PRAGMA journal_size_limit is set, then truncate the WAL to the
-+  ** journal size limit, if possible.
-+  */
-+  if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){
-+    i64 sz = pWal->mxWalSize;
-+    if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){
-+      sz = walFrameOffset(iFrame+nExtra+1, szPage);
++
++/*
++** Translate a string containing an fts5vocab table type to an 
++** FTS5_VOCAB_XXX constant. If successful, set *peType to the output
++** value and return SQLITE_OK. Otherwise, set *pzErr to an error message
++** and return SQLITE_ERROR.
++*/
++static int fts5VocabTableType(const char *zType, char **pzErr, int *peType){
++  int rc = SQLITE_OK;
++  char *zCopy = sqlite3Fts5Strndup(&rc, zType, -1);
++  if( rc==SQLITE_OK ){
++    sqlite3Fts5Dequote(zCopy);
++    if( sqlite3_stricmp(zCopy, "col")==0 ){
++      *peType = FTS5_VOCAB_COL;
++    }else
++
++    if( sqlite3_stricmp(zCopy, "row")==0 ){
++      *peType = FTS5_VOCAB_ROW;
++    }else
++    {
++      *pzErr = sqlite3_mprintf("fts5vocab: unknown table type: %Q", zCopy);
++      rc = SQLITE_ERROR;
 +    }
-+    walLimitSize(pWal, sz);
-+    pWal->truncateOnCommit = 0;
++    sqlite3_free(zCopy);
 +  }
 +
-+  /* Append data to the wal-index. It is not necessary to lock the 
-+  ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index
-+  ** guarantees that there are no other writers, and no data that may
-+  ** be in use by existing readers is being overwritten.
-+  */
-+  iFrame = pWal->hdr.mxFrame;
-+  for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){
-+    iFrame++;
-+    rc = walIndexAppend(pWal, iFrame, p->pgno);
-+  }
-+  while( rc==SQLITE_OK && nExtra>0 ){
-+    iFrame++;
-+    nExtra--;
-+    rc = walIndexAppend(pWal, iFrame, pLast->pgno);
-+  }
++  return rc;
++}
 +
-+  if( rc==SQLITE_OK ){
-+    /* Update the private copy of the header. */
-+    pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
-+    testcase( szPage<=32768 );
-+    testcase( szPage>=65536 );
-+    pWal->hdr.mxFrame = iFrame;
-+    if( isCommit ){
-+      pWal->hdr.iChange++;
-+      pWal->hdr.nPage = nTruncate;
++
++/*
++** The xDisconnect() virtual table method.
++*/
++static int fts5VocabDisconnectMethod(sqlite3_vtab *pVtab){
++  Fts5VocabTable *pTab = (Fts5VocabTable*)pVtab;
++  sqlite3_free(pTab);
++  return SQLITE_OK;
++}
++
++/*
++** The xDestroy() virtual table method.
++*/
++static int fts5VocabDestroyMethod(sqlite3_vtab *pVtab){
++  Fts5VocabTable *pTab = (Fts5VocabTable*)pVtab;
++  sqlite3_free(pTab);
++  return SQLITE_OK;
++}
++
++/*
++** This function is the implementation of both the xConnect and xCreate
++** methods of the FTS3 virtual table.
++**
++** The argv[] array contains the following:
++**
++**   argv[0]   -> module name  ("fts5vocab")
++**   argv[1]   -> database name
++**   argv[2]   -> table name
++**
++** then:
++**
++**   argv[3]   -> name of fts5 table
++**   argv[4]   -> type of fts5vocab table
++**
++** or, for tables in the TEMP schema only.
++**
++**   argv[3]   -> name of fts5 tables database
++**   argv[4]   -> name of fts5 table
++**   argv[5]   -> type of fts5vocab table
++*/
++static int fts5VocabInitVtab(
++  sqlite3 *db,                    /* The SQLite database connection */
++  void *pAux,                     /* Pointer to Fts5Global object */
++  int argc,                       /* Number of elements in argv array */
++  const char * const *argv,       /* xCreate/xConnect argument array */
++  sqlite3_vtab **ppVTab,          /* Write the resulting vtab structure here */
++  char **pzErr                    /* Write any error message here */
++){
++  const char *azSchema[] = { 
++    "CREATE TABlE vocab(" FTS5_VOCAB_COL_SCHEMA  ")", 
++    "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA  ")"
++  };
++
++  Fts5VocabTable *pRet = 0;
++  int rc = SQLITE_OK;             /* Return code */
++  int bDb;
++
++  bDb = (argc==6 && strlen(argv[1])==4 && memcmp("temp", argv[1], 4)==0);
++
++  if( argc!=5 && bDb==0 ){
++    *pzErr = sqlite3_mprintf("wrong number of vtable arguments");
++    rc = SQLITE_ERROR;
++  }else{
++    int nByte;                      /* Bytes of space to allocate */
++    const char *zDb = bDb ? argv[3] : argv[1];
++    const char *zTab = bDb ? argv[4] : argv[3];
++    const char *zType = bDb ? argv[5] : argv[4];
++    int nDb = (int)strlen(zDb)+1; 
++    int nTab = (int)strlen(zTab)+1;
++    int eType = 0;
++    
++    rc = fts5VocabTableType(zType, pzErr, &eType);
++    if( rc==SQLITE_OK ){
++      assert( eType>=0 && eType<ArraySize(azSchema) );
++      rc = sqlite3_declare_vtab(db, azSchema[eType]);
 +    }
-+    /* If this is a commit, update the wal-index header too. */
-+    if( isCommit ){
-+      walIndexWriteHdr(pWal);
-+      pWal->iCallback = iFrame;
++
++    nByte = sizeof(Fts5VocabTable) + nDb + nTab;
++    pRet = sqlite3Fts5MallocZero(&rc, nByte);
++    if( pRet ){
++      pRet->pGlobal = (Fts5Global*)pAux;
++      pRet->eType = eType;
++      pRet->db = db;
++      pRet->zFts5Tbl = (char*)&pRet[1];
++      pRet->zFts5Db = &pRet->zFts5Tbl[nTab];
++      memcpy(pRet->zFts5Tbl, zTab, nTab);
++      memcpy(pRet->zFts5Db, zDb, nDb);
++      sqlite3Fts5Dequote(pRet->zFts5Tbl);
++      sqlite3Fts5Dequote(pRet->zFts5Db);
 +    }
 +  }
 +
-+  WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok"));
++  *ppVTab = (sqlite3_vtab*)pRet;
 +  return rc;
 +}
- 
--/*
--** An instance of this object represents a single database file.
--** 
--** A single database file can be in use at the same time by two
--** or more database connections.  When two or more connections are
--** sharing the same database file, each connection has it own
--** private Btree object for the file and each of those Btrees points
--** to this one BtShared object.  BtShared.nRef is the number of
--** connections currently sharing this database file.
--**
--** Fields in this structure are accessed under the BtShared.mutex
--** mutex, except for nRef and pNext which are accessed under the
--** global SQLITE_MUTEX_STATIC_MASTER mutex.  The pPager field
--** may not be modified once it is initially set as long as nRef>0.
--** The pSchema field may be set once under BtShared.mutex and
--** thereafter is unchanged as long as nRef>0.
--**
--** isPending:
--**
--**   If a BtShared client fails to obtain a write-lock on a database
--**   table (because there exists one or more read-locks on the table),
--**   the shared-cache enters 'pending-lock' state and isPending is
--**   set to true.
--**
--**   The shared-cache leaves the 'pending lock' state when either of
--**   the following occur:
--**
--**     1) The current writer (BtShared.pWriter) concludes its transaction, OR
--**     2) The number of locks held by other connections drops to zero.
++
++
++/*
++** The xConnect() and xCreate() methods for the virtual table. All the
++** work is done in function fts5VocabInitVtab().
++*/
++static int fts5VocabConnectMethod(
++  sqlite3 *db,                    /* Database connection */
++  void *pAux,                     /* Pointer to tokenizer hash table */
++  int argc,                       /* Number of elements in argv array */
++  const char * const *argv,       /* xCreate/xConnect argument array */
++  sqlite3_vtab **ppVtab,          /* OUT: New sqlite3_vtab object */
++  char **pzErr                    /* OUT: sqlite3_malloc'd error message */
++){
++  return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr);
++}
++static int fts5VocabCreateMethod(
++  sqlite3 *db,                    /* Database connection */
++  void *pAux,                     /* Pointer to tokenizer hash table */
++  int argc,                       /* Number of elements in argv array */
++  const char * const *argv,       /* xCreate/xConnect argument array */
++  sqlite3_vtab **ppVtab,          /* OUT: New sqlite3_vtab object */
++  char **pzErr                    /* OUT: sqlite3_malloc'd error message */
++){
++  return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr);
++}
++
 +/* 
-+** This routine is called to implement sqlite3_wal_checkpoint() and
-+** related interfaces.
- **
--**   while in the 'pending-lock' state, no connection may start a new
--**   transaction.
-+** Obtain a CHECKPOINT lock and then backfill as much information as
-+** we can from WAL into the database.
- **
--**   This feature is included to help prevent writer-starvation.
-+** If parameter xBusy is not NULL, it is a pointer to a busy-handler
-+** callback. In this case this function runs a blocking checkpoint.
- */
--struct BtShared {
--  Pager *pPager;        /* The page cache */
--  sqlite3 *db;          /* Database connection currently using this Btree */
--  BtCursor *pCursor;    /* A list of all open cursors */
--  MemPage *pPage1;      /* First page of the database */
--  u8 openFlags;         /* Flags to sqlite3BtreeOpen() */
--#ifndef SQLITE_OMIT_AUTOVACUUM
--  u8 autoVacuum;        /* True if auto-vacuum is enabled */
--  u8 incrVacuum;        /* True if incr-vacuum is enabled */
--  u8 bDoTruncate;       /* True to truncate db on commit */
--#endif
--  u8 inTransaction;     /* Transaction state */
--  u8 max1bytePayload;   /* Maximum first byte of cell for a 1-byte payload */
--#ifdef SQLITE_HAS_CODEC
--  u8 optimalReserve;    /* Desired amount of reserved space per page */
--#endif
--  u16 btsFlags;         /* Boolean parameters.  See BTS_* macros below */
--  u16 maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
--  u16 minLocal;         /* Minimum local payload in non-LEAFDATA tables */
--  u16 maxLeaf;          /* Maximum local payload in a LEAFDATA table */
--  u16 minLeaf;          /* Minimum local payload in a LEAFDATA table */
--  u32 pageSize;         /* Total number of bytes on a page */
--  u32 usableSize;       /* Number of usable bytes on each page */
--  int nTransaction;     /* Number of open transactions (read + write) */
--  u32 nPage;            /* Number of pages in the database */
--  void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
--  void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
--  sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */
--  Bitvec *pHasContent;  /* Set of pages moved to free-list this transaction */
--#ifndef SQLITE_OMIT_SHARED_CACHE
--  int nRef;             /* Number of references to this structure */
--  BtShared *pNext;      /* Next on a list of sharable BtShared structs */
--  BtLock *pLock;        /* List of locks held on this shared-btree struct */
--  Btree *pWriter;       /* Btree with currently open write transaction */
--#endif
--  u8 *pTmpSpace;        /* Temp space sufficient to hold a single cell */
--};
-+SQLITE_PRIVATE int sqlite3WalCheckpoint(
-+  Wal *pWal,                      /* Wal connection */
-+  int eMode,                      /* PASSIVE, FULL, RESTART, or TRUNCATE */
-+  int (*xBusy)(void*),            /* Function to call when busy */
-+  void *pBusyArg,                 /* Context argument for xBusyHandler */
-+  int sync_flags,                 /* Flags to sync db file with (or 0) */
-+  int nBuf,                       /* Size of temporary buffer */
-+  u8 *zBuf,                       /* Temporary buffer to use */
-+  int *pnLog,                     /* OUT: Number of frames in WAL */
-+  int *pnCkpt                     /* OUT: Number of backfilled frames in WAL */
++** Implementation of the xBestIndex method.
++*/
++static int fts5VocabBestIndexMethod(
++  sqlite3_vtab *pUnused,
++  sqlite3_index_info *pInfo
 +){
-+  int rc;                         /* Return code */
-+  int isChanged = 0;              /* True if a new wal-index header is loaded */
-+  int eMode2 = eMode;             /* Mode to pass to walCheckpoint() */
-+  int (*xBusy2)(void*) = xBusy;   /* Busy handler for eMode2 */
- 
--/*
--** Allowed values for BtShared.btsFlags
--*/
--#define BTS_READ_ONLY        0x0001   /* Underlying file is readonly */
--#define BTS_PAGESIZE_FIXED   0x0002   /* Page size can no longer be changed */
--#define BTS_SECURE_DELETE    0x0004   /* PRAGMA secure_delete is enabled */
--#define BTS_INITIALLY_EMPTY  0x0008   /* Database was empty at trans start */
--#define BTS_NO_WAL           0x0010   /* Do not open write-ahead-log files */
--#define BTS_EXCLUSIVE        0x0020   /* pWriter has an exclusive lock */
--#define BTS_PENDING          0x0040   /* Waiting for read-locks to clear */
-+  assert( pWal->ckptLock==0 );
-+  assert( pWal->writeLock==0 );
- 
--/*
--** An instance of the following structure is used to hold information
--** about a cell.  The parseCellPtr() function fills in this structure
--** based on information extract from the raw disk page.
--*/
--typedef struct CellInfo CellInfo;
--struct CellInfo {
--  i64 nKey;      /* The key for INTKEY tables, or nPayload otherwise */
--  u8 *pPayload;  /* Pointer to the start of payload */
--  u32 nPayload;  /* Bytes of payload */
--  u16 nLocal;    /* Amount of payload held locally, not on overflow */
--  u16 iOverflow; /* Offset to overflow page number.  Zero if no overflow */
--  u16 nSize;     /* Size of the cell content on the main b-tree page */
--};
-+  /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
-+  ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
-+  assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
- 
--/*
--** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than
--** this will be declared corrupt. This value is calculated based on a
--** maximum database size of 2^31 pages a minimum fanout of 2 for a
--** root-node and 3 for all other internal nodes.
--**
--** If a tree that appears to be taller than this is encountered, it is
--** assumed that the database is corrupt.
--*/
--#define BTCURSOR_MAX_DEPTH 20
-+  if( pWal->readOnly ) return SQLITE_READONLY;
-+  WALTRACE(("WAL%p: checkpoint begins\n", pWal));
- 
--/*
--** A cursor is a pointer to a particular entry within a particular
--** b-tree within a database file.
--**
--** The entry is identified by its MemPage and the index in
--** MemPage.aCell[] of the entry.
--**
--** A single database file can be shared by two more database connections,
--** but cursors cannot be shared.  Each cursor is associated with a
--** particular database connection identified BtCursor.pBtree.db.
--**
--** Fields in this structure are accessed under the BtShared.mutex
--** found at self->pBt->mutex. 
--**
--** skipNext meaning:
--**    eState==SKIPNEXT && skipNext>0:  Next sqlite3BtreeNext() is no-op.
--**    eState==SKIPNEXT && skipNext<0:  Next sqlite3BtreePrevious() is no-op.
--**    eState==FAULT:                   Cursor fault with skipNext as error code.
--*/
--struct BtCursor {
--  Btree *pBtree;            /* The Btree to which this cursor belongs */
--  BtShared *pBt;            /* The BtShared this cursor points to */
--  BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
--  struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
--  Pgno *aOverflow;          /* Cache of overflow page locations */
--  CellInfo info;            /* A parse of the cell we are pointing at */
--  i64 nKey;                 /* Size of pKey, or last integer key */
--  void *pKey;               /* Saved key that was cursor last known position */
--  Pgno pgnoRoot;            /* The root page of this tree */
--  int nOvflAlloc;           /* Allocated size of aOverflow[] array */
--  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive.
--                   ** Error code if eState==CURSOR_FAULT */
--  u8 curFlags;              /* zero or more BTCF_* flags defined below */
--  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
--  u8 hints;                             /* As configured by CursorSetHints() */
--  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 */
--};
-+  /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive 
-+  ** "checkpoint" lock on the database file. */
-+  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0);
-+  if( rc ){
-+    /* EVIDENCE-OF: R-10421-19736 If any other process is running a
-+    ** checkpoint operation at the same time, the lock cannot be obtained and
-+    ** SQLITE_BUSY is returned.
-+    ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
-+    ** it will not be invoked in this case.
-+    */
-+    testcase( rc==SQLITE_BUSY );
-+    testcase( xBusy!=0 );
-+    return rc;
++  int i;
++  int iTermEq = -1;
++  int iTermGe = -1;
++  int iTermLe = -1;
++  int idxNum = 0;
++  int nArg = 0;
++
++  UNUSED_PARAM(pUnused);
++
++  for(i=0; i<pInfo->nConstraint; i++){
++    struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
++    if( p->usable==0 ) continue;
++    if( p->iColumn==0 ){          /* term column */
++      if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i;
++      if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i;
++      if( p->op==SQLITE_INDEX_CONSTRAINT_LT ) iTermLe = i;
++      if( p->op==SQLITE_INDEX_CONSTRAINT_GE ) iTermGe = i;
++      if( p->op==SQLITE_INDEX_CONSTRAINT_GT ) iTermGe = i;
++    }
++  }
++
++  if( iTermEq>=0 ){
++    idxNum |= FTS5_VOCAB_TERM_EQ;
++    pInfo->aConstraintUsage[iTermEq].argvIndex = ++nArg;
++    pInfo->estimatedCost = 100;
++  }else{
++    pInfo->estimatedCost = 1000000;
++    if( iTermGe>=0 ){
++      idxNum |= FTS5_VOCAB_TERM_GE;
++      pInfo->aConstraintUsage[iTermGe].argvIndex = ++nArg;
++      pInfo->estimatedCost = pInfo->estimatedCost / 2;
++    }
++    if( iTermLe>=0 ){
++      idxNum |= FTS5_VOCAB_TERM_LE;
++      pInfo->aConstraintUsage[iTermLe].argvIndex = ++nArg;
++      pInfo->estimatedCost = pInfo->estimatedCost / 2;
++    }
++  }
++
++  /* This virtual table always delivers results in ascending order of
++  ** the "term" column (column 0). So if the user has requested this
++  ** specifically - "ORDER BY term" or "ORDER BY term ASC" - set the
++  ** sqlite3_index_info.orderByConsumed flag to tell the core the results
++  ** are already in sorted order.  */
++  if( pInfo->nOrderBy==1 
++   && pInfo->aOrderBy[0].iColumn==0 
++   && pInfo->aOrderBy[0].desc==0
++  ){
++    pInfo->orderByConsumed = 1;
 +  }
-+  pWal->ckptLock = 1;
- 
--/*
--** Legal values for BtCursor.curFlags
--*/
--#define BTCF_WriteFlag    0x01   /* True if a write cursor */
--#define BTCF_ValidNKey    0x02   /* True if info.nKey is valid */
--#define BTCF_ValidOvfl    0x04   /* True if aOverflow is valid */
--#define BTCF_AtLast       0x08   /* Cursor is pointing ot the last entry */
--#define BTCF_Incrblob     0x10   /* True if an incremental I/O handle */
-+  /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
-+  ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
-+  ** file.
-+  **
-+  ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
-+  ** immediately, and a busy-handler is configured, it is invoked and the
-+  ** writer lock retried until either the busy-handler returns 0 or the
-+  ** lock is successfully obtained.
-+  */
-+  if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
-+    rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
++
++  pInfo->idxNum = idxNum;
++  return SQLITE_OK;
++}
++
++/*
++** Implementation of xOpen method.
++*/
++static int fts5VocabOpenMethod(
++  sqlite3_vtab *pVTab, 
++  sqlite3_vtab_cursor **ppCsr
++){
++  Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab;
++  Fts5Index *pIndex = 0;
++  Fts5Config *pConfig = 0;
++  Fts5VocabCursor *pCsr = 0;
++  int rc = SQLITE_OK;
++  sqlite3_stmt *pStmt = 0;
++  char *zSql = 0;
++
++  zSql = sqlite3Fts5Mprintf(&rc,
++      "SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'",
++      pTab->zFts5Tbl, pTab->zFts5Db, pTab->zFts5Tbl, pTab->zFts5Tbl
++  );
++  if( zSql ){
++    rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
++  }
++  sqlite3_free(zSql);
++  assert( rc==SQLITE_OK || pStmt==0 );
++  if( rc==SQLITE_ERROR ) rc = SQLITE_OK;
++
++  if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
++    i64 iId = sqlite3_column_int64(pStmt, 0);
++    pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &pConfig);
++  }
++
++  if( rc==SQLITE_OK && pIndex==0 ){
++    rc = sqlite3_finalize(pStmt);
++    pStmt = 0;
 +    if( rc==SQLITE_OK ){
-+      pWal->writeLock = 1;
-+    }else if( rc==SQLITE_BUSY ){
-+      eMode2 = SQLITE_CHECKPOINT_PASSIVE;
-+      xBusy2 = 0;
-+      rc = SQLITE_OK;
++      pVTab->zErrMsg = sqlite3_mprintf(
++          "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
++      );
++      rc = SQLITE_ERROR;
 +    }
 +  }
- 
--/*
--** Potential values for BtCursor.eState.
--**
--** CURSOR_INVALID:
--**   Cursor does not point to a valid entry. This can happen (for example) 
--**   because the table is empty or because BtreeCursorFirst() has not been
--**   called.
--**
--** CURSOR_VALID:
--**   Cursor points to a valid entry. getPayload() etc. may be called.
--**
--** CURSOR_SKIPNEXT:
--**   Cursor is valid except that the Cursor.skipNext field is non-zero
--**   indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
--**   operation should be a no-op.
--**
--** CURSOR_REQUIRESEEK:
--**   The table that this cursor was opened on still exists, but has been 
--**   modified since the cursor was last used. The cursor position is saved
--**   in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in 
--**   this state, restoreCursorPosition() can be called to attempt to
--**   seek the cursor to the saved position.
--**
--** CURSOR_FAULT:
--**   An unrecoverable error (an I/O error or a malloc failure) has occurred
--**   on a different connection that shares the BtShared cache with this
--**   cursor.  The error has left the cache in an inconsistent state.
--**   Do nothing else with this cursor.  Any attempt to use the cursor
--**   should return the error code stored in BtCursor.skipNext
--*/
--#define CURSOR_INVALID           0
--#define CURSOR_VALID             1
--#define CURSOR_SKIPNEXT          2
--#define CURSOR_REQUIRESEEK       3
--#define CURSOR_FAULT             4
-+  /* Read the wal-index header. */
++
 +  if( rc==SQLITE_OK ){
-+    rc = walIndexReadHdr(pWal, &isChanged);
-+    if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
-+      sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
++    int nByte = pConfig->nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor);
++    pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
++  }
++
++  if( pCsr ){
++    pCsr->pIndex = pIndex;
++    pCsr->pStmt = pStmt;
++    pCsr->pConfig = pConfig;
++    pCsr->aCnt = (i64*)&pCsr[1];
++    pCsr->aDoc = &pCsr->aCnt[pConfig->nCol];
++  }else{
++    sqlite3_finalize(pStmt);
++  }
++
++  *ppCsr = (sqlite3_vtab_cursor*)pCsr;
++  return rc;
++}
++
++static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
++  pCsr->rowid = 0;
++  sqlite3Fts5IterClose(pCsr->pIter);
++  pCsr->pIter = 0;
++  sqlite3_free(pCsr->zLeTerm);
++  pCsr->nLeTerm = -1;
++  pCsr->zLeTerm = 0;
++}
++
++/*
++** Close the cursor.  For additional information see the documentation
++** on the xClose method of the virtual table interface.
++*/
++static int fts5VocabCloseMethod(sqlite3_vtab_cursor *pCursor){
++  Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
++  fts5VocabResetCursor(pCsr);
++  sqlite3Fts5BufferFree(&pCsr->term);
++  sqlite3_finalize(pCsr->pStmt);
++  sqlite3_free(pCsr);
++  return SQLITE_OK;
++}
++
++
++/*
++** Advance the cursor to the next row in the table.
++*/
++static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
++  Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
++  Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
++  int rc = SQLITE_OK;
++  int nCol = pCsr->pConfig->nCol;
++
++  pCsr->rowid++;
++
++  if( pTab->eType==FTS5_VOCAB_COL ){
++    for(pCsr->iCol++; pCsr->iCol<nCol; pCsr->iCol++){
++      if( pCsr->aDoc[pCsr->iCol] ) break;
 +    }
 +  }
- 
--/* 
--** The database page the PENDING_BYTE occupies. This page is never used.
--*/
--# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
-+  /* Copy data from the log to the database file. */
-+  if( rc==SQLITE_OK ){
-+    if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
-+      rc = SQLITE_CORRUPT_BKPT;
++
++  if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=nCol ){
++    if( sqlite3Fts5IterEof(pCsr->pIter) ){
++      pCsr->bEof = 1;
 +    }else{
-+      rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
-+    }
- 
--/*
--** These macros define the location of the pointer-map entry for a 
--** database page. The first argument to each is the number of usable
--** bytes on each page of the database (often 1024). The second is the
--** page number to look up in the pointer map.
--**
--** PTRMAP_PAGENO returns the database page number of the pointer-map
--** page that stores the required pointer. PTRMAP_PTROFFSET returns
--** the offset of the requested map entry.
--**
--** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page,
--** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be
--** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
--** this test.
-+    /* If no error occurred, set the output variables. */
-+    if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
-+      if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
-+      if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill);
++      const char *zTerm;
++      int nTerm;
++
++      zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
++      if( pCsr->nLeTerm>=0 ){
++        int nCmp = MIN(nTerm, pCsr->nLeTerm);
++        int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
++        if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){
++          pCsr->bEof = 1;
++          return SQLITE_OK;
++        }
++      }
++
++      sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
++      memset(pCsr->aCnt, 0, nCol * sizeof(i64));
++      memset(pCsr->aDoc, 0, nCol * sizeof(i64));
++      pCsr->iCol = 0;
++
++      assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
++      while( rc==SQLITE_OK ){
++        const u8 *pPos; int nPos;   /* Position list */
++        i64 iPos = 0;               /* 64-bit position read from poslist */
++        int iOff = 0;               /* Current offset within position list */
++
++        pPos = pCsr->pIter->pData;
++        nPos = pCsr->pIter->nData;
++        switch( pCsr->pConfig->eDetail ){
++          case FTS5_DETAIL_FULL:
++            pPos = pCsr->pIter->pData;
++            nPos = pCsr->pIter->nData;
++            if( pTab->eType==FTS5_VOCAB_ROW ){
++              while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
++                pCsr->aCnt[0]++;
++              }
++              pCsr->aDoc[0]++;
++            }else{
++              int iCol = -1;
++              while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
++                int ii = FTS5_POS2COLUMN(iPos);
++                pCsr->aCnt[ii]++;
++                if( iCol!=ii ){
++                  if( ii>=nCol ){
++                    rc = FTS5_CORRUPT;
++                    break;
++                  }
++                  pCsr->aDoc[ii]++;
++                  iCol = ii;
++                }
++              }
++            }
++            break;
++
++          case FTS5_DETAIL_COLUMNS:
++            if( pTab->eType==FTS5_VOCAB_ROW ){
++              pCsr->aDoc[0]++;
++            }else{
++              while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
++                assert_nc( iPos>=0 && iPos<nCol );
++                if( iPos>=nCol ){
++                  rc = FTS5_CORRUPT;
++                  break;
++                }
++                pCsr->aDoc[iPos]++;
++              }
++            }
++            break;
++
++          default: 
++            assert( pCsr->pConfig->eDetail==FTS5_DETAIL_NONE );
++            pCsr->aDoc[0]++;
++            break;
++        }
++
++        if( rc==SQLITE_OK ){
++          rc = sqlite3Fts5IterNextScan(pCsr->pIter);
++        }
++
++        if( rc==SQLITE_OK ){
++          zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
++          if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){
++            break;
++          }
++          if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
++        }
++      }
 +    }
 +  }
 +
-+  if( isChanged ){
-+    /* If a new wal-index header was loaded before the checkpoint was 
-+    ** performed, then the pager-cache associated with pWal is now
-+    ** out of date. So zero the cached wal-index header to ensure that
-+    ** next time the pager opens a snapshot on this database it knows that
-+    ** the cache needs to be reset.
-+    */
-+    memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
++  if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
++    while( pCsr->aDoc[pCsr->iCol]==0 ) pCsr->iCol++;
++    assert( pCsr->iCol<pCsr->pConfig->nCol );
 +  }
-+
-+  /* Release the locks. */
-+  sqlite3WalEndWriteTransaction(pWal);
-+  walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
-+  pWal->ckptLock = 0;
-+  WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
-+  return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
++  return rc;
 +}
 +
-+/* Return the value to pass to a sqlite3_wal_hook callback, the
-+** number of frames in the WAL at the point of the last commit since
-+** sqlite3WalCallback() was called.  If no commits have occurred since
-+** the last call, then return 0.
- */
--#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)
--#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1))
--#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
-+SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){
-+  u32 ret = 0;
-+  if( pWal ){
-+    ret = pWal->iCallback;
-+    pWal->iCallback = 0;
-+  }
-+  return (int)ret;
-+}
- 
- /*
--** The pointer map is a lookup table that identifies the parent page for
--** each child page in the database file.  The parent page is the page that
--** contains a pointer to the child.  Every page in the database contains
--** 0 or 1 parent pages.  (In this context 'database page' refers
--** to any page that is not part of the pointer map itself.)  Each pointer map
--** entry consists of a single byte 'type' and a 4 byte parent page number.
--** The PTRMAP_XXX identifiers below are the valid types.
--**
--** The purpose of the pointer map is to facility moving pages from one
--** position in the file to another as part of autovacuum.  When a page
--** is moved, the pointer in its parent must be updated to point to the
--** new location.  The pointer map is used to locate the parent page quickly.
--**
--** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not
--**                  used in this case.
--**
--** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number 
--**                  is not used in this case.
-+** This function is called to change the WAL subsystem into or out
-+** of locking_mode=EXCLUSIVE.
- **
--** PTRMAP_OVERFLOW1: The database page is the first page in a list of 
--**                   overflow pages. The page number identifies the page that
--**                   contains the cell with a pointer to this overflow page.
-+** If op is zero, then attempt to change from locking_mode=EXCLUSIVE
-+** into locking_mode=NORMAL.  This means that we must acquire a lock
-+** on the pWal->readLock byte.  If the WAL is already in locking_mode=NORMAL
-+** or if the acquisition of the lock fails, then return 0.  If the
-+** transition out of exclusive-mode is successful, return 1.  This
-+** operation must occur while the pager is still holding the exclusive
-+** lock on the main database file.
- **
--** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of
--**                   overflow pages. The page-number identifies the previous
--**                   page in the overflow page list.
-+** If op is one, then change from locking_mode=NORMAL into 
-+** locking_mode=EXCLUSIVE.  This means that the pWal->readLock must
-+** be released.  Return 1 if the transition is made and 0 if the
-+** WAL is already in exclusive-locking mode - meaning that this
-+** routine is a no-op.  The pager must already hold the exclusive lock
-+** on the main database file before invoking this operation.
- **
--** PTRMAP_BTREE: The database page is a non-root btree page. The page number
--**               identifies the parent page in the btree.
-+** If op is negative, then do a dry-run of the op==1 case but do
-+** not actually change anything. The pager uses this to see if it
-+** should acquire the database exclusive lock prior to invoking
-+** the op==1 case.
- */
--#define PTRMAP_ROOTPAGE 1
--#define PTRMAP_FREEPAGE 2
--#define PTRMAP_OVERFLOW1 3
--#define PTRMAP_OVERFLOW2 4
--#define PTRMAP_BTREE 5
-+SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){
-+  int rc;
-+  assert( pWal->writeLock==0 );
-+  assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 );
- 
--/* A bunch of assert() statements to check the transaction state variables
--** of handle p (type Btree*) are internally consistent.
--*/
--#define btreeIntegrity(p) \
--  assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \
--  assert( p->pBt->inTransaction>=p->inTrans ); 
-+  /* pWal->readLock is usually set, but might be -1 if there was a 
-+  ** prior error while attempting to acquire are read-lock. This cannot 
-+  ** happen if the connection is actually in exclusive mode (as no xShmLock
-+  ** locks are taken in this case). Nor should the pager attempt to
-+  ** upgrade to exclusive-mode following such an error.
-+  */
-+  assert( pWal->readLock>=0 || pWal->lockError );
-+  assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) );
++/*
++** This is the xFilter implementation for the virtual table.
++*/
++static int fts5VocabFilterMethod(
++  sqlite3_vtab_cursor *pCursor,   /* The cursor used for this query */
++  int idxNum,                     /* Strategy index */
++  const char *zUnused,            /* Unused */
++  int nUnused,                    /* Number of elements in apVal */
++  sqlite3_value **apVal           /* Arguments for the indexing scheme */
++){
++  Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
++  int rc = SQLITE_OK;
++
++  int iVal = 0;
++  int f = FTS5INDEX_QUERY_SCAN;
++  const char *zTerm = 0;
++  int nTerm = 0;
 +
-+  if( op==0 ){
-+    if( pWal->exclusiveMode ){
-+      pWal->exclusiveMode = 0;
-+      if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){
-+        pWal->exclusiveMode = 1;
++  sqlite3_value *pEq = 0;
++  sqlite3_value *pGe = 0;
++  sqlite3_value *pLe = 0;
++
++  UNUSED_PARAM2(zUnused, nUnused);
++
++  fts5VocabResetCursor(pCsr);
++  if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++];
++  if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++];
++  if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
++
++  if( pEq ){
++    zTerm = (const char *)sqlite3_value_text(pEq);
++    nTerm = sqlite3_value_bytes(pEq);
++    f = 0;
++  }else{
++    if( pGe ){
++      zTerm = (const char *)sqlite3_value_text(pGe);
++      nTerm = sqlite3_value_bytes(pGe);
++    }
++    if( pLe ){
++      const char *zCopy = (const char *)sqlite3_value_text(pLe);
++      pCsr->nLeTerm = sqlite3_value_bytes(pLe);
++      pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1);
++      if( pCsr->zLeTerm==0 ){
++        rc = SQLITE_NOMEM;
++      }else{
++        memcpy(pCsr->zLeTerm, zCopy, pCsr->nLeTerm+1);
 +      }
-+      rc = pWal->exclusiveMode==0;
-+    }else{
-+      /* Already in locking_mode=NORMAL */
-+      rc = 0;
 +    }
-+  }else if( op>0 ){
-+    assert( pWal->exclusiveMode==0 );
-+    assert( pWal->readLock>=0 );
-+    walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
-+    pWal->exclusiveMode = 1;
-+    rc = 1;
-+  }else{
-+    rc = pWal->exclusiveMode==0;
 +  }
++
++
++  if( rc==SQLITE_OK ){
++    rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
++  }
++  if( rc==SQLITE_OK ){
++    rc = fts5VocabNextMethod(pCursor);
++  }
++
 +  return rc;
 +}
- 
++
 +/* 
-+** Return true if the argument is non-NULL and the WAL module is using
-+** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
-+** WAL module is using shared-memory, return false. 
++** This is the xEof method of the virtual table. SQLite calls this 
++** routine to find out if it has reached the end of a result set.
 +*/
-+SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){
-+  return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
++static int fts5VocabEofMethod(sqlite3_vtab_cursor *pCursor){
++  Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
++  return pCsr->bEof;
 +}
- 
-+#ifdef SQLITE_ENABLE_ZIPVFS
- /*
--** The ISAUTOVACUUM macro is used within balance_nonroot() to determine
--** if the database supports auto-vacuum or not. Because it is used
--** within an expression that is an argument to another macro 
--** (sqliteMallocRaw), it is not possible to use conditional compilation.
--** So, this macro is defined instead.
-+** If the argument is not NULL, it points to a Wal object that holds a
-+** read-lock. This function returns the database page-size if it is known,
-+** or zero if it is not (or if pWal is NULL).
- */
--#ifndef SQLITE_OMIT_AUTOVACUUM
--#define ISAUTOVACUUM (pBt->autoVacuum)
--#else
--#define ISAUTOVACUUM 0
-+SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
-+  assert( pWal==0 || pWal->readLock>=0 );
-+  return (pWal ? pWal->szPage : 0);
-+}
- #endif
- 
-+#endif /* #ifndef SQLITE_OMIT_WAL */
- 
-+/************** End of wal.c *************************************************/
-+/************** Begin file btmutex.c *****************************************/
- /*
--** This structure is passed around through all the sanity checking routines
--** in order to keep track of some global state information.
-+** 2007 August 27
- **
--** The aRef[] array is allocated so that there is 1 bit for each page in
--** the database. As the integrity-check proceeds, for each page used in
--** the database the corresponding bit is set. This allows integrity-check to 
--** detect pages that are used twice and orphaned pages (both of which 
--** indicate corruption).
--*/
--typedef struct IntegrityCk IntegrityCk;
--struct IntegrityCk {
--  BtShared *pBt;    /* The tree being checked out */
--  Pager *pPager;    /* The associated pager.  Also accessible by pBt->pPager */
--  u8 *aPgRef;       /* 1 bit per page in the db (see above) */
--  Pgno nPage;       /* Number of pages in the database */
--  int mxErr;        /* Stop accumulating errors when this reaches zero */
--  int nErr;         /* Number of messages written to zErrMsg so far */
--  int mallocFailed; /* A memory allocation error has occurred */
--  const char *zPfx; /* Error message prefix */
--  int v1, v2;       /* Values for up to two %d fields in zPfx */
--  StrAccum errMsg;  /* Accumulate the error message text here */
--};
--
--/*
--** Routines to read or write a two- and four-byte big-endian integer values.
++
++static int fts5VocabColumnMethod(
++  sqlite3_vtab_cursor *pCursor,   /* Cursor to retrieve value from */
++  sqlite3_context *pCtx,          /* Context for sqlite3_result_xxx() calls */
++  int iCol                        /* Index of column to read value from */
++){
++  Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
++  int eDetail = pCsr->pConfig->eDetail;
++  int eType = ((Fts5VocabTable*)(pCursor->pVtab))->eType;
++  i64 iVal = 0;
++
++  if( iCol==0 ){
++    sqlite3_result_text(
++        pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT
++    );
++  }else if( eType==FTS5_VOCAB_COL ){
++    assert( iCol==1 || iCol==2 || iCol==3 );
++    if( iCol==1 ){
++      if( eDetail!=FTS5_DETAIL_NONE ){
++        const char *z = pCsr->pConfig->azCol[pCsr->iCol];
++        sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
++      }
++    }else if( iCol==2 ){
++      iVal = pCsr->aDoc[pCsr->iCol];
++    }else{
++      iVal = pCsr->aCnt[pCsr->iCol];
++    }
++  }else{
++    assert( iCol==1 || iCol==2 );
++    if( iCol==1 ){
++      iVal = pCsr->aDoc[0];
++    }else{
++      iVal = pCsr->aCnt[0];
++    }
++  }
++
++  if( iVal>0 ) sqlite3_result_int64(pCtx, iVal);
++  return SQLITE_OK;
++}
++
++/* 
++** This is the xRowid method. The SQLite core calls this routine to
++** retrieve the rowid for the current row of the result set. The
++** rowid should be written to *pRowid.
++*/
++static int fts5VocabRowidMethod(
++  sqlite3_vtab_cursor *pCursor, 
++  sqlite_int64 *pRowid
++){
++  Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
++  *pRowid = pCsr->rowid;
++  return SQLITE_OK;
++}
++
++static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){
++  static const sqlite3_module fts5Vocab = {
++    /* iVersion      */ 2,
++    /* xCreate       */ fts5VocabCreateMethod,
++    /* xConnect      */ fts5VocabConnectMethod,
++    /* xBestIndex    */ fts5VocabBestIndexMethod,
++    /* xDisconnect   */ fts5VocabDisconnectMethod,
++    /* xDestroy      */ fts5VocabDestroyMethod,
++    /* xOpen         */ fts5VocabOpenMethod,
++    /* xClose        */ fts5VocabCloseMethod,
++    /* xFilter       */ fts5VocabFilterMethod,
++    /* xNext         */ fts5VocabNextMethod,
++    /* xEof          */ fts5VocabEofMethod,
++    /* xColumn       */ fts5VocabColumnMethod,
++    /* xRowid        */ fts5VocabRowidMethod,
++    /* xUpdate       */ 0,
++    /* xBegin        */ 0,
++    /* xSync         */ 0,
++    /* xCommit       */ 0,
++    /* xRollback     */ 0,
++    /* xFindFunction */ 0,
++    /* xRename       */ 0,
++    /* xSavepoint    */ 0,
++    /* xRelease      */ 0,
++    /* xRollbackTo   */ 0,
++  };
++  void *p = (void*)pGlobal;
++
++  return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
++}
++
++
++
++
++    
++#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
++
++/************** End of fts5.c ************************************************/
++/************** Begin file stmt.c ********************************************/
++/*
++** 2017-05-31
++**
 +** The author disclaims copyright to this source code.  In place of
 +** a legal notice, here is a blessing:
 +**
@@ -43865,154 +127406,291 @@
 +**
 +*************************************************************************
 +**
-+** This file contains code used to implement mutexes on Btree objects.
-+** This code really belongs in btree.c.  But btree.c is getting too
-+** big and we want to break it down some.  This packaged seemed like
-+** a good breakout.
- */
--#define get2byte(x)   ((x)[0]<<8 | (x)[1])
--#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v))
--#define get4byte sqlite3Get4byte
--#define put4byte sqlite3Put4byte
--
--/************** End of btreeInt.h ********************************************/
--/************** Continuing where we left off in btmutex.c ********************/
- #ifndef SQLITE_OMIT_SHARED_CACHE
- #if SQLITE_THREADSAFE
- 
-@@ -98030,10 +101008,24 @@
- */
- SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
-   int rc = sqlite3_overload_function(db, "MATCH", 2);
-+/* BEGIN SQLCIPHER */
-+#ifdef SQLITE_HAS_CODEC
-+#ifndef OMIT_EXPORT
-+  extern void sqlcipher_exportFunc(sqlite3_context *, int, sqlite3_value **);
-+#endif
-+#endif
-+/* END SQLCIPHER */
-   assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
-   if( rc==SQLITE_NOMEM ){
-     db->mallocFailed = 1;
-   }
-+/* BEGIN SQLCIPHER */
-+#ifdef SQLITE_HAS_CODEC
-+#ifndef OMIT_EXPORT
-+  sqlite3CreateFunc(db, "sqlcipher_export", 1, SQLITE_TEXT, 0, sqlcipher_exportFunc, 0, 0, 0);
-+#endif
-+#endif
-+/* END SQLCIPHER */
- }
- 
- /*
-@@ -103838,24 +106830,6 @@
-   return azModeName[eMode];
- }
- 
--static char *gdauniqueFuncName (FuncDef *func)
--{
--      char *sname;
--      unsigned int order = 0;
--      FuncDef *n;
--      int size;
--      for (n = func->pNext; n; n = n->pNext)
--              order++;
--
--      size = strlen (func->zName) + 25;
--      sname = sqlite3_malloc (sizeof (char) * size);
--      if (func->nArg < 0)
--              snprintf (sname, size-1, "%s_ANY_%u", func->zName, order);
--      else
--              snprintf (sname, size-1, "%s_%d_%u", func->zName, func->nArg, order);
--      return sname;
--}
--
- /*
- ** Process a pragma statement.  
- **
-@@ -103890,6 +106864,11 @@
-   Db *pDb;                     /* The specific database being pragmaed */
-   Vdbe *v = sqlite3GetVdbe(pParse);  /* Prepared statement */
-   const struct sPragmaNames *pPragma;
-+/* BEGIN SQLCIPHER */
-+#ifdef SQLITE_HAS_CODEC
-+  extern int sqlcipher_codec_pragma(sqlite3*, int, Parse *, const char *, const char *);
++** This file demonstrates an eponymous virtual table that returns information
++** about all prepared statements for the database connection.
++**
++** Usage example:
++**
++**     .load ./stmt
++**     .mode line
++**     .header on
++**     SELECT * FROM stmt;
++*/
++#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB)
++#if !defined(SQLITEINT_H)
++/* #include "sqlite3ext.h" */
 +#endif
-+/* END SQLCIPHER */
- 
-   if( v==0 ) return;
-   sqlite3VdbeRunOnlyOnce(v);
-@@ -103961,8 +106940,18 @@
-     }
-     pParse->nErr++;
-     pParse->rc = rc;
++SQLITE_EXTENSION_INIT1
++/* #include <assert.h> */
++/* #include <string.h> */
 +
-+    goto pragma_out;
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++
++/* stmt_vtab is a subclass of sqlite3_vtab which will
++** serve as the underlying representation of a stmt virtual table
++*/
++typedef struct stmt_vtab stmt_vtab;
++struct stmt_vtab {
++  sqlite3_vtab base;  /* Base class - must be first */
++  sqlite3 *db;        /* Database connection for this stmt vtab */
++};
++
++/* stmt_cursor is a subclass of sqlite3_vtab_cursor which will
++** serve as the underlying representation of a cursor that scans
++** over rows of the result
++*/
++typedef struct stmt_cursor stmt_cursor;
++struct stmt_cursor {
++  sqlite3_vtab_cursor base;  /* Base class - must be first */
++  sqlite3 *db;               /* Database connection for this cursor */
++  sqlite3_stmt *pStmt;       /* Statement cursor is currently pointing at */
++  sqlite3_int64 iRowid;      /* The rowid */
++};
++
++/*
++** The stmtConnect() method is invoked to create a new
++** stmt_vtab that describes the stmt virtual table.
++**
++** Think of this routine as the constructor for stmt_vtab objects.
++**
++** All this routine needs to do is:
++**
++**    (1) Allocate the stmt_vtab object and initialize all fields.
++**
++**    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
++**        result set of queries against stmt will look like.
++*/
++static int stmtConnect(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  stmt_vtab *pNew;
++  int rc;
++
++/* Column numbers */
++#define STMT_COLUMN_SQL     0   /* SQL for the statement */
++#define STMT_COLUMN_NCOL    1   /* Number of result columns */
++#define STMT_COLUMN_RO      2   /* True if read-only */
++#define STMT_COLUMN_BUSY    3   /* True if currently busy */
++#define STMT_COLUMN_NSCAN   4   /* SQLITE_STMTSTATUS_FULLSCAN_STEP */
++#define STMT_COLUMN_NSORT   5   /* SQLITE_STMTSTATUS_SORT */
++#define STMT_COLUMN_NAIDX   6   /* SQLITE_STMTSTATUS_AUTOINDEX */
++#define STMT_COLUMN_NSTEP   7   /* SQLITE_STMTSTATUS_VM_STEP */
++#define STMT_COLUMN_REPREP  8   /* SQLITE_STMTSTATUS_REPREPARE */
++#define STMT_COLUMN_RUN     9   /* SQLITE_STMTSTATUS_RUN */
++#define STMT_COLUMN_MEM    10   /* SQLITE_STMTSTATUS_MEMUSED */
++
++
++  rc = sqlite3_declare_vtab(db,
++     "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep,"
++                    "reprep,run,mem)");
++  if( rc==SQLITE_OK ){
++    pNew = sqlite3_malloc( sizeof(*pNew) );
++    *ppVtab = (sqlite3_vtab*)pNew;
++    if( pNew==0 ) return SQLITE_NOMEM;
++    memset(pNew, 0, sizeof(*pNew));
++    pNew->db = db;
 +  }
++  return rc;
++}
 +
-+/* BEGIN SQLCIPHER */
-+#ifdef SQLITE_HAS_CODEC
-+  if(sqlcipher_codec_pragma(db, iDb, pParse, zLeft, zRight)) { 
-+    /* sqlcipher_codec_pragma executes internal */
-     goto pragma_out;
-   }
++/*
++** This method is the destructor for stmt_cursor objects.
++*/
++static int stmtDisconnect(sqlite3_vtab *pVtab){
++  sqlite3_free(pVtab);
++  return SQLITE_OK;
++}
++
++/*
++** Constructor for a new stmt_cursor object.
++*/
++static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
++  stmt_cursor *pCur;
++  pCur = sqlite3_malloc( sizeof(*pCur) );
++  if( pCur==0 ) return SQLITE_NOMEM;
++  memset(pCur, 0, sizeof(*pCur));
++  pCur->db = ((stmt_vtab*)p)->db;
++  *ppCursor = &pCur->base;
++  return SQLITE_OK;
++}
++
++/*
++** Destructor for a stmt_cursor.
++*/
++static int stmtClose(sqlite3_vtab_cursor *cur){
++  sqlite3_free(cur);
++  return SQLITE_OK;
++}
++
++
++/*
++** Advance a stmt_cursor to its next row of output.
++*/
++static int stmtNext(sqlite3_vtab_cursor *cur){
++  stmt_cursor *pCur = (stmt_cursor*)cur;
++  pCur->iRowid++;
++  pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt);
++  return SQLITE_OK;
++}
++
++/*
++** Return values of columns for the row at which the stmt_cursor
++** is currently pointing.
++*/
++static int stmtColumn(
++  sqlite3_vtab_cursor *cur,   /* The cursor */
++  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
++  int i                       /* Which column to return */
++){
++  stmt_cursor *pCur = (stmt_cursor*)cur;
++  switch( i ){
++    case STMT_COLUMN_SQL: {
++      sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT);
++      break;
++    }
++    case STMT_COLUMN_NCOL: {
++      sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt));
++      break;
++    }
++    case STMT_COLUMN_RO: {
++      sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt));
++      break;
++    }
++    case STMT_COLUMN_BUSY: {
++      sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
++      break;
++    }
++    case STMT_COLUMN_MEM: {
++      i = SQLITE_STMTSTATUS_MEMUSED + 
++            STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
++      /* Fall thru */
++    }
++    case STMT_COLUMN_NSCAN:
++    case STMT_COLUMN_NSORT:
++    case STMT_COLUMN_NAIDX:
++    case STMT_COLUMN_NSTEP:
++    case STMT_COLUMN_REPREP:
++    case STMT_COLUMN_RUN: {
++      sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt,
++                      i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0));
++      break;
++    }
++  }
++  return SQLITE_OK;
++}
++
++/*
++** Return the rowid for the current row.  In this implementation, the
++** rowid is the same as the output value.
++*/
++static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
++  stmt_cursor *pCur = (stmt_cursor*)cur;
++  *pRowid = pCur->iRowid;
++  return SQLITE_OK;
++}
++
++/*
++** Return TRUE if the cursor has been moved off of the last
++** row of output.
++*/
++static int stmtEof(sqlite3_vtab_cursor *cur){
++  stmt_cursor *pCur = (stmt_cursor*)cur;
++  return pCur->pStmt==0;
++}
++
++/*
++** This method is called to "rewind" the stmt_cursor object back
++** to the first row of output.  This method is always called at least
++** once prior to any call to stmtColumn() or stmtRowid() or 
++** stmtEof().
++*/
++static int stmtFilter(
++  sqlite3_vtab_cursor *pVtabCursor, 
++  int idxNum, const char *idxStr,
++  int argc, sqlite3_value **argv
++){
++  stmt_cursor *pCur = (stmt_cursor *)pVtabCursor;
++  pCur->pStmt = 0;
++  pCur->iRowid = 0;
++  return stmtNext(pVtabCursor);
++}
++
++/*
++** SQLite will invoke this method one or more times while planning a query
++** that uses the stmt virtual table.  This routine needs to create
++** a query plan for each invocation and compute an estimated cost for that
++** plan.
++*/
++static int stmtBestIndex(
++  sqlite3_vtab *tab,
++  sqlite3_index_info *pIdxInfo
++){
++  pIdxInfo->estimatedCost = (double)500;
++  pIdxInfo->estimatedRows = 500;
++  return SQLITE_OK;
++}
++
++/*
++** This following structure defines all the methods for the 
++** stmt virtual table.
++*/
++static sqlite3_module stmtModule = {
++  0,                         /* iVersion */
++  0,                         /* xCreate */
++  stmtConnect,               /* xConnect */
++  stmtBestIndex,             /* xBestIndex */
++  stmtDisconnect,            /* xDisconnect */
++  0,                         /* xDestroy */
++  stmtOpen,                  /* xOpen - open a cursor */
++  stmtClose,                 /* xClose - close a cursor */
++  stmtFilter,                /* xFilter - configure scan constraints */
++  stmtNext,                  /* xNext - advance a cursor */
++  stmtEof,                   /* xEof - check for end of scan */
++  stmtColumn,                /* xColumn - read data */
++  stmtRowid,                 /* xRowid - read data */
++  0,                         /* xUpdate */
++  0,                         /* xBegin */
++  0,                         /* xSync */
++  0,                         /* xCommit */
++  0,                         /* xRollback */
++  0,                         /* xFindMethod */
++  0,                         /* xRename */
++  0,                         /* xSavepoint */
++  0,                         /* xRelease */
++  0,                         /* xRollbackTo */
++};
++
++#endif /* SQLITE_OMIT_VIRTUALTABLE */
++
++SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3 *db){
++  int rc = SQLITE_OK;
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  rc = sqlite3_create_module(db, "sqlite_stmt", &stmtModule, 0);
 +#endif
-+/* END SQLCIPHER */  
- 
-   /* Locate the pragma in the lookup table */
-   lwr = 0;
-@@ -104602,54 +107591,6 @@
- 
- #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
-   /*
--  **   PRAGMA proc_list
--  **
--  ** Return a single row for each procedure, the returned data set are:
--  **
--  ** name:         Procedure name
--  ** is_aggregate: True is procedure is an aggregate
--  ** nargs:        Number of arguments of the procedure, or -1 if unlimited
--  ** spe_name:     Specific name (unique procedure name)
--  */
--  if( sqlite3StrICmp(zLeft, "proc_list")==0 ){
--    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
--
--    sqlite3VdbeSetNumCols(v, 4);
--    pParse->nMem = 4;
--    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "name", SQLITE_STATIC);
--    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "is_aggregate", SQLITE_STATIC);
--    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "nargs", SQLITE_STATIC);
--    sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "spe_name", SQLITE_STATIC);
--    int j;
--    for(j=0; j<ArraySize(db->aFunc.a); j++){
--      FuncDef *func;
--      for (func =db->aFunc.a[j]; func; func = func->pNext) {
--      char *sname;
--      sname = gdauniqueFuncName (func);
--      sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
--      sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
--      sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
--      sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, sname, 0);
--      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
--      sqlite3_free (sname);
--      }
--    }
--    for(j=0; j<ArraySize(sqlite3GlobalFunctions.a); j++){
--      FuncDef *func;
--      for (func =sqlite3GlobalFunctions.a[j]; func; func = func->pNext) {
--      char *sname;
--      sname = gdauniqueFuncName (func);
--      sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
--      sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
--      sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
--      sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, sname, 0);
--      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
--      sqlite3_free (sname);
--      }
--    }
--  }else
--
-- /*
-   **   PRAGMA table_info(<table>)
-   **
-   ** Return a single row for each column of the named table. The columns of
++  return rc;
++}
++
++#ifndef SQLITE_CORE
++#ifdef _WIN32
++__declspec(dllexport)
++#endif
++SQLITE_API int sqlite3_stmt_init(
++  sqlite3 *db, 
++  char **pzErrMsg, 
++  const sqlite3_api_routines *pApi
++){
++  int rc = SQLITE_OK;
++  SQLITE_EXTENSION_INIT2(pApi);
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  rc = sqlite3StmtVtabInit(db);
++#endif
++  return rc;
++}
++#endif /* SQLITE_CORE */
++#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
++
++/************** End of stmt.c ************************************************/


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